2 // Mono.ILASM.ClassTable.cs
5 // Jackson Harper (Jackson@LatitudeGeo.com)
7 // (C) 2003 Jackson Harper, All rights reserved
12 using System.Collections;
14 namespace Mono.ILASM {
16 public class ClassTable {
18 private class ClassTableItem {
20 private static readonly int DefinedFlag = 2;
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)
33 LocationList = new ArrayList ();
34 LocationList.Add (location);
35 method_table = new MethodTable (klass);
36 field_table = new FieldTable (klass);
40 get { return ((flags & DefinedFlag) != 0); }
49 public bool CheckDefined ()
54 if (!FieldTable.CheckDefined ())
57 if (!MethodTable.CheckDefined ())
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;
81 table = new Hashtable ();
84 public Class Get (string full_name)
86 ClassTableItem item = table[full_name] as ClassTableItem;
94 public Class GetReference (string full_name, Location location)
96 ClassTableItem item = table[full_name] as ClassTableItem;
99 item.LocationList.Add (location);
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);
111 public MethodTable GetMethodTable (string full_name, Location location)
113 ClassTableItem item = table[full_name] as ClassTableItem;
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;
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)
140 if (name_space != null)
141 full_name = String.Format ("{0}.{1}", name_space, name);
145 ClassTableItem item = (ClassTableItem) table[full_name];
148 ClassDef klass = pefile.AddClass (attr, name_space, name);
149 AddDefined (full_name, klass, location);
153 item.Class.AddAttribute (attr);
159 public ClassDef AddDefinition (string name_space, string name,
160 TypeAttr attr, Class parent, Location location)
164 if (name_space != null)
165 full_name = String.Format ("{0}.{1}", name_space, name);
169 ClassTableItem item = (ClassTableItem) table[full_name];
172 ClassDef klass = pefile.AddClass (attr, name_space, name, parent);
173 AddDefined (full_name, klass, location);
177 /// TODO: Need to set parent, will need to modify PEAPI for this.
178 item.Class.AddAttribute (attr);
185 /// When there is no code left to compile, check to make sure referenced types where defined
186 /// TODO: Proper error reporting
188 public void CheckForUndefined ()
190 foreach (DictionaryEntry dic_entry in table) {
191 ClassTableItem table_item = (ClassTableItem) dic_entry.Value;
192 if (table_item.CheckDefined ())
194 throw new Exception (String.Format ("Type: {0} is not defined.", dic_entry.Key));
199 /// If a type is allready defined throw an Error
201 protected void CheckExists (string full_name)
203 ClassTableItem item = table[full_name] as ClassTableItem;
205 if ((item != null) && (item.Defined)) {
206 throw new Exception (String.Format ("Class: {0} defined in multiple locations.",
211 protected void AddDefined (string full_name, ClassDef klass, Location location)
213 if (table.Contains (full_name))
216 ClassTableItem item = new ClassTableItem (klass, location);
219 table[full_name] = item;
222 protected void AddReference (string full_name, ClassDef klass, Location location)
224 if (table.Contains (full_name))
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 ('.');
238 name_space = String.Empty;
243 name_space = full_name.Substring (0, last_dot);
244 name = full_name.Substring (last_dot + 1);