//
// Contains loaded assemblies and our generated code as we go.
//
- TypeManager type_manager;
+ public TypeManager TypeManager;
//
// The System.Reflection.Emit CodeGenerator
//
- CilCodeGen cg;
+ CodeGen cg;
//
// The module builder pointer
//
ModuleBuilder mb;
- //
- // Error reporting object
- //
- Report report;
-
- //
- // The `System.Object' and `System.ValueType' types, as they
- // are used often
- //
- Type object_type;
- Type value_type;
-
//
// Whether we are being linked against the standard libraries.
// This is only used to tell whether `System.Object' should
// have a parent or not.
//
bool stdlib = true;
+
+ //
+ // This keeps track of the order in which classes were defined
+ // so that we can poulate them in that order.
+ //
+ // Order is important, because we need to be able to tell by
+ // examining the parent's list of methods which ones are virtual
+ // or abstract as well as the parent names (to implement new,
+ // override).
+ //
+ ArrayList type_container_resolve_order;
+ ArrayList interface_resolve_order;
public RootContext ()
{
tree = new Tree (this);
- type_manager = new TypeManager ();
- report = new Report ();
-
- object_type = System.Type.GetType ("System.Object");
- value_type = System.Type.GetType ("System.ValueType");
- }
-
- public TypeManager TypeManager {
- get {
- return type_manager;
- }
+ TypeManager = new TypeManager ();
}
public Tree Tree {
}
}
- public CilCodeGen CodeGen {
+ public CodeGen CodeGen {
get {
return cg;
}
Type GetInterfaceTypeByName (string name)
{
Interface parent;
- Type t = type_manager.LookupType (name);
+ Type t = TypeManager.LookupType (name);
if (t != null) {
else
cause = "Should not happen.";
- report.Error (527, "`"+name+"' " + cause + ", need an interface instead");
+ Report.Error (527, "`"+name+"' " + cause + ", need an interface instead");
return null;
}
else if (tree.Structs [name] != null)
cause = "is a struct";
- report.Error (527, "`"+name+"' " + cause + ", need an interface instead");
+ Report.Error (527, "`"+name+"' " + cause + ", need an interface instead");
return null;
}
-
+
t = CreateInterface ((Interface) parent);
if (t == null){
- report.Error (529,
+ Report.Error (529,
"Inherited interface `"+name+"' is circular");
return null;
}
if (error)
return null;
- // FIXME: use the actual accesibility here, not
- // TypeAttributes.Public.
tb = mb.DefineType (name,
TypeAttributes.Interface |
- TypeAttributes.Public |
+ iface.InterfaceAttr |
TypeAttributes.Abstract,
null, // Parent Type
ifaces);
iface.TypeBuilder = tb;
- type_manager.AddUserType (name, tb);
+ interface_resolve_order.Add (iface);
+
+ TypeManager.AddUserInterface (name, tb, iface);
iface.InTransit = false;
+
return tb;
}
error = false;
name = MakeFQN (ns, name);
- Console.WriteLine ("Attempting to locate " + name);
-
- t = type_manager.LookupType (name);
+
+ t = TypeManager.LookupType (name);
if (t != null)
return t;
if (parent != null){
t = CreateType (parent, is_class);
if (t == null){
- report.Error (146, "Class definition is circular: `"+name+"'");
+ Report.Error (146, "Class definition is circular: `"+name+"'");
error = true;
return null;
}
if (error)
return null;
- if (t != null)
+ if (t != null)
return t;
//
// Attempt to lookup the class on any of the `using'
// namespaces
//
+
for (Namespace ns = tc.Namespace; ns != null; ns = ns.Parent){
ArrayList using_list = ns.UsingTable;
if (using_list == null)
continue;
-
+
foreach (string n in using_list){
t = LookupInterfaceOrClass (n, name, is_class, out error);
if (error)
}
}
- report.Error (246, "Can not find type `"+name+"'");
+ Report.Error (246, "Can not find type `"+name+"'");
return null;
}
if (is_class)
parent = null;
else
- parent = value_type;
+ parent = TypeManager.value_type;
if (bases == null){
if (is_class){
if (stdlib)
- parent = object_type;
+ parent = TypeManager.object_type;
else if (tc.Name != "System.Object")
- parent = object_type;
+ parent = TypeManager.object_type;
} else {
//
// If we are compiling our runtime,
// parent is `System.Object'.
//
if (!stdlib && tc. Name == "System.ValueType")
- parent = object_type;
+ parent = TypeManager.object_type;
}
return null;
parent = first;
start = 1;
} else {
- parent = object_type;
+ parent = TypeManager.object_type;
start = 0;
}
} else {
}
if (is_class == false && !t.IsInterface){
- report.Error (527, "In Struct `"+tc.Name+"', type `"+
+ Report.Error (527, "In Struct `"+tc.Name+"', type `"+
name+"' is not an interface");
error = true;
return null;
if (t.IsValueType)
detail = " (a class can not inherit from a struct)";
- report.Error (509, "class `"+tc.Name+
+ Report.Error (509, "class `"+tc.Name+
"': Cannot inherit from sealed class `"+
bases [i]+"'"+detail);
error = true;
if (t.IsClass) {
if (parent != null){
- report.Error (527, "In Class `"+tc.Name+"', type `"+
+ Report.Error (527, "In Class `"+tc.Name+"', type `"+
name+"' is not an interface");
error = true;
return null;
if (error)
return null;
+ type_container_resolve_order.Add (tc);
+
tb = mb.DefineType (name,
tc.TypeAttr | TypeAttributes.Class,
parent,
ifaces);
-
tc.TypeBuilder = tb;
- type_manager.AddUserType (name, tb);
+
+ TypeManager.AddUserType (name, tb, tc);
tc.InTransit = false;
return tb;
{
Hashtable ifaces, classes, structs;
+ type_container_resolve_order = new ArrayList ();
+
//
// Interfaces are processed first, as classes and
// structs might inherit from an object or implement
//
ifaces = tree.Interfaces;
if (ifaces != null){
+ interface_resolve_order = new ArrayList ();
+
foreach (DictionaryEntry de in ifaces)
CreateInterface ((Interface) de.Value);
}
//
// <remarks>
// We usually use TypeBuilder types. When we are done
- // creating the type (which will happen after we have addded
+ // creating the type (which will happen after we have added
// methods, fields, etc) we need to "Define" them before we
// can save the Assembly
// </remarks>
public void CloseTypes ()
{
- foreach (TypeBuilder t in type_manager.UserTypes){
- t.CreateType ();
+ foreach (TypeBuilder t in TypeManager.UserTypes){
+ try {
+ t.CreateType ();
+ } catch (Exception e){
+ Console.WriteLine ("Caught Exception while creating type for " + t);
+ Console.WriteLine (e);
+ }
}
}
{
Type t;
- t = type_manager.LookupType (MakeFQN (tc.Namespace.Name, name));
+ t = TypeManager.LookupType (MakeFQN (tc.Namespace.Name, name));
if (t != null)
return t;
+ // It's possible that name already is fully qualified. So we do
+ // a simple direct lookup without adding any namespace names
+
+ t = TypeManager.LookupType (name);
+ if (t != null)
+ return t;
+
for (Namespace ns = tc.Namespace; ns != null; ns = ns.Parent){
ArrayList using_list = ns.UsingTable;
continue;
foreach (string n in using_list){
- t = type_manager.LookupType (MakeFQN (n, name));
+ t = TypeManager.LookupType (MakeFQN (n, name));
if (t != null)
return t;
}
}
if (!silent)
- report.Error (246, "Can not find type `"+name+"'");
+ Report.Error (246, "Cannot find type `"+name+"'");
return null;
}
{
return LookupType (tc, name, true);
}
-
+
+ public bool IsNamespace (string name)
+ {
+ Namespace ns;
+
+ if (tree.Namespaces != null){
+ ns = (Namespace) tree.Namespaces [name];
+
+ if (ns != null)
+ return true;
+ }
+
+ return false;
+ }
+
// <summary>
// Populates the structs and classes with fields and methods
// </summary>
// have been defined through `ResolveTree'
public void PopulateTypes ()
{
- Hashtable ifaces, classes;
+ if (interface_resolve_order != null)
+ foreach (Interface iface in interface_resolve_order)
+ iface.Populate ();
+
+ if (type_container_resolve_order != null)
+ foreach (TypeContainer tc in type_container_resolve_order)
+ tc.Populate ();
+ }
+
+ public void EmitCode ()
+ {
+ Hashtable classes, structs;
- if ((ifaces = tree.Interfaces) != null){
- foreach (DictionaryEntry de in ifaces){
- Interface iface = (Interface) de.Value;
+ if ((classes = tree.Classes) != null){
+ foreach (DictionaryEntry de in classes){
+ TypeContainer tc = (TypeContainer) de.Value;
- iface.Populate ();
+ tc.Emit ();
}
}
- if ((classes = tree.Classes) != null){
- foreach (DictionaryEntry de in classes){
+ if ((structs = tree.Structs) != null){
+ foreach (DictionaryEntry de in structs){
TypeContainer tc = (TypeContainer) de.Value;
- tc.Populate (this);
+ tc.Emit ();
}
}
}
-
+
// <summary>
// Compiling against Standard Libraries property.
// </summary>
}
}
- public Report Report {
- get {
- return report;
- }
- }
+ //
+ // Public Field, used to track which method is the public entry
+ // point.
+ //
+ public MethodInfo EntryPoint;
}
}