2 // Mono.ILASM.ExternTypeRef
5 // Jackson Harper (Jackson@LatitudeGeo.com)
7 // (C) 2003 Jackson Harper, All rights reserved
12 using System.Collections;
14 namespace Mono.ILASM {
17 /// A reference to a type in another assembly
19 public class ExternTypeRef : ModifiableType, IClassRef, IScope {
21 private PEAPI.Type type;
22 private IScope extern_ref;
23 private string full_name;
24 private string sig_mod;
25 private bool is_valuetype;
27 private bool is_resolved;
29 private Hashtable nestedtypes_table;
30 private Hashtable nestedclass_table;
31 private Hashtable method_table;
32 private Hashtable field_table;
33 private Hashtable p_genericinst_table;
35 public ExternTypeRef (IScope extern_ref, string full_name, bool is_valuetype)
36 : this (extern_ref, full_name, is_valuetype, null, null)
40 private ExternTypeRef (IScope extern_ref, string full_name,
41 bool is_valuetype, ArrayList conv_list, string sig_mod)
43 this.extern_ref = extern_ref;
44 this.full_name = full_name;
45 this.is_valuetype = is_valuetype;
46 this.sig_mod = sig_mod;
48 nestedclass_table = new Hashtable ();
49 nestedtypes_table = new Hashtable ();
50 method_table = new Hashtable ();
51 field_table = new Hashtable ();
54 if (conv_list != null)
55 ConversionList = conv_list;
58 public IClassRef Clone ()
60 return new ExternTypeRef (extern_ref, full_name, is_valuetype,
61 (ArrayList) ConversionList.Clone (), sig_mod);
64 public GenericTypeInst GetGenericTypeInst (GenericArguments gen_args)
66 return new GenericTypeInst (this, gen_args, is_valuetype);
69 public PEAPI.Type ResolveInstance (CodeGen code_gen, GenericArguments gen_args)
71 string sig = gen_args.ToString ();
72 PEAPI.GenericTypeInst gti = null;
74 if (p_genericinst_table == null)
75 p_genericinst_table = new Hashtable ();
77 gti = p_genericinst_table [sig] as PEAPI.GenericTypeInst;
81 throw new Exception ("Can't ResolveInstance on unresolved ExternTypeRef");
83 gti = new PEAPI.GenericTypeInst (PeapiType, gen_args.Resolve (code_gen));
84 p_genericinst_table [sig] = gti;
90 public PEAPI.Type PeapiType {
94 public PEAPI.Class PeapiClass {
95 get { return type as PEAPI.Class; }
98 public string FullName {
100 if (extern_ref == null)
101 return full_name + sig_mod;
103 return extern_ref.FullName + (extern_ref is ExternTypeRef ? "/" : "") + full_name + sig_mod;
108 get { return full_name + sig_mod; }
111 public override string SigMod {
112 get { return sig_mod; }
113 set { sig_mod = value; }
116 public IScope ExternRef {
117 get { return extern_ref; }
120 public void Resolve (CodeGen code_gen)
125 ExternTypeRef etr = extern_ref as ExternTypeRef;
127 //This is a nested class, so resolve parent
128 etr.Resolve (code_gen);
130 type = extern_ref.GetType (full_name, is_valuetype);
131 type = Modify (code_gen, type);
136 public void MakeValueClass ()
141 public IMethodRef GetMethodRef (ITypeRef ret_type, PEAPI.CallConv call_conv,
142 string name, ITypeRef[] param, int gen_param_count)
144 string sig = MethodDef.CreateSignature (ret_type, name, param, gen_param_count);
145 ExternMethodRef mr = method_table [sig] as ExternMethodRef;
148 mr = new ExternMethodRef (this, ret_type, call_conv, name, param, gen_param_count);
149 method_table [sig] = mr;
155 public IFieldRef GetFieldRef (ITypeRef ret_type, string name)
157 ExternFieldRef fr = field_table [name] as ExternFieldRef;
160 fr = new ExternFieldRef (this, ret_type, name);
161 field_table [name] = fr;
167 public ExternTypeRef GetTypeRef (string _name, bool is_valuetype)
171 int slash = _name.IndexOf ('/');
174 first = _name.Substring (0, slash);
175 rest = _name.Substring (slash + 1);
178 ExternTypeRef ext_typeref = nestedtypes_table [first] as ExternTypeRef;
180 if (ext_typeref != null) {
181 if (is_valuetype && rest == "")
182 ext_typeref.MakeValueClass ();
184 ext_typeref = new ExternTypeRef (this, first, is_valuetype);
185 nestedtypes_table [first] = ext_typeref;
188 return (rest == "" ? ext_typeref : ext_typeref.GetTypeRef (rest, is_valuetype));
191 public PEAPI.IExternRef GetExternTypeRef ()
193 //called by GetType for a nested type
194 //should this cant be 'modified' type, so it should
196 return (PEAPI.ClassRef) type;
199 public PEAPI.ClassRef GetType (string _name, bool is_valuetype)
201 PEAPI.ClassRef klass = nestedclass_table [_name] as PEAPI.ClassRef;
206 string name_space, name;
207 ExternTable.GetNameAndNamespace (_name, out name_space, out name);
210 klass = (PEAPI.ClassRef) GetExternTypeRef ().AddValueClass (name_space, name);
212 klass = (PEAPI.ClassRef) GetExternTypeRef ().AddClass (name_space, name);
214 nestedclass_table [_name] = klass;
219 public System.Type GetReflectedType ()
221 ExternRef er = extern_ref as ExternRef;
223 ExternAssembly ea = er as ExternAssembly;
225 System.Reflection.Assembly asm = System.Reflection.Assembly.Load (ea.Name);
227 //Type name required here, so don't use FullName
228 return asm.GetType (Name);
229 }/* else ExternModule */
231 } /*else - nested type? */