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;
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)
138 string full_name = String.Format ("{0}.{1}", name_space, name);
140 CheckExists (full_name);
142 ClassDef klass = pefile.AddClass (attr, name_space, name);
143 AddDefined (full_name, klass, location);
148 public ClassDef AddDefinition (string name_space, string name,
149 TypeAttr attr, Class parent, Location location)
151 string full_name = String.Format ("{0}.{1}", name_space, name);
153 CheckExists (full_name);
155 ClassDef klass = pefile.AddClass (attr, name_space, name, parent);
156 AddDefined (full_name, klass, location);
162 /// When there is no code left to compile, check to make sure referenced types where defined
163 /// TODO: Proper error reporting
165 public void CheckForUndefined ()
167 foreach (DictionaryEntry dic_entry in table) {
168 ClassTableItem table_item = (ClassTableItem) dic_entry.Value;
169 if (table_item.CheckDefined ())
171 throw new Exception (String.Format ("Type: {0} is not defined.", dic_entry.Key));
176 /// If a type is allready defined throw an Error
178 protected void CheckExists (string full_name)
180 ClassTableItem item = table[full_name] as ClassTableItem;
182 if ((item != null) && (item.Defined)) {
183 throw new Exception (String.Format ("Class: {0} defined in multiple locations.",
188 protected void AddDefined (string full_name, ClassDef klass, Location location)
190 if (table.Contains (full_name))
193 ClassTableItem item = new ClassTableItem (klass, location);
196 table[full_name] = item;
199 protected void AddReference (string full_name, ClassDef klass, Location location)
201 if (table.Contains (full_name))
204 ClassTableItem item = new ClassTableItem (klass, location);
206 table[full_name] = item;
209 protected void GetNameAndNamespace (string full_name,
210 out string name_space, out string name) {
212 int last_dot = full_name.LastIndexOf ('.');
215 name_space = String.Empty;
220 name_space = full_name.Substring (0, last_dot);
221 name = full_name.Substring (last_dot + 1);