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 Report
.Error (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 Report
.Error (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);