Fix bug #534965.
[mcs.git] / ilasm / codegen / ExternTypeRef.cs
blob1e4d01d0cf8293cee012b369113866586213d64f
1 //
2 // Mono.ILASM.ExternTypeRef
3 //
4 // Author(s):
5 // Jackson Harper (Jackson@LatitudeGeo.com)
6 //
7 // (C) 2003 Jackson Harper, All rights reserved
8 //
11 using System;
12 using System.Collections;
14 namespace Mono.ILASM {
16 /// <summary>
17 /// A reference to a type in another assembly
18 /// </summary>
19 public class ExternTypeRef : BaseClassRef , IScope {
21 private IScope extern_ref;
22 private Hashtable nestedtypes_table;
23 private Hashtable nestedclass_table;
25 public ExternTypeRef (IScope extern_ref, string full_name, bool is_valuetype)
26 : this (extern_ref, full_name, is_valuetype, null, null)
30 private ExternTypeRef (IScope extern_ref, string full_name,
31 bool is_valuetype, ArrayList conv_list, string sig_mod)
32 : base (full_name, is_valuetype, conv_list, sig_mod)
34 this.extern_ref = extern_ref;
36 nestedclass_table = new Hashtable ();
37 nestedtypes_table = new Hashtable ();
40 public override BaseTypeRef Clone ()
42 return new ExternTypeRef (extern_ref, full_name, is_valuetype,
43 (ArrayList) ConversionList.Clone (), sig_mod);
46 public override string FullName {
47 get {
48 if (extern_ref == null)
49 return full_name + sig_mod;
50 else
51 return extern_ref.FullName + (extern_ref is ExternTypeRef ? "/" : "") + full_name + sig_mod;
55 public string Name {
56 get { return full_name + sig_mod; }
59 public IScope ExternRef {
60 get { return extern_ref; }
63 public override void Resolve (CodeGen code_gen)
65 if (is_resolved)
66 return;
68 ExternTypeRef etr = extern_ref as ExternTypeRef;
69 if (etr != null)
70 //This is a nested class, so resolve parent
71 etr.Resolve (code_gen);
73 type = extern_ref.GetType (full_name, is_valuetype);
74 type = Modify (code_gen, type);
76 is_resolved = true;
79 protected override BaseMethodRef CreateMethodRef (BaseTypeRef ret_type, PEAPI.CallConv call_conv,
80 string name, BaseTypeRef[] param, int gen_param_count)
82 return new ExternMethodRef (this, ret_type, call_conv, name, param, gen_param_count);
85 protected override IFieldRef CreateFieldRef (BaseTypeRef ret_type, string name)
87 return new ExternFieldRef (this, ret_type, name);
90 public ExternTypeRef GetTypeRef (string _name, bool is_valuetype)
92 string first= _name;
93 string rest = "";
94 int slash = _name.IndexOf ('/');
96 if (slash > 0) {
97 first = _name.Substring (0, slash);
98 rest = _name.Substring (slash + 1);
101 ExternTypeRef ext_typeref = nestedtypes_table [first] as ExternTypeRef;
103 if (ext_typeref != null) {
104 if (is_valuetype && rest == "")
105 ext_typeref.MakeValueClass ();
106 } else {
107 ext_typeref = new ExternTypeRef (this, first, is_valuetype);
108 nestedtypes_table [first] = ext_typeref;
111 return (rest == "" ? ext_typeref : ext_typeref.GetTypeRef (rest, is_valuetype));
114 public PEAPI.IExternRef GetExternTypeRef ()
116 //called by GetType for a nested type
117 //should this cant be 'modified' type, so it should
118 //be ClassRef
119 return (PEAPI.ClassRef) type;
122 public PEAPI.ClassRef GetType (string _name, bool is_valuetype)
124 PEAPI.ClassRef klass = nestedclass_table [_name] as PEAPI.ClassRef;
126 if (klass != null)
127 return klass;
129 string name_space, name;
130 ExternTable.GetNameAndNamespace (_name, out name_space, out name);
132 if (is_valuetype)
133 klass = (PEAPI.ClassRef) GetExternTypeRef ().AddValueClass (name_space, name);
134 else
135 klass = (PEAPI.ClassRef) GetExternTypeRef ().AddClass (name_space, name);
137 nestedclass_table [_name] = klass;
139 return klass;
142 public System.Type GetReflectedType ()
144 ExternRef er = extern_ref as ExternRef;
145 if (er != null) {
146 ExternAssembly ea = er as ExternAssembly;
147 if (ea != null) {
148 System.Reflection.Assembly asm = System.Reflection.Assembly.Load (ea.Name);
150 //Type name required here, so don't use FullName
151 return asm.GetType (Name);
152 }/* else ExternModule */
154 } /*else - nested type? */
155 return null;