//
// rootcontext.cs: keeps track of our tree representation, and assemblies loaded.
//
// Author: Miguel de Icaza (miguel@ximian.com)
//
// Licensed under the terms of the GNU GPL
//
// (C) 2001 Ximian, Inc (http://www.ximian.com)
using System;
using System.Collections;
using System.Reflection;
using System.Reflection.Emit;
namespace CIR {
public class RootContext {
//
// Contains the parsed tree
//
Tree tree;
//
// Contains loaded assemblies and our generated code as we go.
//
TypeManager type_manager;
//
// The System.Reflection.Emit CodeGenerator
//
CilCodeGen cg;
ModuleBuilder mb;
Report report;
public RootContext ()
{
tree = new Tree ();
type_manager = new TypeManager ();
report = new Report ();
}
public TypeManager TypeManager {
get {
return type_manager;
}
}
public Tree Tree {
get {
return tree;
}
}
public CilCodeGen CodeGen {
get {
return cg;
}
set {
//
// Temporary hack, we should probably
// intialize `cg' rather than depending on
// external initialization of it.
//
cg = value;
mb = cg.ModuleBuilder;
}
}
//
// Returns the list of interfaces that this interface implements
// Null on error
//
Type [] GetInterfaces (Interface iface)
{
ArrayList bases = iface.Bases;
Type [] tbases = new Type [bases.Count];
int i = 0;
Hashtable source_ifaces = tree.Interfaces;
foreach (string name in iface.Bases){
Type t = type_manager.LookupType (name);
Interface parent;
if (t != null){
tbases [i++] = t;
continue;
}
parent = (Interface) source_ifaces [name];
if (parent == null){
report.Error (246, "Can not find type `"+name+"'");
return null;
}
t = CreateInterface (parent);
if (t == null){
report.Error (529,
"Inherited interface `"+name+"' in `"+
iface.Name+"' is recursive");
return null;
}
tbases [i++] = t;
}
return tbases;
}
//
// Creates the Interface @iface using the ModuleBuilder
//
// TODO:
// Resolve recursively dependencies.
//
TypeBuilder CreateInterface (Interface iface)
{
TypeBuilder tb;
if (iface.InTransit)
return null;
iface.InTransit = true;
string name = iface.Name;
Type [] ifaces = GetInterfaces (iface);
if (ifaces == null)
return null;
tb = mb.DefineType (name,
TypeAttributes.Interface |
TypeAttributes.Public |
TypeAttributes.Abstract);
iface.Definition = tb;
//
// if Recursive_Def (child) == false
// error (child.Name recursive def with iface.Name)
//
type_manager.AddUserType (name, tb);
iface.InTransit = false;
return tb;
}
public void ResolveInterfaceBases ()
{
Hashtable ifaces = tree.Interfaces;
foreach (Interface iface in ifaces){
string name = iface.Name;
CreateInterface (iface);
}
}
public void ResolveClassBases ()
{
}
//
// Closes all open types
//
//
//
// We usually use TypeBuilder types. When we are done
// creating the type (which will happen after we have addded
// methods, fields, etc) we need to "Define" them before we
// can save the Assembly
//
public void CloseTypes ()
{
foreach (TypeBuilder t in type_manager.UserTypes){
t.CreateType ();
}
}
}
}