2002-02-22 Miguel de Icaza <miguel@ximian.com>
[mono.git] / mcs / mcs / rootcontext.cs
index 09b8d3fca34db891db3d104ba31c1eb17cf39c0f..c3a6ac55f67c5ec1c4c2266c0222e69f7b7c65f1 100755 (executable)
@@ -20,17 +20,17 @@ namespace Mono.CSharp {
                //
                // Contains the parsed tree
                //
-               Tree tree;
+               static Tree tree;
 
                //
                // Contains loaded assemblies and our generated code as we go.
                //
-               public TypeManager TypeManager;
+               static public TypeManager TypeManager;
 
                //
                // The System.Reflection.Emit CodeGenerator
                //
-               CodeGen cg;
+               static CodeGen cg;
 
                static public bool Optimize;
                
@@ -39,12 +39,17 @@ namespace Mono.CSharp {
                //
                static ModuleBuilder mb;
 
+               //
+               // The list of global attributes (those that target the assembly)
+               //
+               static Attributes global_attributes;
+               
                //
                // Whether we are being linked against the standard libraries.
                // This is only used to tell whether `System.Object' should
                // have a parent or not.
                //
-               static bool stdlib = true;
+               public static bool StdLib = true;
 
                //
                // This keeps track of the order in which classes were defined
@@ -55,31 +60,35 @@ namespace Mono.CSharp {
                // or abstract as well as the parent names (to implement new, 
                // override).
                //
-               ArrayList type_container_resolve_order;
-               ArrayList interface_resolve_order;
-               
+               static ArrayList type_container_resolve_order;
+               static ArrayList interface_resolve_order;
+
                //
                // Holds a reference to the Private Implementation Details
                // class.
                //
-               TypeBuilder impl_details_class;
+               static TypeBuilder impl_details_class;
 
+               public static int WarningLevel = 2;
+               
                //
                // Constructor
                //
-               public RootContext ()
+               static RootContext ()
                {
-                       tree = new Tree (this);
+                       tree = new Tree ();
                        TypeManager = new TypeManager ();
                }
 
-               public Tree Tree {
+               static public Tree Tree {
                        get {
                                return tree;
                        }
                }
 
-               public CodeGen CodeGen {
+               static public string MainClass;
+               
+               static public CodeGen CodeGen {
                        get {
                                return cg;
                        }
@@ -95,12 +104,27 @@ namespace Mono.CSharp {
                        }
                }
 
+               public static void RegisterOrder (Interface iface)
+               {
+                       interface_resolve_order.Add (iface);
+               }
+               
+               public static void RegisterOrder (TypeContainer tc)
+               {
+                       type_container_resolve_order.Add (tc);
+               }
+               
                // 
                // The default compiler checked state
                //
-               public bool Checked = false;
+               static public bool Checked = false;
 
-               string MakeFQN (string nsn, string name)
+               //
+               // Whether to allow Unsafe code
+               //
+               static public bool Unsafe = false;
+               
+               static string MakeFQN (string nsn, string name)
                {
                        string prefix = (nsn == "" ? "" : nsn + ".");
 
@@ -114,7 +138,7 @@ namespace Mono.CSharp {
                //   It creates the TypeBuilder's as it processes the user defined
                //   types.  
                // </remarks>
-               public void ResolveTree ()
+               static public void ResolveTree ()
                {
                        //
                        // Interfaces are processed first, as classes and
@@ -129,20 +153,14 @@ namespace Mono.CSharp {
                        if (ifaces != null){
                                interface_resolve_order = new ArrayList ();
                                
-                               foreach (Interface i in ifaces) {
-                                       Type t = i.DefineInterface (mb);
-                                       if (t != null)
-                                               interface_resolve_order.Add (i);
-                               }
+                               foreach (Interface i in ifaces) 
+                                       i.DefineInterface (mb);
                        }
                                                
                        type_container_resolve_order = new ArrayList ();
                        
-                       foreach (TypeContainer tc in root.Types) {
-                               Type t = tc.DefineType (mb);
-                               if (t != null)
-                                       type_container_resolve_order.Add (tc);
-                       }
+                       foreach (TypeContainer tc in root.Types) 
+                               tc.DefineType (mb);
 
                        if (root.Delegates != null)
                                foreach (Delegate d in root.Delegates) 
@@ -164,27 +182,44 @@ namespace Mono.CSharp {
                //   methods, fields, etc) we need to "Define" them before we
                //   can save the Assembly
                // </remarks>
-               public void CloseTypes ()
+               static public void CloseTypes ()
                {
                        TypeContainer root = Tree.Types;
                        
                        ArrayList ifaces = root.Interfaces;
 
-                       if (ifaces != null)
-                               foreach (Interface i in ifaces) 
-                                       i.CloseType ();
-                       
-                       foreach (TypeContainer tc in root.Types)
-                               tc.CloseType ();
+                       if (root.Enums != null)
+                               foreach (Enum en in root.Enums)
+                                       en.CloseType ();
+
+                       if (interface_resolve_order != null){
+                               foreach (Interface iface in interface_resolve_order)
+                                       iface.CloseType ();
+                       }
 
+                       //
+                       // We do this in two passes, first we close the structs,
+                       // then the classes, because it seems the code needs it this
+                       // way.  If this is really what is going on, we should probably
+                       // make sure that we define the structs in order as well.
+                       //
+                       if (type_container_resolve_order != null){
+                               foreach (TypeContainer tc in type_container_resolve_order){
+                                       if (tc is Struct && tc.Parent == tree.Types){
+                                               tc.CloseType ();
+                                       }
+                               }
+
+                               foreach (TypeContainer tc in type_container_resolve_order){
+                                       if (!(tc is Struct && tc.Parent == tree.Types))
+                                               tc.CloseType ();                                        
+                               }
+                       }
+                       
                        if (root.Delegates != null)
                                foreach (Delegate d in root.Delegates)
                                        d.CloseDelegate ();
 
-                       if (root.Enums != null)
-                               foreach (Enum en in root.Enums)
-                                       en.CloseEnum ();
-                       
 
                        //
                        // If we have a <PrivateImplementationDetails> class, close it
@@ -200,11 +235,29 @@ namespace Mono.CSharp {
                //
                // Returns: Type or null if they type can not be found.
                //
-               public Type LookupType (TypeContainer tc, string name, bool silent)
+               static public Type LookupType (DeclSpace ds, string name, bool silent, Location loc)
                {
                        Type t;
 
-                       t = TypeManager.LookupType (MakeFQN (tc.Namespace.Name, name));
+                       //
+                       // For the case the type we are looking for is nested within this one
+                       // or any base class
+                       //
+                       DeclSpace containing_ds = ds;
+                       while (containing_ds != null){
+                               Type current_type = containing_ds.TypeBuilder;
+
+                               while (current_type != null) {
+                                       t = TypeManager.LookupType (current_type.FullName + "+" + name);
+                                       if (t != null)
+                                               return t;
+                                       current_type = current_type.BaseType;
+                               }
+
+                               containing_ds = containing_ds.Parent;
+                       }
+
+                       t = TypeManager.LookupType (MakeFQN (ds.Namespace.Name, name));
                        if (t != null)
                                return t;
 
@@ -215,7 +268,7 @@ namespace Mono.CSharp {
                        if (t != null)
                                return t;
                        
-                       for (Namespace ns = tc.Namespace; ns != null; ns = ns.Parent){
+                       for (Namespace ns = ds.Namespace; ns != null; ns = ns.Parent){
                                ArrayList using_list = ns.UsingTable;
 
                                if (using_list == null)
@@ -228,13 +281,8 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       // For the case the type we are looking for is nested within this one.
-                       t = TypeManager.LookupType (tc.Name + "." + name);
-                       if (t != null)
-                               return t;
-                       
                        if (!silent)
-                               Report.Error (246, "Cannot find type `"+name+"'");
+                               Report.Error (246, loc, "Cannot find type `"+name+"'");
                        
                        return null;
                }
@@ -243,12 +291,12 @@ namespace Mono.CSharp {
                //   This is the silent version of LookupType, you can use this
                //   to `probe' for a type
                // </summary>
-               public Type LookupType (TypeContainer tc, string name)
+               static public Type LookupType (TypeContainer tc, string name, Location loc)
                {
-                       return LookupType (tc, name, true);
+                       return LookupType (tc, name, true, loc);
                }
 
-               public bool IsNamespace (string name)
+               static public bool IsNamespace (string name)
                {
                        Namespace ns;
 
@@ -262,57 +310,90 @@ namespace Mono.CSharp {
                        return false;
                }
 
+               static void Report1530 (Location loc)
+               {
+                       Report.Error (1530, loc, "Keyword new not allowed for namespace elements");
+               }
+               
                // <summary>
                //   Populates the structs and classes with fields and methods
                // </summary>
                //
                // This is invoked after all interfaces, structs and classes
                // have been defined through `ResolveTree' 
-               public void PopulateTypes ()
+               static public void PopulateTypes ()
                {
-                       if (interface_resolve_order != null)
+                       TypeContainer root = Tree.Types;
+
+                       if (interface_resolve_order != null){
                                foreach (Interface iface in interface_resolve_order)
-                                       iface.Populate ();
+                                       if ((iface.ModFlags & Modifiers.NEW) == 0)
+                                               iface.Define (root);
+                                       else
+                                               Report1530 (iface.Location);
+                       }
 
-                       if (type_container_resolve_order != null)
-                               foreach (TypeContainer tc in type_container_resolve_order)
-                                       tc.Populate ();
 
-                       TypeContainer root = Tree.Types;
+                       if (type_container_resolve_order != null){
+                               foreach (TypeContainer tc in type_container_resolve_order)
+                                       if ((tc.ModFlags & Modifiers.NEW) == 0)
+                                               tc.Define (root);
+                                       else
+                                               Report1530 (tc.Location);
+                       }
 
                        ArrayList delegates = root.Delegates;
-                       if (delegates != null)
+                       if (delegates != null){
                                foreach (Delegate d in delegates)
-                                       d.Populate (root);
+                                       if ((d.ModFlags & Modifiers.NEW) == 0)
+                                               d.Define (root);
+                                       else
+                                               Report1530 (d.Location);
+                       }
 
                        ArrayList enums = root.Enums;
-                       if (enums != null)
+                       if (enums != null){
                                foreach (Enum en in enums)
-                                       en.Populate (root);
-                       
+                                       if ((en.ModFlags & Modifiers.NEW) == 0)
+                                               en.Define (root);
+                                       else
+                                               Report1530 (en.Location);
+                       }
                }
 
-               public void EmitCode ()
+               static public void EmitCode ()
                {
-                       if (type_container_resolve_order != null)
+                       if (type_container_resolve_order != null){
+                               foreach (TypeContainer tc in type_container_resolve_order)
+                                       tc.EmitConstants ();
+                               
                                foreach (TypeContainer tc in type_container_resolve_order)
                                        tc.Emit ();
-               }
-               
-               // <summary>
-               //   Compiling against Standard Libraries property.
-               // </summary>
-               public bool StdLib {
-                       get {
-                               return stdlib;
                        }
 
-                       set {
-                               stdlib = value;
+                       if (global_attributes != null){
+                               EmitContext ec = new EmitContext (
+                                       tree.Types, Mono.CSharp.Location.Null, null, null, 0, false);
+                               AssemblyBuilder ab = cg.AssemblyBuilder;
+
+                               Attribute.ApplyAttributes (ec, ab, ab, global_attributes,
+                                                          global_attributes.Location);
+                       } 
+
+                       if (Unsafe) {
+                               ConstructorInfo ci = TypeManager.unverifiable_code_type.GetConstructor (new Type [0]);
+                                       
+                               if (ci == null) {
+                                       Console.WriteLine ("Internal error !");
+                                       return;
+                               }
+                               
+                               CustomAttributeBuilder cb = new CustomAttributeBuilder (ci, new object [0]);
+                               mb.SetCustomAttribute (cb);
                        }
                }
-
-               public static ModuleBuilder ModuleBuilder {
+               
+               static public ModuleBuilder ModuleBuilder {
                        get {
                                return mb;
                        }
@@ -322,12 +403,12 @@ namespace Mono.CSharp {
                // Public Field, used to track which method is the public entry
                // point.
                //
-               public MethodInfo EntryPoint;
+               static public MethodInfo EntryPoint;
 
                //
                // These are used to generate unique names on the structs and fields.
                //
-               int field_count;
+               static int field_count;
                
                //
                // Makes an initialized struct, returns the field builder that
@@ -343,7 +424,7 @@ namespace Mono.CSharp {
                //
                // 2. Define the field on the impl_details_class
                //
-               public FieldBuilder MakeStaticData (byte [] data)
+               static public FieldBuilder MakeStaticData (byte [] data)
                {
                        FieldBuilder fb;
                        int size = data.Length;
@@ -358,6 +439,14 @@ namespace Mono.CSharp {
                        
                        return fb;
                }
+
+               static public void AddGlobalAttributes (AttributeSection sect, Location loc)
+               {
+                       if (global_attributes == null)
+                               global_attributes = new Attributes (sect, loc);
+
+                       global_attributes.AddAttribute (sect);
+               }
        }
 }