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;
87 string MakeFQN (string nsn, string name)
89 string prefix = (nsn == "" ? "" : nsn + ".");
95 // This function is used to resolve the hierarchy tree.
96 // It processes interfaces, structs and classes in that order.
98 // It creates the TypeBuilder's as it processes the user defined
101 public void ResolveTree ()
104 // Interfaces are processed first, as classes and
105 // structs might inherit from an object or implement
106 // a set of interfaces, we need to be able to tell
107 // them appart by just using the TypeManager.
110 TypeContainer root = Tree.Types;
112 ArrayList ifaces = root.Interfaces;
114 interface_resolve_order = new ArrayList ();
116 foreach (Interface i in ifaces) {
117 Type t = i.DefineInterface (mb);
119 interface_resolve_order.Add (i);
123 type_container_resolve_order = new ArrayList ();
125 foreach (TypeContainer tc in root.Types) {
126 Type t = tc.DefineType (mb);
128 type_container_resolve_order.Add (tc);
131 if (root.Delegates != null)
132 foreach (Delegate d in root.Delegates)
133 d.DefineDelegate (mb);
138 // Closes all open types
142 // We usually use TypeBuilder types. When we are done
143 // creating the type (which will happen after we have added
144 // methods, fields, etc) we need to "Define" them before we
145 // can save the Assembly
147 public void CloseTypes ()
149 TypeContainer root = Tree.Types;
151 ArrayList ifaces = root.Interfaces;
154 foreach (Interface i in ifaces)
157 foreach (TypeContainer tc in root.Types)
160 if (root.Delegates != null)
161 foreach (Delegate d in root.Delegates)
167 // Public function used to locate types, this can only
168 // be used after the ResolveTree function has been invoked.
170 // Returns: Type or null if they type can not be found.
172 public Type LookupType (TypeContainer tc, string name, bool silent)
176 t = TypeManager.LookupType (MakeFQN (tc.Namespace.Name, name));
180 // It's possible that name already is fully qualified. So we do
181 // a simple direct lookup without adding any namespace names
183 t = TypeManager.LookupType (name);
187 for (Namespace ns = tc.Namespace; ns != null; ns = ns.Parent){
188 ArrayList using_list = ns.UsingTable;
190 if (using_list == null)
193 foreach (string n in using_list){
194 t = TypeManager.LookupType (MakeFQN (n, name));
200 // For the case the type we are looking for is nested within this one.
201 t = TypeManager.LookupType (tc.Name + "." + name);
206 Report.Error (246, "Cannot find type `"+name+"'");
212 // This is the silent version of LookupType, you can use this
213 // to `probe' for a type
215 public Type LookupType (TypeContainer tc, string name)
217 return LookupType (tc, name, true);
220 public bool IsNamespace (string name)
224 if (tree.Namespaces != null){
225 ns = (Namespace) tree.Namespaces [name];
235 // Populates the structs and classes with fields and methods
238 // This is invoked after all interfaces, structs and classes
239 // have been defined through `ResolveTree'
240 public void PopulateTypes ()
242 if (interface_resolve_order != null)
243 foreach (Interface iface in interface_resolve_order)
246 if (type_container_resolve_order != null)
247 foreach (TypeContainer tc in type_container_resolve_order)
250 ArrayList delegates = Tree.Types.Delegates;
251 if (delegates != null)
252 foreach (Delegate d in delegates)
253 d.Populate (Tree.Types);
257 public void EmitCode ()
259 if (type_container_resolve_order != null)
260 foreach (TypeContainer tc in type_container_resolve_order)
266 // Compiling against Standard Libraries property.
279 // Public Field, used to track which method is the public entry
282 public MethodInfo EntryPoint;