From 9db6f795b5e607b9976d1701a50abf131906cfdd Mon Sep 17 00:00:00 2001 From: Martin Baulig Date: Mon, 16 Aug 2004 14:56:24 +0000 Subject: [PATCH] 2004-08-14 Martin Baulig * typemanager.cs (TypeManager.IsEqualGenericInstance): New static method. (TypeManager.IsSubclassOrNestedChildOf, IsSubclassOf): This is just used to check accessibility, so follow the rules of 26.1.6. * expression.cs (MemberAccess.ResolveAsTypeStep): Return a ConstructedType instead of a TypeExpression if we have type arguments. * cs-parser.jay (typeof_expression): Support unbound generic types. * ecore.cs (UnboundTypeExpression): New public class. svn path=/trunk/mcs/; revision=32372 --- mcs/gmcs/ChangeLog | 14 ++++++++++++++ mcs/gmcs/cs-parser.jay | 35 +++++++++++++++++++++++++++++++++++ mcs/gmcs/decl.cs | 3 +++ mcs/gmcs/ecore.cs | 12 +++++++++++- mcs/gmcs/expression.cs | 10 ++++++++-- mcs/gmcs/typemanager.cs | 41 ++++++++++++++++++++++++++++++----------- 6 files changed, 101 insertions(+), 14 deletions(-) diff --git a/mcs/gmcs/ChangeLog b/mcs/gmcs/ChangeLog index ad498fd2ea1..cee5882b9de 100755 --- a/mcs/gmcs/ChangeLog +++ b/mcs/gmcs/ChangeLog @@ -1,3 +1,17 @@ +2004-08-14 Martin Baulig + + * typemanager.cs + (TypeManager.IsEqualGenericInstance): New static method. + (TypeManager.IsSubclassOrNestedChildOf, IsSubclassOf): This is + just used to check accessibility, so follow the rules of 26.1.6. + + * expression.cs (MemberAccess.ResolveAsTypeStep): Return a + ConstructedType instead of a TypeExpression if we have type arguments. + + * cs-parser.jay (typeof_expression): Support unbound generic types. + + * ecore.cs (UnboundTypeExpression): New public class. + 2004-08-12 Martin Baulig * typemanager.cs (TypeManager.IsNestedChildOf): Use diff --git a/mcs/gmcs/cs-parser.jay b/mcs/gmcs/cs-parser.jay index 3cf203e82f4..a1c13e93513 100755 --- a/mcs/gmcs/cs-parser.jay +++ b/mcs/gmcs/cs-parser.jay @@ -2683,6 +2683,41 @@ typeof_expression { $$ = new TypeOf ((Expression) $3, lexer.Location); } + | TYPEOF OPEN_PARENS unbound_type_name CLOSE_PARENS + { + $$ = new TypeOf ((Expression) $3, lexer.Location); + } + ; + +unbound_type_name + : IDENTIFIER generic_dimension_specifier + { + $$ = new UnboundTypeExpression ((string) $1, (int) $2); + } + ; + +generic_dimension_specifier + : OP_LT opt_commas OP_GT + { + $$ = $2; + } + ; + +opt_commas + : /* empty */ + { + $$ = 1; + } + | commas + ; + +commas + : COMMA { + $$ = 2; + } + | commas COMMA { + $$ = ((int) $1) + 1; + } ; sizeof_expression diff --git a/mcs/gmcs/decl.cs b/mcs/gmcs/decl.cs index b7c90fb98cc..4569892e46c 100755 --- a/mcs/gmcs/decl.cs +++ b/mcs/gmcs/decl.cs @@ -760,6 +760,9 @@ namespace Mono.CSharp { if (t == null) return null; + if (d is UnboundTypeExpression) + return t; + TypeContainer tc = TypeManager.LookupTypeContainer (t); if ((tc != null) && tc.IsGeneric) { if (!IsGeneric) { diff --git a/mcs/gmcs/ecore.cs b/mcs/gmcs/ecore.cs index db24c889068..bd96d84aa88 100755 --- a/mcs/gmcs/ecore.cs +++ b/mcs/gmcs/ecore.cs @@ -2262,7 +2262,7 @@ namespace Mono.CSharp { if (!me.IsStatic && TypeManager.IsSubclassOrNestedChildOf (me.InstanceExpression.Type, me.DeclaringType) && me.InstanceExpression.Type != me.DeclaringType && - !me.InstanceExpression.Type.IsSubclassOf (me.DeclaringType) && + !TypeManager.IsSubclassOf (me.InstanceExpression.Type, me.DeclaringType) && (!intermediate || !MemberAccess.IdenticalNameAndTypeName (ec, this, e, loc))) { Error (38, "Cannot access nonstatic member `" + me.Name + "' of " + "outer type `" + me.DeclaringType + "' via nested type `" + @@ -2478,6 +2478,16 @@ namespace Mono.CSharp { } } + /// + /// Represents an "unbound generic type", ie. typeof (Foo<>). + /// See 14.5.11. + /// + public class UnboundTypeExpression : TypeLookupExpression { + public UnboundTypeExpression (string name, int num_type_args) + : base (MemberName.MakeName (name, num_type_args)) + { } + } + public class TypeAliasExpression : TypeExpr, IAlias { TypeExpr texpr; TypeArguments args; diff --git a/mcs/gmcs/expression.cs b/mcs/gmcs/expression.cs index 7738a939436..03a28b723c9 100755 --- a/mcs/gmcs/expression.cs +++ b/mcs/gmcs/expression.cs @@ -7625,8 +7625,14 @@ namespace Mono.CSharp { if (full_expr.Expr is SimpleName) { string full_name = String.Concat (((SimpleName) full_expr.Expr).Name, ".", fname); Type fully_qualified = ec.DeclSpace.FindType (loc, full_name); - if (fully_qualified != null) - return new TypeExpression (fully_qualified, loc); + if (fully_qualified != null) { + if (args != null) + return new ConstructedType ( + fully_qualified, args, loc); + else + return new TypeExpression ( + fully_qualified, loc); + } } full_expr = full_expr.Expr as MemberAccess; diff --git a/mcs/gmcs/typemanager.cs b/mcs/gmcs/typemanager.cs index 7d9c3889aaf..8bb5b151b95 100755 --- a/mcs/gmcs/typemanager.cs +++ b/mcs/gmcs/typemanager.cs @@ -1852,12 +1852,32 @@ public class TypeManager { return false; } - public static bool IsSubclassOf (Type type, Type parent) + public static bool IsEqualGenericInstance (Type type, Type parent) { - if (type.IsGenericInstance && !parent.IsGenericInstance) + int tcount = GetNumberOfTypeArguments (type); + int pcount = GetNumberOfTypeArguments (parent); + + if (type.IsGenericInstance) type = type.GetGenericTypeDefinition (); + if (parent.IsGenericInstance) + parent = parent.GetGenericTypeDefinition (); + + if (tcount != pcount) + return false; + + return type.Equals (parent); + } + + public static bool IsSubclassOf (Type type, Type parent) + { + do { + if (IsEqualGenericInstance (type, parent)) + return true; - return type.IsSubclassOf (parent); + type = type.BaseType; + } while (type != null); + + return false; } // @@ -1866,8 +1886,7 @@ public class TypeManager { public static bool IsSubclassOrNestedChildOf (Type type, Type parent) { do { - if ((type == parent) || type.IsSubclassOf (parent) || - IsEqualGenericType (type, parent)) + if (IsSubclassOf (type, parent)) return true; // Handle nested types. @@ -2777,9 +2796,9 @@ public class TypeManager { // Although a derived class can access protected members of its base class // it cannot do so through an instance of the base class (CS1540). - if (!mb.IsStatic && (invocation_type != qualifier_type) && - (qualifier_type != null) && - invocation_type.IsSubclassOf (qualifier_type) && + if (!mb.IsStatic && (qualifier_type != null) && + !IsEqualGenericInstance (invocation_type, qualifier_type) && + TypeManager.IsSubclassOf (invocation_type, qualifier_type) && !TypeManager.IsNestedChildOf (invocation_type, qualifier_type)) return false; @@ -2828,9 +2847,9 @@ public class TypeManager { // Although a derived class can access protected members of its base class // it cannot do so through an instance of the base class (CS1540). - if (!fi.IsStatic && (invocation_type != qualifier_type) && - (qualifier_type != null) && - invocation_type.IsSubclassOf (qualifier_type) && + if (!fi.IsStatic && (qualifier_type != null) && + !IsEqualGenericInstance (invocation_type, qualifier_type) && + TypeManager.IsSubclassOf (invocation_type, qualifier_type) && !TypeManager.IsNestedChildOf (invocation_type, qualifier_type)) return false; -- 2.25.1