Merge pull request #4248 from Unity-Technologies/boehm-gc-alloc-fixed
[mono.git] / mcs / class / Mono.Debugger.Soft / Mono.Debugger.Soft / AssemblyMirror.cs
1 using System;
2 using System.Reflection;
3 using Mono.Debugger;
4 using Mono.Cecil;
5 using System.Collections.Generic;
6
7 namespace Mono.Debugger.Soft
8 {
9         public class AssemblyMirror : Mirror
10         {
11                 string location;
12                 MethodMirror entry_point;
13                 bool entry_point_set;
14                 ModuleMirror main_module;
15                 AssemblyName aname;
16                 AssemblyDefinition meta;
17                 AppDomainMirror domain;
18                 Dictionary<string, long> typeCacheIgnoreCase = new Dictionary<string, long> (StringComparer.InvariantCultureIgnoreCase);
19                 Dictionary<string, long> typeCache = new Dictionary<string, long> ();
20
21                 internal AssemblyMirror (VirtualMachine vm, long id) : base (vm, id) {
22                 }
23
24                 public string Location {
25                         get {
26                                 if (location == null)
27                                         location = vm.conn.Assembly_GetLocation (id);
28                                 return location;
29                         }
30             }
31
32                 public MethodMirror EntryPoint {
33                         get {
34                                 if (!entry_point_set) {
35                                         long mid = vm.conn.Assembly_GetEntryPoint (id);
36
37                                         if (mid != 0)
38                                                 entry_point = vm.GetMethod (mid);
39                                         entry_point_set = true;
40                                 }
41                                 return entry_point;
42                         }
43             }
44
45                 public ModuleMirror ManifestModule {
46                         get {
47                                 if (main_module == null) {
48                                         main_module = vm.GetModule (vm.conn.Assembly_GetManifestModule (id));
49                                 }
50                                 return main_module;
51                         }
52                 }
53
54                 // Since Protocol version 2.45
55                 public AppDomainMirror Domain {
56                         get {
57                                 if (domain == null) {
58                                         vm.CheckProtocolVersion (2, 45);
59                                         domain = vm.GetDomain (vm.conn.Assembly_GetIdDomain (id));
60                                 }
61                                 return domain;
62                         }
63                 }
64
65                 public virtual AssemblyName GetName () {
66                         if (aname == null) {
67                                 string name = vm.conn.Assembly_GetName (id);
68                                 aname = new AssemblyName (name);
69                         }
70                         return aname;
71                 }
72
73                 public ObjectMirror GetAssemblyObject () {
74                         return vm.GetObject (vm.conn.Assembly_GetObject (id));
75                 }
76
77                 public TypeMirror GetType (string name, bool throwOnError, bool ignoreCase)
78                 {
79                         if (name == null)
80                                 throw new ArgumentNullException ("name");
81                         if (name.Length == 0)
82                                 throw new ArgumentException ("name", "Name cannot be empty");
83
84                         if (throwOnError)
85                                 throw new NotImplementedException ();
86                         long typeId;
87                         if (ignoreCase) {
88                                 if (!typeCacheIgnoreCase.TryGetValue (name, out typeId)) {
89                                         typeId = vm.conn.Assembly_GetType (id, name, ignoreCase);
90                                         typeCacheIgnoreCase.Add (name, typeId);
91                                         var type = vm.GetType (typeId);
92                                         if (type != null) {
93                                                 typeCache.Add (type.FullName, typeId);
94                                         }
95                                         return type;
96                                 }
97                         } else {
98                                 if (!typeCache.TryGetValue (name, out typeId)) {
99                                         typeId = vm.conn.Assembly_GetType (id, name, ignoreCase);
100                                         typeCache.Add (name, typeId);
101                                 }
102                         }
103                         return vm.GetType (typeId);
104                 }
105
106                 public TypeMirror GetType (String name, Boolean throwOnError)
107                 {
108                         return GetType (name, throwOnError, false);
109                 }
110
111                 public TypeMirror GetType (String name) {
112                         return GetType (name, false, false);
113                 }
114
115                 /* 
116                  * An optional Cecil assembly which could be used to access metadata instead
117                  * of reading it from the debuggee.
118                  */
119                 public AssemblyDefinition Metadata {
120                         get {
121                                 return meta;
122                         }
123                         set {
124                                 if (value.MainModule.Name != ManifestModule.Name)
125                                         throw new ArgumentException ("The supplied assembly is named '" + value.MainModule.Name + "', while the assembly in the debuggee is named '" + ManifestModule.Name + "'.");
126                                 if (value.MainModule.Mvid != ManifestModule.ModuleVersionId)
127                                         throw new ArgumentException ("The supplied assembly's main module has guid '" + value.MainModule.Mvid + ", while the assembly in the debuggee has guid '" + ManifestModule.ModuleVersionId + "'.", "value");
128                                 meta = value;
129                         }
130                 }
131     }
132 }