//
// 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;
//
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
// 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;
}
}
}
+ 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 + ".");
// 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
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)
// 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
//
// 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;
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)
}
}
- // 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;
}
// 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;
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;
}
// 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
//
// 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;
return fb;
}
+
+ static public void AddGlobalAttributes (AttributeSection sect, Location loc)
+ {
+ if (global_attributes == null)
+ global_attributes = new Attributes (sect, loc);
+
+ global_attributes.AddAttribute (sect);
+ }
}
}