Example #1
0
		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;
		}
Example #2
0
		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;
		}
Example #3
0
		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;
		}
Example #4
0
		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;
		}
Example #5
0
		public ImportedGenericMethodDefinition (MethodInfo provider, TypeSpec type, AParametersCollection parameters, TypeParameterSpec[] tparams, MetadataImporter importer)
			: base (provider, type, parameters, importer)
		{
			this.tparams = tparams;
		}
Example #6
0
		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 ();
		}
Example #7
0
		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);
			}
		}