//
// (C) 2001 Ximian, Inc (http://www.ximian.com)
//
-// TODO:
-//
-// a. Maybe keep a list of defined names in the order they
-// appeared, so we can walk things in this way to present
-// the users with errors in that order?
//
using System.Collections;
+using System.Reflection;
+using System.Reflection.Emit;
using System;
namespace CIR {
public class TypeContainer : DeclSpace {
protected int mod_flags;
- Hashtable types, fields, properties;
- Hashtable enums, constants, interfaces, method_groups;
- ArrayList constructor_list;
+ // Holds a list of classes and structures
+ ArrayList types;
+
+ // Holds the list of properties
+ ArrayList properties;
+
+ // Holds the list of enumerations
+ ArrayList enums;
+
+ // Holds the list of delegates
+ ArrayList delegates;
+
+ // Holds the list of constructors
+ ArrayList constructors;
+
+ // Holds the list of fields
+ ArrayList fields;
+
+ // Holds a list of fields that have initializers
+ ArrayList initialized_fields;
+ // Holds a list of static fields that have initializers
+ ArrayList initialized_static_fields;
+
+ // Holds the list of constants
+ ArrayList constants;
+
+ // Holds the list of
+ ArrayList interfaces;
+
+ // Holds the methods.
+ ArrayList methods;
+
+ // Holds the events
+ ArrayList events;
+
+ // Holds the indexers
+ ArrayList indexers;
+
+ // Holds the operators
+ ArrayList operators;
+
+ //
+ // Pointers to the default constructor and the default static constructor
+ //
+ Constructor default_constructor;
+ Constructor default_static_constructor;
+
+ //
+ // Whether we have seen a static constructor for this class or not
+ //
+ bool have_static_constructor = false;
+
//
// This is the namespace in which this typecontainer
// was declared. We use this to resolve names.
//
- CSC.Namespace my_namespace;
+ Namespace my_namespace;
//
// This one is computed after we can distinguish interfaces
TypeContainer parent;
ArrayList type_bases;
- public TypeContainer (TypeContainer parent, string name) : base (name)
+ //
+ // This behaves like a property ;-)
+ //
+ public readonly RootContext RootContext;
+
+ // Attributes for this type
+ protected Attributes attributes;
+
+ public TypeContainer (RootContext rc, TypeContainer parent, string name) : base (name)
{
- types = new Hashtable ();
+ string n;
+ types = new ArrayList ();
this.parent = parent;
+ RootContext = rc;
- string n;
+ object a = rc.Report;
+
if (parent == null)
n = "";
else
return res;
if (constants == null)
- constants = new Hashtable ();
+ constants = new ArrayList ();
- constants.Add (name, constant);
+ constants.Add (constant);
DefineName (name, constant);
return AdditionResult.Success;
return res;
if (enums == null)
- enums = new Hashtable ();
+ enums = new ArrayList ();
- enums.Add (name, e);
+ enums.Add (e);
DefineName (name, e);
return AdditionResult.Success;
return res;
DefineName (name, c);
- types.Add (name, c);
+ types.Add (c);
return AdditionResult.Success;
}
return res;
DefineName (name, s);
- types.Add (name, s);
+ types.Add (s);
+
+ return AdditionResult.Success;
+ }
+
+ public AdditionResult AddDelegate (Delegate d)
+ {
+ AdditionResult res;
+ string name = d.Name;
+
+ if ((res = IsValid (name)) != AdditionResult.Success)
+ return res;
+
+ if (delegates == null)
+ delegates = new ArrayList ();
+
+ DefineName (name, d);
+ delegates.Add (d);
return AdditionResult.Success;
}
string name = method.Name;
Object value = defined_names [name];
- if (value != null && (!(value is MethodGroup)))
+ if (value != null && (!(value is Method)))
return AdditionResult.NameExists;
- if (method_groups == null)
- method_groups = new Hashtable ();
-
- MethodGroup mg = (MethodGroup) method_groups [name];
- if (mg == null){
- mg = new MethodGroup (name);
-
- mg.Add (method);
- method_groups.Add (name, mg);
+ if (methods == null)
+ methods = new ArrayList ();
- return AdditionResult.Success;
- }
- mg.Add (method);
+ methods.Add (method);
+ DefineName (name, method);
- if (value == null)
- DefineName (name, mg);
-
return AdditionResult.Success;
}
if (c.Name != Basename)
return AdditionResult.NotAConstructor;
- if (constructor_list == null)
- constructor_list = new ArrayList ();
+ if (constructors == null)
+ constructors = new ArrayList ();
- constructor_list.Add (c);
+ constructors.Add (c);
+
+ bool is_static = (c.ModFlags & Modifiers.STATIC) != 0;
+
+ if (is_static)
+ have_static_constructor = true;
+
+ if (c.IsDefault ()){
+ if (is_static)
+ default_static_constructor = c;
+ else
+ default_constructor = c;
+ }
return AdditionResult.Success;
}
return res;
if (interfaces == null)
- interfaces = new Hashtable ();
- interfaces.Add (name, iface);
+ interfaces = new ArrayList ();
+ interfaces.Add (iface);
DefineName (name, iface);
return AdditionResult.Success;
return res;
if (fields == null)
- fields = new Hashtable ();
-
- fields.Add (name, field);
+ fields = new ArrayList ();
+
+ fields.Add (field);
+ if (field.Initializer != null){
+ if ((field.ModFlags & Modifiers.STATIC) != 0){
+ if (initialized_static_fields == null)
+ initialized_static_fields = new ArrayList ();
+
+ initialized_static_fields.Add (field);
+
+ //
+ // We have not seen a static constructor,
+ // but we will provide static initialization of fields
+ //
+ have_static_constructor = true;
+ } else {
+ if (initialized_fields == null)
+ initialized_fields = new ArrayList ();
+
+ initialized_fields.Add (field);
+ }
+ }
+
DefineName (name, field);
return AdditionResult.Success;
}
return res;
if (properties == null)
- properties = new Hashtable ();
+ properties = new ArrayList ();
- properties.Add (name, prop);
+ properties.Add (prop);
DefineName (name, prop);
return AdditionResult.Success;
}
-
- public Constant GetConstant (string name) {
- return (Constant) constants [name];
+
+ public AdditionResult AddEvent (Event e)
+ {
+ AdditionResult res;
+ string name = e.Name;
+
+ if ((res = IsValid (name)) != AdditionResult.Success)
+ return res;
+
+ if (events == null)
+ events = new ArrayList ();
+
+ events.Add (e);
+ DefineName (name, e);
+
+ return AdditionResult.Success;
+ }
+
+ public AdditionResult AddIndexer (Indexer i)
+ {
+ if (indexers == null)
+ indexers = new ArrayList ();
+
+ indexers.Add (i);
+
+ return AdditionResult.Success;
+ }
+
+ public AdditionResult AddOperator (Operator op)
+ {
+ if (operators == null)
+ operators = new ArrayList ();
+
+ operators.Add (op);
+
+ return AdditionResult.Success;
}
public TypeContainer Parent {
}
}
- public Hashtable Types {
+ public ArrayList Types {
get {
return types;
}
}
- public Hashtable MethodGroups {
+ public ArrayList Methods {
get {
- return method_groups;
+ return methods;
}
}
- public Hashtable Constants {
+ public ArrayList Constants {
get {
return constants;
}
}
- public Hashtable Interfaces {
+ public ArrayList Interfaces {
get {
return interfaces;
}
}
}
- public Hashtable Fields {
+ public ArrayList Fields {
get {
return fields;
}
}
- public Hashtable Constructors {
+ public ArrayList Constructors {
get {
- return null; // constructors;
+ return constructors;
}
}
- public Hashtable Properties {
+ public ArrayList Properties {
get {
return properties;
}
}
- public Hashtable Enums {
+ public ArrayList Events {
+ get {
+ return events;
+ }
+ }
+
+ public ArrayList Enums {
get {
return enums;
}
}
- public Type ResolveName (string name)
- {
- return null;
+ public ArrayList Indexers {
+ get {
+ return indexers;
+ }
}
- public CSC.Namespace Namespace {
+ public ArrayList Operators {
+ get {
+ return operators;
+ }
+ }
+
+ public ArrayList Delegates {
+ get {
+ return delegates;
+ }
+ }
+
+ public Attributes OptAttributes {
+ get {
+ return attributes;
+ }
+ }
+
+ public Namespace Namespace {
get {
return my_namespace;
}
my_namespace = value;
}
}
-
- public int ResolveParents (Tree root)
- {
- if (Bases != null){
- if (type_bases.Count == 0){
- base_class_name = "System.Object";
- return 0;
+
+ //
+ // The Toplevel is `root_types'Â which is a containerfor all
+ // types defined, hence the non-obviios parent.parent.
+ //
+ // If we were not tracking Namespaces we could remove this.
+ //
+ bool IsTopLevel {
+ get {
+ if (parent != null){
+ if (parent.parent == null)
+ return true;
}
- } else
- return 0;
-
- foreach (Type t in Bases){
- Type resolved = ResolveName (t.Name);
-
+ return false;
}
- return 0;
}
- public delegate void VisitContainer (TypeContainer container, object cback_data);
+ // <summary>
+ // Returns the TypeAttributes for this TypeContainer
+ // </summary>
+ public virtual TypeAttributes TypeAttr {
+ get {
+ TypeAttributes x = 0;
+
+ //
+ // FIXME: Figure out exactly how private, public and protected
+ // map to the TypeAttribute flags.
+ //
+ // FIXME: Figure out what `new' in the context of a class/struct means.
+ //
+ // FIXME: figure out what `internal' means in the context of class/structs
+ //
+ if ((mod_flags & Modifiers.PUBLIC) != 0)
+ x |= TypeAttributes.Public;
+
+ if ((mod_flags & Modifiers.PRIVATE) != 0)
+ x |= TypeAttributes.NotPublic;
+
+ if ((mod_flags & Modifiers.ABSTRACT) != 0)
+ x |= TypeAttributes.Abstract;
+
+ if ((mod_flags & Modifiers.SEALED) != 0)
+ x |= TypeAttributes.Sealed;
+
+ if (!IsTopLevel){
+ if ((mod_flags & Modifiers.PUBLIC) != 0)
+ x |= TypeAttributes.NestedPublic;
+ else
+ x |= TypeAttributes.NestedPrivate;
+ }
- void VisitTypesAt (TypeContainer root, VisitContainer visit, object cback)
+ //
+ // If we have static constructors, the runtime needs to
+ // initialize the class, otherwise we can optimize
+ // the case.
+ //
+ if (!have_static_constructor)
+ x |= TypeAttributes.BeforeFieldInit;
+ return x;
+ }
+ }
+
+ void EmitField (Field f)
{
- if (root == null)
+ Type t = LookupType (f.Type, false);
+
+ if (t == null)
return;
- foreach (DictionaryEntry de in root.Types){
- TypeContainer type = (TypeContainer) de.Value;
+ TypeBuilder.DefineField (f.Name, t, Modifiers.FieldAttr (f.ModFlags));
+ }
- visit (type, cback);
- VisitTypesAt (type, visit, cback);
- }
+ //
+ // Emits the class field initializers
+ //
+ void EmitStaticFieldInitializers (ConstructorBuilder cb)
+ {
+ // FIXME: Implement
}
- // <summary>
- // Use this method to visit all the types in a type container.
- // You can use cback to pass arbitrary data to your callback.
- // </summary>
- public void VisitTypes (VisitContainer visit, object cback)
+ //
+ // Emits the instance field initializers
+ //
+ void EmitFieldInitializers (ConstructorBuilder cb)
{
- foreach (DictionaryEntry de in types){
- TypeContainer type = (TypeContainer) de.Value;
+ // FIXME: Implement
+ }
- VisitTypesAt (type, visit, cback);
+ //
+ // Emits a constructor
+ //
+ void EmitConstructor (Constructor c)
+ {
+ if ((c.ModFlags & Modifiers.STATIC) != 0){
+ if (initialized_static_fields != null)
+ EmitStaticFieldInitializers (c.ConstructorBuilder);
+ } else {
+ if (initialized_fields != null)
+ EmitFieldInitializers (c.ConstructorBuilder);
}
-
+
}
- internal class VisitExpressions_Lambda {
- VisitExpressionRoot vb;
- object user_data;
+ //
+ // This function is used to emit instance and static constructors
+ // when the user did not provide one.
+ //
+ void EmitDefaultConstructor (bool is_static)
+ {
+ ConstructorBuilder cb;
+ MethodAttributes ca = (MethodAttributes.RTSpecialName |
+ MethodAttributes.SpecialName);
- void walk_arguments (ArrayList args)
- {
- if (args == null)
- return;
-
- int top = args.Count;
+ if (is_static)
+ ca |= MethodAttributes.Static;
+
+ //
+ // Default constructors provided by the compiler should be `protected'
+ // if the class is abstract, otherwise it is public
+ //
+ if ((mod_flags & Modifiers.ABSTRACT) != 0)
+ ca |= MethodAttributes.Family;
+ else
+ ca |= MethodAttributes.Public;
+
+ cb = TypeBuilder.DefineDefaultConstructor (ca);
- for (int i = 0; i < top; i++){
- Argument arg = (Argument) args [i];
+ if (is_static)
+ EmitStaticFieldInitializers (cb);
+ else
+ EmitFieldInitializers (cb);
+ }
- vb (arg.Expr, user_data);
- }
+ //
+ // Populates our TypeBuilder with fields and methods
+ //
+ public void Populate ()
+ {
+ if (Constants != null){
+ foreach (Constant c in Constants)
+ c.EmitConstant (RootContext, this);
}
- void walk_block (Block b)
- {
+ if (Fields != null){
+ foreach (Field f in Fields)
+ EmitField (f);
}
-
- void walk_constructor (Constructor c)
- {
- ConstructorInitializer init = c.Initializer;
-
- if (init != null && init.Arguments != null)
- walk_arguments (init.Arguments);
- walk_block (c.Block);
+ if (Constructors != null){
+ foreach (Constructor c in Constructors)
+ c.Define (this);
}
- void walk_properties (Property p)
- {
+ if (Methods != null){
+ foreach (Method m in Methods)
+ m.Define (this);
}
- void walk_method (Method m)
- {
+ if (Properties != null) {
+ foreach (Property p in Properties)
+ p.Define (this);
}
-
- void type_walker_1 (TypeContainer type, object cback)
- {
- if (type.Fields != null){
- foreach (DictionaryEntry de in type.Fields){
- Field f = (Field) de.Value;
-
- if (f.Initializer != null){
- if (f.Initializer is Expression)
- vb ((Expression) f.Initializer, user_data);
- }
- }
- }
- if (type.Constructors != null){
- foreach (DictionaryEntry de in type.Constructors)
- walk_constructor ((Constructor) de.Value);
- }
+ if (Enums != null) {
+ foreach (Enum e in Enums)
+ e.Define (this);
+ }
- if (type.Properties != null){
- foreach (DictionaryEntry de in type.Properties)
- walk_properties ((Property) de.Value);
- }
+ if (Events != null) {
+ foreach (Event e in Events)
+ e.Define (this);
+ }
- if (type.MethodGroups != null){
- foreach (DictionaryEntry de in type.MethodGroups){
- Hashtable methods = ((MethodGroup) de.Value).Methods;
- foreach (Method m in methods)
- walk_method (m);
- }
- }
+ if (Indexers != null) {
+ foreach (Indexer i in Indexers)
+ i.Define (this);
}
-
- internal VisitExpressions_Lambda (TypeContainer tc,
- VisitExpressionRoot vb,
- object user_data)
- {
- this.vb = vb;
- this.user_data = user_data;
+ if (Operators != null) {
+ foreach (Operator o in Operators)
+ o.Define (this);
+ }
- tc.VisitTypes (new VisitContainer (type_walker_1), null);
+ if (Delegates != null) {
+ foreach (Delegate d in Delegates)
+ d.Define (this);
}
+
+
+ }
+
+ //
+ // Emits the code, this step is performed after all
+ // the types, enumerations, constructors
+ //
+ public void Emit ()
+ {
+ if (default_constructor == null)
+ EmitDefaultConstructor (false);
+
+ if (initialized_static_fields != null && default_static_constructor == null)
+ EmitDefaultConstructor (true);
+
+ if (Constructors != null)
+ foreach (Constructor c in Constructors)
+ c.Emit ();
+
+ if (Methods != null)
+ foreach (Method m in Methods)
+ m.Emit (this);
}
- public delegate void VisitExpressionRoot (Expression e, object cback);
+ public delegate void ExamineType (TypeContainer container, object cback_data);
+
+ void WalkTypesAt (TypeContainer root, ExamineType visit, object cback_data)
+ {
+ if (root == null)
+ return;
+
+ foreach (TypeContainer type in root.Types){
+ visit (type, cback_data);
+ WalkTypesAt (type, visit, cback_data);
+ }
+ }
+
+ public void WalkTypes (ExamineType visit, object cback)
+ {
+ WalkTypesAt (this, visit, cback);
+ }
+
+ public Type LookupType (string name, bool silent)
+ {
+ return RootContext.LookupType (this, name, silent);
+ }
+
// <summary>
- // Use this method to visit all the code blocks in a TypeContainer
+ // This method returns the members of this type just like Type.FindMembers would
+ // Only, we need to use this for types which are _being_ defined because MS' brain
+ // dead implementation can't take care of that ;-)
// </summary>
- public void VisitExpressionRoots (VisitExpressionRoot vb, object cback)
+ public MemberInfo [] FindMembers (MemberTypes mt, BindingFlags bf, MemberFilter filter, object criteria)
{
- VisitExpressions_Lambda l = new VisitExpressions_Lambda (this, vb, cback);
+ // FIXME : Need to actually take care of all the various
+ // arguments being passed in but for now, we only bother with
+ // the MemberTypes and criteria arguments.
+
+ switch (mt) {
+
+ case MemberTypes.All:
+
+ break;
+
+ case MemberTypes.Constructor:
+
+ break;
+
+ case MemberTypes.Custom:
+
+ break;
+
+ case MemberTypes.Event:
+
+ break;
+
+ case MemberTypes.Field:
+
+ break;
+
+ case MemberTypes.Method:
+
+ break;
+
+ case MemberTypes.NestedType:
+
+ break;
+
+ case MemberTypes.Property:
+
+ break;
+
+ case MemberTypes.TypeInfo:
+
+ break;
+
+ }
+
+ return null;
+
}
+
}
public class Class : TypeContainer {
Modifiers.ABSTRACT |
Modifiers.SEALED;
- public Class (TypeContainer parent, string name, int mod)
- : base (parent, name)
+ public Class (RootContext rc, TypeContainer parent, string name, int mod, Attributes attrs)
+ : base (rc, parent, name)
{
int accmods;
accmods = Modifiers.PRIVATE;
this.mod_flags = Modifiers.Check (AllowedModifiers, mod, accmods);
+ this.attributes = attrs;
+ }
+
+ //
+ // FIXME: How do we deal with the user specifying a different
+ // layout?
+ //
+ public override TypeAttributes TypeAttr {
+ get {
+ return base.TypeAttr | TypeAttributes.AutoLayout;
+ }
}
}
Modifiers.INTERNAL |
Modifiers.PRIVATE;
- public Struct (TypeContainer parent, string name, int mod)
- : base (parent, name)
+ public Struct (RootContext rc, TypeContainer parent, string name, int mod, Attributes attrs)
+ : base (rc, parent, name)
{
int accmods;
accmods = Modifiers.PRIVATE;
this.mod_flags = Modifiers.Check (AllowedModifiers, mod, accmods);
+
+ this.mod_flags |= Modifiers.SEALED;
+ this.attributes = attrs;
+
+ }
+
+ //
+ // FIXME: Allow the user to specify a different set of attributes
+ // in some cases (Sealed for example is mandatory for a class,
+ // but what SequentialLayout can be changed
+ //
+ public override TypeAttributes TypeAttr {
+ get {
+ return base.TypeAttr |
+ TypeAttributes.SequentialLayout |
+ TypeAttributes.Sealed |
+ TypeAttributes.BeforeFieldInit;
+ }
}
}
public class Method {
- Parameters parameters;
- TypeRef return_typeref;
- string name;
- int modifiers;
- Block block;
-
+ public readonly Parameters Parameters;
+ public readonly string ReturnType;
+ public readonly string Name;
+ public readonly int ModFlags;
+ public MethodBuilder MethodBuilder;
+ public readonly Attributes OptAttributes;
+
+ Block block;
+
// return_type can be "null" for VOID values.
- public Method (TypeRef return_typeref, int mod, string name, Parameters parameters)
+ public Method (string return_type, int mod, string name, Parameters parameters, Attributes attrs)
{
- this.return_typeref = return_typeref;
- this.name = name;
- this.parameters = parameters;
- this.modifiers = Modifiers.Check (AllowedModifiers, mod, Modifiers.PRIVATE);
+ Name = name;
+ ReturnType = return_type;
+ Parameters = parameters;
+ ModFlags = Modifiers.Check (AllowedModifiers, mod, Modifiers.PRIVATE);
+ OptAttributes = attrs;
}
// <summary>
}
}
- public string Name {
- get {
- return name;
- }
+ //
+ // Returns the `System.Type' for the ReturnType of this
+ // function. Provides a nice cache. (used between semantic analysis
+ // and actual code generation
+ //
+ Type type_return_type;
+ public Type GetReturnType (TypeContainer parent)
+ {
+ if (type_return_type == null)
+ type_return_type = parent.LookupType (ReturnType, false);
+
+ return type_return_type;
}
- public int ModFlags {
- get {
- return modifiers;
- }
+ //
+ // Returns the System.Type array for the parameters of this method
+ //
+ Type [] parameter_types;
+ public Type [] ParameterTypes (TypeContainer parent)
+ {
+ if (Parameters == null)
+ return null;
+
+ if (parameter_types == null)
+ parameter_types = Parameters.GetParameterInfo (parent);
+
+ return parameter_types;
}
- public Parameters Parameters {
- get {
- return parameters;
- }
+ public CallingConventions GetCallingConvention (bool is_class)
+ {
+ CallingConventions cc = 0;
+
+ cc = Parameters.GetCallingConvention ();
+
+ if (is_class)
+ if ((ModFlags & Modifiers.STATIC) == 0)
+ cc |= CallingConventions.HasThis;
+
+ return cc;
}
- public Type ReturnType {
- get {
- return return_typeref.Type;
+ //
+ // Creates the type
+ //
+ public void Define (TypeContainer parent)
+ {
+ Type ret_type = GetReturnType (parent);
+ Type [] parameters = ParameterTypes (parent);
+
+ //
+ // Create the method
+ //
+ MethodBuilder = parent.TypeBuilder.DefineMethod (
+ Name, Modifiers.MethodAttr (ModFlags),
+ GetCallingConvention (parent is Class),
+ ret_type, parameters);
+
+ //
+ // This is used to track the Entry Point,
+ //
+ // FIXME: Allow pluggable entry point, check arguments, etc.
+ //
+ if (Name == "Main"){
+ if ((ModFlags & Modifiers.STATIC) != 0){
+ parent.RootContext.EntryPoint = MethodBuilder;
+ }
}
- }
+
+ //
+ // Define each type attribute (in/out/ref) and
+ // the argument names.
+ //
+ Parameter [] p = Parameters.FixedParameters;
+ if (p != null){
+ int i;
+
+ for (i = 0; i < p.Length; i++)
+ MethodBuilder.DefineParameter (
+ i + 1, p [i].Attributes, p [i].Name);
- public string ArgumentSignature {
- get {
- return ""; // TYPEFIX: Type.MakeParameterSignature (name, parameters);
+ if (i != parameters.Length)
+ Console.WriteLine ("Implement the type definition for params");
}
}
+
+ //
+ // Emits the code
+ //
+ public void Emit (TypeContainer parent)
+ {
+ ILGenerator ig = MethodBuilder.GetILGenerator ();
+ EmitContext ec = new EmitContext (parent, ig);
+
+ ec.EmitTopBlock (block);
+ }
}
public class Field {
- Type type;
- Object expr_or_array_init;
- string name;
- int modifiers;
+ public readonly string Type;
+ public readonly Object Initializer;
+ public readonly string Name;
+ public readonly int ModFlags;
+ public readonly Attributes OptAttributes;
// <summary>
// Modifiers allowed in a class declaration
Modifiers.STATIC |
Modifiers.READONLY;
- public Field (TypeRef typeref, int mod, string name, Object expr_or_array_init)
+ public Field (string type, int mod, string name, Object expr_or_array_init, Attributes attrs)
{
- this.type = type;
- this.modifiers = Modifiers.Check (AllowedModifiers, mod, Modifiers.PRIVATE);
- this.name = name;
- this.expr_or_array_init = expr_or_array_init;
- }
-
- public Type Type {
- get {
- return type;
- }
- }
-
- public object Initializer {
- get {
- return expr_or_array_init;
- }
- }
-
- public string Name {
- get {
- return name;
- }
- }
-
- public int ModFlags {
- get {
- return modifiers;
- }
+ Type = type;
+ ModFlags = Modifiers.Check (AllowedModifiers, mod, Modifiers.PRIVATE);
+ Name = name;
+ Initializer = expr_or_array_init;
+ OptAttributes = attrs;
}
}
}
public class Constructor {
- ConstructorInitializer init;
- string name;
- Parameters args;
+ public ConstructorBuilder ConstructorBuilder;
+ public readonly ConstructorInitializer Initializer;
+ public readonly Parameters Parameters;
+ public readonly string Name;
Block block;
int mod_flags;
// The spec claims that static is not permitted, but
// my very own code has static constructors.
//
-
public Constructor (string name, Parameters args, ConstructorInitializer init)
{
- this.name = name;
- this.args = args;
- this.init = init;
+ Name = name;
+ Parameters = args;
+ Initializer = init;
}
- public string Name {
- get {
- return name;
- }
+ //
+ // Returns true if this is a default constructor
+ //
+ public bool IsDefault ()
+ {
+ return (Parameters == null) &&
+ (Initializer is ConstructorBaseInitializer) &&
+ (Initializer.Arguments == null);
}
- public ConstructorInitializer Initializer {
+ public int ModFlags {
get {
- return init;
+ return mod_flags;
}
- }
- public Parameters Parameters {
- get {
- return args;
+ set {
+ mod_flags = value;
}
}
-
+
public Block Block {
get {
return block;
}
}
- public int ModFlags {
- get {
- return mod_flags;
- }
+ public CallingConventions GetCallingConvention (bool parent_is_class)
+ {
+ CallingConventions cc = 0;
+
+ if (Parameters.ArrayParameter != null)
+ cc |= CallingConventions.VarArgs;
+ else
+ cc |= CallingConventions.Standard;
- set {
- mod_flags = Modifiers.Check (AllowedModifiers, value, 0);
- }
+ if (parent_is_class)
+ if ((ModFlags & Modifiers.STATIC) != 0)
+ cc |= CallingConventions.HasThis;
+
+ // FIXME: How is `ExplicitThis' used in C#?
+
+ return cc;
+ }
+
+ //
+ // Cached representation
+ ///
+ Type [] parameter_types;
+ public Type [] ParameterTypes (TypeContainer tc)
+ {
+ if (Parameters == null)
+ return null;
+
+ if (parameter_types == null)
+ parameter_types = Parameters.GetParameterInfo (tc);
+
+ return parameter_types;
+ }
+
+ //
+ // Creates the ConstructorBuilder
+ //
+ public void Define (TypeContainer parent)
+ {
+ MethodAttributes ca = (MethodAttributes.RTSpecialName |
+ MethodAttributes.SpecialName);
+
+ if ((ModFlags & Modifiers.STATIC) != 0)
+ ca |= MethodAttributes.Static;
+
+ ConstructorBuilder = parent.TypeBuilder.DefineConstructor (
+ ca, GetCallingConvention (parent is Class),
+ ParameterTypes (parent));
+ }
+
+ //
+ // Emits the code
+ //
+ public void Emit ()
+ {
}
}
public class Property {
- TypeRef typeref;
- string name;
- int mod_flags;
- Block get_block, set_block;
-
+
+ public readonly string Type;
+ public readonly string Name;
+ public readonly int ModFlags;
+ public Block Get, Set;
+ public PropertyBuilder PropertyBuilder;
+ public Attributes OptAttributes;
+
const int AllowedModifiers =
Modifiers.NEW |
Modifiers.PUBLIC |
Modifiers.ABSTRACT |
Modifiers.VIRTUAL;
- public Property (TypeRef typeref, string name, int mod_flags, Block get_block, Block set_block)
+ public Property (string type, string name, int mod_flags, Block get_block, Block set_block, Attributes attrs)
{
- this.typeref = typeref;
- this.name = name;
- this.mod_flags = Modifiers.Check (AllowedModifiers, mod_flags, Modifiers.PRIVATE);
- this.get_block = get_block;
- this.set_block = set_block;
+ Type = type;
+ Name = name;
+ ModFlags = Modifiers.Check (AllowedModifiers, mod_flags, Modifiers.PRIVATE);
+ Get = get_block;
+ Set = set_block;
+ OptAttributes = attrs;
}
- public Type Type {
- get {
- return typeref.Type;
+ public void Define (TypeContainer parent)
+ {
+
+ MethodAttributes method_attr = Modifiers.MethodAttr(ModFlags);
+
+ // FIXME - how to handle PropertyAttributes.HasDefault
+
+ PropertyAttributes prop_attr = PropertyAttributes.RTSpecialName |
+ PropertyAttributes.SpecialName;
+
+
+ Type tp = parent.LookupType (Type, false);
+ Type [] prop_type = new Type [1];
+ prop_type [0] = tp;
+
+ MethodBuilder mb;
+
+ PropertyBuilder = parent.TypeBuilder.DefineProperty(Name, prop_attr, tp, null);
+
+ if (Get != null)
+ {
+ mb = parent.TypeBuilder.DefineMethod("get_" + Name, method_attr, tp, null);
+ PropertyBuilder.SetGetMethod (mb);
}
+
+ if (Set != null)
+ {
+ mb = parent.TypeBuilder.DefineMethod("set_" + Name, method_attr, null, prop_type);
+ mb.DefineParameter(1, ParameterAttributes.None, "value");
+ PropertyBuilder.SetSetMethod (mb);
+ }
+
}
- public string Name {
- get {
- return name;
- }
+ }
+
+ public class Event {
+
+ const int AllowedModifiers =
+ Modifiers.NEW |
+ Modifiers.PUBLIC |
+ Modifiers.PROTECTED |
+ Modifiers.INTERNAL |
+ Modifiers.PRIVATE |
+ Modifiers.STATIC |
+ Modifiers.VIRTUAL |
+ Modifiers.SEALED |
+ Modifiers.OVERRIDE |
+ Modifiers.ABSTRACT;
+
+ public readonly string Type;
+ public readonly string Name;
+ public readonly Object Initializer;
+ public readonly int ModFlags;
+ public readonly Block Add;
+ public readonly Block Remove;
+ public EventBuilder EventBuilder;
+ public Attributes OptAttributes;
+
+ public Event (string type, string name, Object init, int flags, Block add_block, Block rem_block,
+ Attributes attrs)
+ {
+ Type = type;
+ Name = name;
+ Initializer = init;
+ ModFlags = Modifiers.Check (AllowedModifiers, flags, Modifiers.PRIVATE);
+ Add = add_block;
+ Remove = rem_block;
+ OptAttributes = attrs;
}
- public int ModFlags {
- get {
- return mod_flags;
+ public void Define (TypeContainer parent)
+ {
+ MethodAttributes m_attr = Modifiers.MethodAttr (ModFlags);
+
+ EventAttributes e_attr = EventAttributes.RTSpecialName | EventAttributes.SpecialName;
+
+ MethodBuilder mb;
+
+ Type t = parent.LookupType (Type, false);
+ Type [] p_type = new Type [1];
+ p_type [0] = t;
+
+ EventBuilder = parent.TypeBuilder.DefineEvent (Name, e_attr, t);
+
+ if (Add != null) {
+ mb = parent.TypeBuilder.DefineMethod ("add_" + Name, m_attr, null, p_type);
+ mb.DefineParameter (1, ParameterAttributes.None, "value");
+ EventBuilder.SetAddOnMethod (mb);
}
- }
- public Block Get {
- get {
- return get_block;
+ if (Remove != null) {
+ mb = parent.TypeBuilder.DefineMethod ("remove_" + Name, m_attr, null, p_type);
+ mb.DefineParameter (1, ParameterAttributes.None, "value");
+ EventBuilder.SetRemoveOnMethod (mb);
}
}
+
+ }
+
+ public class Indexer {
+
+ const int AllowedModifiers =
+ Modifiers.NEW |
+ Modifiers.PUBLIC |
+ Modifiers.PROTECTED |
+ Modifiers.INTERNAL |
+ Modifiers.PRIVATE |
+ Modifiers.VIRTUAL |
+ Modifiers.SEALED |
+ Modifiers.OVERRIDE |
+ Modifiers.ABSTRACT;
+
+ public readonly string Type;
+ public readonly string InterfaceType;
+ public readonly Parameters FormalParameters;
+ public readonly int ModFlags;
+ public readonly Block Get;
+ public readonly Block Set;
+ public Attributes OptAttributes;
+ public MethodBuilder GetMethodBuilder;
+ public MethodBuilder SetMethodBuilder;
+
+
+ public Indexer (string type, string int_type, int flags, Parameters parms,
+ Block get_block, Block set_block, Attributes attrs)
+ {
+
+ Type = type;
+ InterfaceType = int_type;
+ ModFlags = Modifiers.Check (AllowedModifiers, flags, Modifiers.PRIVATE);
+ FormalParameters = parms;
+ Get = get_block;
+ Set = set_block;
+ OptAttributes = attrs;
+ }
- public Block Set {
- get {
- return set_block;
+ public void Define (TypeContainer parent)
+ {
+ MethodAttributes attr = Modifiers.MethodAttr (ModFlags);
+
+ Type ret_type = parent.LookupType (Type, false);
+ Type [] param_types = FormalParameters.GetParameterInfo (parent);
+
+ GetMethodBuilder = parent.TypeBuilder.DefineMethod ("get_Item", attr, ret_type, param_types);
+ SetMethodBuilder = parent.TypeBuilder.DefineMethod ("set_Item", attr, ret_type, param_types);
+
+ Parameter [] p = FormalParameters.FixedParameters;
+
+ if (p != null) {
+ int i;
+
+ for (i = 0; i < p.Length; ++i) {
+ GetMethodBuilder.DefineParameter (i + 1, p [i].Attributes, p [i].Name);
+ SetMethodBuilder.DefineParameter (i + 1, p [i].Attributes, p [i].Name);
+ }
+
+ if (i != param_types.Length)
+ Console.WriteLine ("Implement type definition for params");
}
+
}
+
+ }
+
+ public class Operator {
+
+ const int AllowedModifiers =
+ Modifiers.PUBLIC |
+ Modifiers.STATIC;
+
+ public enum OpType {
+
+ // Unary operators
+ Bang,
+ Tilde,
+ Increment,
+ Decrement,
+ True,
+ False,
+
+ // Unary and Binary operators
+ Plus,
+ Minus,
+
+ // Binary operators
+ Star,
+ Div,
+ Percent,
+ BitAnd,
+ BitOr,
+ Carret,
+ ShiftLeft,
+ ShiftRight,
+ Eq,
+ NotEq,
+ GreaterThan,
+ LesserThan,
+ GreaterOrEq,
+ LesserOrEq,
+
+ // Implicit and Explicit
+ Implicit,
+ Explicit
+ };
+
+ public readonly OpType OperatorType;
+ public readonly string ReturnType;
+ public readonly string FirstArgType;
+ public readonly string FirstArgName;
+ public readonly string SecondArgType;
+ public readonly string SecondArgName;
+ public readonly int ModFlags;
+ public readonly Block Block;
+ public Attributes OptAttributes;
+ public MethodBuilder OperatorMethodBuilder;
+
+ public Operator (OpType type, string ret_type, int flags, string arg1type, string arg1name,
+ string arg2type, string arg2name, Block block, Attributes attrs)
+ {
+ OperatorType = type;
+ ReturnType = ret_type;
+ ModFlags = Modifiers.Check (AllowedModifiers, flags, Modifiers.PUBLIC);
+ FirstArgType = arg1type;
+ FirstArgName = arg1name;
+ SecondArgType = arg2type;
+ SecondArgName = arg2name;
+ Block = block;
+ OptAttributes = attrs;
+ }
+
+ public void Define (TypeContainer parent)
+ {
+ MethodAttributes attr = Modifiers.MethodAttr (ModFlags);
+
+ string name = "Operator" + OperatorType;
+
+ Type ret_type = parent.LookupType (ReturnType, false);
+
+ Type [] param_types = new Type [2];
+
+ param_types [0] = parent.LookupType (FirstArgType, false);
+ if (SecondArgType != null)
+ param_types [1] = parent.LookupType (SecondArgType, false);
+
+ OperatorMethodBuilder = parent.TypeBuilder.DefineMethod (name, attr, ret_type, param_types);
+
+ OperatorMethodBuilder.DefineParameter (1, ParameterAttributes.None, FirstArgName);
+
+ if (SecondArgType != null)
+ OperatorMethodBuilder.DefineParameter (2, ParameterAttributes.None, SecondArgName);
+
+ }
+
+
}
+
}