+2001-08-13 Miguel de Icaza <miguel@ximian.com>
+
+ * class.cs: Put back walking code for type containers.
+
2001-08-11 Miguel de Icaza <miguel@ximian.com>
* class.cs (MakeConstant): Code to define constants.
-* Namespaces.
+* Ordering
- Currently the code can not resolve identifiers in other
- namespaces.
+ First define methods and operator overloads.
- namespace A {
- class X : B {
- }
- }
+ Do enumerations and constants.
- namespace A {
- class B {
- }
- }
+ Process function bodies
+
+ Can a constant_expression invoke overloaded operators?
+ Explicit user-defined conversions?
+
+* Tokenizer
+
+ Propagate file/location to upper layers
+
+* Error handling
+
+ Normalize, and use Tokenizer location
+
+* Enumerations
+
+ Currently I am not resolving enumerations.
+
+ Either I track them with `RecordEnum' as I do with classes,
+ structs and interfaces or I rewrite the code to visit type
+ containers and `walk' the enums with this process.
* Known problems:
Array r = (string []) object
Wont be parsed.
+
+
\ No newline at end of file
TypeContainer parent;
ArrayList type_bases;
- public TypeContainer (TypeContainer parent, string name) : base (name)
+ //
+ // This behaves like a property ;-)
+ //
+ readonly public RootContext RootContext;
+
+ public TypeContainer (RootContext rc, TypeContainer parent, string name) : base (name)
{
types = new Hashtable ();
this.parent = parent;
-
+ RootContext = rc;
+
string n;
if (parent == null)
n = "";
my_namespace = value;
}
}
-
+
//
// The Toplevel is `root_types' which is a containerfor all
// types defined, hence the non-obviios parent.parent.
}
}
- void MakeConstant (RootContext rc, Constant c)
- {
- FieldBuilder fb;
-
- fb = Definition.DefineField (c.Name,
- rc.LookupType (this, c.ConstantType),
- c.FieldAttr);
-
-
- }
-
//
// Populates our TypeBuilder with fields and methods
//
public void Populate (RootContext rc)
{
if (Constants != null){
- foreach (DictionaryEntry cde in Constants)
- MakeConstant (rc, (Constant) cde.Value);
+ foreach (DictionaryEntry cde in Constants){
+ Constant c = (Constant) cde.Value;
+
+ c.MakeConstant (rc, this);
+ }
+ }
+ }
+
+ public delegate void ExamineType (TypeContainer container, object cback_data);
+
+ void WalkTypesAt (TypeContainer root, ExamineType visit, object cback_data)
+ {
+ if (root == null)
+ return;
+
+ foreach (DictionaryEntry de in root.Types){
+ TypeContainer type = (TypeContainer) de.Value;
+
+ 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)
+ {
+ Console.WriteLine ("Is type container null? " + (this == null).ToString ());
+ return RootContext.LookupType (this, name, silent);
+ }
}
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)
+ : base (rc, parent, name)
{
int accmods;
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)
+ : base (rc, parent, name)
{
int accmods;
using System;
using System.Reflection;
+ using System.Reflection.Emit;
public class Constant : Expression {
string name;
return FieldAttributes.Literal | Modifiers.Map (mod_flags) ;
}
}
+
+ // <summary>
+ // Defines the constant in the @parent
+ // </summary>
+ public void MakeConstant (RootContext rc, TypeContainer parent)
+ {
+ FieldBuilder fb;
+ TypeCode tc;
+ Type t;
+
+ t = rc.LookupType (parent, type);
+ if (t == null)
+ return;
+
+ tc = System.Type.GetTypeCode (t);
+
+ if ((tc == TypeCode.SByte) || (tc == TypeCode.Byte) ||
+ (tc == TypeCode.Int16) || (tc == TypeCode.UInt16) ||
+ (tc == TypeCode.Int32) || (tc == TypeCode.Int64) ||
+ (tc == TypeCode.UInt32) || (tc == TypeCode.UInt64)) {
+
+ } else if ((tc == TypeCode.Double) || (tc == TypeCode.Single)) {
+
+ } else if (tc == TypeCode.Char) {
+ } else if (tc == TypeCode.Decimal) {
+
+ } else if (t.IsSubclassOf (typeof (System.String))) {
+
+ } else if (t.IsSubclassOf (typeof (System.Enum))) {
+
+ } else {
+ rc.Report.Error (-3, "Constant type is not valid (only system types are allowed");
+ return;
+ }
+
+ fb = parent.TypeBuilder.DefineField (name, t, FieldAttr);
+
+ }
}
}
// <summary>\r
// Used to record all types defined\r
// </summary>\r
- CIR.Tree tree;\r
+ Tree tree;\r
+ RootContext rc;\r
\r
// Name of the file we are parsing\r
public string name;\r
Struct new_struct;\r
string full_struct_name = MakeName ((string) $4);\r
\r
- new_struct = new Struct (current_container, full_struct_name, (int) $2);\r
+ new_struct = new Struct (rc, current_container, full_struct_name, (int) $2);\r
current_container = new_struct;\r
current_container.Namespace = current_namespace;\r
tree.RecordStruct (full_struct_name, new_struct);\r
Class new_class;\r
string full_class_name = MakeName ((string) $4);\r
\r
- new_class = new Class (current_container, full_class_name, (int) $2);\r
+ new_class = new Class (rc, current_container, full_class_name, (int) $2);\r
current_container = new_class;\r
current_container.Namespace = current_namespace;\r
tree.RecordClass (full_class_name, new_class);\r
\r
Tokenizer lexer;\r
\r
-public CSharpParser(CIR.Tree tree, string name, System.IO.Stream input) \r
+public CSharpParser(RootContext rc, string name, System.IO.Stream input) \r
{\r
current_namespace = new Namespace (null, "");\r
- this.tree = tree;\r
+ this.rc = rc;\r
+ this.tree = rc.Tree;\r
this.name = name;\r
this.input = input;\r
current_container = tree.Types;\r
}
}
- public TypeBuilder Definition {
+ public TypeBuilder TypeBuilder {
get {
return definition;
}
\r
int error_count = 0;\r
\r
- public int parse (Tree context, string input_file)\r
+ public int parse (string input_file)\r
{\r
CSharpParser parser;\r
System.IO.Stream input;\r
continue;\r
}\r
\r
- errors += parse (context.Tree, arg);\r
+ errors += parse (arg);\r
}\r
\r
//\r
Hashtable defined_events;
Hashtable defined_properties;
+ TypeContainer parent;
+
// These will happen after the semantic analysis
// Hashtable defined_indexers;
defined_properties = new Hashtable ();
this.mod_flags = Modifiers.Check (AllowedModifiers, mod, Modifiers.PUBLIC);
+ this.parent = parent;
}
public AdditionResult AddMethod (InterfaceMethod imethod)
bases = value;
}
}
+
+ void Error111 (InterfaceMethod im)
+ {
+ parent.RootContext.Report.Error (
+ 111,
+ "Interface `" + Name + "' already contains a definition with the " +
+ "same return value and paramenter types for method `" + im.Name + "'");
+ }
+
+ void PopulateMethods ()
+ {
+ foreach (InterfaceMethod im in defined_method_list){
+ Type ReturnType = parent.LookupType (im.ReturnType, true);
+
+ TypeBuilder.DefineMethod (
+ im.Name, MethodAttributes.Public,
+ ReturnType, im.ParameterTypes (parent));
+ }
+ }
+
+ // <summary>
+ // Performs the semantic analysis for all the interface members
+ // that were declared
+ // </summary>
+ bool SemanticAnalysis ()
+ {
+ Hashtable methods = new Hashtable ();
+
+ //
+ // First check that all methods with the same name
+ // have a different signature.
+ //
+ foreach (InterfaceMethod im in defined_method_list){
+ string sig = im.GetSignature (parent);
+
+ //
+ // If there was an undefined Type on the signatures
+ //
+ if (sig == null)
+ continue;
+
+ if (methods [sig] != null){
+ Error111 (im);
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ // <summary>
+ // Performs semantic analysis, and then generates the IL interfaces
+ // </summary>
+ public void Populate ()
+ {
+ if (!SemanticAnalysis ())
+ return;
+
+ PopulateMethods ();
+ }
}
public class InterfaceMemberBase {
}
public class InterfaceMethod : InterfaceMemberBase {
- string return_type;
- bool is_new;
- Parameters args;
+ public readonly string ReturnType;
+ public readonly bool IsNew;
+ public readonly Parameters Parameters;
public InterfaceMethod (string return_type, string name, bool is_new, Parameters args)
: base (name)
{
- this.return_type = return_type;
- this.is_new = is_new;
- this.args = args;
+ this.ReturnType = return_type;
+ this.IsNew = is_new;
+ this.Parameters = args;
}
- public string ReturnType {
- get {
- return return_type;
- }
- }
+ // <summary>
+ // Returns the signature for this interface method
+ // </summary>
+ public string GetSignature (TypeContainer tc)
+ {
+ Type ret = tc.LookupType (ReturnType, false);
+ string args = Parameters.GetSignature (tc);
- public bool IsNew {
- get {
- return is_new;
- }
+ if ((ret == null) || (args == null))
+ return null;
+
+ return (IsNew ? "new-" : "") + ret.FullName + "(" + args + ")";
}
- public Parameters Parameters {
- get {
- return args;
- }
+ public Type [] ParameterTypes (TypeContainer tc)
+ {
+ return Parameters.GetTypes (tc);
}
+
}
public class InterfaceIndexer : InterfaceMemberBase {
namespace CIR {
using System;
-
- public class Parameter {
+ public class Parameter {
public enum Modifier {
NONE,
REF,
PARAMS,
}
- string type;
- string name;
- Modifier mod;
+ public readonly string Type;
+ public readonly string Name;
+ public readonly Modifier ModFlags;
public Parameter (string type, string name, Modifier mod)
{
- this.name = name;
- this.mod = mod;
- this.type = type;
+ Name = name;
+ ModFlags = mod;
+ Type = type = type;
}
string ModSignature ()
{
- switch (mod){
+ switch (ModFlags){
case Modifier.NONE:
return "";
case Modifier.REF:
// This should not happen.
return (string) null;
}
-
- public string Signature {
- get {
- return ModSignature (); // TYPEFIX: + Type.GetTypeEncoding (typeref.Type);
- }
- }
-
- public string Type {
- get {
- return type;
- }
- }
- public string Name {
- get {
- return name;
- }
- }
+ // <summary>
+ // Returns the signature for this parameter evaluating it on the
+ // @tc context
+ // </summary>
+ public string GetSignature (TypeContainer tc)
+ {
+ Type t = tc.LookupType (Type, false);
- public Modifier ModFlags {
- get {
- return mod;
- }
+ if (t == null)
+ return "";
+
+ return ModSignature () + t.FullName;
}
}
this.array_parameter = array_parameter;
}
- void compute_signature ()
- {
- signature = "";
-
- if (fixed_parameters != null){
- for (int i = 0; i < fixed_parameters.Count; i++){
- Parameter par = (Parameter) fixed_parameters [i];
-
- signature += par.Signature;
- }
- }
-
- //
- // Note: as per the spec, the `params' arguments (array_parameter)
- // are not used in the signature computation for a method
- //
- }
-
+ // <summary>
+ // Returns the fixed parameters element
+ // </summary>
public ParameterCollection FixedParameters {
get {
return fixed_parameters;
}
}
+ // <summary>
+ // Returns the array parameter.
+ // </summary>
public Parameter ArrayParameter {
get {
return array_parameter;
}
}
- // Removed for now, as we can not compute this at
- // boot strap.
- public string Signature {
- get {
- return signature;
+ public void ComputeSignature (TypeContainer tc)
+ {
+ signature = "";
+ if (fixed_parameters != null){
+ for (int i = 0; i < fixed_parameters.Count; i++){
+ Parameter par = (Parameter) fixed_parameters [i];
+
+ signature += par.GetSignature (tc);
+ }
}
+ //
+ // Note: as per the spec, the `params' arguments (array_parameter)
+ // are not used in the signature computation for a method
+ //
}
+ // <summary>
+ // Returns the signature of the Parameters evaluated in
+ // the @tc environment
+ // </summary>
+ public string GetSignature (TypeContainer tc)
+ {
+ if (signature == null)
+ ComputeSignature (tc);
+
+ return signature;
+ }
+
+ // <summary>
+ // Returns the paramenter information based on the name
+ // </summary>
public Parameter GetParameterByName (string name)
{
if (fixed_parameters == null)
foreach (Parameter par in fixed_parameters)
if (par.Name == name)
return par;
+
return null;
}
+
+ // <summary>
+ // Returns the argument types as an array
+ // </summary>
+ public Type [] GetTypes (TypeContainer tc)
+ {
+ int extra = (array_parameter != null) ? 1 : 0;
+ Type [] types = new Type [fixed_parameters.Count + extra];
+ int i = 0;
+
+ foreach (Parameter p in fixed_parameters){
+ types [i++] = tc.LookupType (p.Name, false);
+ }
+
+ if (extra > 0)
+ types [i] = Type.GetType ("System.Object");
+
+ return types;
+ }
}
}
+
public RootContext ()
{
- tree = new Tree ();
+ tree = new Tree (null);
type_manager = new TypeManager ();
report = new Report ();
//
TypeBuilder CreateInterface (Interface iface)
{
- TypeBuilder tb = iface.Definition;
+ TypeBuilder tb = iface.TypeBuilder;
Type [] ifaces;
string name;
bool error;
TypeAttributes.Abstract,
null, // Parent Type
ifaces);
- iface.Definition = tb;
+ iface.TypeBuilder = tb;
type_manager.AddUserType (name, tb);
//
TypeBuilder CreateType (TypeContainer tc, bool is_class)
{
- TypeBuilder tb = tc.Definition;
+ TypeBuilder tb = tc.TypeBuilder;
Type parent;
Type [] ifaces;
bool error;
parent,
ifaces);
- tc.Definition = tb;
+ tc.TypeBuilder = tb;
type_manager.AddUserType (name, tb);
tc.InTransit = false;
return LookupType (tc, name, true);
}
- public void PopulateInterface (Interface ifacex)
- {
-
- }
-
// <summary>
// Populates the structs and classes with fields and methods
// </summary>
{
Hashtable ifaces, classes;
- if ((ifaces = tree.Interfaces) != null)
- foreach (DictionaryEntry de in ifaces)
- PopulateInterface ((Interface) de.Value);
+ if ((ifaces = tree.Interfaces) != null){
+ foreach (DictionaryEntry de in ifaces){
+ Interface iface = (Interface) de.Value;
+
+ iface.Populate ();
+ }
+ }
if ((classes = tree.Classes) != null){
foreach (DictionaryEntry de in classes){
tc.Populate (this);
}
}
-
}
-
+
// <summary>
// Compiling against Standard Libraries property.
// </summary>
// </summary>
Hashtable classes;
- public Tree ()
+ RootContext rc;
+
+ public Tree (RootContext rc)
{
- root_types = new TypeContainer (null, "");
+ root_types = new TypeContainer (rc, null, "");
+ this.rc = rc;
}