예제 #1
0
파일: convert.cs 프로젝트: nberardi/mono
		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;
		}
예제 #2
0
파일: generic.cs 프로젝트: speier/shake
        public TypeParameterInflator(TypeSpec type, TypeParameterSpec[] tparams, TypeSpec[] targs)
        {
            if (tparams.Length != targs.Length)
                throw new ArgumentException ("Invalid arguments");

            this.tparams = tparams;
            this.targs = targs;
            this.type = type;
        }
예제 #3
0
		public HoistedStoreyClass (DeclSpace parent, MemberName name, TypeParameter[] tparams, Modifiers mod)
			: base (parent, name, mod | Modifiers.PRIVATE)
		{
			if (tparams != null) {
				type_params = new TypeParameter[tparams.Length];
				var src = new TypeParameterSpec[tparams.Length];
				var dst = new TypeParameterSpec[tparams.Length];

				for (int i = 0; i < type_params.Length; ++i) {
					type_params[i] = tparams[i].CreateHoistedCopy (this, 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 (null, src, dst);
				for (int i = 0; i < type_params.Length; ++i) {
					src[i].InflateConstraints (inflator, dst[i]);
				}
			}
		}
예제 #4
0
파일: import.cs 프로젝트: telurmasin/mono
		public ImportedGenericMethodDefinition (MethodInfo provider, AParametersCollection parameters, TypeParameterSpec[] tparams)
			: base (provider, parameters)
		{
			this.tparams = tparams;
		}
예제 #5
0
파일: convert.cs 프로젝트: frje/SharpLang
		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;
		}
예제 #6
0
파일: generic.cs 프로젝트: afaerber/mono
		public TypeParameter (TypeParameterSpec spec, DeclSpace parent, TypeSpec parentSpec, MemberName name, Attributes attrs)
			: base (parent, name, attrs)
		{
			this.spec = new TypeParameterSpec (parentSpec, spec.DeclaredPosition, spec.MemberDefinition, spec.SpecialConstraint, spec.Variance, null) {
				BaseType = spec.BaseType,
				InterfacesDefined = spec.InterfacesDefined,
				TypeArguments = spec.TypeArguments
			};
		}
예제 #7
0
파일: import.cs 프로젝트: Gobiner/ILSpy
		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;
		}
예제 #8
0
파일: import.cs 프로젝트: Gobiner/ILSpy
		public ImportedGenericMethodDefinition (MethodInfo provider, TypeSpec type, AParametersCollection parameters, TypeParameterSpec[] tparams, MetadataImporter importer)
			: base (provider, type, parameters, importer)
		{
			this.tparams = tparams;
		}
예제 #9
0
파일: generic.cs 프로젝트: ikvm/mono
		//
		// Constraints have to match by definition but not position, used by
		// partial classes or methods
		//
		public bool HasSameConstraintsDefinition (TypeParameterSpec other)
		{
			if (spec != other.spec)
				return false;

			if (BaseType != other.BaseType)
				return false;

			if (!TypeSpecComparer.Override.IsSame (InterfacesDefined, other.InterfacesDefined))
				return false;

			if (!TypeSpecComparer.Override.IsSame (targs, other.targs))
				return false;

			return true;
		}
예제 #10
0
파일: generic.cs 프로젝트: ikvm/mono
		public TypeParameter (DeclSpace parent, int index, MemberName name, Constraints constraints, Attributes attrs, Variance variance)
			: base (parent, name, attrs)
		{
			this.constraints = constraints;
//			this.variance = variance;
			this.spec = new TypeParameterSpec (null, index, this, SpecialConstraint.None, variance, null);
		}
예제 #11
0
파일: generic.cs 프로젝트: ikvm/mono
		static void CheckConversion (IMemberContext mc, MemberSpec context, TypeSpec atype, TypeParameterSpec tparam, TypeSpec ttype, Location loc)
		{
			var expr = new EmptyExpression (atype);
			if (!Convert.ImplicitStandardConversionExists (expr, ttype)) {
				mc.Compiler.Report.SymbolRelatedToPreviousError (tparam);
				if (TypeManager.IsValueType (atype)) {
					mc.Compiler.Report.Error (315, loc, "The type `{0}' cannot be used as type parameter `{1}' in the generic type or method `{2}'. There is no boxing conversion from `{0}' to `{3}'",
						atype.GetSignatureForError (), tparam.GetSignatureForError (), context.GetSignatureForError (), ttype.GetSignatureForError ());
				} else if (atype.IsGenericParameter) {
					mc.Compiler.Report.Error (314, loc, "The type `{0}' cannot be used as type parameter `{1}' in the generic type or method `{2}'. There is no boxing or type parameter conversion from `{0}' to `{3}'",
						atype.GetSignatureForError (), tparam.GetSignatureForError (), context.GetSignatureForError (), ttype.GetSignatureForError ());
				} else {
					mc.Compiler.Report.Error (311, loc, "The type `{0}' cannot be used as type parameter `{1}' in the generic type or method `{2}'. There is no implicit reference conversion from `{0}' to `{3}'",
						atype.GetSignatureForError (), tparam.GetSignatureForError (), context.GetSignatureForError (), ttype.GetSignatureForError ());
				}
			}
		}
예제 #12
0
파일: generic.cs 프로젝트: ikvm/mono
		static bool CheckConstraint (IMemberContext mc, MemberSpec context, TypeSpec atype, TypeParameterSpec tparam, Location loc)
		{
			//
			// First, check the `class' and `struct' constraints.
			//
			if (tparam.HasSpecialClass && !TypeManager.IsReferenceType (atype)) {
				mc.Compiler.Report.Error (452, loc,
					"The type `{0}' must be a reference type in order to use it as type parameter `{1}' in the generic type or method `{2}'",
					TypeManager.CSharpName (atype), tparam.GetSignatureForError (), context.GetSignatureForError ());
				return false;
			}

			if (tparam.HasSpecialStruct && (!TypeManager.IsValueType (atype) || TypeManager.IsNullableType (atype))) {
				mc.Compiler.Report.Error (453, loc,
					"The type `{0}' must be a non-nullable value type in order to use it as type parameter `{1}' in the generic type or method `{2}'",
					TypeManager.CSharpName (atype), tparam.GetSignatureForError (), context.GetSignatureForError ());
				return false;
			}

			//
			// The class constraint comes next.
			//
			if (tparam.HasTypeConstraint) {
				CheckConversion (mc, context, atype, tparam, tparam.BaseType, loc);
			}

			//
			// Now, check the interfaces and type parameters constraints
			//
			if (tparam.Interfaces != null) {
				if (TypeManager.IsNullableType (atype)) {
					mc.Compiler.Report.Error (313, loc,
						"The type `{0}' cannot be used as type parameter `{1}' in the generic type or method `{2}'. The nullable type `{0}' never satisfies interface constraint",
						atype.GetSignatureForError (), tparam.GetSignatureForError (), context.GetSignatureForError ());
				} else {
					foreach (TypeSpec iface in tparam.Interfaces) {
						CheckConversion (mc, context, atype, tparam, iface, loc);
					}
				}
			}

			//
			// Finally, check the constructor constraint.
			//
			if (!tparam.HasSpecialConstructor)
				return true;

			if (!HasDefaultConstructor (atype)) {
				mc.Compiler.Report.SymbolRelatedToPreviousError (atype);
				mc.Compiler.Report.Error (310, loc,
					"The type `{0}' must have a public parameterless constructor in order to use it as parameter `{1}' in the generic type or method `{2}'",
					TypeManager.CSharpName (atype), tparam.GetSignatureForError (), context.GetSignatureForError ());
				return false;
			}

			return true;
		}
예제 #13
0
파일: generic.cs 프로젝트: ikvm/mono
		/// <summary>
		///   Check the constraints; we're called from ResolveAsTypeTerminal()
		///   after fully resolving the constructed type.
		/// </summary>
		public static bool CheckAll (IMemberContext mc, MemberSpec context, TypeSpec[] targs, TypeParameterSpec[] tparams, Location loc)
		{
			for (int i = 0; i < tparams.Length; i++) {
				if (!CheckConstraint (mc, context, targs [i], tparams [i], loc))
					return false;
			}

			return true;
		}
예제 #14
0
파일: generic.cs 프로젝트: ikvm/mono
		public TypeParameterSpec Mutate (TypeParameterSpec tp)
		{
			for (int i = 0; i < mvar.Length; ++i) {
				if (mvar[i].Type == tp)
					return var[i].Type;
			}

			return tp;
		}
예제 #15
0
파일: generic.cs 프로젝트: ikvm/mono
		public TypeSpec Inflate (TypeParameterSpec tp)
		{
			for (int i = 0; i < tparams.Length; ++i)
				if (tparams [i] == tp)
					return targs[i];

			// This can happen when inflating nested types
			// without type arguments specified
			return tp;
		}
예제 #16
0
파일: import.cs 프로젝트: telurmasin/mono
		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);
			if (type.DeclaringMethod != null)
				spec = new TypeParameterSpec (type.GenericParameterPosition, def, special, variance, type);
			else
				spec = new TypeParameterSpec (declaringType, type.GenericParameterPosition, def, special, variance, type);

			// Add it now, so any constraint can reference it and get same instance
			import_cache.Add (type, spec);

			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;
				}

				if (ct.IsClass) {
					spec.BaseType = CreateType (ct);
					continue;
				}

				spec.AddInterface (CreateType (ct));
			}

			if (spec.BaseType == null)
				spec.BaseType = TypeManager.object_type;

			if (tparams != null)
				spec.TypeArguments = tparams.ToArray ();

			return spec;
		}
예제 #17
0
파일: import.cs 프로젝트: Gobiner/ILSpy
		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;
				}

				if (!IsMissingType (ct) && ct.IsClass) {
					spec.BaseType = CreateType (ct);
					continue;
				}

				spec.AddInterface (CreateType (ct));
			}

			if (spec.BaseType == null)
				spec.BaseType = module.Compiler.BuiltinTypes.Object;

			if (tparams != null)
				spec.TypeArguments = tparams.ToArray ();
		}
예제 #18
0
파일: generic.cs 프로젝트: ikvm/mono
		//
		// Constraints have to match by using same set of types, used by
		// implicit interface implementation
		//
		public bool HasSameConstraintsImplementation (TypeParameterSpec other)
		{
			if (spec != other.spec)
				return false;

			//
			// It can be same base type or inflated type parameter
			//
			// interface I<T> { void Foo<U> where U : T; }
			// class A : I<int> { void Foo<X> where X : int {} }
			//
			bool found;
			if (!TypeSpecComparer.Override.IsEqual (BaseType, other.BaseType)) {
				if (other.targs == null)
					return false;

				found = false;
				foreach (var otarg in other.targs) {
					if (TypeSpecComparer.Override.IsEqual (BaseType, otarg)) {
						found = true;
						break;
					}
				}

				if (!found)
					return false;
			}

			// Check interfaces implementation -> definition
			if (InterfacesDefined != null) {
				foreach (var iface in InterfacesDefined) {
					found = false;
					if (other.InterfacesDefined != null) {
						foreach (var oiface in other.InterfacesDefined) {
							if (TypeSpecComparer.Override.IsEqual (iface, oiface)) {
								found = true;
								break;
							}
						}
					}

					if (found)
						continue;

					if (other.targs != null) {
						foreach (var otarg in other.targs) {
							if (TypeSpecComparer.Override.IsEqual (BaseType, otarg)) {
								found = true;
								break;
							}
						}
					}

					if (!found)
						return false;
				}
			}

			// Check interfaces implementation <- definition
			if (other.InterfacesDefined != null) {
				if (InterfacesDefined == null)
					return false;

				foreach (var oiface in other.InterfacesDefined) {
					found = false;
					foreach (var iface in InterfacesDefined) {
						if (TypeSpecComparer.Override.IsEqual (iface, oiface)) {
							found = true;
							break;
						}
					}

					if (!found)
						return false;
				}
			}

			// Check type parameters implementation -> definition
			if (targs != null) {
				if (other.targs == null)
					return false;

				foreach (var targ in targs) {
					found = false;
					foreach (var otarg in other.targs) {
						if (TypeSpecComparer.Override.IsEqual (targ, otarg)) {
							found = true;
							break;
						}
					}

					if (!found)
						return false;
				}
			}

			// Check type parameters implementation <- definition
			if (other.targs != null) {
				foreach (var otarg in other.targs) {
					// Ignore inflated type arguments, were checked above
					if (!otarg.IsGenericParameter)
						continue;

					if (targs == null)
						return false;

					found = false;
					foreach (var targ in targs) {
						if (TypeSpecComparer.Override.IsEqual (targ, otarg)) {
							found = true;
							break;
						}
					}

					if (!found)
						return false;
				}				
			}

			return true;
		}
예제 #19
0
파일: import.cs 프로젝트: Gobiner/ILSpy
		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;
		}
예제 #20
0
파일: generic.cs 프로젝트: ikvm/mono
		public static TypeParameterSpec[] InflateConstraints (TypeParameterInflator inflator, TypeParameterSpec[] tparams)
		{
			TypeParameterSpec[] constraints = null;

			for (int i = 0; i < tparams.Length; ++i) {
				var tp = tparams[i];
				if (tp.HasTypeConstraint || tp.Interfaces != null || tp.TypeArguments != null) {
					if (constraints == null) {
						constraints = new TypeParameterSpec[tparams.Length];
						Array.Copy (tparams, constraints, constraints.Length);
					}

					constraints[i] = (TypeParameterSpec) constraints[i].InflateMember (inflator);
				}
			}

			if (constraints == null)
				constraints = tparams;

			return constraints;
		}
예제 #21
0
파일: anonymous.cs 프로젝트: rabink/mono
		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);
			}
		}
예제 #22
0
파일: generic.cs 프로젝트: ikvm/mono
		public void InflateConstraints (TypeParameterInflator inflator, TypeParameterSpec tps)
		{
			tps.BaseType = inflator.Inflate (BaseType);
			if (ifaces != null) {
				tps.ifaces = new List<TypeSpec> (ifaces.Count);
				for (int i = 0; i < ifaces.Count; ++i)
					tps.ifaces.Add (inflator.Inflate (ifaces[i]));
			}
			if (targs != null) {
				tps.targs = new TypeSpec[targs.Length];
				for (int i = 0; i < targs.Length; ++i)
					tps.targs[i] = inflator.Inflate (targs[i]);
			}
		}