dlr bug
[mcs.git] / ilasm / codegen / ClassTable.cs
blob0c2b5adcacaeb63d6fc29dc9fa097ccfaa4401a2
1 //
2 // Mono.ILASM.ClassTable.cs
3 //
4 // Author(s):
5 // Jackson Harper (Jackson@LatitudeGeo.com)
6 //
7 // (C) 2003 Jackson Harper, All rights reserved
8 //
10 using PEAPI;
11 using System;
12 using System.Collections;
14 namespace Mono.ILASM {
16 public class ClassTable {
18 private class ClassTableItem {
20 private static readonly int DefinedFlag = 2;
22 private int flags;
24 public ArrayList LocationList;
25 public ClassDef Class;
26 public MethodTable method_table;
27 public FieldTable field_table;
29 public ClassTableItem (ClassDef klass, Location location)
31 flags = 0;
32 Class = klass;
33 LocationList = new ArrayList ();
34 LocationList.Add (location);
35 method_table = new MethodTable (klass);
36 field_table = new FieldTable (klass);
39 public bool Defined {
40 get { return ((flags & DefinedFlag) != 0); }
41 set {
42 if (value)
43 flags |= DefinedFlag;
44 else
45 flags ^= DefinedFlag;
49 public bool CheckDefined ()
51 if (!Defined)
52 return false;
54 if (!FieldTable.CheckDefined ())
55 return false;
57 if (!MethodTable.CheckDefined ())
58 return false;
60 return true;
63 public MethodTable MethodTable {
64 get { return method_table; }
67 public FieldTable FieldTable {
68 get { return field_table; }
73 protected readonly TypeAttr DefaultAttr;
74 protected Hashtable table;
75 protected PEFile pefile;
77 public ClassTable (PEFile pefile)
79 DefaultAttr = TypeAttr.Public;
80 this.pefile = pefile;
81 table = new Hashtable ();
84 public Class Get (string full_name)
86 ClassTableItem item = table[full_name] as ClassTableItem;
88 if (item == null)
89 return null;
91 return item.Class;
94 public Class GetReference (string full_name, Location location)
96 ClassTableItem item = table[full_name] as ClassTableItem;
98 if (item != null) {
99 item.LocationList.Add (location);
100 return item.Class;
103 string name_space, name;
104 GetNameAndNamespace (full_name, out name_space, out name);
105 ClassDef klass = pefile.AddClass (DefaultAttr, name_space, name);
106 AddReference (full_name, klass, location);
108 return klass;
111 public MethodTable GetMethodTable (string full_name, Location location)
113 ClassTableItem item = table[full_name] as ClassTableItem;
115 if (item == null) {
116 GetReference (full_name, location);
117 return GetMethodTable (full_name, location);
120 return item.MethodTable;
123 public FieldTable GetFieldTable (string full_name, Location location)
125 ClassTableItem item = table[full_name] as ClassTableItem;
127 if (item == null) {
128 GetReference (full_name, location);
129 return GetFieldTable (full_name, location);
132 return item.FieldTable;
135 public ClassDef AddDefinition (string name_space, string name,
136 TypeAttr attr, Location location)
138 string full_name;
140 if (name_space != null)
141 full_name = String.Format ("{0}.{1}", name_space, name);
142 else
143 full_name = name;
145 ClassTableItem item = (ClassTableItem) table[full_name];
147 if (item == null) {
148 ClassDef klass = pefile.AddClass (attr, name_space, name);
149 AddDefined (full_name, klass, location);
150 return klass;
153 item.Class.AddAttribute (attr);
154 item.Defined = true;
156 return item.Class;
159 public ClassDef AddDefinition (string name_space, string name,
160 TypeAttr attr, Class parent, Location location)
162 string full_name;
164 if (name_space != null)
165 full_name = String.Format ("{0}.{1}", name_space, name);
166 else
167 full_name = name;
169 ClassTableItem item = (ClassTableItem) table[full_name];
171 if (item == null) {
172 ClassDef klass = pefile.AddClass (attr, name_space, name, parent);
173 AddDefined (full_name, klass, location);
174 return klass;
177 /// TODO: Need to set parent, will need to modify PEAPI for this.
178 item.Class.AddAttribute (attr);
179 item.Defined = true;
181 return item.Class;
184 /// <summary>
185 /// When there is no code left to compile, check to make sure referenced types where defined
186 /// TODO: Proper error reporting
187 /// </summary>
188 public void CheckForUndefined ()
190 foreach (DictionaryEntry dic_entry in table) {
191 ClassTableItem table_item = (ClassTableItem) dic_entry.Value;
192 if (table_item.CheckDefined ())
193 continue;
194 Report.Error (String.Format ("Type: {0} is not defined.", dic_entry.Key));
198 /// <summary>
199 /// If a type is allready defined throw an Error
200 /// </summary>
201 protected void CheckExists (string full_name)
203 ClassTableItem item = table[full_name] as ClassTableItem;
205 if ((item != null) && (item.Defined)) {
206 Report.Error (String.Format ("Class: {0} defined in multiple locations.",
207 full_name));
211 protected void AddDefined (string full_name, ClassDef klass, Location location)
213 if (table.Contains (full_name))
214 return;
216 ClassTableItem item = new ClassTableItem (klass, location);
217 item.Defined = true;
219 table[full_name] = item;
222 protected void AddReference (string full_name, ClassDef klass, Location location)
224 if (table.Contains (full_name))
225 return;
227 ClassTableItem item = new ClassTableItem (klass, location);
229 table[full_name] = item;
232 public static void GetNameAndNamespace (string full_name,
233 out string name_space, out string name) {
235 int last_dot = full_name.LastIndexOf ('.');
237 if (last_dot < 0) {
238 name_space = String.Empty;
239 name = full_name;
240 return;
243 name_space = full_name.Substring (0, last_dot);
244 name = full_name.Substring (last_dot + 1);