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;
13 using System.Security;
15 namespace Mono.ILASM {
17 public interface IScope {
18 ExternTypeRef GetTypeRef (string full_name, bool is_valuetype, ExternTable table);
19 PEAPI.ClassRef GetType (string full_name, bool is_valuetype);
22 public abstract class ExternRef : ICustomAttrTarget, IScope {
24 protected string name;
25 protected Hashtable class_table;
26 protected Hashtable typeref_table;
27 protected ArrayList customattr_list;
28 protected bool is_resolved;
30 public abstract void Resolve (CodeGen codegen);
31 public abstract PEAPI.IExternRef GetExternRef ();
33 public ExternRef (string name)
36 typeref_table = new Hashtable ();
37 class_table = new Hashtable ();
44 public void AddCustomAttribute (CustomAttr customattr)
46 if (customattr_list == null)
47 customattr_list = new ArrayList ();
49 customattr_list.Add (customattr);
52 public ExternTypeRef GetTypeRef (string full_name, bool is_valuetype, ExternTable table)
54 string first= full_name;
56 int slash = full_name.IndexOf ('/');
58 first = full_name.Substring (0, slash);
59 rest = full_name.Substring (slash + 1);
62 ExternTypeRef type_ref = typeref_table [first] as ExternTypeRef;
64 if (type_ref != null) {
65 if (is_valuetype && rest == "")
66 type_ref.MakeValueClass ();
68 type_ref = new ExternTypeRef (this, first, is_valuetype, table);
69 typeref_table [first] = type_ref;
72 return (rest == "" ? type_ref : type_ref.GetTypeRef (rest, is_valuetype, table));
75 public PEAPI.ClassRef GetType (string full_name, bool is_valuetype)
77 PEAPI.ClassRef klass = class_table[full_name] as PEAPI.ClassRef;
82 string name_space, name;
83 ExternTable.GetNameAndNamespace (full_name, out name_space, out name);
86 klass = (PEAPI.ClassRef) GetExternRef ().AddValueClass (name_space, name);
88 klass = (PEAPI.ClassRef) GetExternRef ().AddClass (name_space, name);
90 class_table [full_name] = klass;
96 public class ExternModule : ExternRef {
98 public PEAPI.ModuleRef ModuleRef;
100 public ExternModule (string name) : base (name)
104 public override void Resolve (CodeGen codegen)
109 ModuleRef = codegen.PEFile.AddExternModule (name);
110 if (customattr_list != null)
111 foreach (CustomAttr customattr in customattr_list)
112 customattr.AddTo (codegen, ModuleRef);
118 public override PEAPI.IExternRef GetExternRef ()
124 public class ExternAssembly : ExternRef, IDeclSecurityTarget {
126 public PEAPI.AssemblyRef AssemblyRef;
128 private int major, minor, build, revision;
129 private byte [] public_key;
130 private byte [] public_key_token;
131 private string locale;
132 private byte [] hash;
133 private DeclSecurity decl_sec;
135 public ExternAssembly (string name, AssemblyName asmb_name) : base (name)
138 major = minor = build = revision = -1;
141 public override void Resolve (CodeGen code_gen)
146 AssemblyRef = code_gen.PEFile.AddExternAssembly (name);
148 AssemblyRef.AddVersionInfo (major, minor, build, revision);
149 if (public_key != null)
150 AssemblyRef.AddKey (public_key);
151 if (public_key_token != null)
152 AssemblyRef.AddKeyToken (public_key_token);
154 AssemblyRef.AddCulture (locale);
156 AssemblyRef.AddHash (hash);
158 if (customattr_list != null)
159 foreach (CustomAttr customattr in customattr_list)
160 customattr.AddTo (code_gen, AssemblyRef);
162 if (decl_sec != null)
163 decl_sec.AddTo (code_gen, AssemblyRef);
165 class_table = new Hashtable ();
170 public override PEAPI.IExternRef GetExternRef ()
175 public void AddPermissionSet (PEAPI.SecurityAction sec_action, PermissionSet ps)
177 if (decl_sec == null)
178 decl_sec = new DeclSecurity ();
180 decl_sec.AddPermissionSet (sec_action, ps);
183 public void AddPermission (PEAPI.SecurityAction sec_action, IPermission iper)
185 if (decl_sec == null)
186 decl_sec = new DeclSecurity ();
188 decl_sec.AddPermission (sec_action, iper);
191 public void SetVersion (int major, int minor, int build, int revision)
196 this.revision = revision;
199 public void SetPublicKey (byte [] public_key)
201 this.public_key = public_key;
204 public void SetPublicKeyToken (byte [] public_key_token)
206 this.public_key_token = public_key_token;
209 public void SetLocale (string locale)
211 this.locale = locale;
214 public void SetHash (byte [] hash)
222 public class ExternTable {
224 Hashtable assembly_table;
225 Hashtable module_table;
228 public void AddCorlib ()
231 string mscorlib_name = "mscorlib";
232 AssemblyName mscorlib = new AssemblyName ();
233 mscorlib.Name = mscorlib_name;
234 AddAssembly (mscorlib_name, mscorlib);
236 // Also need to alias corlib, normally corlib and
237 // mscorlib are used interchangably
238 assembly_table["corlib"] = assembly_table["mscorlib"];
241 public ExternAssembly AddAssembly (string name, AssemblyName asmb_name)
243 ExternAssembly ea = null;
245 if (assembly_table == null) {
246 assembly_table = new Hashtable ();
248 ea = assembly_table [name] as ExternAssembly;
253 ea = new ExternAssembly (name, asmb_name);
255 assembly_table [name] = ea;
260 public ExternModule AddModule (string name)
262 ExternModule em = null;
264 if (module_table == null) {
265 module_table = new Hashtable ();
267 em = module_table [name] as ExternModule;
272 em = new ExternModule (name);
274 module_table [name] = em;
279 public void Resolve (CodeGen code_gen)
284 if (assembly_table != null)
285 foreach (ExternAssembly ext in assembly_table.Values)
286 ext.Resolve (code_gen);
287 if (module_table == null)
289 foreach (ExternModule ext in module_table.Values)
290 ext.Resolve (code_gen);
295 public ExternTypeRef GetTypeRef (string asmb_name, string full_name, bool is_valuetype)
297 ExternAssembly ext_asmb = null;
298 if (assembly_table == null && (asmb_name == "mscorlib" || asmb_name == "corlib"))
299 /* AddCorlib if mscorlib is being referenced but
300 we haven't encountered a ".assembly 'name'" as yet. */
302 if (assembly_table != null)
303 ext_asmb = assembly_table[asmb_name] as ExternAssembly;
305 if (ext_asmb == null)
306 throw new Exception (String.Format ("Assembly {0} not defined.", asmb_name));
308 return ext_asmb.GetTypeRef (full_name, is_valuetype, this);
311 public ExternTypeRef GetModuleTypeRef (string mod_name, string full_name, bool is_valuetype)
314 mod = module_table [mod_name] as ExternModule;
317 throw new Exception (String.Format ("Module {0} not defined.", mod_name));
319 return mod.GetTypeRef (full_name, is_valuetype, this);
322 public static void GetNameAndNamespace (string full_name,
323 out string name_space, out string name) {
325 int last_dot = full_name.LastIndexOf ('.');
328 name_space = String.Empty;
333 name_space = full_name.Substring (0, last_dot);
334 name = full_name.Substring (last_dot + 1);