2 // Mono.ILASM.ExternTable.cs
5 // Jackson Harper (Jackson@LatitudeGeo.com)
7 // (C) 2003 Jackson Harper, All rights reserved
11 using System.Collections;
12 using System.Reflection;
14 namespace Mono.ILASM {
16 public abstract class ExternRef : ICustomAttrTarget {
18 protected string name;
19 protected Hashtable class_table;
20 protected Hashtable typeref_table;
21 protected ArrayList customattr_list;
23 public abstract void Resolve (CodeGen codegen);
24 public abstract PEAPI.IExternRef GetExternRef ();
26 public ExternRef (string name)
29 typeref_table = new Hashtable ();
30 class_table = new Hashtable ();
33 public void AddCustomAttribute (CustomAttr customattr)
35 if (customattr_list == null)
36 customattr_list = new ArrayList ();
38 customattr_list.Add (customattr);
41 public ExternTypeRef GetTypeRef (string full_name, bool is_valuetype, ExternTable table)
43 ExternTypeRef type_ref = typeref_table [full_name] as ExternTypeRef;
48 type_ref = new ExternTypeRef (this, full_name, is_valuetype, table);
49 typeref_table [full_name] = type_ref;
54 public PEAPI.ClassRef GetType (string full_name)
56 PEAPI.ClassRef klass = class_table[full_name] as PEAPI.ClassRef;
61 string name_space, name;
62 ExternTable.GetNameAndNamespace (full_name, out name_space, out name);
64 klass = (PEAPI.ClassRef) GetExternRef ().AddClass (name_space, name);
65 class_table[full_name] = klass;
70 public PEAPI.ClassRef GetValueType (string full_name)
72 PEAPI.ClassRef klass = class_table[full_name] as PEAPI.ClassRef;
77 string name_space, name;
78 ExternTable.GetNameAndNamespace (full_name, out name_space, out name);
80 klass = (PEAPI.ClassRef) GetExternRef ().AddValueClass (name_space, name);
81 class_table[full_name] = klass;
87 public class ExternModule : ExternRef {
89 public PEAPI.ModuleRef ModuleRef;
91 public ExternModule (string name) : base (name)
95 public override void Resolve (CodeGen codegen)
97 ModuleRef = codegen.PEFile.AddExternModule (name);
98 if (customattr_list != null)
99 foreach (CustomAttr customattr in customattr_list)
100 customattr.AddTo (codegen, ModuleRef);
104 public override PEAPI.IExternRef GetExternRef ()
110 public class ExternAssembly : ExternRef {
112 public PEAPI.AssemblyRef AssemblyRef;
114 private int major, minor, build, revision;
115 private byte [] public_key;
116 private byte [] public_key_token;
117 private string locale;
118 private byte [] hash;
120 public ExternAssembly (string name, AssemblyName asmb_name) : base (name)
123 major = minor = build = revision = -1;
126 public override void Resolve (CodeGen code_gen)
128 AssemblyRef = code_gen.PEFile.AddExternAssembly (name);
130 AssemblyRef.AddVersionInfo (major, minor, build, revision);
131 if (public_key != null)
132 AssemblyRef.AddKey (public_key);
133 if (public_key_token != null)
134 AssemblyRef.AddKeyToken (public_key_token);
136 AssemblyRef.AddCulture (locale);
138 AssemblyRef.AddHash (hash);
140 if (customattr_list != null)
141 foreach (CustomAttr customattr in customattr_list)
142 customattr.AddTo (code_gen, AssemblyRef);
144 class_table = new Hashtable ();
147 public override PEAPI.IExternRef GetExternRef ()
152 public void SetVersion (int major, int minor, int build, int revision)
157 this.revision = revision;
160 public void SetPublicKey (byte [] public_key)
162 this.public_key = public_key;
165 public void SetPublicKeyToken (byte [] public_key_token)
167 this.public_key_token = public_key_token;
170 public void SetLocale (string locale)
172 this.locale = locale;
175 public void SetHash (byte [] hash)
183 public class ExternTable {
185 Hashtable assembly_table;
186 Hashtable module_table;
188 public ExternTable ()
191 string mscorlib_name = "mscorlib";
192 AssemblyName mscorlib = new AssemblyName ();
193 mscorlib.Name = mscorlib_name;
194 AddAssembly (mscorlib_name, mscorlib);
196 // Also need to alias corlib, normally corlib and
197 // mscorlib are used interchangably
198 assembly_table["corlib"] = assembly_table["mscorlib"];
201 public ExternAssembly AddAssembly (string name, AssemblyName asmb_name)
203 ExternAssembly ea = null;
205 if (assembly_table == null) {
206 assembly_table = new Hashtable ();
208 ea = assembly_table [name] as ExternAssembly;
213 ea = new ExternAssembly (name, asmb_name);
215 assembly_table [name] = ea;
220 public ExternModule AddModule (string name)
222 ExternModule em = null;
224 if (module_table == null) {
225 module_table = new Hashtable ();
227 em = module_table [name] as ExternModule;
232 em = new ExternModule (name);
234 module_table [name] = em;
239 public void Resolve (CodeGen code_gen)
241 // Assembly table is never null because we add mscorlib
242 foreach (ExternAssembly ext in assembly_table.Values)
243 ext.Resolve (code_gen);
244 if (module_table == null)
246 foreach (ExternModule ext in module_table.Values)
247 ext.Resolve (code_gen);
250 public ExternTypeRef GetTypeRef (string asmb_name, string full_name, bool is_valuetype)
252 ExternAssembly ext_asmb;
253 ext_asmb = assembly_table[asmb_name] as ExternAssembly;
255 if (ext_asmb == null)
256 throw new Exception (String.Format ("Assembly {0} not defined.", asmb_name));
258 return ext_asmb.GetTypeRef (full_name, is_valuetype, this);
261 public ExternTypeRef GetModuleTypeRef (string mod_name, string full_name, bool is_valuetype)
264 mod = module_table [mod_name] as ExternModule;
267 throw new Exception (String.Format ("Module {0} not defined.", mod_name));
269 return mod.GetTypeRef (full_name, is_valuetype, this);
272 public static void GetNameAndNamespace (string full_name,
273 out string name_space, out string name) {
275 int last_dot = full_name.LastIndexOf ('.');
278 name_space = String.Empty;
283 name_space = full_name.Substring (0, last_dot);
284 name = full_name.Substring (last_dot + 1);