Clean up a few partial-class semantics.
authorRaja R Harinath <harinath@hurrynot.org>
Wed, 9 Mar 2005 10:04:11 +0000 (10:04 -0000)
committerRaja R Harinath <harinath@hurrynot.org>
Wed, 9 Mar 2005 10:04:11 +0000 (10:04 -0000)
Fixes test-357.cs and cs1618-2.cs.
* cs-parser.jay (struct_declaration): Use 'current_class' as
parent of newly-created struct.  Remove call to Register ().
Use 'pop_current_class' to complete handing the current struct.
(interface_declaration): Likewise.
(class_declaration): Likewise.
(enum_declaration): Use 'current_class' as parent of newly created
enum.
(delegate_declaration): Likewise.
(pop_current_class): New function.  This is used to handle closing
up the 'current_class' and 'current_container', and pointing them
to the enclosing class/container.
(CSharpParser): Initialize 'current_class' too.
 decl.cs (MemberCore): Add check for invariant: a partial
container is not a parsed entity, and thus does not enclose any
parsed members.
(DeclSpace.TypeResolveEmitContext): Expose 'type_resolve_ec'.
(DeclSpace.BaseTypeExpr): Use it.
(DeclSpace.LookupType): Add check for invariant.
* class.cs (TypeContainer): Add check for invariant: a nested
class should have the same NamespaceEntry as its enclosing class.
(TypeContainer.EmitFieldInitializers): Make virtual.
(TypeContainer.DefineDefaultConstructor): Adhere to invariant in
MemberCore.
(TypeContainer.Register): Remove.
(TypeContainer.DefineType): Set the 'ec' of a PartialContainer to
null.  Use TypeResolveEmitContext for resolving base types and
interfaces.  Move initialization of Parts.TypeBuilder here from
...
(TypeContainer.DefineNestedTypes): ... here.
(PartialContainer): Take a Namespace not a NamespaceEntry.
(PartialContainer.Create): Don't use Register.  Call the
appropriate Add... function directly.
(ClassPart): Take both the PartialContainer and the enclosing
class as constructor arguments.
(ClassPart.EmitFieldInitializers): Override.
(ClassPart.PartFindNestedTypes): Remove.
(FieldBase.GetInitializerExpression): Resolve the initializer
expression in the emit context of the enclosing class.
* tree.cs (RootTypes): Remove Register ().

svn path=/trunk/mcs/; revision=41590

mcs/errors/ChangeLog
mcs/errors/cs1618-2.cs [new file with mode: 0644]
mcs/errors/gmcs-expect-no-error
mcs/mcs/ChangeLog
mcs/mcs/class.cs
mcs/mcs/cs-parser.jay
mcs/mcs/decl.cs
mcs/mcs/tree.cs
mcs/tests/ChangeLog
mcs/tests/Makefile
mcs/tests/test-357.cs [new file with mode: 0644]

index f8d81a96999bef9ac7cc1c7302658aa85ef4ee70..d1e1528944d63351f7e3a6d2972eda779f1eddd0 100644 (file)
@@ -1,3 +1,7 @@
+2005-03-09  Raja R Harinath  <rharinath@novell.com>
+
+       * cs1618-2.cs: New test for partial classes.
+
 2005-03-07  Raja R Harinath  <rharinath@novell.com>
 
        * cs0120-6.cs, cs0120-7.cs: New tests from #73394.
diff --git a/mcs/errors/cs1618-2.cs b/mcs/errors/cs1618-2.cs
new file mode 100644 (file)
index 0000000..7a252f4
--- /dev/null
@@ -0,0 +1,23 @@
+// cs1618: Cannot create delegate with 'System.Diagnostics.Debug.Assert(bool)' because it has a Conditional attribute
+// Line: 8
+
+namespace Foo {
+       using System.Diagnostics;
+       partial class Bar {
+               delegate void assert_t (bool condition);
+               assert_t assert = new assert_t (Debug.Assert);
+       }
+}
+
+namespace Foo {
+       using System;
+       partial class Bar
+       {
+               public Bar () {}
+               static void Main ()
+               {
+                       if (new Bar ().assert == null)
+                               throw new Exception ("Didn't resolve Debug.Assert?");
+               }
+       }
+}
index ab56a2a94a3385d5b70fc3764a2c64490ce29f9b..f9999de27f80267ffb4dc959faaa63cc0fd52310 100644 (file)
@@ -19,6 +19,7 @@ cs0187-1.cs
 cs0187-2.cs
 cs0229.cs
 cs0249.cs
+cs0266-2.cs
 cs0534-3.cs
 cs0534-4.cs
 cs0576.cs
@@ -30,7 +31,6 @@ cs0652.cs
 cs1035.cs
 cs1540-3.cs # new in GMCS
 cs1540-5.cs # new in GMCS
-cs2023.cs
+cs1618-2.cs
 cs1635.cs
-
-cs0266-2.cs
+cs2023.cs
index f188d7d478efc807f1cbd190e45d5e022369c32b..71db586ad686f54bd1fe56700a5717ab4fd0a064 100644 (file)
@@ -1,3 +1,47 @@
+2005-03-09  Raja R Harinath  <rharinath@novell.com>
+
+       Clean up a few partial-class semantics.  
+       Fixes test-357.cs and cs1618-2.cs.
+       * cs-parser.jay (struct_declaration): Use 'current_class' as
+       parent of newly-created struct.  Remove call to Register ().
+       Use 'pop_current_class' to complete handing the current struct.
+       (interface_declaration): Likewise.
+       (class_declaration): Likewise.
+       (enum_declaration): Use 'current_class' as parent of newly created
+       enum.
+       (delegate_declaration): Likewise.
+       (pop_current_class): New function.  This is used to handle closing
+       up the 'current_class' and 'current_container', and pointing them
+       to the enclosing class/container.
+       (CSharpParser): Initialize 'current_class' too.
+       * decl.cs (MemberCore): Add check for invariant: a partial
+       container is not a parsed entity, and thus does not enclose any
+       parsed members.
+       (DeclSpace.TypeResolveEmitContext): Expose 'type_resolve_ec'.
+       (DeclSpace.BaseTypeExpr): Use it.
+       (DeclSpace.LookupType): Add check for invariant.
+       * class.cs (TypeContainer): Add check for invariant: a nested
+       class should have the same NamespaceEntry as its enclosing class.
+       (TypeContainer.EmitFieldInitializers): Make virtual.
+       (TypeContainer.DefineDefaultConstructor): Adhere to invariant in
+       MemberCore.
+       (TypeContainer.Register): Remove.
+       (TypeContainer.DefineType): Set the 'ec' of a PartialContainer to
+       null.  Use TypeResolveEmitContext for resolving base types and
+       interfaces.  Move initialization of Parts.TypeBuilder here from
+       ...
+       (TypeContainer.DefineNestedTypes): ... here.
+       (PartialContainer): Take a Namespace not a NamespaceEntry.
+       (PartialContainer.Create): Don't use Register.  Call the
+       appropriate Add... function directly.
+       (ClassPart): Take both the PartialContainer and the enclosing
+       class as constructor arguments.
+       (ClassPart.EmitFieldInitializers): Override.
+       (ClassPart.PartFindNestedTypes): Remove.
+       (FieldBase.GetInitializerExpression): Resolve the initializer
+       expression in the emit context of the enclosing class.
+       * tree.cs (RootTypes): Remove Register ().
+       
 2005-03-08  Marek Safar  <marek.safar@seznam.cz>
 
        * cs-parser.jay: Removed CS0134.
index e9b6e6394f110386342e8575f378af6ecf338e6a..6f75049f6febbe7ea1ac0f5aa78b3b2616c719d9 100644 (file)
@@ -465,6 +465,9 @@ namespace Mono.CSharp {
                                      Attributes attrs, Kind kind, Location l)
                        : base (ns, parent, name, attrs, l)
                {
+                       if (parent != null && parent != RootContext.Tree.Types && parent.NamespaceEntry != ns)
+                               throw new InternalErrorException ("A nested type should be in the same NamespaceEntry as its enclosing class");
+
                        this.Kind = kind;
 
                        types = new ArrayList ();
@@ -841,7 +844,7 @@ namespace Mono.CSharp {
                //
                // Emits the instance field initializers
                //
-               public bool EmitFieldInitializers (EmitContext ec)
+               public virtual bool EmitFieldInitializers (EmitContext ec)
                {
                        ArrayList fields;
                        Expression instance_expr;
@@ -902,7 +905,12 @@ namespace Mono.CSharp {
                        else if ((ModFlags & Modifiers.ABSTRACT) != 0)
                                mods = Modifiers.PROTECTED;
 
-                       c = new Constructor (this, Basename, mods, Parameters.EmptyReadOnlyParameters,
+                       TypeContainer constructor_parent = this;
+                       if (Parts != null)
+                               constructor_parent = (TypeContainer) Parts [0];
+
+                       c = new Constructor (constructor_parent, Basename, mods,
+                                            Parameters.EmptyReadOnlyParameters,
                                             new ConstructorBaseInitializer (
                                                     null, Parameters.EmptyReadOnlyParameters,
                                                     Location),
@@ -920,8 +928,6 @@ namespace Mono.CSharp {
                /// </remarks>
                public PendingImplementation Pending;
 
-               public abstract void Register ();
-
                public abstract PendingImplementation GetPendingImplementations ();
 
                TypeExpr[] GetPartialBases (out TypeExpr base_class, out bool error)
@@ -1164,8 +1170,6 @@ namespace Mono.CSharp {
                        
                        InTransit = true;
 
-                       ec = new EmitContext (this, Mono.CSharp.Location.Null, null, null, ModFlags);
-
                        TypeExpr[] iface_exprs = GetClassBases (out base_type, out error);
                        if (error)
                                return null;
@@ -1197,7 +1201,7 @@ namespace Mono.CSharp {
                        if (base_type != null) {
                                // FIXME: I think this should be ...ResolveType (Parent.EmitContext).
                                //        However, if Parent == RootContext.Tree.Types, its NamespaceEntry will be null.
-                               ptype = base_type.ResolveType (ec);
+                               ptype = base_type.ResolveType (TypeResolveEmitContext);
                                if (ptype == null) {
                                        error = true;
                                        return null;
@@ -1216,7 +1220,7 @@ namespace Mono.CSharp {
                                                Name, type_attributes, ptype, null);
                                
                                } else {
-                                       TypeBuilder builder = Parent.DefineType ();
+                                       TypeBuilder builder = Parent.TypeBuilder;
                                        if (builder == null)
                                                return null;
                                
@@ -1228,7 +1232,21 @@ namespace Mono.CSharp {
                                Report.RuntimeMissingSupport (Location, "static classes");
                                return null;
                        }
-                               
+
+                       if (Parts != null) {
+                               ec = null;
+                               foreach (ClassPart part in Parts) {
+                                       part.TypeBuilder = TypeBuilder;
+                                       part.ptype = ptype;
+                                       part.ec = new EmitContext (part, Mono.CSharp.Location.Null, null, null, ModFlags);
+                                       part.ec.ContainerType = TypeBuilder;
+                               }
+                       }
+                       else {
+                               ec = new EmitContext (this, Mono.CSharp.Location.Null, null, null, ModFlags);
+                               ec.ContainerType = TypeBuilder;
+                       }
+
                        //
                        // Structs with no fields need to have at least one byte.
                        // The right thing would be to set the PackingSize in a DefineType
@@ -1245,7 +1263,8 @@ namespace Mono.CSharp {
                        if (iface_exprs != null) {
                                // FIXME: I think this should be ...ExpandInterfaces (Parent.EmitContext, ...).
                                //        However, if Parent == RootContext.Tree.Types, its NamespaceEntry will be null.
-                               ifaces = TypeManager.ExpandInterfaces (ec, iface_exprs);
+                               TypeResolveEmitContext.ContainerType = TypeBuilder;
+                               ifaces = TypeManager.ExpandInterfaces (TypeResolveEmitContext, iface_exprs);
                                if (ifaces == null) {
                                        error = true;
                                        return null;
@@ -1257,11 +1276,6 @@ namespace Mono.CSharp {
                                TypeManager.RegisterBuilder (TypeBuilder, ifaces);
                        }
 
-                       //
-                       // Finish the setup for the EmitContext
-                       //
-                       ec.ContainerType = TypeBuilder;
-
                        TypeManager.AddUserType (Name, TypeBuilder, this);
 
                        if (!(this is Iterator))
@@ -1302,14 +1316,6 @@ namespace Mono.CSharp {
                                                return false;
                        }
 
-                       if (Parts != null) {
-                               foreach (ClassPart part in Parts) {
-                                       part.TypeBuilder = TypeBuilder;
-                                       part.ptype = ptype;
-                                       part.ec = new EmitContext (part, Mono.CSharp.Location.Null, null, null, ModFlags);
-                               }
-                       }
-
                        return true;
                }
 
@@ -1574,14 +1580,6 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       if (Parts != null) {
-                               foreach (ClassPart cp in Parts) {
-                                       Type t = cp.PartFindNestedType (name);
-                                       if (t != null)
-                                               return t;
-                               }
-                       }
-
                        return null;
                }
 
@@ -2483,10 +2481,19 @@ namespace Mono.CSharp {
                                return pc;
                        }
 
-                       pc = new PartialContainer (ns, parent, member_name, mod_flags, kind, loc);
+                       if (parent is ClassPart)
+                               parent = ((ClassPart) parent).PartialContainer;
+
+                       pc = new PartialContainer (ns.NS, parent, member_name, mod_flags, kind, loc);
                        RootContext.Tree.RecordDecl (full_name, pc);
-                       parent.AddType (pc);
-                       pc.Register ();
+
+                       if (kind == Kind.Interface)
+                               parent.AddInterface (pc);
+                       else if (kind == Kind.Class || kind == Kind.Struct)
+                               parent.AddClassOrStruct (pc);
+                       else
+                               throw new InvalidOperationException ();
+
                        return pc;
                }
 
@@ -2498,19 +2505,19 @@ namespace Mono.CSharp {
                        if (pc == null) {
                                // An error occured; create a dummy container, but don't
                                // register it.
-                               pc = new PartialContainer (ns, parent, name, mod, kind, loc);
+                               pc = new PartialContainer (ns.NS, parent, name, mod, kind, loc);
                        }
 
-                       ClassPart part = new ClassPart (ns, pc, mod, attrs, kind, loc);
+                       ClassPart part = new ClassPart (ns, pc, parent, mod, attrs, kind, loc);
                        pc.AddPart (part);
                        return part;
                }
 
-               protected PartialContainer (NamespaceEntry ns, TypeContainer parent,
+               protected PartialContainer (Namespace ns, TypeContainer parent,
                                            MemberName name, int mod, Kind kind, Location l)
-                       : base (ns, parent, name, null, kind, l)
+                       : base (null, parent, name, null, kind, l)
                {
-                       this.Namespace = ns.NS;
+                       this.Namespace = ns;
 
                        switch (kind) {
                        case Kind.Class:
@@ -2542,29 +2549,11 @@ namespace Mono.CSharp {
                        this.OriginalModFlags = mod;
                }
 
-               public override void Register ()
-               {
-                       if (Kind == Kind.Interface)
-                               Parent.AddInterface (this);
-                       else if (Kind == Kind.Class || Kind == Kind.Struct)
-                               Parent.AddClassOrStruct (this);
-                       else
-                               throw new InvalidOperationException ();
-               }
-
                public override PendingImplementation GetPendingImplementations ()
                {
                        return PendingImplementation.GetPendingImplementations (this);
                }
 
-               public ClassPart AddPart (NamespaceEntry ns, int mod, Attributes attrs,
-                                         Location l)
-               {
-                       ClassPart part = new ClassPart (ns, this, mod, attrs, Kind, l);
-                       AddPart (part);
-                       return part;
-               }
-
                public override TypeAttributes TypeAttr {
                        get {
                                return base.TypeAttr | DefaultTypeAttributes;
@@ -2576,25 +2565,20 @@ namespace Mono.CSharp {
                public readonly PartialContainer PartialContainer;
                public readonly bool IsPartial;
 
-               public ClassPart (NamespaceEntry ns, PartialContainer parent,
+               public ClassPart (NamespaceEntry ns, PartialContainer pc, TypeContainer parent,
                                  int mod, Attributes attrs, Kind kind, Location l)
-                       : base (ns, parent.Parent, parent.MemberName, attrs, kind, l)
+                       : base (ns, parent, pc.MemberName, attrs, kind, l)
                {
-                       this.PartialContainer = parent;
+                       this.PartialContainer = pc;
                        this.IsPartial = true;
 
                        int accmods;
-                       if (parent.Parent == null)
+                       if (parent == null || parent == RootContext.Tree.Types)
                                accmods = Modifiers.INTERNAL;
                        else
                                accmods = Modifiers.PRIVATE;
 
-                       this.ModFlags = Modifiers.Check (
-                               parent.AllowedModifiers, mod, accmods, l);
-               }
-
-               public override void Register ()
-               {
+                       this.ModFlags = Modifiers.Check (pc.AllowedModifiers, mod, accmods, l);
                }
 
                public override PendingImplementation GetPendingImplementations ()
@@ -2609,14 +2593,14 @@ namespace Mono.CSharp {
                                interface_type, full, name, loc);
                }
 
-               public override Type FindNestedType (string name)
+               public override bool EmitFieldInitializers (EmitContext ec)
                {
-                       return PartialContainer.FindNestedType (name);
+                       return PartialContainer.EmitFieldInitializers (ec);
                }
 
-               public Type PartFindNestedType (string name)
+               public override Type FindNestedType (string name)
                {
-                       return base.FindNestedType (name);
+                       return PartialContainer.FindNestedType (name);
                }
 
                public override MemberCache BaseCache {
@@ -2687,11 +2671,6 @@ namespace Mono.CSharp {
                                }
                        }
                }
-
-               public override void Register ()
-               {
-                       Parent.AddClassOrStruct (this);
-               }
        }
 
        /// <summary>
@@ -2917,11 +2896,6 @@ namespace Mono.CSharp {
                        this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
                }
 
-               public override void Register ()
-               {
-                       Parent.AddInterface (this);
-               }
-
                public override PendingImplementation GetPendingImplementations ()
                {
                        return null;
@@ -4330,7 +4304,7 @@ namespace Mono.CSharp {
                                }
                        }
                        if (Initializer != null) {
-                               if (GetObsoleteAttribute (Parent) == null && Parent.GetObsoleteAttribute (Parent.Parent) == null)
+                               if (GetObsoleteAttribute (Parent) == null && Parent.GetObsoleteAttribute (Parent) == null)
                                        Initializer.CheckObsoleteAttribute (Parent, Location);
                                else
                                        ec.TestObsoleteMethodUsage = false;
@@ -5184,9 +5158,14 @@ namespace Mono.CSharp {
                        else
                                e = new ArrayCreation (Type, "", (ArrayList)init, Location);
 
-                       ec.IsFieldInitializer = true;
-                       e = e.DoResolve (ec);
-                       ec.IsFieldInitializer = false;
+                       EmitContext parent_ec = Parent.EmitContext;
+
+                       bool old_is_static = parent_ec.IsStatic;
+                       parent_ec.IsStatic = ec.IsStatic;
+                       parent_ec.IsFieldInitializer = true;
+                       e = e.DoResolve (parent_ec);
+                       parent_ec.IsFieldInitializer = false;
+                       parent_ec.IsStatic = old_is_static;
 
                        init_expr = e;
                        init_expr_initialized = true;
index e2fec90c2741234e332c7e011e41cd32d2cce9e4..727fa2059024b28ed23ff0f5275993a41bc7684e 100644 (file)
@@ -756,16 +756,17 @@ struct_declaration
 
                if (partial) {
                        ClassPart part = PartialContainer.CreatePart (
-                               current_namespace, current_container, name, (int) $2,
+                               current_namespace, current_class, name, (int) $2,
                                (Attributes) $1, Kind.Struct, lexer.Location);
 
                        current_container = part.PartialContainer;
                        current_class = part;
                } else {
                        current_class = new Struct (
-                               current_namespace, current_container, name, (int) $2,
+                               current_namespace, current_class, name, (int) $2,
                                (Attributes) $1, lexer.Location);
 
+                       current_container.AddClassOrStruct (current_class);
                        current_container = current_class;
                        RootContext.Tree.RecordDecl (name.GetName (true), current_class);
                }
@@ -777,8 +778,6 @@ struct_declaration
 
                if (RootContext.Documentation != null)
                        current_class.DocComment = Lexer.consume_doc_comment ();
-
-               current_class.Register ();
          }
          struct_body
          {
@@ -787,10 +786,7 @@ struct_declaration
          }
          opt_semicolon
          {
-               $$ = current_class;
-
-               current_container = current_container.Parent;
-               current_class = current_container;
+               $$ = pop_current_class ();
          }
        | opt_attributes opt_modifiers opt_partial STRUCT error {
                CheckIdentifierToken (yyToken);
@@ -1441,16 +1437,17 @@ interface_declaration
 
                if (partial) {
                        ClassPart part = PartialContainer.CreatePart (
-                               current_namespace, current_container, name, (int) $2,
+                               current_namespace, current_class, name, (int) $2,
                                (Attributes) $1, Kind.Interface, lexer.Location);
 
                        current_container = part.PartialContainer;
                        current_class = part;
                } else {
                        current_class = new Interface (
-                               current_namespace, current_container, name, (int) $2,
+                               current_namespace, current_class, name, (int) $2,
                                (Attributes) $1, lexer.Location);
 
+                       current_container.AddInterface (current_class);
                        current_container = current_class;
                        RootContext.Tree.RecordDecl (name.GetName (true), current_class);
                }
@@ -1463,8 +1460,6 @@ interface_declaration
                        current_class.DocComment = Lexer.consume_doc_comment ();
                        Lexer.doc_state = XmlCommentState.Allowed;
                }
-
-               current_class.Register ();
          }
          interface_body 
          {
@@ -1473,10 +1468,7 @@ interface_declaration
          }
          opt_semicolon 
          {
-               $$ = current_class;
-
-               current_container = current_container.Parent;
-               current_class = current_container;
+               $$ = pop_current_class ();
          }
        | opt_attributes opt_modifiers opt_partial INTERFACE error {
                CheckIdentifierToken (yyToken);
@@ -2308,7 +2300,7 @@ enum_declaration
                Location enum_location = lexer.Location;
 
                MemberName full_name = MakeName (new MemberName ((string) $4));
-               Enum e = new Enum (current_namespace, current_container, (Expression) $5, (int) $2,
+               Enum e = new Enum (current_namespace, current_class, (Expression) $5, (int) $2,
                                   full_name, (Attributes) $1, enum_location);
                
                if (RootContext.Documentation != null)
@@ -2414,7 +2406,7 @@ delegate_declaration
          {
                Location l = lexer.Location;
                MemberName name = MakeName ((MemberName) $5);
-               Delegate del = new Delegate (current_namespace, current_container, (Expression) $4,
+               Delegate del = new Delegate (current_namespace, current_class, (Expression) $4,
                                             (int) $2, name, (Parameters) $7, (Attributes) $1, l);
 
                if (RootContext.Documentation != null) {
@@ -3415,7 +3407,7 @@ class_declaration
 
                if (partial) {
                        ClassPart part = PartialContainer.CreatePart (
-                               current_namespace, current_container, name, mod_flags,
+                               current_namespace, current_class, name, mod_flags,
                                (Attributes) $1, Kind.Class, lexer.Location);
 
                        current_container = part.PartialContainer;
@@ -3423,14 +3415,15 @@ class_declaration
                } else {
                        if ((mod_flags & Modifiers.STATIC) != 0) {
                                current_class = new StaticClass (
-                                       current_namespace, current_container, name,
+                                       current_namespace, current_class, name,
                                        mod_flags, (Attributes) $1, lexer.Location);
                        } else {
                                current_class = new Class (
-                                       current_namespace, current_container, name,
+                                       current_namespace, current_class, name,
                                        mod_flags, (Attributes) $1, lexer.Location);
                        }
 
+                       current_container.AddClassOrStruct (current_class);
                        current_container = current_class;
                        RootContext.Tree.RecordDecl (name.GetName (true), current_class);
                }
@@ -3450,8 +3443,6 @@ class_declaration
                        current_class.DocComment = Lexer.consume_doc_comment ();
                        Lexer.doc_state = XmlCommentState.Allowed;
                }
-
-               current_class.Register ();
          }
          class_body
          {
@@ -3460,10 +3451,7 @@ class_declaration
          }
          opt_semicolon 
          {
-               $$ = current_class;
-
-               current_container = current_container.Parent;
-               current_class = current_container;
+               $$ = pop_current_class ();
          }
        ;       
 
@@ -4630,6 +4618,23 @@ void Error_ExpectingTypeName (Location l, Expression expr)
        }
 }
 
+TypeContainer pop_current_class ()
+{
+       TypeContainer retval = current_class;
+
+       current_class = current_class.Parent;
+       current_container = current_container.Parent;
+       
+       if (current_class != current_container) {
+               if (!(current_class is ClassPart) ||
+                   ((ClassPart) current_class).PartialContainer != current_container)
+                       throw new InternalErrorException ();
+       } else if (current_container is ClassPart)
+               current_container = ((ClassPart) current_class).PartialContainer;
+
+       return retval;
+}
+
 // <summary>
 //   Given the @class_name name, it creates a fully qualified name
 //   based on the containing declaration space
@@ -4826,6 +4831,8 @@ public CSharpParser (SeekableStreamReader reader, SourceFile file, ArrayList def
        this.name = file.Name;
        this.file = file;
        current_container = RootContext.Tree.Types;
+       // TODO: Make RootContext.Tree.Types a PartialContainer.
+       current_class = current_container;
        current_container.NamespaceEntry = current_namespace;
        oob_stack = new Stack ();
        switch_stack = new Stack ();
index 38de3ef7c60d6e7d4c7a6b2dc4b96a0cbfff50cc..65db9a8ea8085cd5e4829868bc1cfde88b630ebc 100644 (file)
@@ -181,6 +181,9 @@ namespace Mono.CSharp {
                                   Location loc)
                        : base (attrs)
                {
+                       if (parent is PartialContainer && !(this is PartialContainer))
+                               throw new InternalErrorException ("A PartialContainer cannot be the direct parent of a member");
+
                        Parent = parent;
                        MemberName = name;
                        Location = loc;
@@ -590,6 +593,21 @@ namespace Mono.CSharp {
                }
 
                EmitContext type_resolve_ec;
+               protected EmitContext TypeResolveEmitContext {
+                       get {
+                               if (type_resolve_ec == null) {
+                                       // FIXME: I think this should really be one of:
+                                       //
+                                       // a. type_resolve_ec = Parent.EmitContext;
+                                       // b. type_resolve_ec = new EmitContext (Parent, Parent, loc, null, null, ModFlags, false);
+                                       //
+                                       // However, if Parent == RootContext.Tree.Types, its NamespaceEntry will be null.
+                                       //
+                                       type_resolve_ec = new EmitContext (Parent, this, Location.Null, null, null, ModFlags, false);
+                               }
+                               return type_resolve_ec;
+                       }
+               }
 
                // <summary>
                //    Resolves the expression `e' for a type, and will recursively define
@@ -597,20 +615,10 @@ namespace Mono.CSharp {
                // </summary>
                public TypeExpr ResolveBaseTypeExpr (Expression e, bool silent, Location loc)
                {
-                       if (type_resolve_ec == null) {
-                               // FIXME: I think this should really be one of:
-                               //
-                               // a. type_resolve_ec = Parent.EmitContext;
-                               // b. type_resolve_ec = new EmitContext (Parent, Parent, loc, null, null, ModFlags, false);
-                               //
-                               // However, if Parent == RootContext.Tree.Types, its NamespaceEntry will be null.
-                               //
-                               type_resolve_ec = new EmitContext (Parent, this, loc, null, null, ModFlags, false);
-                       }
-                       type_resolve_ec.loc = loc;
-                       type_resolve_ec.ContainerType = TypeBuilder;
+                       TypeResolveEmitContext.loc = loc;
+                       TypeResolveEmitContext.ContainerType = TypeBuilder;
 
-                       return e.ResolveAsTypeTerminal (type_resolve_ec, silent);
+                       return e.ResolveAsTypeTerminal (TypeResolveEmitContext, silent);
                }
                
                public bool CheckAccessLevel (Type check_type)
@@ -814,6 +822,9 @@ namespace Mono.CSharp {
                //
                public FullNamedExpression LookupType (string name, Location loc, bool ignore_cs0104)
                {
+                       if (this is PartialContainer)
+                               throw new InternalErrorException ("Should not get here");
+
                        FullNamedExpression e;
 
                        if (Cache.Contains (name)) {
index ad3423754ea6366d2519f09e2dd8e04c8161139d..6de03da4864b3cbafcdf94b7c8f59089f4b56c78 100644 (file)
@@ -117,11 +117,6 @@ namespace Mono.CSharp
                        ec = new EmitContext (null, this, Location.Null, null, null, 0, false);
                }
 
-               public override void Register ()
-               {
-                       throw new InvalidOperationException ();
-               }
-
                public override PendingImplementation GetPendingImplementations ()
                {
                        throw new InvalidOperationException ();
index 74e33b88548a45bb62871d2b47f7b79859fc91ca..51d617e41fcef7b3c582a10ad82e9d269244ccbf 100644 (file)
@@ -1,3 +1,7 @@
+2005-03-09  Raja R Harinath  <rharinath@novell.com>
+
+       * test-357.cs: New test for partial classes.
+
 2005-03-08  Marek Safar <marek.safar@seznam.cz>
 
        * test-355.cs, test-356.cs: New tests.
index c82e1477326a88a6985547e32179c7e368d97bed..8334738705599549186df7c1dbdac0e5dd396bc7 100644 (file)
@@ -30,7 +30,7 @@ USE_MCS_FLAGS :=
 NEW_TEST_SOURCES_common = xml-033 xml-034 xml-035 test-329 2test-16 test-330 a-parameter5 test-331 test-332 \
                          test-333 test-311 test-335 test-336 test-337 test-287 test-338 test-339 test-341 test-334 test-342 \
                          test-344 test-345 test-346 test-347 test-348 test-349 test-351 test-352 test-353 test-354 test-355 \
-                         test-356
+                         test-356 test-357
 
 #
 # Please do _not_ add any tests here - all new tests should go into NEW_TEST_SOURCES_common
diff --git a/mcs/tests/test-357.cs b/mcs/tests/test-357.cs
new file mode 100644 (file)
index 0000000..214a425
--- /dev/null
@@ -0,0 +1,25 @@
+namespace SD {
+       public class Sd {
+               static public void F (bool b) { }
+       }
+}
+
+namespace Foo {
+       using SD;
+       partial class Bar {
+               delegate void f_t (bool b);
+               f_t f = new f_t (Sd.F);
+       }
+}
+
+namespace Foo {
+       partial class Bar
+       {
+               public Bar () {}
+               static void Main ()
+               {
+                       if (new Bar ().f == null)
+                               throw new System.Exception ("Didn't resolve Sd.F?");
+               }
+       }
+}