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
+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.
--- /dev/null
+// 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?");
+ }
+ }
+}
cs0187-2.cs
cs0229.cs
cs0249.cs
+cs0266-2.cs
cs0534-3.cs
cs0534-4.cs
cs0576.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
+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.
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 ();
//
// Emits the instance field initializers
//
- public bool EmitFieldInitializers (EmitContext ec)
+ public virtual bool EmitFieldInitializers (EmitContext ec)
{
ArrayList fields;
Expression instance_expr;
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),
/// </remarks>
public PendingImplementation Pending;
- public abstract void Register ();
-
public abstract PendingImplementation GetPendingImplementations ();
TypeExpr[] GetPartialBases (out TypeExpr base_class, out bool error)
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;
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;
Name, type_attributes, ptype, null);
} else {
- TypeBuilder builder = Parent.DefineType ();
+ TypeBuilder builder = Parent.TypeBuilder;
if (builder == null)
return null;
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
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;
TypeManager.RegisterBuilder (TypeBuilder, ifaces);
}
- //
- // Finish the setup for the EmitContext
- //
- ec.ContainerType = TypeBuilder;
-
TypeManager.AddUserType (Name, TypeBuilder, this);
if (!(this is Iterator))
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;
}
}
}
- if (Parts != null) {
- foreach (ClassPart cp in Parts) {
- Type t = cp.PartFindNestedType (name);
- if (t != null)
- return t;
- }
- }
-
return null;
}
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;
}
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:
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;
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 ()
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 {
}
}
}
-
- public override void Register ()
- {
- Parent.AddClassOrStruct (this);
- }
}
/// <summary>
this.ModFlags = Modifiers.Check (AllowedModifiers, mod, accmods, l);
}
- public override void Register ()
- {
- Parent.AddInterface (this);
- }
-
public override PendingImplementation GetPendingImplementations ()
{
return null;
}
}
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;
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;
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);
}
if (RootContext.Documentation != null)
current_class.DocComment = Lexer.consume_doc_comment ();
-
- current_class.Register ();
}
struct_body
{
}
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);
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);
}
current_class.DocComment = Lexer.consume_doc_comment ();
Lexer.doc_state = XmlCommentState.Allowed;
}
-
- current_class.Register ();
}
interface_body
{
}
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);
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)
{
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) {
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;
} 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);
}
current_class.DocComment = Lexer.consume_doc_comment ();
Lexer.doc_state = XmlCommentState.Allowed;
}
-
- current_class.Register ();
}
class_body
{
}
opt_semicolon
{
- $$ = current_class;
-
- current_container = current_container.Parent;
- current_class = current_container;
+ $$ = pop_current_class ();
}
;
}
}
+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
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 ();
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;
}
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
// </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)
//
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)) {
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 ();
+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.
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
--- /dev/null
+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?");
+ }
+ }
+}