[Mono-list] patch : nested types support

Ravi Pratap ravi@ximian.com
12 Oct 2001 13:54:15 +0530


Hey guys,

	Okay, patches start going here from now :-)

	Here's a patch I committed last night .We now have full support
for nested types. On the agenda next is delegate support.

	Regards,

		Ravi

Index: ChangeLog
===================================================================
RCS file: /cvs/public/mcs/mcs/ChangeLog,v
retrieving revision 1.128
diff -u -r1.128 ChangeLog
--- ChangeLog	2001/10/10 02:36:47	1.128
+++ ChangeLog	2001/10/11 16:43:53
@@ -1,3 +1,61 @@
+2001-10-11  Ravi Pratap  <ravi@ximian.com>
+
+	* class.cs (TypeContainer::DefineType): Method to actually do the business of
+	defining the type in the Modulebuilder or Typebuilder. This is to take
+	care of nested types which need to be defined on the TypeBuilder using
+	DefineNestedMethod.
+
+	(TypeContainer::GetClassBases): Implement. Essentially the code from the 
+	methods in RootContext, only ported to be part of TypeContainer.
+
+	(TypeContainer::GetInterfaceOrClass): Ditto.
+
+	(TypeContainer::LookupInterfaceOrClass, ::MakeFQN): Ditto.
+
+	* interface.cs (Interface::DefineInterface): New method. Does exactly
+	what RootContext.CreateInterface did earlier, only it takes care of nested types 
+	too.
+
+	(Interface::GetInterfaces): Move from RootContext here and port.
+
+	(Interface::GetInterfaceByName): Same here.
+
+	* rootcontext.cs (ResolveTree): Re-write.
+
+	(PopulateTypes): Re-write.
+
+	* class.cs (TypeContainer::Populate): Populate nested types too.
+	(TypeContainer::Emit): Emit nested members too.
+
+	* typemanager.cs (AddUserType): Do not make use of the FullName property,
+	instead just use the name argument passed in as it is already fully
+	qualified.
+
+	(FindMembers): Check in the Builders to TypeContainer mapping instead of the name
+	to TypeContainer mapping to see if a type is user-defined.
+
+	* class.cs (TypeContainer::CloseType): Implement. 
+
+	(TypeContainer::DefineDefaultConstructor): Use Basename, not Name while creating
+	the default constructor.
+	
+	(TypeContainer::Populate): Fix minor bug which led to creating default constructors
+	twice.
+
+	(Constructor::IsDefault): Fix up logic to determine if it is the default constructor
+
+	* interface.cs (CloseType): Create the type here.
+	
+	* rootcontext.cs (CloseTypes): Re-write to recursively close types by running through
+	the hierarchy.
+
+	Remove all the methods which are now in TypeContainer.
+
+2001-10-10  Ravi Pratap  <ravi@ximian.com>
+
+	* delegate.cs (Define): Re-write bits to define the delegate
+	correctly.
+
 2001-10-10  Miguel de Icaza  <miguel@ximian.com>
 
 	* makefile: Renamed the compiler to `mcs.exe' instead of compiler.exe
Index: class.cs
===================================================================
RCS file: /cvs/public/mcs/mcs/class.cs,v
retrieving revision 1.71
diff -u -r1.71 class.cs
--- class.cs	2001/10/10 02:36:47	1.71
+++ class.cs	2001/10/11 16:44:00
@@ -537,16 +537,19 @@
 			Constructor c;
 			int mods = 0;
 
-			c = new Constructor (Name, new Parameters (null, null),
+			c = new Constructor (Basename, new Parameters (null, null),
 					     new ConstructorBaseInitializer (null, new Location (-1)),
 					     new Location (-1));
+			
 			AddConstructor (c);
+			
 			c.Block = new Block (null);
 			
 			if (is_static)
 				mods = Modifiers.STATIC;
+
+			c.ModFlags = mods;
 
-			c.ModFlags = mods;	
 		}
 
 		public void ReportStructInitializedInstanceError ()
@@ -594,6 +597,282 @@
 			else
 				return mb.MethodHandle.ToString ();
 		}
+
+
+		public static string MakeFQN (string nsn, string name)
+		{
+			string prefix = (nsn == "" ? "" : nsn + ".");
+
+			return prefix + name;
+		}
+		       
+		Type LookupInterfaceOrClass (object builder, string ns, string name, bool is_class, out bool error)
+		{
+			TypeContainer parent;
+			Type t;
+
+			error = false;
+			name = MakeFQN (ns, name);
+			
+			t  = RootContext.TypeManager.LookupType (name);
+			if (t != null)
+				return t;
+
+			if (is_class){
+				parent = (Class) RootContext.Tree.Classes [name];
+			} else {
+				parent = (Struct) RootContext.Tree.Structs [name];
+			}
+			
+			if (parent != null){
+				t = parent.DefineType (builder);
+				if (t == null){
+					Report.Error (146, "Class definition is circular: `"+name+"'");
+					error = true;
+					return null;
+				}
+
+				return t;
+			}
+
+			return null;
+		}
+		
+		//
+		// returns the type for an interface or a class, this will recursively
+		// try to define the types that it depends on.
+		//
+		Type GetInterfaceOrClass (object builder, string name, bool is_class)
+		{
+			Type t;
+			bool error;
+
+			//
+			// Attempt to lookup the class on our namespace
+			//
+			t = LookupInterfaceOrClass (builder, Namespace.Name, name, is_class, out error);
+			if (error)
+				return null;
+			
+			if (t != null) 
+				return t;
+
+			//
+			// Attempt to lookup the class on any of the `using'
+			// namespaces
+			//
+
+			for (Namespace ns = Namespace; ns != null; ns = ns.Parent){
+				ArrayList using_list = ns.UsingTable;
+				
+				if (using_list == null)
+					continue;
+
+				foreach (string n in using_list){
+					t = LookupInterfaceOrClass (builder, n, name, is_class, out error);
+					if (error)
+						return null;
+
+					if (t != null)
+						return t;
+				}
+				
+			}
+			Report.Error (246, "Can not find type `"+name+"'");
+			return null;
+		}
+
+		//
+		// This function computes the Base class and also the
+		// list of interfaces that the class or struct @c implements.
+		//
+		// The return value is an array (might be null) of
+		// interfaces implemented (as Types).
+		//
+		// The @parent argument is set to the parent object or null
+		// if this is `System.Object'. 
+		//
+		Type [] GetClassBases (object builder, bool is_class, out Type parent, out bool error)
+		{
+			ArrayList bases = Bases;
+			int count;
+			int start, j, i;
+			
+			error = false;
+
+			if (is_class)
+				parent = null;
+			else
+				parent = TypeManager.value_type;
+
+			if (bases == null){
+				if (is_class){
+					if (RootContext.StdLib)
+						parent = TypeManager.object_type;
+					else if (Name != "System.Object")
+						parent = TypeManager.object_type;
+				} else {
+					//
+					// If we are compiling our runtime,
+					// and we are defining ValueType, then our
+					// parent is `System.Object'.
+					//
+					if (!RootContext.StdLib && Name == "System.ValueType")
+						parent = TypeManager.object_type;
+				}
+
+				return null;
+			}
+
+			//
+			// Bases should be null if there are no bases at all
+			//
+			count = bases.Count;
+
+			if (is_class){
+				string name = (string) bases [0];
+				Type first = GetInterfaceOrClass (builder, name, is_class);
+
+				if (first == null){
+					error = true;
+					return null;
+				}
+				
+				if (first.IsClass){
+					parent = first;
+					start = 1;
+				} else {
+					parent = TypeManager.object_type;
+					start = 0;
+				}
+			} else {
+				start = 0;
+			}
+
+			Type [] ifaces = new Type [count-start];
+			
+			for (i = start, j = 0; i < count; i++, j++){
+				string name = (string) bases [i];
+				Type t = GetInterfaceOrClass (builder, name, is_class);
+				
+				if (t == null){
+					error = true;
+					return null;
+				}
+
+				if (is_class == false && !t.IsInterface){
+					Report.Error (527, "In Struct `" + Name + "', type `"+
+						      name +"' is not an interface");
+					error = true;
+					return null;
+				}
+				
+				if (t.IsSealed) {
+					string detail = "";
+					
+					if (t.IsValueType)
+						detail = " (a class can not inherit from a struct)";
+							
+					Report.Error (509, "class `"+ Name +
+						      "': Cannot inherit from sealed class `"+
+						      bases [i]+"'"+detail);
+					error = true;
+					return null;
+				}
+
+				if (t.IsClass) {
+					if (parent != null){
+						Report.Error (527, "In Class `" + Name + "', type `"+
+							      name+"' is not an interface");
+						error = true;
+						return null;
+					}
+				}
+				
+				ifaces [j] = t;
+			}
+
+			return ifaces;
+		}
+		
+		//
+		// Defines the type in the appropriate ModuleBuilder or TypeBuilder.
+		//
+		public TypeBuilder DefineType (object parent_builder)
+		{
+			Type parent;
+			Type [] ifaces;
+			bool error;
+			bool is_class;
+			
+			if (InTransit)
+				return null;
+			
+			InTransit = true;
+			
+			if (this is Class)
+				is_class = true;
+			else
+				is_class = false;
+			
+			ifaces = GetClassBases (parent_builder, is_class, out parent, out error); 
+			
+			if (error)
+				return null;
+			
+			if (parent_builder is ModuleBuilder) {
+				ModuleBuilder builder = (ModuleBuilder) parent_builder;
+				
+				//
+				// Structs with no fields need to have a ".size 1"
+				// appended
+				//
+				if (!is_class && Fields == null)
+					TypeBuilder = builder.DefineType (Name,
+									  TypeAttr,
+									  parent, 
+									  PackingSize.Unspecified, 1);
+				else
+				//
+				// classes or structs with fields
+				//
+					TypeBuilder = builder.DefineType (Name,
+									  TypeAttr,
+									  parent,
+									  ifaces);
+
+			} else {
+				TypeBuilder builder = (TypeBuilder) parent_builder;
+				
+				//
+				// Structs with no fields need to have a ".size 1"
+				// appended
+				//
+				if (!is_class && Fields == null)
+					TypeBuilder = builder.DefineNestedType (Name,
+										TypeAttr,
+										parent, 
+										PackingSize.Unspecified);
+				else
+				//
+				// classes or structs with fields
+				//
+					TypeBuilder = builder.DefineNestedType (Name,
+										TypeAttr,
+										parent,
+										ifaces);
+			}
+
+			RootContext.TypeManager.AddUserType (Name, TypeBuilder, this);
+
+			if (Types != null) {
+				foreach (TypeContainer tc in Types)
+					tc.DefineType (TypeBuilder);
+			}
+			
+			InTransit = false;
+			return TypeBuilder;
+		}
 		
 		//
 		// Populates our TypeBuilder with fields and methods
@@ -610,7 +889,7 @@
 					f.Define (this);
 			} 
 
-			if (this is Class){
+			if (this is Class && constructors == null){
 				if (default_constructor == null) 
 					DefineDefaultConstructor (false);
 
@@ -713,6 +992,11 @@
 				foreach (Delegate d in Delegates)
 					d.Define (this);
 			}
+			
+			if (Types != null) {
+				foreach (TypeContainer tc in Types)
+					tc.Populate ();
+			}
 		}
 
 		//
@@ -1003,6 +1287,19 @@
 
 			if (pending_implementations != null)
 				VerifyPendingMethods ();
+
+			if (types != null)
+				foreach (TypeContainer tc in types)
+					tc.Emit ();
+			
+		}
+
+		public void CloseType ()
+		{
+			TypeBuilder.CreateType ();
+			
+			foreach (TypeContainer tc in Types)
+				tc.CloseType ();
 		}
 
 		string MakeName (string n)
@@ -1575,7 +1872,8 @@
 		//
 		public bool IsDefault ()
 		{
-			return  (Parameters == null ? true : Parameters.Empty) &&
+			return  (Parameters.FixedParameters == null ? true : Parameters.Empty) &&
+				(Parameters.ArrayParameter == null ? true : Parameters.Empty) &&
 				(Initializer is ConstructorBaseInitializer) &&
 				(Initializer.Arguments == null);
 		}
Index: cs-parser.jay
===================================================================
RCS file: /cvs/public/mcs/mcs/cs-parser.jay,v
retrieving revision 1.62
diff -u -r1.62 cs-parser.jay
--- cs-parser.jay	2001/10/10 02:36:47	1.62
+++ cs-parser.jay	2001/10/11 16:44:06
@@ -916,7 +916,7 @@
 		Interface new_interface;
 		string full_interface_name = MakeName ((string) $4);
 
-		new_interface = new Interface (current_container, full_interface_name, (int) $2, 
+		new_interface = new Interface (rc, current_container, full_interface_name, (int) $2, 
 					       (Attributes) $1, lexer.Location);
 		if (current_interface != null) {
 			Location l = lexer.Location;
Index: delegate.cs
===================================================================
RCS file: /cvs/public/mcs/mcs/delegate.cs,v
retrieving revision 1.5
diff -u -r1.5 delegate.cs
--- delegate.cs	2001/09/30 02:22:09	1.5
+++ delegate.cs	2001/10/11 16:44:06
@@ -16,15 +16,17 @@
 
 namespace CIR {
 	
-	public class Delegate : DeclSpace {
+	public class Delegate {
 
-		public string name;
+		public string Name;
 		public string type;
 		public int    mod_flags;
 		public Parameters Parameters;
 		public Attributes OptAttributes;
 		public TypeBuilder DelegateBuilder;
 
+		Location loc;
+
 		const int AllowedModifiers =
 			Modifiers.NEW |
 			Modifiers.PUBLIC |
@@ -33,26 +35,32 @@
 			Modifiers.PRIVATE;
 
 		public Delegate (string type, int mod_flags, string name, Parameters param_list,
-				 Attributes attrs, Location l) : base (name, l)
+				 Attributes attrs, Location loc)
 		{
-			this.name       = name;
+			this.Name       = name;
 			this.type       = type;
 			this.mod_flags  = Modifiers.Check (AllowedModifiers, mod_flags, Modifiers.PUBLIC);
 			Parameters      = param_list;
 			OptAttributes   = attrs;
+			this.loc        = loc;
 		}
 
 		public void Define (TypeContainer parent)
 		{
-			TypeAttributes attr = Modifiers.TypeAttr (ModFlags, parent);
-
+			TypeAttributes attr;
+			
+			if (parent.IsTopLevel)
+				attr = TypeAttributes.NestedPublic | TypeAttributes.Class;
+			else
+				attr = TypeAttributes.Public | TypeAttributes.Class;
+			
 			Type t = parent.LookupType (type, false);
 			Type [] param_types = Parameters.GetParameterInfo (parent);
 			Type base_type = System.Type.GetType ("System.MulticastDelegate");
 
-			DelegateBuilder = parent.TypeBuilder.DefineNestedType (name, attr, base_type);
+			DelegateBuilder = parent.TypeBuilder.DefineNestedType (Name, attr, base_type);
 
-			// FIXME : Need to figure out how to proceed from here. 
+			//DelegateBuilder.CreateType ();
 
 		}
 		
Index: expression.cs
===================================================================
RCS file: /cvs/public/mcs/mcs/expression.cs,v
retrieving revision 1.78
diff -u -r1.78 expression.cs
--- expression.cs	2001/10/10 02:36:47	1.78
+++ expression.cs	2001/10/11 16:44:13
@@ -3982,7 +3982,7 @@
 					return null;
 				
 				Expression ml;
-				
+
 				ml = MemberLookup (ec, type, ".ctor", false,
 						   MemberTypes.Constructor, AllBindingsFlags);
 				
@@ -4012,7 +4012,7 @@
 					       "New invocation: Can not find a constructor for this argument list");
 					return null;
 				}
-
+				
 				eclass = ExprClass.Value;
 				return this;
 			}
Index: interface.cs
===================================================================
RCS file: /cvs/public/mcs/mcs/interface.cs,v
retrieving revision 1.14
diff -u -r1.14 interface.cs
--- interface.cs	2001/10/03 21:37:52	1.14
+++ interface.cs	2001/10/11 16:44:15
@@ -44,6 +44,8 @@
 		TypeContainer parent;
 
 		Attributes OptAttributes;
+
+		public readonly RootContext RootContext;
 		
 		// These will happen after the semantic analysis
 		
@@ -60,13 +62,14 @@
 			Modifiers.INTERNAL |
 			Modifiers.PRIVATE;
 
-		public Interface (TypeContainer parent, string name, int mod, Attributes attrs, Location l)
+		public Interface (RootContext rc, TypeContainer parent, string name, int mod, Attributes attrs, Location l)
 			: base (name, l)
 		{
 			this.mod_flags = Modifiers.Check (AllowedModifiers, mod, Modifiers.PUBLIC);
 			this.parent = parent;
 			OptAttributes = attrs;
-
+			RootContext = rc;
+			
 			method_builders = new ArrayList ();
 		}
 
@@ -439,6 +442,143 @@
 			return true;
 		}
 
+		//
+		// Returns the Type that represents the interface whose name
+		// is `name'.
+		//
+		
+		Type GetInterfaceTypeByName (object builder, string name)
+		{
+			Interface parent;
+			Type t = RootContext.TypeManager.LookupType (name);
+			
+			if (t != null) {
+
+				if (t.IsInterface)
+					return t;
+				
+				string cause;
+				
+				if (t.IsValueType)
+					cause = "is a struct";
+				else if (t.IsClass) 
+					cause = "is a class";
+				else
+					cause = "Should not happen.";
+
+				Report.Error (527, "`"+name+"' " + cause + ", need an interface instead");
+				
+				return null;
+			}
+
+			Tree tree = RootContext.Tree;
+			parent = (Interface) tree.Interfaces [name];
+			if (parent == null){
+				string cause = "is undefined";
+				
+				if (tree.Classes [name] != null)
+					cause = "is a class";
+				else if (tree.Structs [name] != null)
+					cause = "is a struct";
+				
+				Report.Error (527, "`"+name+"' " + cause + ", need an interface instead");
+				return null;
+			}
+			
+			t = parent.DefineInterface (builder);
+			if (t == null){
+				Report.Error (529,
+					      "Inherited interface `"+name+"' is circular");
+				return null;
+			}
+
+			return t;
+		}
+		
+		//
+		// Returns the list of interfaces that this interface implements
+		// Or null if it does not implement any interface.
+		//
+		// Sets the error boolean accoringly.
+		//
+		Type [] GetInterfaceBases (object builder, out bool error)
+		{
+			Type [] tbases;
+			int i;
+
+			error = false;
+			if (Bases == null)
+				return null;
+			
+			tbases = new Type [Bases.Count];
+			i = 0;
+
+			foreach (string name in Bases){
+				Type t;
+				
+				t = GetInterfaceTypeByName (builder, name);
+				if (t == null){
+					error = true;
+					return null;
+				}
+				
+				tbases [i++] = t;
+			}
+			
+			return tbases;
+		}
+		
+		//
+		// <summary>
+		//  Defines the Interface in the appropriate ModuleBuilder or TypeBuilder
+		// </summary>
+		// TODO:
+		//   Rework the way we recurse, because for recursive
+		//   definitions of interfaces (A:B and B:A) we report the
+		//   error twice, rather than once.  
+		
+		public TypeBuilder DefineInterface (object parent_builder)
+		{
+			Type [] ifaces;
+			bool error;
+
+			if (InTransit)
+				return null;
+			
+			InTransit = true;
+			
+			ifaces = GetInterfaceBases (parent_builder, out error);
+
+			if (error)
+				return null;
+
+			if (parent_builder is ModuleBuilder) {
+				ModuleBuilder builder = (ModuleBuilder) parent_builder;
+				
+				TypeBuilder = builder.DefineType (Name,
+								  TypeAttributes.Interface |
+								  InterfaceAttr |
+								  TypeAttributes.Abstract,
+								  null,   // Parent Type
+								  ifaces);
+			} else {
+				TypeBuilder builder = (TypeBuilder) parent_builder;
+
+				TypeBuilder = builder.DefineNestedType (Name,
+									TypeAttributes.Interface |
+									InterfaceAttr |
+									TypeAttributes.Abstract,
+									null,   // Parent Type
+									ifaces);
+			}
+			
+			RootContext.TypeManager.AddUserInterface (Name, TypeBuilder, this);
+			
+			InTransit = false;
+			
+			return TypeBuilder;
+		}
+		
 		// <summary>
 		//   Performs semantic analysis, and then generates the IL interfaces
 		// </summary>
@@ -465,6 +605,12 @@
 				foreach (InterfaceIndexer ii in defined_indexer)
 					PopulateIndexer (ii);
 		}
+
+		public void CloseType ()
+		{
+			TypeBuilder.CreateType ();
+		}
+		
 	}
 
 	public class InterfaceMemberBase {
Index: rootcontext.cs
===================================================================
RCS file: /cvs/public/mcs/mcs/rootcontext.cs,v
retrieving revision 1.33
diff -u -r1.33 rootcontext.cs
--- rootcontext.cs	2001/10/10 02:36:47	1.33
+++ rootcontext.cs	2001/10/11 16:44:15
@@ -84,139 +84,6 @@
 			}
 		}
 
-		//
-		// Returns the Type that represents the interface whose name
-		// is `name'.
-		//
-		
-		Type GetInterfaceTypeByName (string name)
-		{
-			Interface parent;
-			Type t = TypeManager.LookupType (name);
-
-			if (t != null) {
-
-				if (t.IsInterface)
-					return t;
-				
-				string cause;
-				
-				if (t.IsValueType)
-					cause = "is a struct";
-				else if (t.IsClass) 
-					cause = "is a class";
-				else
-					cause = "Should not happen.";
-
-				Report.Error (527, "`"+name+"' " + cause + ", need an interface instead");
-				
-				return null;
-			}
-
-			parent = (Interface) tree.Interfaces [name];
-			if (parent == null){
-				string cause = "is undefined";
-				
-				if (tree.Classes [name] != null)
-					cause = "is a class";
-				else if (tree.Structs [name] != null)
-					cause = "is a struct";
-				
-				Report.Error (527, "`"+name+"' " + cause + ", need an interface instead");
-				return null;
-			}
-
-			t = CreateInterface ((Interface) parent);
-			if (t == null){
-				Report.Error (529,
-					      "Inherited interface `"+name+"' is circular");
-				return null;
-			}
-
-			return t;
-		}
-		
-		//
-		// Returns the list of interfaces that this interface implements
-		// Or null if it does not implement any interface.
-		//
-		// Sets the error boolean accoringly.
-		//
-		Type [] GetInterfaceBases (Interface iface, out bool error)
-		{
-			ArrayList bases = iface.Bases;
-			Type [] tbases;
-			int i;
-
-			error = false;
-			if (bases == null)
-				return null;
-			
-			tbases = new Type [bases.Count];
-			i = 0;
-
-			foreach (string name in iface.Bases){
-				Type t;
-
-				t = GetInterfaceTypeByName (name);
-				if (t == null){
-					error = true;
-					return null;
-				}
-				
-				tbases [i++] = t;
-			}
-
-			return tbases;
-		}
-		
-		//
-		// Creates the Interface @iface using the ModuleBuilder
-		//
-		// TODO:
-		//   Rework the way we recurse, because for recursive
-		//   definitions of interfaces (A:B and B:A) we report the
-		//   error twice, rather than once.  
-		//
-		TypeBuilder CreateInterface (Interface iface)
-		{
-			TypeBuilder tb = iface.TypeBuilder;
-			Type [] ifaces;
-			string name;
-			bool error;
-
-			if (tb != null)
-				return tb;
-			
-			if (iface.InTransit)
-				return null;
-			
-			iface.InTransit = true;
-
-			name = iface.Name;
-
-			ifaces = GetInterfaceBases (iface, out error);
-
-			if (error)
-				return null;
-
-			tb = mb.DefineType (name,
-					    TypeAttributes.Interface |
-					    iface.InterfaceAttr |
-					    TypeAttributes.Abstract,
-					    null,   // Parent Type
-					    ifaces);
-			iface.TypeBuilder = tb;
-
-			interface_resolve_order.Add (iface);
-			
-			TypeManager.AddUserInterface (name, tb, iface);
-
-			iface.InTransit = false;
-
-			return tb;
-		}
-
 		string MakeFQN (string nsn, string name)
 		{
 			string prefix = (nsn == "" ? "" : nsn + ".");
@@ -224,252 +91,6 @@
 			return prefix + name;
 		}
 		       
-		Type LookupInterfaceOrClass (string ns, string name, bool is_class, out bool error)
-		{
-			TypeContainer parent;
-			Type t;
-
-			error = false;
-			name = MakeFQN (ns, name);
-			
-			t  = TypeManager.LookupType (name);
-			if (t != null)
-				return t;
-
-			if (is_class){
-				parent = (Class) tree.Classes [name];
-			} else {
-				parent = (Struct) tree.Structs [name];
-			}
-
-			if (parent != null){
-				t = CreateType (parent, is_class);
-				if (t == null){
-					Report.Error (146, "Class definition is circular: `"+name+"'");
-					error = true;
-					return null;
-				}
-
-				return t;
-			}
-
-			return null;
-		}
-		
-		//
-		// returns the type for an interface or a class, this will recursively
-		// try to define the types that it depends on.
-		//
-		Type GetInterfaceOrClass (TypeContainer tc, string name, bool is_class)
-		{
-			Type t;
-			bool error;
-
-			//
-			// Attempt to lookup the class on our namespace
-			//
-			t = LookupInterfaceOrClass (tc.Namespace.Name, name, is_class, out error);
-			if (error)
-				return null;
-			
-			if (t != null) 
-				return t;
-
-			//
-			// Attempt to lookup the class on any of the `using'
-			// namespaces
-			//
-
-			for (Namespace ns = tc.Namespace; ns != null; ns = ns.Parent){
-				ArrayList using_list = ns.UsingTable;
-
-				if (using_list == null)
-					continue;
-
-				foreach (string n in using_list){
-					t = LookupInterfaceOrClass (n, name, is_class, out error);
-					if (error)
-						return null;
-
-					if (t != null)
-						return t;
-				}
-				
-			}
-			Report.Error (246, "Can not find type `"+name+"'");
-			return null;
-		}
-
-		//
-		// This function computes the Base class and also the
-		// list of interfaces that the class or struct @c implements.
-		//
-		// The return value is an array (might be null) of
-		// interfaces implemented (as Types).
-		//
-		// The @parent argument is set to the parent object or null
-		// if this is `System.Object'. 
-		//
-		Type [] GetClassBases (TypeContainer tc, bool is_class, out Type parent, out bool error)
-		{
-			ArrayList bases = tc.Bases;
-			int count;
-			int start, j, i;
-			
-			error = false;
-
-			if (is_class)
-				parent = null;
-			else
-				parent = TypeManager.value_type;
-
-			if (bases == null){
-				if (is_class){
-					if (stdlib)
-						parent = TypeManager.object_type;
-					else if (tc.Name != "System.Object")
-						parent = TypeManager.object_type;
-				} else {
-					//
-					// If we are compiling our runtime,
-					// and we are defining ValueType, then our
-					// parent is `System.Object'.
-					//
-					if (!stdlib && tc. Name == "System.ValueType")
-						parent = TypeManager.object_type;
-				}
-
-				return null;
-			}
-
-			//
-			// Bases should be null if there are no bases at all
-			//
-			count = bases.Count;
-			Debug.Assert (count > 0);
-
-			if (is_class){
-				string name = (string) bases [0];
-				Type first = GetInterfaceOrClass (tc, name, is_class);
-
-				if (first == null){
-					error = true;
-					return null;
-				}
-				
-				if (first.IsClass){
-					parent = first;
-					start = 1;
-				} else {
-					parent = TypeManager.object_type;
-					start = 0;
-				}
-			} else {
-				start = 0;
-			}
-
-			Type [] ifaces = new Type [count-start];
-			
-			for (i = start, j = 0; i < count; i++, j++){
-				string name = (string) bases [i];
-				Type t = GetInterfaceOrClass (tc, name, is_class);
-
-				if (t == null){
-					error = true;
-					return null;
-				}
-
-				if (is_class == false && !t.IsInterface){
-					Report.Error (527, "In Struct `"+tc.Name+"', type `"+
-						      name+"' is not an interface");
-					error = true;
-					return null;
-				}
-				
-				if (t.IsSealed) {
-					string detail = "";
-					
-					if (t.IsValueType)
-						detail = " (a class can not inherit from a struct)";
-							
-					Report.Error (509, "class `"+tc.Name+
-						      "': Cannot inherit from sealed class `"+
-						      bases [i]+"'"+detail);
-					error = true;
-					return null;
-				}
-
-				if (t.IsClass) {
-					if (parent != null){
-						Report.Error (527, "In Class `"+tc.Name+"', type `"+
-							      name+"' is not an interface");
-						error = true;
-						return null;
-					}
-				}
-				
-				ifaces [j] = t;
-			}
-
-			return ifaces;
-		}
-
-		// <remarks>
-		//   Creates the TypeBuilder for the TypeContainer @tc (a Class or a Struct)
-		// </remarks>
-		//
-		TypeBuilder CreateType (TypeContainer tc, bool is_class)
-		{
-			TypeBuilder tb = tc.TypeBuilder;
-			Type parent;
-			Type [] ifaces;
-			bool error;
-			string name;
-			
-			if (tb != null)
-				return tb;
-
-			if (tc.InTransit)
-				return null;
-			tc.InTransit = true;
-
-			name = tc.Name;
-
-			ifaces = GetClassBases (tc, is_class, out parent, out error); 
-
-			if (error)
-				return null;
-
-			type_container_resolve_order.Add (tc);
-
-			//
-			// Structs with no fields need to have a ".size 1"
-			// appended
-			//
-			if (!is_class && tc.Fields == null)
-				tb = mb.DefineType(
-					name,
-					tc.TypeAttr,
-					parent, 
-					PackingSize.Unspecified, 1);
-			else
-				//
-				// classes or structs with fields
-				//
-				tb = mb.DefineType (
-					name,
-					tc.TypeAttr,
-					parent,
-					ifaces);
-			
-			tc.TypeBuilder = tb;
-
-			TypeManager.AddUserType (name, tb, tc);
-			tc.InTransit = false;
-			
-			return tb;
-		}
-
 		// <remarks>
 		//   This function is used to resolve the hierarchy tree.
 		//   It processes interfaces, structs and classes in that order.
@@ -479,39 +100,34 @@
 		// </remarks>
 		public void ResolveTree ()
 		{
-			Hashtable ifaces, classes, structs;
-
-			type_container_resolve_order = new ArrayList ();
-			
 			//
 			// Interfaces are processed first, as classes and
 			// structs might inherit from an object or implement
 			// a set of interfaces, we need to be able to tell
 			// them appart by just using the TypeManager.
 			//
-			ifaces = tree.Interfaces;
+
+			TypeContainer root = Tree.Types;
+
+			ArrayList ifaces = root.Interfaces;
 			if (ifaces != null){
 				interface_resolve_order = new ArrayList ();
 				
-				foreach (DictionaryEntry de in ifaces)
-					CreateInterface ((Interface) de.Value);
+				foreach (Interface i in ifaces) {
+					Type t = i.DefineInterface (mb);
+					if (t != null)
+						interface_resolve_order.Add (i);
+				}
 			}
-
-			//
-			// Process structs and classes next.  Our code assumes
-			// this order (just for error reporting purposes).
-			//
-			structs = tree.Structs;
-			if (structs != null){
-				foreach (DictionaryEntry de in structs)
-					CreateType ((Struct) de.Value, false);
+						
+			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);
 			}
 
-			classes = tree.Classes;
-			if (classes != null){
-				foreach (DictionaryEntry de in classes)
-					CreateType ((Class) de.Value, true);
-			}
 		}
 			
 		// <summary>
@@ -526,16 +142,19 @@
 		// </remarks>
 		public void CloseTypes ()
 		{
-			foreach (TypeBuilder t in TypeManager.UserTypes){
-				try {
-					t.CreateType ();
-				} catch (Exception e){
-					Console.WriteLine ("Caught Exception while creating type for " + t);
-					Console.WriteLine (e);
-				}
-			}
-		}
+			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 ();
+			
+		}
+		
 		//
 		// Public function used to locate types, this can only
 		// be used after the ResolveTree function has been invoked.
@@ -545,7 +164,7 @@
 		public Type LookupType (TypeContainer tc, string name, bool silent)
 		{
 			Type t;
-
+			
 			t = TypeManager.LookupType (MakeFQN (tc.Namespace.Name, name));
 			if (t != null)
 				return t;
@@ -570,6 +189,11 @@
 				}
 			}
 
+			// 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+"'");
 			
@@ -618,23 +242,10 @@
 
 		public void EmitCode ()
 		{
-			Hashtable classes, structs;
-			
-			if ((classes = tree.Classes) != null){
-				foreach (DictionaryEntry de in classes){
-					TypeContainer tc = (TypeContainer) de.Value;
-
-					tc.Emit ();
-				}
-			}
-
-			if ((structs = tree.Structs) != null){
-				foreach (DictionaryEntry de in structs){
-					TypeContainer tc = (TypeContainer) de.Value;
-
+			if (type_container_resolve_order != null)
+				foreach (TypeContainer tc in type_container_resolve_order)
 					tc.Emit ();
-				}
-			}
+			
 		}
 		
 		// <summary>
Index: typemanager.cs
===================================================================
RCS file: /cvs/public/mcs/mcs/typemanager.cs,v
retrieving revision 1.27
diff -u -r1.27 typemanager.cs
--- typemanager.cs	2001/10/05 21:13:47	1.27
+++ typemanager.cs	2001/10/11 16:44:15
@@ -106,7 +106,7 @@
 	
 	public void AddUserType (string name, TypeBuilder t)
 	{
-		types.Add (t.FullName, t);
+		types.Add (name, t);
 		user_types.Add (t);
 	}
 
@@ -114,7 +114,7 @@
 	{
 		AddUserType (name, t);
 		builder_to_container.Add (t, tc);
-		typecontainers.Add (t.FullName, tc);
+		typecontainers.Add (name, tc);
 	}
 
 	public void AddUserInterface (string name, TypeBuilder t, Interface i)
@@ -293,8 +293,8 @@
 	{
 		TypeContainer tc;
 		
-		tc = (TypeContainer) typecontainers [t.FullName];
-
+		tc = (TypeContainer) builder_to_container [t];
+		
 		if (tc == null)
 			return t.FindMembers (mt, bf, filter, criteria);
 		else 


-- 
"If you're smart, you'll be humble. There always is somebody
who hasn't read a book and knows twice as much as you do."

              -- David Duchovny in Readers' Digest

	Ravi Pratap M         <ravi@ximian.com>
                      <http://www.iitm.ac.in/~ravi>