public static Expression ImplicitTypeParameterConversion (Expression expr, TypeParameterSpec expr_type, TypeSpec target_type) { // // From T to a type parameter U, provided T depends on U // if (target_type.IsGenericParameter) { if (expr_type.TypeArguments != null && expr_type.HasDependencyOn (target_type)) { if (expr == null) return EmptyExpression.Null; if (expr_type.IsReferenceType && !((TypeParameterSpec) target_type).IsReferenceType) return new BoxedCast (expr, target_type); return new ClassCast (expr, target_type); } return null; } // // LAMESPEC: From T to dynamic type because it's like T to object // if (target_type.BuiltinType == BuiltinTypeSpec.Type.Dynamic) { if (expr == null) return EmptyExpression.Null; if (expr_type.IsReferenceType) return new ClassCast (expr, target_type); return new BoxedCast (expr, target_type); } // // From T to its effective base class C // From T to any base class of C (it cannot contain dynamic or be of dynamic type) // From T to any interface implemented by C // var base_type = expr_type.GetEffectiveBase (); if (base_type == target_type || TypeSpec.IsBaseClass (base_type, target_type, false) || base_type.ImplementsInterface (target_type, true)) { if (expr == null) return EmptyExpression.Null; if (expr_type.IsReferenceType) return new ClassCast (expr, target_type); return new BoxedCast (expr, target_type); } if (target_type.IsInterface && expr_type.IsConvertibleToInterface (target_type)) { if (expr == null) return EmptyExpression.Null; if (expr_type.IsReferenceType) return new ClassCast (expr, target_type); return new BoxedCast (expr, target_type); } return null; }
static Expression ExplicitTypeParameterConversionToT (Expression source, TypeSpec source_type, TypeParameterSpec target_type) { // // From the effective base class C of T to T and from any base class of C to T // var effective = target_type.GetEffectiveBase (); if (TypeSpecComparer.IsEqual (effective, source_type) || TypeSpec.IsBaseClass (effective, source_type, false)) return source == null ? EmptyExpression.Null : new ClassCast (source, target_type); return null; }
TypeParameterSpec CreateTypeParameter (MetaType type, TypeSpec declaringType) { Variance variance; switch (type.GenericParameterAttributes & GenericParameterAttributes.VarianceMask) { case GenericParameterAttributes.Covariant: variance = Variance.Covariant; break; case GenericParameterAttributes.Contravariant: variance = Variance.Contravariant; break; default: variance = Variance.None; break; } SpecialConstraint special = SpecialConstraint.None; var import_special = type.GenericParameterAttributes & GenericParameterAttributes.SpecialConstraintMask; if ((import_special & GenericParameterAttributes.NotNullableValueTypeConstraint) != 0) { special |= SpecialConstraint.Struct; } else if ((import_special & GenericParameterAttributes.DefaultConstructorConstraint) != 0) { special = SpecialConstraint.Constructor; } if ((import_special & GenericParameterAttributes.ReferenceTypeConstraint) != 0) { special |= SpecialConstraint.Class; } TypeParameterSpec spec; var def = new ImportedTypeParameterDefinition (type, this); if (type.DeclaringMethod != null) { spec = new TypeParameterSpec (type.GenericParameterPosition, def, special, variance, type); } else { spec = new TypeParameterSpec (declaringType, type.GenericParameterPosition, def, special, variance, type); } return spec; }
TypeParameterSpec[] CreateGenericParameters (int first, MetaType[] tparams) { var tspec = new TypeParameterSpec[tparams.Length - first]; for (int pos = first; pos < tparams.Length; ++pos) { var type = tparams[pos]; int index = pos - first; tspec[index] = (TypeParameterSpec) CreateType (type, new DynamicTypeReader (), false); } return tspec; }
public ImportedGenericMethodDefinition (MethodInfo provider, TypeSpec type, AParametersCollection parameters, TypeParameterSpec[] tparams, MetadataImporter importer) : base (provider, type, parameters, importer) { this.tparams = tparams; }
void ImportTypeParameterTypeConstraints (TypeParameterSpec spec, MetaType type) { var constraints = type.GetGenericParameterConstraints (); List<TypeSpec> tparams = null; foreach (var ct in constraints) { if (ct.IsGenericParameter) { if (tparams == null) tparams = new List<TypeSpec> (); tparams.Add (CreateType (ct)); continue; } var constraint_type = CreateType (ct); if (constraint_type.IsClass) { spec.BaseType = constraint_type; continue; } spec.AddInterface (constraint_type); } if (spec.BaseType == null) spec.BaseType = module.Compiler.BuiltinTypes.Object; if (tparams != null) spec.TypeArguments = tparams.ToArray (); }
public HoistedStoreyClass (TypeDefinition parent, MemberName name, TypeParameters tparams, Modifiers mods, MemberKind kind) : base (parent, name, mods | Modifiers.PRIVATE, kind) { if (tparams != null) { var type_params = name.TypeParameters; var src = new TypeParameterSpec[tparams.Count]; var dst = new TypeParameterSpec[tparams.Count]; for (int i = 0; i < tparams.Count; ++i) { type_params[i] = tparams[i].CreateHoistedCopy (spec); src[i] = tparams[i].Type; dst[i] = type_params[i].Type; } // A copy is not enough, inflate any type parameter constraints // using a new type parameters var inflator = new TypeParameterInflator (this, null, src, dst); for (int i = 0; i < tparams.Count; ++i) { src[i].InflateConstraints (inflator, dst[i]); } mutator = new TypeParameterMutator (tparams, type_params); } }