}
}
+ public Constraints Clone ()
+ {
+ return new Constraints (name, constraints, loc);
+ }
+
GenericParameterAttributes attrs;
TypeExpr class_constraint;
ArrayList iface_constraints;
return true;
}
+
+ public void VerifyClsCompliance ()
+ {
+ if (class_constraint_type != null && !AttributeTester.IsClsCompliant (class_constraint_type))
+ Warning_ConstrainIsNotClsCompliant (class_constraint_type, class_constraint.Location);
+
+ if (iface_constraint_types != null) {
+ for (int i = 0; i < iface_constraint_types.Length; ++i) {
+ if (!AttributeTester.IsClsCompliant (iface_constraint_types [i]))
+ Warning_ConstrainIsNotClsCompliant (iface_constraint_types [i],
+ ((TypeExpr)iface_constraints [i]).Location);
+ }
+ }
+ }
+
+ void Warning_ConstrainIsNotClsCompliant (Type t, Location loc)
+ {
+ Report.SymbolRelatedToPreviousError (t);
+ Report.Warning (3024, 1, loc, "Constraint type `{0}' is not CLS-compliant",
+ TypeManager.CSharpName (t));
+ }
}
/// <summary>
TypeManager.CSharpName (mparam), TypeManager.CSharpSignature (mb));
return false;
}
- } else if (DeclSpace is Iterator) {
+ } else if (DeclSpace is CompilerGeneratedClass) {
TypeParameter[] tparams = DeclSpace.TypeParameters;
Type[] types = new Type [tparams.Length];
for (int i = 0; i < tparams.Length; i++)
if (te is TypeParameterExpr)
has_type_args = true;
+#if !MS_COMPATIBLE
if (te.Type.IsSealed && te.Type.IsAbstract) {
Report.Error (718, Location, "`{0}': static classes cannot be used as generic arguments",
te.GetSignatureForError ());
return false;
}
+#endif
if (te.Type.IsPointer) {
Report.Error (306, Location, "The type `{0}' may not be used " +
"as a type argument", TypeManager.CSharpName (te.Type));
public override bool AsAccessible (DeclSpace ds, int flags)
{
+ foreach (Type t in atypes) {
+ if (!ds.AsAccessible (t, flags))
+ return false;
+ }
+
return ds.AsAccessible (gt, flags);
}
}
}
-
public override string FullName {
get {
return full_name;
if (agc != null) {
if (agc is Constraints)
((Constraints) agc).Resolve (ec);
- is_class = agc.HasReferenceTypeConstraint;
- is_struct = agc.HasValueTypeConstraint;
+ is_class = agc.IsReferenceType;
+ is_struct = agc.IsValueType;
} else {
is_class = is_struct = false;
}
public override string DocCommentHeader {
get { return "M:"; }
}
+
+ public new void VerifyClsCompliance ()
+ {
+ foreach (TypeParameter tp in TypeParameters) {
+ if (tp.Constraints == null)
+ continue;
+
+ tp.Constraints.VerifyClsCompliance ();
+ }
+ }
}
public class DefaultValueExpression : Expression
type = texpr.Type;
+ if (type == TypeManager.void_type) {
+ Error_VoidInvalidInTheContext (loc);
+ return null;
+ }
+
+ if (type.IsGenericParameter)
+ {
+ GenericConstraints constraints = TypeManager.GetTypeParameterConstraints(type);
+ if (constraints != null && constraints.IsReferenceType)
+ return new NullDefault (new NullLiteral (Location), type);
+ }
+ else
+ {
+ Constant c = New.Constantify(type);
+ if (c != null)
+ return new NullDefault (c, type);
+
+ if (!TypeManager.IsValueType (type))
+ return new NullDefault (new NullLiteral (Location), type);
+ }
eclass = ExprClass.Variable;
return this;
}
public override void Emit (EmitContext ec)
{
- if (type.IsGenericParameter || TypeManager.IsValueType (type)) {
- LocalTemporary temp_storage = new LocalTemporary (type);
+ LocalTemporary temp_storage = new LocalTemporary(type);
- temp_storage.AddressOf (ec, AddressOp.LoadStore);
- ec.ig.Emit (OpCodes.Initobj, type);
- temp_storage.Emit (ec);
- } else
- ec.ig.Emit (OpCodes.Ldnull);
+ temp_storage.AddressOf(ec, AddressOp.LoadStore);
+ ec.ig.Emit(OpCodes.Initobj, type);
+ temp_storage.Emit(ec);
}
}
static public Type generic_ienumerable_type;
static public Type generic_nullable_type;
- // <remarks>
- // Tracks the generic parameters.
- // </remarks>
- static PtrHashtable builder_to_type_param;
-
//
// These methods are called by code generated by the compiler
//
static public MethodInfo activator_create_instance;
- static void InitGenerics ()
- {
- builder_to_type_param = new PtrHashtable ();
- }
-
- static void CleanUpGenerics ()
- {
- builder_to_type_param = null;
- }
-
static void InitGenericCoreTypes ()
{
activator_type = CoreLookupType ("System", "Activator");
return CoreLookupType (ns, MemberName.MakeName (name, arity));
}
- public static void AddTypeParameter (Type t, TypeParameter tparam)
- {
- if (!builder_to_type_param.Contains (t))
- builder_to_type_param.Add (t, tparam);
- }
-
public static TypeContainer LookupGenericTypeContainer (Type t)
{
t = DropGenericTypeArguments (t);
return LookupTypeContainer (t);
}
- public static TypeParameter LookupTypeParameter (Type t)
- {
- return (TypeParameter) builder_to_type_param [t];
- }
-
public static GenericConstraints GetTypeParameterConstraints (Type t)
{
if (!t.IsGenericParameter)
return ReflectionConstraints.GetConstraints (t);
}
- public static FieldInfo GetGenericFieldDefinition (FieldInfo fi)
- {
- if (fi.DeclaringType.IsGenericTypeDefinition ||
- !fi.DeclaringType.IsGenericType)
- return fi;
-
- Type t = fi.DeclaringType.GetGenericTypeDefinition ();
- BindingFlags bf = BindingFlags.Public | BindingFlags.NonPublic |
- BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly;
-
- foreach (FieldInfo f in t.GetFields (bf))
- if (f.MetadataToken == fi.MetadataToken)
- return f;
-
- return fi;
- }
-
/// <summary>
/// Check whether `a' and `b' may become equal generic types.
/// The algorithm to do that is a little bit complicated.
return true;
}
- /// <summary>
- /// Whether `mb' is a generic method definition.
- /// </summary>
- public static bool IsGenericMethodDefinition (MethodBase mb)
- {
- if (mb.DeclaringType is TypeBuilder) {
- IMethodData method = (IMethodData) builder_to_method [mb];
- if (method == null)
- return false;
-
- return method.GenericMethod != null;
- }
-
- return mb.IsGenericMethodDefinition;
- }
-
- /// <summary>
- /// Whether `mb' is a generic method definition.
- /// </summary>
- public static bool IsGenericMethod (MethodBase mb)
- {
- if (mb.DeclaringType is TypeBuilder) {
- IMethodData method = (IMethodData) builder_to_method [mb];
- if (method == null)
- return false;
-
- return method.GenericMethod != null;
- }
-
- return mb.IsGenericMethod;
- }
-
//
// Type inference.
//
Argument a = (Argument) arguments [i];
if ((a.Expr is NullLiteral) || (a.Expr is MethodGroupExpr) ||
- (a.Expr is AnonymousMethod))
+ (a.Expr is AnonymousMethodExpression))
continue;
arg_types [i] = a.Type;
method = ((MethodInfo)method).MakeGenericMethod (infered_types);
return true;
}
-
- public static bool IsNullableType (Type t)
- {
- return generic_nullable_type == DropGenericTypeArguments (t);
- }
-
- public static bool IsNullableTypeOf (Type t, Type nullable)
- {
- if (!IsNullableType (t))
- return false;
-
- return GetTypeArguments (t) [0] == nullable;
- }
-
- public static bool IsNullableValueType (Type t)
- {
- if (!IsNullableType (t))
- return false;
-
- return GetTypeArguments (t) [0].IsValueType;
- }
}
public abstract class Nullable
return this;
}
- if (unwrap != null) {
- expr = Convert.ImplicitConversion (ec, unwrap, rtype, loc);
- if (expr != null) {
- left = expr;
- expr = right;
- type = expr.Type;
- return this;
- }
+ Expression left_null = unwrap != null ? unwrap : left;
+ expr = Convert.ImplicitConversion (ec, left_null, rtype, loc);
+ if (expr != null) {
+ left = expr;
+ expr = right;
+ type = rtype;
+ return this;
}
Binary.Error_OperatorCannotBeApplied (loc, "??", ltype, rtype);