Merge pull request #5714 from alexischr/update_bockbuild
[mono.git] / mcs / ilasm / codegen / ExternTypeRef.cs
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 //
9
10
11 using System;
12 using System.Collections;
13
14 namespace Mono.ILASM {
15
16         /// <summary>
17         /// A reference to a type in another assembly
18         /// </summary>
19         public class ExternTypeRef : BaseClassRef , IScope {
20
21                 private IScope extern_ref;
22                 private Hashtable nestedtypes_table;
23                 private Hashtable nestedclass_table;
24                 
25                 public ExternTypeRef (IScope extern_ref, string full_name, bool is_valuetype) 
26                         : this (extern_ref, full_name, is_valuetype, null, null)
27                 {
28                 }
29
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)
33                 {
34                         this.extern_ref = extern_ref;
35
36                         nestedclass_table = new Hashtable ();
37                         nestedtypes_table = new Hashtable ();
38                 }
39                 
40                 public override BaseTypeRef Clone ()
41                 {
42                         return new ExternTypeRef (extern_ref, full_name, is_valuetype, 
43                                         (ArrayList) ConversionList.Clone (), sig_mod);
44                 }
45
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;
52                         }
53                 }
54
55                 public string Name {
56                         get { return full_name + sig_mod; }
57                 }
58
59                 public IScope ExternRef {
60                         get { return extern_ref; }
61                 }
62
63                 public override void Resolve (CodeGen code_gen)
64                 {
65                         if (is_resolved)
66                                 return;
67
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);
72
73                         type = extern_ref.GetType (full_name, is_valuetype);
74                         type = Modify (code_gen, type);
75
76                         is_resolved = true;
77                 }
78
79                 protected override BaseMethodRef CreateMethodRef (BaseTypeRef ret_type, PEAPI.CallConv call_conv,
80                                 string name, BaseTypeRef[] param, int gen_param_count)
81                 {
82                         return new ExternMethodRef (this, ret_type, call_conv, name, param, gen_param_count);
83                 }
84
85                 protected override IFieldRef CreateFieldRef (BaseTypeRef ret_type, string name)
86                 {
87                         return new ExternFieldRef (this, ret_type, name);
88                 }
89
90                 public ExternTypeRef GetTypeRef (string _name, bool is_valuetype)
91                 {
92                         string first= _name;
93                         string rest = "";
94                         int slash = _name.IndexOf ('/');
95
96                         if (slash > 0) {
97                                 first = _name.Substring (0, slash);
98                                 rest = _name.Substring (slash + 1);
99                         }
100
101                         ExternTypeRef ext_typeref = nestedtypes_table [first] as ExternTypeRef;
102                         
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;
109                         }        
110                         
111                         return (rest == "" ? ext_typeref : ext_typeref.GetTypeRef (rest, is_valuetype));
112                 }
113
114                 public PEAPI.IExternRef GetExternTypeRef ()
115                 {
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;
120                 }
121
122                 public PEAPI.ClassRef GetType (string _name, bool is_valuetype)
123                 {
124                         PEAPI.ClassRef klass = nestedclass_table [_name] as PEAPI.ClassRef;
125                         
126                         if (klass != null)
127                                 return klass;
128
129                         string name_space, name;
130                         ExternTable.GetNameAndNamespace (_name, out name_space, out name);
131
132                         if (is_valuetype)
133                                 klass = (PEAPI.ClassRef) GetExternTypeRef ().AddValueClass (name_space, name);
134                         else        
135                                 klass = (PEAPI.ClassRef) GetExternTypeRef ().AddClass (name_space, name);
136
137                         nestedclass_table [_name] = klass;
138
139                         return klass;
140                 }        
141
142                 public System.Type GetReflectedType ()
143                 {
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);
149
150                                         //Type name required here, so don't use FullName
151                                         return asm.GetType (Name);
152                                 }/* else ExternModule */
153
154                         } /*else - nested type? */
155                         return null;
156                 }
157         }
158
159 }
160