+2008-11-18 Marek Safar <marek.safar@gmail.com>
+
+ * generic.cs, iterators.cs, anonymous.cs, nullable.cs, ecore.cs,
+ expression.cs, namespace.cs, generic-mcs.cs, class.cs: Small cleanup
+ of ConstructedType expression, renamed to GenericTypeExpr.
+
2008-11-17 Marek Safar <marek.safar@gmail.com>
A fix for bug #445303
ec.CurrentAnonymousMethod.Storey.TypeParameters :
ec.GenericDeclContainer.TypeParameters;
- if (tparams.Length != CountTypeParameters) {
- TypeParameter [] full = new TypeParameter [CountTypeParameters];
- DeclSpace parent = ec.DeclContainer.Parent;
- parent.CurrentTypeParameters.CopyTo (full, 0);
- tparams.CopyTo (full, parent.CountTypeParameters);
- tparams = full;
+ TypeArguments targs = new TypeArguments (Location);
+
+ if (tparams.Length < CountTypeParameters) {
+ TypeParameter[] parent_tparams = ec.DeclContainer.Parent.CurrentTypeParameters;
+ for (int i = 0; i < parent_tparams.Length; ++i)
+ targs.Add (new TypeParameterExpr (parent_tparams[i], Location));
}
+
+ for (int i = 0; i < tparams.Length; ++i)
+ targs.Add (new TypeParameterExpr (tparams[i], Location));
- storey_type_expr = new ConstructedType (TypeBuilder, tparams, Location);
+ storey_type_expr = new GenericTypeExpr (TypeBuilder, targs, Location);
} else {
storey_type_expr = new TypeExpression (TypeBuilder, Location);
}
ToplevelBlock equals_block = new ToplevelBlock (equals.Parameters, loc);
TypeExpr current_type;
if (IsGeneric)
- current_type = new ConstructedType (TypeBuilder, TypeParameters, loc);
+ current_type = new GenericTypeExpr (this, loc);
else
current_type = new TypeExpression (TypeBuilder, loc);
}
}
- current_type = new ConstructedType (TypeBuilder, TypeParameters, Location);
+ // TODO: Very strange, why not simple make generic type from
+ // current type parameters
+ current_type = new GenericTypeExpr (this, Location);
current_type = current_type.ResolveAsTypeTerminal (this, false);
if (current_type == null) {
error = true;
AttributeTester.Report_ObsoleteMessage (
oa, iface.GetSignatureForError (), Location);
- ConstructedType ct = iface as ConstructedType;
+ GenericTypeExpr ct = iface as GenericTypeExpr;
if ((ct != null) && !ct.CheckConstraints (this))
return false;
}
if (obsolete_attr != null && !IsInObsoleteScope)
AttributeTester.Report_ObsoleteMessage (obsolete_attr, base_type.GetSignatureForError (), Location);
- ConstructedType ct = base_type as ConstructedType;
+ GenericTypeExpr ct = base_type as GenericTypeExpr;
if ((ct != null) && !ct.CheckConstraints (this))
return false;
}
}
- ConstructedType ct = te as ConstructedType;
+ GenericTypeExpr ct = te as GenericTypeExpr;
if (ct != null) {
// Skip constrains check for overrides and explicit implementations
// TODO: they should use different overload
if (e.eclass == ExprClass.Invalid)
throw new Exception ("Expression " + e + " ExprClass is Invalid after resolve");
- if ((e.type == null) && !(e is ConstructedType))
+ if ((e.type == null) && !(e is GenericTypeExpr))
throw new Exception ("Expression " + e + " did not set its type after Resolve");
return e;
}
}
+ public void Error_ExpressionCannotBeGeneric (Location loc)
+ {
+ Report.Error (307, loc, "The {0} `{1}' cannot be used with type arguments",
+ ExprClassName, GetSignatureForError ());
+ }
+
//
// Converts `source' to an int, uint, long or ulong.
//
if (targs != null)
new_args.Add (targs);
- return new ConstructedType (t, new_args, loc);
+ return new GenericTypeExpr (t, new_args, loc);
}
}
return nested.ResolveAsTypeStep (ec, false);
if (targs != null) {
- ConstructedType ct = new ConstructedType (fne, targs, loc);
+ GenericTypeExpr ct = new GenericTypeExpr (fne.Type, targs, loc);
return ct.ResolveAsTypeStep (ec, false);
}
if (targs != null) {
FullNamedExpression retval = ec.DeclContainer.LookupNamespaceOrType (SimpleName.RemoveGenericArity (Name), loc, true);
if (retval != null) {
- Namespace.Error_TypeArgumentsCannotBeUsed (retval.Type, loc);
+ Namespace.Error_TypeArgumentsCannotBeUsed (retval, loc);
return;
}
}
if (current_block != null){
LocalInfo vi = current_block.GetLocalInfo (Name);
if (vi != null){
- if (targs != null) {
- Report.Error (307, loc,
- "The variable `{0}' cannot be used with type arguments",
- Name);
- return null;
- }
-
LocalVariableReference var = new LocalVariableReference (ec.CurrentBlock, Name, loc);
if (right_side != null) {
return var.ResolveLValue (ec, right_side, loc);
}
}
- ParameterReference pref = current_block.Toplevel.GetParameterReference (Name, loc);
- if (pref != null) {
- if (targs != null) {
- Report.Error (307, loc,
- "The variable `{0}' cannot be used with type arguments",
- Name);
- return null;
- }
-
- if (right_side != null)
- return pref.ResolveLValue (ec, right_side, loc);
- else
- return pref.Resolve (ec);
- }
+ Expression expr = current_block.Toplevel.GetParameterReference (Name, loc);
+ if (expr == null)
+ expr = current_block.Toplevel.GetTransparentIdentifier (Name);
- Expression expr = current_block.Toplevel.GetTransparentIdentifier (Name);
if (expr != null) {
if (right_side != null)
return expr.ResolveLValue (ec, right_side, loc);
+
return expr.Resolve (ec);
}
}
if (targs == null)
return e;
- ConstructedType ct = new ConstructedType (
+ GenericTypeExpr ct = new GenericTypeExpr (
e.Type, targs, loc);
return ct.ResolveAsTypeStep (ec, false);
}
AttributeTester.Report_ObsoleteMessage (oa, left.GetSignatureForError (), loc);
}
- ConstructedType ct = left as ConstructedType;
+ GenericTypeExpr ct = left as GenericTypeExpr;
if (ct != null && !ct.CheckConstraints (ec))
return null;
//
this.expr = expr;
}
- // TODO: this method has very poor performace for Enum fields and
- // probably for other constants as well
Expression DoResolve (EmitContext ec, Expression right_side)
{
if (type != null)
string LookupIdentifier = MemberName.MakeName (Name, targs);
- if (expr_resolved is Namespace) {
- Namespace ns = (Namespace) expr_resolved;
+ Namespace ns = expr_resolved as Namespace;
+ if (ns != null) {
FullNamedExpression retval = ns.Lookup (ec.DeclContainer, LookupIdentifier, loc);
-#if GMCS_SOURCE
- if ((retval != null) && (targs != null))
- retval = new ConstructedType (retval, targs, loc).ResolveAsTypeStep (ec, false);
-#endif
if (retval == null)
- ns.Error_NamespaceDoesNotExist (ec.DeclContainer, loc, Name);
+ ns.Error_NamespaceDoesNotExist (ec.DeclContainer, loc, LookupIdentifier);
+ else if (targs != null)
+ retval = new GenericTypeExpr (retval.Type, targs, loc).ResolveAsTypeStep (ec, false);
+
return retval;
}
}
#if GMCS_SOURCE
- ConstructedType ct = expr_resolved as ConstructedType;
+ GenericTypeExpr ct = expr_resolved as GenericTypeExpr;
if (ct != null) {
//
// When looking up a nested type in a generic instance
//
// See gtest-172-lib.cs and gtest-172.cs for an example.
//
- ct = new ConstructedType (
+ ct = new GenericTypeExpr (
member_lookup.Type, ct.TypeArguments, loc);
return ct.ResolveAsTypeStep (ec, false);
public FullNamedExpression ResolveNamespaceOrType (IResolveContext rc, bool silent)
{
- FullNamedExpression new_expr = expr.ResolveAsTypeStep (rc, silent);
+ FullNamedExpression expr_resolved = expr.ResolveAsTypeStep (rc, silent);
- if (new_expr == null)
+ if (expr_resolved == null)
return null;
string LookupIdentifier = MemberName.MakeName (Name, targs);
- if (new_expr is Namespace) {
- Namespace ns = (Namespace) new_expr;
+ Namespace ns = expr_resolved as Namespace;
+ if (ns != null) {
FullNamedExpression retval = ns.Lookup (rc.DeclContainer, LookupIdentifier, loc);
-#if GMCS_SOURCE
- if ((retval != null) && (targs != null))
- retval = new ConstructedType (retval, targs, loc).ResolveAsTypeStep (rc, false);
-#endif
- if (!silent && retval == null)
+
+ if (retval == null && !silent)
ns.Error_NamespaceDoesNotExist (rc.DeclContainer, loc, LookupIdentifier);
+ else if (targs != null)
+ retval = new GenericTypeExpr (retval.Type, targs, loc).ResolveAsTypeStep (rc, silent);
+
return retval;
}
- TypeExpr tnew_expr = new_expr.ResolveAsTypeTerminal (rc, false);
+ TypeExpr tnew_expr = expr_resolved.ResolveAsTypeTerminal (rc, false);
if (tnew_expr == null)
return null;
if (silent)
return null;
- Error_IdentifierNotFound (rc, new_expr, LookupIdentifier);
+ Error_IdentifierNotFound (rc, expr_resolved, LookupIdentifier);
return null;
}
}
if (the_args != null) {
- ConstructedType ctype = new ConstructedType (texpr.Type, the_args, loc);
+ GenericTypeExpr ctype = new GenericTypeExpr (texpr.Type, the_args, loc);
return ctype.ResolveAsTypeStep (rc, false);
}
#endif
if (expr_type == null)
return;
- Namespace.Error_TypeArgumentsCannotBeUsed (expr_type.Type, loc);
+ Namespace.Error_TypeArgumentsCannotBeUsed (expr_type, loc);
return;
}
if (anonymous_type == null)
return null;
- ConstructedType te = new ConstructedType (anonymous_type.TypeBuilder,
+ GenericTypeExpr te = new GenericTypeExpr (anonymous_type.TypeBuilder,
new TypeArguments (loc, t_args), loc);
return new New (te, arguments, loc).Resolve (ec);
}
}
- public class ConstructedType : TypeExpr
+ public class GenericTypeExpr : TypeExpr
{
- public ConstructedType (FullNamedExpression fname, TypeArguments args, Location l)
+ public GenericTypeExpr (DeclSpace t, Location l)
{
throw new NotImplementedException ();
}
- public ConstructedType (Type t, TypeParameter[] type_params, Location l)
- {
- throw new NotImplementedException ();
- }
-
- public ConstructedType (Type t, TypeArguments args, Location l)
+ public GenericTypeExpr (Type t, TypeArguments args, Location l)
{
throw new NotImplementedException ();
}
}
TypeExpr expr;
- ConstructedType cexpr = fn as ConstructedType;
+ GenericTypeExpr cexpr = fn as GenericTypeExpr;
if (cexpr != null) {
- if (!cexpr.ResolveConstructedType (ec))
- return false;
-
- expr = cexpr;
+ expr = cexpr.ResolveAsBaseTerminal (ec, false);
} else
expr = ((Expression) obj).ResolveAsTypeTerminal (ec, false);
resolved_types = true;
foreach (object obj in constraints) {
- ConstructedType cexpr = obj as ConstructedType;
+ GenericTypeExpr cexpr = obj as GenericTypeExpr;
if (cexpr == null)
continue;
}
/// <summary>
- /// An instantiation of a generic type.
+ /// A reference expression to generic type
/// </summary>
- public class ConstructedType : TypeExpr {
- FullNamedExpression name;
+ class GenericTypeExpr : TypeExpr
+ {
TypeArguments args;
- Type[] gen_params, atypes;
- Type gt;
+ Type[] gen_params; // TODO: Waiting for constrains check cleanup
+ Type open_type;
- /// <summary>
- /// Instantiate the generic type `fname' with the type arguments `args'.
- /// </summary>
- public ConstructedType (FullNamedExpression fname, TypeArguments args, Location l)
- {
- loc = l;
- this.name = fname;
- this.args = args;
-
- eclass = ExprClass.Type;
- }
-
- /// <summary>
- /// This is used to construct the `this' type inside a generic type definition.
- /// </summary>
- public ConstructedType (Type t, TypeParameter[] type_params, Location l)
+ //
+ // Should be carefully used only with defined generic containers. Type parameters
+ // can be used as type arguments in this case.
+ //
+ // TODO: This could be GenericTypeExpr specialization
+ //
+ public GenericTypeExpr (DeclSpace gType, Location l)
{
- gt = t.GetGenericTypeDefinition ();
+ open_type = gType.TypeBuilder.GetGenericTypeDefinition ();
args = new TypeArguments (l);
- foreach (TypeParameter type_param in type_params)
+ foreach (TypeParameter type_param in gType.TypeParameters)
args.Add (new TypeParameterExpr (type_param, l));
this.loc = l;
- this.name = new TypeExpression (gt, l);
- eclass = ExprClass.Type;
}
/// <summary>
/// Use this constructor if you already know the fully resolved
/// generic type.
/// </summary>
- public ConstructedType (Type t, TypeArguments args, Location l)
- : this ((FullNamedExpression)null, args, l)
+ public GenericTypeExpr (Type t, TypeArguments args, Location l)
{
- gt = t.GetGenericTypeDefinition ();
- this.name = new TypeExpression (gt, l);
+ open_type = t.GetGenericTypeDefinition ();
+
+ loc = l;
+ this.args = args;
}
public TypeArguments TypeArguments {
protected override TypeExpr DoResolveAsTypeStep (IResolveContext ec)
{
- if (!ResolveConstructedType (ec))
+ if (!args.Resolve (ec))
+ return null;
+
+ gen_params = open_type.GetGenericArguments ();
+ Type[] atypes = args.Arguments;
+
+ if (atypes.Length != gen_params.Length) {
+ Namespace.Error_InvalidNumberOfTypeArguments (open_type, loc);
return null;
+ }
+ //
+ // Now bind the parameters
+ //
+ type = open_type.MakeGenericType (atypes);
+ eclass = ExprClass.Type;
return this;
}
/// </summary>
public bool CheckConstraints (IResolveContext ec)
{
- return ConstraintChecker.CheckConstraints (ec, gt, gen_params, atypes, loc);
- }
-
- /// <summary>
- /// Resolve the constructed type, but don't check the constraints.
- /// </summary>
- public bool ResolveConstructedType (IResolveContext ec)
- {
- if (type != null)
- return true;
- // If we already know the fully resolved generic type.
- if (gt != null)
- return DoResolveType (ec);
-
- int num_args;
- Type t = name.Type;
-
- if (t == null) {
- Report.Error (246, loc, "Cannot find type `{0}'<...>", GetSignatureForError ());
- return false;
- }
-
- num_args = TypeManager.GetNumberOfTypeArguments (t);
- if (num_args == 0) {
- Report.Error (308, loc,
- "The non-generic type `{0}' cannot " +
- "be used with type arguments.",
- TypeManager.CSharpName (t));
- return false;
- }
-
- gt = t.GetGenericTypeDefinition ();
- return DoResolveType (ec);
- }
-
- bool DoResolveType (IResolveContext ec)
- {
- //
- // Resolve the arguments.
- //
- if (args.Resolve (ec) == false)
- return false;
-
- gen_params = gt.GetGenericArguments ();
- atypes = args.Arguments;
-
- if (atypes.Length != gen_params.Length) {
- Report.Error (305, loc,
- "Using the generic type `{0}' " +
- "requires {1} type arguments",
- TypeManager.CSharpName (gt),
- gen_params.Length.ToString ());
- return false;
- }
-
- //
- // Now bind the parameters.
- //
- type = gt.MakeGenericType (atypes);
- return true;
+ return ConstraintChecker.CheckConstraints (ec, open_type, gen_params, args.Arguments, loc);
}
public override bool CheckAccessLevel (DeclSpace ds)
{
- return ds.CheckAccessLevel (gt);
+ return ds.CheckAccessLevel (open_type);
}
public override bool AsAccessible (DeclSpace ds)
{
- foreach (Type t in atypes) {
+ foreach (Type t in args.Arguments) {
if (!ds.IsAccessibleAs (t))
return false;
}
- return ds.IsAccessibleAs (gt);
+ return ds.IsAccessibleAs (open_type);
}
public override bool IsClass {
- get { return gt.IsClass; }
+ get { return open_type.IsClass; }
}
public override bool IsValueType {
- get { return gt.IsValueType; }
+ get { return open_type.IsValueType; }
}
public override bool IsInterface {
- get { return gt.IsInterface; }
+ get { return open_type.IsInterface; }
}
public override bool IsSealed {
- get { return gt.IsSealed; }
+ get { return open_type.IsSealed; }
}
public override bool Equals (object obj)
{
- ConstructedType cobj = obj as ConstructedType;
+ GenericTypeExpr cobj = obj as GenericTypeExpr;
if (cobj == null)
return false;
new_args.Add (new TypeExpression (t, loc));
}
- TypeExpr ct = new ConstructedType (ctype, new_args, loc);
+ TypeExpr ct = new GenericTypeExpr (ctype, new_args, loc);
if (ct.ResolveAsTypeStep (ec, false) == null)
return false;
ctype = ct.Type;
list.Add (enumerable_type);
#if GMCS_SOURCE
- generic_enumerable_type = new ConstructedType (
+ generic_enumerable_type = new GenericTypeExpr (
TypeManager.generic_ienumerable_type,
generic_args, Location);
list.Add (generic_enumerable_type);
list.Add (new TypeExpression (TypeManager.idisposable_type, Location));
#if GMCS_SOURCE
- generic_enumerator_type = new ConstructedType (
+ generic_enumerator_type = new GenericTypeExpr (
TypeManager.generic_ienumerator_type,
generic_args, Location);
list.Add (generic_enumerator_type);
if (name.IndexOf ('`') > 0) {
FullNamedExpression retval = Lookup (ds, SimpleName.RemoveGenericArity (name), loc);
if (retval != null) {
- Error_TypeArgumentsCannotBeUsed (retval.Type, loc);
+ Error_TypeArgumentsCannotBeUsed (retval, loc);
return;
}
} else {
TypeManager.CSharpName(t), TypeManager.GetNumberOfTypeArguments(t).ToString());
}
- public static void Error_TypeArgumentsCannotBeUsed (Type t, Location loc)
+ public static void Error_TypeArgumentsCannotBeUsed (FullNamedExpression expr, Location loc)
{
- Report.SymbolRelatedToPreviousError (t);
- Error_TypeArgumentsCannotBeUsed (loc, "type", TypeManager.CSharpName (t));
+ if (expr is TypeExpr) {
+ Report.SymbolRelatedToPreviousError (expr.Type);
+ Error_TypeArgumentsCannotBeUsed (loc, "type", expr.GetSignatureForError ());
+ } else {
+ expr.Error_ExpressionCannotBeGeneric (loc);
+ }
}
public static void Error_TypeArgumentsCannotBeUsed (MethodBase mi, Location loc)
"System", "Nullable`1", Kind.Struct, true);
}
- ConstructedType ctype = new ConstructedType (TypeManager.generic_nullable_type, args, loc);
+ GenericTypeExpr ctype = new GenericTypeExpr (TypeManager.generic_nullable_type, args, loc);
return ctype.ResolveAsTypeTerminal (ec, false);
}