svn path=/branches/mono-1-1-9/mcs/; revision=50439
[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 : ModifiableType, IClassRef, IScope {
20
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;
26                 private ExternTable extern_table;
27
28                 private bool is_resolved;
29
30                 private Hashtable nestedtypes_table;
31                 private Hashtable nestedclass_table;
32                 private Hashtable method_table;
33                 private Hashtable field_table;
34                 
35                 public ExternTypeRef (IScope extern_ref, string full_name,
36                                 bool is_valuetype, ExternTable extern_table)
37                 {
38                         this.extern_ref = extern_ref;
39                         this.full_name = full_name;
40                         this.is_valuetype = is_valuetype;
41                         this.extern_table = extern_table;
42                         sig_mod = String.Empty;
43
44                         nestedclass_table = new Hashtable ();
45                         nestedtypes_table = new Hashtable ();
46                         method_table = new Hashtable ();
47                         field_table = new Hashtable ();
48                         
49                         is_resolved = false;
50                 }
51
52                 private ExternTypeRef (IScope extern_ref, string full_name,
53                                 bool is_valuetype, ExternTable extern_table,
54                                 ArrayList conv_list) : this (extern_ref, full_name,
55                                                 is_valuetype, extern_table)
56                 {
57                         ConversionList = conv_list;
58                 }
59                 
60                 public ExternTypeRef Clone ()
61                 {
62                         return new ExternTypeRef (extern_ref, full_name, is_valuetype,
63                                         extern_table, (ArrayList) ConversionList.Clone ());
64                 }
65                 
66                 public PEAPI.Type PeapiType {
67                         get { return type; }
68                 }
69
70                 public PEAPI.Class PeapiClass {
71                         get { return type as PEAPI.Class; }
72                 }
73
74                 public string FullName {
75                         get { return full_name + sig_mod; }
76                 }
77
78
79                 public override string SigMod {
80                         get { return sig_mod; }
81                         set { sig_mod = value; }
82                 }
83
84                 public IScope ExternRef {
85                         get { return extern_ref; }
86                 }
87
88                 public void Resolve (CodeGen code_gen)
89                 {
90                         if (is_resolved)
91                                 return;
92
93                         ExternTypeRef etr = extern_ref as ExternTypeRef;        
94                         if (etr != null)        
95                                 //This is a nested class, so resolve parent
96                                 etr.Resolve (code_gen);
97
98                         type = extern_ref.GetType (full_name, is_valuetype);
99                         type = Modify (code_gen, type);
100
101                         is_resolved = true;
102                 }
103
104                 public void MakeValueClass ()
105                 {
106                         is_valuetype = true;
107                 }
108
109                 public IMethodRef GetMethodRef (ITypeRef ret_type, PEAPI.CallConv call_conv,
110                                 string name, ITypeRef[] param)
111                 {
112                         string sig = MethodDef.CreateSignature (ret_type, name, param);
113                         ExternMethodRef mr = method_table [sig] as ExternMethodRef;
114                         
115                         if (mr == null) {
116                                 mr = new ExternMethodRef (this, ret_type, call_conv, name, param);
117                                 method_table [sig] = mr;
118                         }
119
120                         return mr;
121                 }
122
123                 public IFieldRef GetFieldRef (ITypeRef ret_type, string name)
124                 {
125                         ExternFieldRef fr = field_table [name] as ExternFieldRef;
126
127                         if (fr == null) {
128                                 fr = new ExternFieldRef (this, ret_type, name);
129                                 field_table [name] = fr;
130                         }
131
132                         return fr;
133                 }
134
135                 public ExternTypeRef GetTypeRef (string _name, bool is_valuetype, ExternTable table)
136                 {
137                         string first= _name;
138                         string rest = "";
139                         int slash = _name.IndexOf ('/');
140
141                         if (slash > 0) {
142                                 first = _name.Substring (0, slash);
143                                 rest = _name.Substring (slash + 1);
144                         }
145
146                         ExternTypeRef ext_typeref = nestedtypes_table [first] as ExternTypeRef;
147                         
148                         if (ext_typeref != null) {
149                                 if (is_valuetype && rest == "")
150                                         ext_typeref.MakeValueClass ();
151                         } else {
152                                 ext_typeref = new ExternTypeRef (this, first, is_valuetype, table);
153                                 nestedtypes_table [first] = ext_typeref;
154                         }        
155                         
156                         return (rest == "" ? ext_typeref : ext_typeref.GetTypeRef (rest, is_valuetype, table));
157                 }
158
159                 public PEAPI.IExternRef GetExternTypeRef ()
160                 {
161                         //called by GetType for a nested type
162                         //should this cant be 'modified' type, so it should
163                         //be ClassRef 
164                         return (PEAPI.ClassRef) type;
165                 }
166
167                 public PEAPI.ClassRef GetType (string _name, bool is_valuetype)
168                 {
169                         PEAPI.ClassRef klass = nestedclass_table [_name] as PEAPI.ClassRef;
170                         
171                         if (klass != null)
172                                 return klass;
173
174                         string name_space, name;
175                         ExternTable.GetNameAndNamespace (_name, out name_space, out name);
176
177                         if (is_valuetype)
178                                 klass = (PEAPI.ClassRef) GetExternTypeRef ().AddValueClass (name_space, name);
179                         else        
180                                 klass = (PEAPI.ClassRef) GetExternTypeRef ().AddClass (name_space, name);
181
182                         nestedclass_table [_name] = klass;
183
184                         return klass;
185                 }        
186         }
187
188 }
189