2 // rootcontext.cs: keeps track of our tree representation, and assemblies loaded.
4 // Author: Miguel de Icaza (miguel@ximian.com)
6 // Licensed under the terms of the GNU GPL
8 // (C) 2001 Ximian, Inc (http://www.ximian.com)
11 using System.Collections;
12 using System.Reflection;
13 using System.Reflection.Emit;
14 using System.Diagnostics;
18 public class RootContext {
21 // Contains the parsed tree
26 // Contains loaded assemblies and our generated code as we go.
28 public TypeManager TypeManager;
31 // The System.Reflection.Emit CodeGenerator
36 // The module builder pointer
41 // Whether we are being linked against the standard libraries.
42 // This is only used to tell whether `System.Object' should
43 // have a parent or not.
48 // This keeps track of the order in which classes were defined
49 // so that we can poulate them in that order.
51 // Order is important, because we need to be able to tell by
52 // examining the parent's list of methods which ones are virtual
53 // or abstract as well as the parent names (to implement new,
56 ArrayList type_container_resolve_order;
57 ArrayList interface_resolve_order;
61 tree = new Tree (this);
62 TypeManager = new TypeManager ();
71 public CodeGen CodeGen {
78 // Temporary hack, we should probably
79 // intialize `cg' rather than depending on
80 // external initialization of it.
83 mb = cg.ModuleBuilder;
88 // The default compiler checked state
90 public bool Checked = false;
92 string MakeFQN (string nsn, string name)
94 string prefix = (nsn == "" ? "" : nsn + ".");
100 // This function is used to resolve the hierarchy tree.
101 // It processes interfaces, structs and classes in that order.
103 // It creates the TypeBuilder's as it processes the user defined
106 public void ResolveTree ()
109 // Interfaces are processed first, as classes and
110 // structs might inherit from an object or implement
111 // a set of interfaces, we need to be able to tell
112 // them appart by just using the TypeManager.
115 TypeContainer root = Tree.Types;
117 ArrayList ifaces = root.Interfaces;
119 interface_resolve_order = new ArrayList ();
121 foreach (Interface i in ifaces) {
122 Type t = i.DefineInterface (mb);
124 interface_resolve_order.Add (i);
128 type_container_resolve_order = new ArrayList ();
130 foreach (TypeContainer tc in root.Types) {
131 Type t = tc.DefineType (mb);
133 type_container_resolve_order.Add (tc);
136 if (root.Delegates != null)
137 foreach (Delegate d in root.Delegates)
138 d.DefineDelegate (mb);
143 // Closes all open types
147 // We usually use TypeBuilder types. When we are done
148 // creating the type (which will happen after we have added
149 // methods, fields, etc) we need to "Define" them before we
150 // can save the Assembly
152 public void CloseTypes ()
154 TypeContainer root = Tree.Types;
156 ArrayList ifaces = root.Interfaces;
159 foreach (Interface i in ifaces)
162 foreach (TypeContainer tc in root.Types)
165 if (root.Delegates != null)
166 foreach (Delegate d in root.Delegates)
172 // Public function used to locate types, this can only
173 // be used after the ResolveTree function has been invoked.
175 // Returns: Type or null if they type can not be found.
177 public Type LookupType (TypeContainer tc, string name, bool silent)
181 t = TypeManager.LookupType (MakeFQN (tc.Namespace.Name, name));
185 // It's possible that name already is fully qualified. So we do
186 // a simple direct lookup without adding any namespace names
188 t = TypeManager.LookupType (name);
192 for (Namespace ns = tc.Namespace; ns != null; ns = ns.Parent){
193 ArrayList using_list = ns.UsingTable;
195 if (using_list == null)
198 foreach (string n in using_list){
199 t = TypeManager.LookupType (MakeFQN (n, name));
205 // For the case the type we are looking for is nested within this one.
206 t = TypeManager.LookupType (tc.Name + "." + name);
211 Report.Error (246, "Cannot find type `"+name+"'");
217 // This is the silent version of LookupType, you can use this
218 // to `probe' for a type
220 public Type LookupType (TypeContainer tc, string name)
222 return LookupType (tc, name, true);
225 public bool IsNamespace (string name)
229 if (tree.Namespaces != null){
230 ns = (Namespace) tree.Namespaces [name];
240 // Populates the structs and classes with fields and methods
243 // This is invoked after all interfaces, structs and classes
244 // have been defined through `ResolveTree'
245 public void PopulateTypes ()
247 if (interface_resolve_order != null)
248 foreach (Interface iface in interface_resolve_order)
251 if (type_container_resolve_order != null)
252 foreach (TypeContainer tc in type_container_resolve_order)
255 ArrayList delegates = Tree.Types.Delegates;
256 if (delegates != null)
257 foreach (Delegate d in delegates)
258 d.Populate (Tree.Types);
262 public void EmitCode ()
264 if (type_container_resolve_order != null)
265 foreach (TypeContainer tc in type_container_resolve_order)
271 // Compiling against Standard Libraries property.
283 public ModuleBuilder ModuleBuilder {
290 // Public Field, used to track which method is the public entry
293 public MethodInfo EntryPoint;