Exemplo n.º 1
0
		public virtual MemberSpec InflateMember (TypeParameterInflator inflator)
		{
			var inflated = (MemberSpec) MemberwiseClone ();
			inflated.declaringType = inflator.TypeInstance;
			if (DeclaringType.IsGenericOrParentIsGeneric)
				inflated.state |= StateFlags.PendingMetaInflate;
#if DEBUG
			inflated.ID += 1000000;
#endif
			return inflated;
		}
Exemplo n.º 2
0
		public override MemberSpec InflateMember (TypeParameterInflator inflator)
		{
			var fs = (FieldSpec) base.InflateMember (inflator);
			fs.memberType = inflator.Inflate (memberType);
			return fs;
		}
Exemplo n.º 3
0
Arquivo: generic.cs Projeto: ikvm/mono
		public TypeParameterInflator (TypeParameterInflator nested, TypeSpec type)
			: this (type, nested.tparams, nested.targs)
		{
		}
Exemplo n.º 4
0
		public override MemberSpec InflateMember (TypeParameterInflator inflator)
		{
			var spec = (IndexerSpec) base.InflateMember (inflator);
			spec.parameters = parameters.Inflate (inflator);
			return spec;
		}
Exemplo n.º 5
0
		public override MemberSpec InflateMember (TypeParameterInflator inflator)
		{
			var ms = (MethodSpec) base.InflateMember (inflator);
			ms.inflatedMetaInfo = null;
			ms.returnType = inflator.Inflate (returnType);
			ms.parameters = parameters.Inflate (inflator);
			if (IsGeneric)
				ms.constraints = TypeParameterSpec.InflateConstraints (inflator, Constraints);

			return ms;
		}
Exemplo n.º 6
0
		//
		// Creates a nested container in this context for all dynamic compiler generated stuff
		//
		internal DynamicSiteClass CreateDynamicSite ()
		{
			if (dynamic_site_container == null) {
				var mc = member_context.CurrentMemberDefinition as MemberBase;
				dynamic_site_container = new DynamicSiteClass (CurrentTypeDefinition.Parent.PartialContainer, mc, member_context.CurrentTypeParameters);

				CurrentTypeDefinition.Module.AddCompilerGeneratedClass (dynamic_site_container);
				dynamic_site_container.CreateContainer ();
				dynamic_site_container.DefineContainer ();
				dynamic_site_container.Define ();

				var inflator = new TypeParameterInflator (Module, CurrentType, TypeParameterSpec.EmptyTypes, TypeSpec.EmptyTypes);
				var inflated = dynamic_site_container.CurrentType.InflateMember (inflator);
				CurrentType.MemberCache.AddMember (inflated);
			}

			return dynamic_site_container;
		}
Exemplo n.º 7
0
		public override MemberSpec InflateMember (TypeParameterInflator inflator)
		{
			var es = (EventSpec) base.InflateMember (inflator);
			es.MemberType = inflator.Inflate (MemberType);

			if (backing_field != null)
				es.backing_field = (FieldSpec) backing_field.InflateMember (inflator);

			return es;
		}
Exemplo n.º 8
0
		protected virtual void DefineTypeParameters ()
		{
			var tparams = CurrentTypeParameters;

			TypeParameterSpec[] base_tparams = null;
			TypeParameterSpec[] base_decl_tparams = TypeParameterSpec.EmptyTypes;
			TypeSpec[] base_targs = TypeSpec.EmptyTypes;
			if (((ModFlags & Modifiers.OVERRIDE) != 0 || IsExplicitImpl)) {
				if (base_method != null) {
					base_tparams = base_method.GenericDefinition.TypeParameters;
				
					if (base_method.DeclaringType.IsGeneric) {
						base_decl_tparams = base_method.DeclaringType.MemberDefinition.TypeParameters;
						base_targs = Parent.BaseType.TypeArguments;
					}

					if (base_method.IsGeneric) {
						if (base_decl_tparams.Length != 0) {
							base_decl_tparams = base_decl_tparams.Concat (base_tparams).ToArray ();
							base_targs = base_targs.Concat (tparams.Select<TypeParameter, TypeSpec> (l => l.Type)).ToArray ();
						} else {
							base_decl_tparams = base_tparams;
							base_targs = tparams.Select (l => l.Type).ToArray ();
						}
					}
				} else if (MethodData.implementing != null) {
					base_tparams = MethodData.implementing.GenericDefinition.TypeParameters;
					if (MethodData.implementing.DeclaringType.IsGeneric) {
						base_decl_tparams = MethodData.implementing.DeclaringType.MemberDefinition.TypeParameters;
						foreach (var iface in Parent.CurrentType.Interfaces) {
							if (iface == MethodData.implementing.DeclaringType) {
								base_targs = iface.TypeArguments;
								break;
							}
						}
					}
				}
			}

			for (int i = 0; i < tparams.Length; ++i) {
				var tp = tparams[i];

				if (!tp.ResolveConstraints (this))
					continue;

				//
				// Copy base constraints for override/explicit methods
				//
				if (base_tparams != null) {
					var base_tparam = base_tparams[i];
					tp.Type.SpecialConstraint = base_tparam.SpecialConstraint;

					var inflator = new TypeParameterInflator (CurrentType, base_decl_tparams, base_targs);
					base_tparam.InflateConstraints (inflator, tp.Type);
				} else if (MethodData.implementing != null) {
					var base_tp = MethodData.implementing.Constraints[i];
					if (!tp.Type.HasSameConstraintsImplementation (base_tp)) {
						Report.SymbolRelatedToPreviousError (MethodData.implementing);
						Report.Error (425, Location,
							"The constraints for type parameter `{0}' of method `{1}' must match the constraints for type parameter `{2}' of interface method `{3}'. Consider using an explicit interface implementation instead",
							tp.GetSignatureForError (), GetSignatureForError (), base_tp.GetSignatureForError (), MethodData.implementing.GetSignatureForError ());
					}
				}
			}
		}
Exemplo n.º 9
0
        public override TypeSpec AddDelegate(Delegate d)
        {
            TypeSpec inflated;

            base.AddDelegate (d);

            // Inflated type instance has to be updated manually
            if (instance_type is InflatedTypeSpec) {
                var inflator = new TypeParameterInflator (this, instance_type, TypeParameterSpec.EmptyTypes, TypeSpec.EmptyTypes);
                inflated = (TypeSpec) d.CurrentType.InflateMember (inflator);
                instance_type.MemberCache.AddMember (inflated);

                //inflator = new TypeParameterInflator (d.Parent.CurrentType, TypeParameterSpec.EmptyTypes, TypeSpec.EmptyTypes);
                //d.Parent.CurrentType.MemberCache.AddMember (d.CurrentType.InflateMember (inflator));
            } else {
                inflated = d.CurrentType;
            }

            return inflated;
        }
Exemplo n.º 10
0
Arquivo: generic.cs Projeto: ikvm/mono
		public override MemberSpec InflateMember (TypeParameterInflator inflator)
		{
			var tps = (TypeParameterSpec) MemberwiseClone ();
			InflateConstraints (inflator, tps);
			return tps;
		}
Exemplo n.º 11
0
		protected void EmitCallWithInvoke (EmitContext ec, Expression binder, Arguments arguments, bool isStatement)
		{
			var module = ec.Module;

			var site_container = ec.CreateDynamicSite ();

			BlockContext bc = new BlockContext (ec.MemberContext, null, ec.BuiltinTypes.Void);

			FieldExpr site_field_expr = null;
			StatementExpression s = null;

			// create call site
			var call_site = binder;
			if (call_site != null) {
				// resolve call site
				call_site = call_site.Resolve(bc);

				// create field for call site
				var site_type_decl = call_site.Type;  
				var field = site_container.CreateCallSiteField (new TypeExpression(site_type_decl, loc), loc);
				if (field == null) {
					throw new InvalidOperationException("Could not create call site field");
				}

				// ???
				bool inflate_using_mvar = context_mvars != null && ec.IsAnonymousStoreyMutateRequired;

				// ???
				TypeSpec gt;
				if (inflate_using_mvar || context_mvars == null) {
					gt = site_container.CurrentType;
				} else {
					gt = site_container.CurrentType.MakeGenericType (module, context_mvars.Types);
				}

				// When site container already exists the inflated version has to be
				// updated manually to contain newly created field
				if (gt is InflatedTypeSpec && site_container.AnonymousMethodsCounter > 1) {
					var tparams = gt.MemberDefinition.TypeParametersCount > 0 ? gt.MemberDefinition.TypeParameters : TypeParameterSpec.EmptyTypes;
					var inflator = new TypeParameterInflator (module, gt, tparams, gt.TypeArguments);
					gt.MemberCache.AddMember (field.InflateMember (inflator));
				}

				site_field_expr = new FieldExpr (MemberCache.GetMember (gt, field), loc);

				s = new StatementExpression (new SimpleAssign (site_field_expr, call_site));
			}



			using (ec.With (BuilderContext.Options.OmitDebugInfo, true)) {
				if (s!= null && s.Resolve (bc)) {
					Statement init = new If (new Binary (Binary.Operator.Equality, site_field_expr, new NullLiteral (loc)), s, loc);
					init.Emit (ec);
				}

				// remove dynamics from argument list
				arguments.CastDynamicArgs(bc);

				IDynamicCallSite dynamicCallSite = (IDynamicCallSite)this.binder;
				Expression target = dynamicCallSite.InvokeCallSite(bc, site_field_expr, arguments, type, isStatement);
				if (target != null) 
					target = target.Resolve(bc);

				if (target != null)
				{
					var statement = target as ExpressionStatement;
					if (isStatement && statement != null)
					{
						statement.EmitStatement(ec);
					}
					else
					{
						if (!isStatement && (target.Type != type)) {
							// PlayScript: If doing an invoke, we have to cast the return type to the type expected by the expression..
							target = new Cast(new TypeExpression(type, loc), target, loc).Resolve (bc);
						} 

						target.Emit(ec);
					}
				}
			}

		}
Exemplo n.º 12
0
Arquivo: generic.cs Projeto: 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]);
			}
		}
Exemplo n.º 13
0
Arquivo: generic.cs Projeto: 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;
		}
Exemplo n.º 14
0
Arquivo: generic.cs Projeto: ikvm/mono
		protected override void InitializeMemberCache (bool onlyTypes)
		{
			if (cache == null)
				cache = new MemberCache (onlyTypes ? open_type.MemberCacheTypes : open_type.MemberCache);

			TypeParameterSpec[] tparams_full;
			TypeSpec[] targs_full = targs;
			if (IsNested) {
				//
				// Special case is needed when we are inflating an open type (nested type definition)
				// on inflated parent. Consider following case
				//
				// Foo<T>.Bar<U> => Foo<string>.Bar<U>
				//
				// Any later inflation of Foo<string>.Bar<U> has to also inflate T if used inside Bar<U>
				//
				List<TypeSpec> merged_targs = null;
				List<TypeParameterSpec> merged_tparams = null;

				var type = DeclaringType;

				do {
					if (type.TypeArguments.Length > 0) {
						if (merged_targs == null) {
							merged_targs = new List<TypeSpec> ();
							merged_tparams = new List<TypeParameterSpec> ();
							if (targs.Length > 0) {
								merged_targs.AddRange (targs);
								merged_tparams.AddRange (open_type.MemberDefinition.TypeParameters);
							}
						}
						merged_tparams.AddRange (type.MemberDefinition.TypeParameters);
						merged_targs.AddRange (type.TypeArguments);
					}
					type = type.DeclaringType;
				} while (type != null);

				if (merged_targs != null) {
					// Type arguments are not in the right order but it should not matter in this case
					targs_full = merged_targs.ToArray ();
					tparams_full = merged_tparams.ToArray ();
				} else if (targs.Length == 0) {
					tparams_full = TypeParameterSpec.EmptyTypes;
				} else {
					tparams_full = open_type.MemberDefinition.TypeParameters;
				}
			} else if (targs.Length == 0) {
				tparams_full = TypeParameterSpec.EmptyTypes;
			} else {
				tparams_full = open_type.MemberDefinition.TypeParameters;
			}

			var inflator = new TypeParameterInflator (this, tparams_full, targs_full);

			//
			// Two stage inflate due to possible nested types recursive
			// references
			//
			// class A<T> {
			//    B b;
			//    class B {
			//      T Value;
			//    }
			// }
			//
			// When resolving type of `b' members of `B' cannot be 
			// inflated because are not yet available in membercache
			//
			if ((state & StateFlags.PendingMemberCacheMembers) == 0) {
				open_type.MemberCacheTypes.InflateTypes (cache, inflator);

				//
				// Inflate any implemented interfaces
				//
				if (open_type.Interfaces != null) {
					ifaces = new List<TypeSpec> (open_type.Interfaces.Count);
					foreach (var iface in open_type.Interfaces) {
						var iface_inflated = inflator.Inflate (iface);
						AddInterface (iface_inflated);
					}
				}

				//
				// Handles the tricky case of recursive nested base generic type
				//
				// class A<T> : Base<A<T>.Nested> {
				//    class Nested {}
				// }
				//
				// When inflating A<T>. base type is not yet known, secondary
				// inflation is required (not common case) once base scope
				// is known
				//
				if (open_type.BaseType == null) {
					if (IsClass)
						state |= StateFlags.PendingBaseTypeInflate;
				} else {
					BaseType = inflator.Inflate (open_type.BaseType);
				}
			} else if ((state & StateFlags.PendingBaseTypeInflate) != 0) {
				BaseType = inflator.Inflate (open_type.BaseType);
				state &= ~StateFlags.PendingBaseTypeInflate;
			}

			if (onlyTypes) {
				state |= StateFlags.PendingMemberCacheMembers;
				return;
			}

			var tc = open_type.MemberDefinition as TypeContainer;
			if (tc != null && !tc.HasMembersDefined)
				throw new InternalErrorException ("Inflating MemberCache with undefined members");

			if ((state & StateFlags.PendingBaseTypeInflate) != 0) {
				BaseType = inflator.Inflate (open_type.BaseType);
				state &= ~StateFlags.PendingBaseTypeInflate;
			}

			state &= ~StateFlags.PendingMemberCacheMembers;
			open_type.MemberCache.InflateMembers (cache, open_type, inflator);
		}
Exemplo n.º 15
0
		protected void EmitCall (EmitContext ec, Expression binder, Arguments arguments, bool isStatement)
		{
			//
			// This method generates all internal infrastructure for a dynamic call. The
			// reason why it's quite complicated is the mixture of dynamic and anonymous
			// methods. Dynamic itself requires a temporary class (ContainerX) and anonymous
			// methods can generate temporary storey as well (AnonStorey). Handling MVAR
			// type parameters rewrite is non-trivial in such case as there are various
			// combinations possible therefore the mutator is not straightforward. Secondly
			// we need to keep both MVAR(possibly VAR for anon storey) and type VAR to emit
			// correct Site field type and its access from EmitContext.
			//

			int dyn_args_count = arguments == null ? 0 : arguments.Count;
			int default_args = isStatement ? 1 : 2;
			var module = ec.Module;

			bool has_ref_out_argument = false;
			var targs = new TypeExpression[dyn_args_count + default_args];
			targs[0] = new TypeExpression (module.PredefinedTypes.CallSite.TypeSpec, loc);

			TypeExpression[] targs_for_instance = null;
			TypeParameterMutator mutator;

			var site_container = ec.CreateDynamicSite ();

			if (context_mvars != null) {
				TypeParameters tparam;
				TypeContainer sc = site_container;
				do {
					tparam = sc.CurrentTypeParameters;
					sc = sc.Parent;
				} while (tparam == null);

				mutator = new TypeParameterMutator (context_mvars, tparam);

				if (!ec.IsAnonymousStoreyMutateRequired) {
					targs_for_instance = new TypeExpression[targs.Length];
					targs_for_instance[0] = targs[0];
				}
			} else {
				mutator = null;
			}

			for (int i = 0; i < dyn_args_count; ++i) {
				Argument a = arguments[i];
				if (a.ArgType == Argument.AType.Out || a.ArgType == Argument.AType.Ref)
					has_ref_out_argument = true;

				var t = a.Type;

				// Convert any internal type like dynamic or null to object
				if (t.Kind == MemberKind.InternalCompilerType)
					t = ec.BuiltinTypes.Object;

				if (targs_for_instance != null)
					targs_for_instance[i + 1] = new TypeExpression (t, loc);

				if (mutator != null)
					t = t.Mutate (mutator);

				targs[i + 1] = new TypeExpression (t, loc);
			}

			TypeExpr del_type = null;
			TypeExpr del_type_instance_access = null;
			if (!has_ref_out_argument) {
				string d_name = isStatement ? "Action" : "Func";

				TypeSpec te = null;
				Namespace type_ns = module.GlobalRootNamespace.GetNamespace ("System", true);
				if (type_ns != null) {
					te = type_ns.LookupType (module, d_name, dyn_args_count + default_args, LookupMode.Normal, loc);
				}

				if (te != null) {
					if (!isStatement) {
						var t = type;
						if (t.Kind == MemberKind.InternalCompilerType)
							t = ec.BuiltinTypes.Object;

						if (targs_for_instance != null)
							targs_for_instance[targs_for_instance.Length - 1] = new TypeExpression (t, loc);

						if (mutator != null)
							t = t.Mutate (mutator);

						targs[targs.Length - 1] = new TypeExpression (t, loc);
					}

					del_type = new GenericTypeExpr (te, new TypeArguments (targs), loc);
					if (targs_for_instance != null)
						del_type_instance_access = new GenericTypeExpr (te, new TypeArguments (targs_for_instance), loc);
					else
						del_type_instance_access = del_type;
				}
			}

			//
			// Create custom delegate when no appropriate predefined delegate has been found
			//
			Delegate d;
			if (del_type == null) {
				TypeSpec rt = isStatement ? ec.BuiltinTypes.Void : type;
				Parameter[] p = new Parameter[dyn_args_count + 1];
				p[0] = new Parameter (targs[0], "p0", Parameter.Modifier.NONE, null, loc);

				var site = ec.CreateDynamicSite ();
				int index = site.Containers == null ? 0 : site.Containers.Count;

				if (mutator != null)
					rt = mutator.Mutate (rt);

				for (int i = 1; i < dyn_args_count + 1; ++i) {
					p[i] = new Parameter (targs[i], "p" + i.ToString ("X"), arguments[i - 1].Modifier, null, loc);
				}

				d = new Delegate (site, new TypeExpression (rt, loc),
					Modifiers.INTERNAL | Modifiers.COMPILER_GENERATED,
					new MemberName ("Container" + index.ToString ("X")),
					new ParametersCompiled (p), null);

				d.CreateContainer ();
				d.DefineContainer ();
				d.Define ();
				d.PrepareEmit ();

				site.AddTypeContainer (d);

				//
				// Add new container to inflated site container when the
				// member cache already exists
				//
				if (site.CurrentType is InflatedTypeSpec && index > 0)
					site.CurrentType.MemberCache.AddMember (d.CurrentType);

				del_type = new TypeExpression (d.CurrentType, loc);
				if (targs_for_instance != null) {
					del_type_instance_access = null;
				} else {
					del_type_instance_access = del_type;
				}
			} else {
				d = null;
			}

			var site_type_decl = new GenericTypeExpr (module.PredefinedTypes.CallSiteGeneric.TypeSpec, new TypeArguments (del_type), loc);
			var field = site_container.CreateCallSiteField (site_type_decl, loc);
			if (field == null)
				return;

			if (del_type_instance_access == null) {
				var dt = d.CurrentType.DeclaringType.MakeGenericType (module, context_mvars.Types);
				del_type_instance_access = new TypeExpression (MemberCache.GetMember (dt, d.CurrentType), loc);
			}

			var instanceAccessExprType = new GenericTypeExpr (module.PredefinedTypes.CallSiteGeneric.TypeSpec,
				new TypeArguments (del_type_instance_access), loc);

			if (instanceAccessExprType.ResolveAsType (ec.MemberContext) == null)
				return;

			bool inflate_using_mvar = context_mvars != null && ec.IsAnonymousStoreyMutateRequired;

			TypeSpec gt;
			if (inflate_using_mvar || context_mvars == null) {
				gt = site_container.CurrentType;
			} else {
				gt = site_container.CurrentType.MakeGenericType (module, context_mvars.Types);
			}

			// When site container already exists the inflated version has to be
			// updated manually to contain newly created field
			if (gt is InflatedTypeSpec && site_container.AnonymousMethodsCounter > 1) {
				var tparams = gt.MemberDefinition.TypeParametersCount > 0 ? gt.MemberDefinition.TypeParameters : TypeParameterSpec.EmptyTypes;
				var inflator = new TypeParameterInflator (module, gt, tparams, gt.TypeArguments);
				gt.MemberCache.AddMember (field.InflateMember (inflator));
			}

			FieldExpr site_field_expr = new FieldExpr (MemberCache.GetMember (gt, field), loc);

			BlockContext bc = new BlockContext (ec.MemberContext, null, ec.BuiltinTypes.Void);

			Arguments args = new Arguments (1);
			args.Add (new Argument (binder));
			StatementExpression s = new StatementExpression (new SimpleAssign (site_field_expr, new Invocation (new MemberAccess (instanceAccessExprType, "Create"), args)));

			using (ec.With (BuilderContext.Options.OmitDebugInfo, true)) {

				var conditionalAccessReceiver = IsConditionalAccessReceiver;
				var ca = ec.ConditionalAccess;

				if (conditionalAccessReceiver) {
					ec.ConditionalAccess = new ConditionalAccessContext (type, ec.DefineLabel ()) {
						Statement = isStatement
					};

					//
					// Emit conditional access expressions before dynamic call
					// is initialized. It pushes site_field_expr on stack before
					// the actual instance argument is emited which would cause
					// jump from non-empty stack.
					//
					EmitConditionalAccess (ec);
				}

				if (s.Resolve (bc)) {
					Statement init = new If (new Binary (Binary.Operator.Equality, site_field_expr, new NullLiteral (loc)), s, loc);
					init.Emit (ec);
				}

				args = new Arguments (1 + dyn_args_count);
				args.Add (new Argument (site_field_expr));
				if (arguments != null) {
					int arg_pos = 1;
					foreach (Argument a in arguments) {
						if (a is NamedArgument) {
							// Name is not valid in this context
							args.Add (new Argument (a.Expr, a.ArgType));
						} else {
							args.Add (a);
						}

						if (inflate_using_mvar && a.Type != targs[arg_pos].Type)
							a.Expr.Type = targs[arg_pos].Type;

						++arg_pos;
					}
				}

				var target = new DelegateInvocation (new MemberAccess (site_field_expr, "Target", loc).Resolve (bc), args, false, loc).Resolve (bc);
				if (target != null) {
					target.Emit (ec);
				}

				if (conditionalAccessReceiver) {
					ec.CloseConditionalAccess (!isStatement && type.IsNullableType ? type : null);
					ec.ConditionalAccess = ca;
				}
			}
		}
Exemplo n.º 16
0
        public FieldSpec CreateCallSiteField(FullNamedExpression type, Location loc)
        {
            int index = fields == null ? 0 : fields.Count;
            Field f = new HoistedField (this, type, Modifiers.PUBLIC | Modifiers.STATIC, "Site" + index.ToString ("X"), null, loc);
            f.Define ();

            AddField (f);

            var fs = f.Spec;
            if (mutator != null) {
                //
                // Inflate the field, no need to keep it in MemberCache as it's accessed only once
                //
                var inflator = new TypeParameterInflator (this, instance_type, spec.MemberDefinition.TypeParameters, instance_type.TypeArguments);
                fs = (FieldSpec) fs.InflateMember (inflator);
            }

            return fs;
        }
Exemplo n.º 17
0
		public AParametersCollection Inflate (TypeParameterInflator inflator)
		{
			TypeSpec[] inflated_types = null;
			bool default_value = false;

			for (int i = 0; i < Count; ++i) {
				var inflated_param = inflator.Inflate (types[i]);
				if (inflated_types == null) {
					if (inflated_param == types[i])
						continue;

					default_value |= FixedParameters[i] is DefaultValueExpression;
					inflated_types = new TypeSpec[types.Length];
					Array.Copy (types, inflated_types, types.Length);	
				}

				inflated_types[i] = inflated_param;
			}

			if (inflated_types == null)
				return this;

			var clone = (AParametersCollection) MemberwiseClone ();
			clone.types = inflated_types;
			if (default_value) {
				for (int i = 0; i < Count; ++i) {
					var dve = clone.FixedParameters[i] as DefaultValueExpression;
					if (dve != null) {
						throw new NotImplementedException ("net");
						//	clone.FixedParameters [i].DefaultValue = new DefaultValueExpression ();
					}
				}
			}

			return clone;
		}
Exemplo n.º 18
0
		public virtual MemberSpec InflateMember (TypeParameterInflator inflator)
		{
			var inflated = (MemberSpec) MemberwiseClone ();
			inflated.declaringType = inflator.TypeInstance;
			inflated.state |= StateFlags.PendingMetaInflate;
#if DEBUG
			if (inflated.ID > 0)
				inflated.ID = -inflated.ID;
#endif
			return inflated;
		}
Exemplo n.º 19
0
		public AParametersCollection Inflate (TypeParameterInflator inflator)
		{
			TypeSpec[] inflated_types = null;
			bool default_value = false;

			for (int i = 0; i < Count; ++i) {
				var inflated_param = inflator.Inflate (types[i]);
				if (inflated_types == null) {
					if (inflated_param == types[i])
						continue;

					default_value |= FixedParameters[i].HasDefaultValue;
					inflated_types = new TypeSpec[types.Length];
					Array.Copy (types, inflated_types, types.Length);
				} else {
					if (inflated_param == types[i])
						continue;

					default_value |= FixedParameters[i].HasDefaultValue;
				}

				inflated_types[i] = inflated_param;
			}

			if (inflated_types == null)
				return this;

			var clone = (AParametersCollection) MemberwiseClone ();
			clone.types = inflated_types;

			//
			// Default expression is original expression from the parameter
			// declaration context which can be of nested enum in generic class type.
			// In such case we end up with expression type of G<T>.E and e.g. parameter
			// type of G<int>.E and conversion would fail without inflate in this
			// context.
			//
			if (default_value) {
				clone.parameters = new IParameterData[Count];
				for (int i = 0; i < Count; ++i) {
					var fp = FixedParameters[i];
					clone.FixedParameters[i] = fp;

					if (!fp.HasDefaultValue)
						continue;

					var expr = fp.DefaultValue;

					if (inflated_types[i] == expr.Type)
						continue;

					var c = expr as Constant;
					if (c != null) {
						//
						// It may fail we are inflating before type validation is done
						//
						c = Constant.ExtractConstantFromValue (inflated_types[i], c.GetValue (), expr.Location);
						if (c == null)
							expr = new DefaultValueExpression (new TypeExpression (inflated_types[i], expr.Location), expr.Location);
						else
							expr = c;
					} else if (expr is DefaultValueExpression)
						expr = new DefaultValueExpression (new TypeExpression (inflated_types[i], expr.Location), expr.Location);

					clone.FixedParameters[i] = new ParameterData (fp.Name, fp.ModFlags, expr);
				}
			}

			return clone;
		}
Exemplo n.º 20
0
		public HoistedStoreyClass (TypeContainer 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 (this, null, src, dst);
				for (int i = 0; i < type_params.Length; ++i) {
					src[i].InflateConstraints (inflator, dst[i]);
				}

				mutator = new TypeParameterMutator (tparams, type_params);
			}
		}
Exemplo n.º 21
0
		public override MemberSpec InflateMember (TypeParameterInflator inflator)
		{
			var ps = (PropertySpec) base.InflateMember (inflator);
			ps.memberType = inflator.Inflate (memberType);
			return ps;
		}
Exemplo n.º 22
0
		protected virtual void DefineTypeParameters ()
		{
			var tparams = CurrentTypeParameters;

			TypeParameterSpec[] base_tparams = null;
			TypeParameterSpec[] base_decl_tparams = TypeParameterSpec.EmptyTypes;
			TypeSpec[] base_targs = TypeSpec.EmptyTypes;
			if (((ModFlags & Modifiers.OVERRIDE) != 0 || IsExplicitImpl)) {
				if (base_method != null) {
					base_tparams = base_method.GenericDefinition.TypeParameters;
				
					if (base_method.DeclaringType.IsGeneric) {
						base_decl_tparams = base_method.DeclaringType.MemberDefinition.TypeParameters;
						base_targs = Parent.BaseType.TypeArguments;
					}

					if (base_method.IsGeneric) {
						if (base_decl_tparams.Length != 0) {
							base_decl_tparams = base_decl_tparams.Concat (base_tparams).ToArray ();
							base_targs = base_targs.Concat (tparams.Select<TypeParameter, TypeSpec> (l => l.Type)).ToArray ();
						} else {
							base_decl_tparams = base_tparams;
							base_targs = tparams.Select (l => l.Type).ToArray ();
						}
					}
				} else if (MethodData.implementing != null) {
					base_tparams = MethodData.implementing.GenericDefinition.TypeParameters;
					if (MethodData.implementing.DeclaringType.IsGeneric) {
						base_decl_tparams = MethodData.implementing.DeclaringType.MemberDefinition.TypeParameters;
						foreach (var iface in Parent.CurrentType.Interfaces) {
							if (iface == MethodData.implementing.DeclaringType) {
								base_targs = iface.TypeArguments;
								break;
							}
						}
					}
				}
			}

			for (int i = 0; i < tparams.Length; ++i) {
				var tp = tparams[i];

				if (!tp.ResolveConstraints (this))
					continue;

				//
				// Copy base constraints for override/explicit methods
				//
				if (base_tparams != null) {
					var base_tparam = base_tparams[i];
					var local_tparam = tp.Type;
					local_tparam.SpecialConstraint = base_tparam.SpecialConstraint;

					var inflator = new TypeParameterInflator (CurrentType, base_decl_tparams, base_targs);
					base_tparam.InflateConstraints (inflator, local_tparam);

					//
					// Check all type argument constraints for possible collision
					// introduced by inflating inherited constraints in this context
					//
					// Conflict example:
					//
					// class A<T> { virtual void Foo<U> () where U : class, T {} }
					// class B : A<int> { override void Foo<U> {} }
					//
					var local_tparam_targs = local_tparam.TypeArguments;
					if (local_tparam_targs != null) {					
						for (int ii = 0; ii < local_tparam_targs.Length; ++ii) {
							var ta = local_tparam_targs [ii];
							if (!ta.IsClass && !ta.IsStruct)
								continue;

							if (Constraints.CheckConflictingInheritedConstraint (local_tparam, ta, this, Location)) {
								local_tparam.ChangeTypeArgumentToBaseType (ii);
							}
						}
					}

					continue;
				}
				
				if (MethodData.implementing != null) {
					var base_tp = MethodData.implementing.Constraints[i];
					if (!tp.Type.HasSameConstraintsImplementation (base_tp)) {
						Report.SymbolRelatedToPreviousError (MethodData.implementing);
						Report.Error (425, Location,
							"The constraints for type parameter `{0}' of method `{1}' must match the constraints for type parameter `{2}' of interface method `{3}'. Consider using an explicit interface implementation instead",
							tp.GetSignatureForError (), GetSignatureForError (), base_tp.GetSignatureForError (), MethodData.implementing.GetSignatureForError ());
					}
				}
			}
		}
Exemplo n.º 23
0
		protected virtual void DefineTypeParameters ()
		{
			var tparams = CurrentTypeParameters;

			TypeParameterSpec[] base_tparams = null;
			TypeParameterSpec[] base_decl_tparams = TypeParameterSpec.EmptyTypes;
			TypeSpec[] base_targs = TypeSpec.EmptyTypes;
			if (((ModFlags & Modifiers.OVERRIDE) != 0 || IsExplicitImpl)) {
				MethodSpec base_override = base_method ?? MethodData.implementing;

				if (base_override != null) {
					base_tparams = base_override.GenericDefinition.TypeParameters;

					if (base_override.DeclaringType.IsGeneric) {
						base_decl_tparams = base_override.DeclaringType.MemberDefinition.TypeParameters;

						if (base_method != null) {
							var base_type_parent = CurrentType;
							while (base_type_parent.BaseType != base_override.DeclaringType) {
								base_type_parent = base_type_parent.BaseType;
							}

							base_targs = base_type_parent.BaseType.TypeArguments;
						} else {
							foreach (var iface in Parent.CurrentType.Interfaces) {
								if (iface == base_override.DeclaringType) {
									base_targs = iface.TypeArguments;
									break;
								}
							}
						}
					}

					if (base_override.IsGeneric) {
						ObsoleteAttribute oa;
						foreach (var base_tp in base_tparams) {
							oa = base_tp.BaseType.GetAttributeObsolete ();
							if (oa != null) {
								AttributeTester.Report_ObsoleteMessage (oa, base_tp.BaseType.GetSignatureForError (), Location, Report);
							}

							if (base_tp.InterfacesDefined != null) {
								foreach (var iface in base_tp.InterfacesDefined) {
									oa = iface.GetAttributeObsolete ();
									if (oa != null) {
										AttributeTester.Report_ObsoleteMessage (oa, iface.GetSignatureForError (), Location, Report);
									}
								}
							}
						}

						if (base_decl_tparams.Length != 0) {
							base_decl_tparams = base_decl_tparams.Concat (base_tparams).ToArray ();
							base_targs = base_targs.Concat (tparams.Types).ToArray ();
						} else {
							base_decl_tparams = base_tparams;
							base_targs = tparams.Types;
						}
					}
				}
			}

			for (int i = 0; i < tparams.Count; ++i) {
				var tp = tparams[i];

				if (!tp.ResolveConstraints (this))
					continue;

				//
				// Copy base constraints for override/explicit methods
				//
				if (base_tparams != null) {
					var base_tparam = base_tparams[i];
					var local_tparam = tp.Type;
					local_tparam.SpecialConstraint = base_tparam.SpecialConstraint;

					var inflator = new TypeParameterInflator (this, CurrentType, base_decl_tparams, base_targs);
					base_tparam.InflateConstraints (inflator, local_tparam);

					//
					// Check all type argument constraints for possible collision or unification
					// introduced by inflating inherited constraints in this context
					//
					// Conflict example:
					//
					// class A<T> { virtual void Foo<U> () where U : class, T {} }
					// class B : A<int> { override void Foo<U> {} }
					//
					var local_tparam_targs = local_tparam.TypeArguments;
					if (local_tparam_targs != null) {
						for (int ii = 0; ii < local_tparam_targs.Length; ++ii) {
							var ta = local_tparam_targs [ii];
							if (!ta.IsClass && !ta.IsStruct)
								continue;

							TypeSpec[] unique_tparams = null;
							for (int iii = ii + 1; iii < local_tparam_targs.Length; ++iii) {
								//
								// Remove any identical or unified constraint types
								//
								var tparam_checked = local_tparam_targs[iii];
								if (TypeSpecComparer.IsEqual (ta, tparam_checked) || TypeSpec.IsBaseClass (ta, tparam_checked, false)) {
									unique_tparams = new TypeSpec[local_tparam_targs.Length - 1];
									Array.Copy (local_tparam_targs, 0, unique_tparams, 0, iii);
									Array.Copy (local_tparam_targs, iii + 1, unique_tparams, iii, local_tparam_targs.Length - iii - 1);
								} else if (!TypeSpec.IsBaseClass (tparam_checked, ta, false)) {
									Constraints.Error_ConflictingConstraints (this, local_tparam, ta, tparam_checked, Location);
								}
							}

							if (unique_tparams != null) {
								local_tparam_targs = unique_tparams;
								local_tparam.TypeArguments = local_tparam_targs;
								continue;
							}

							Constraints.CheckConflictingInheritedConstraint (local_tparam, ta, this, Location);
						}
					}
				}
			}

			if (base_tparams == null && MethodData != null && MethodData.implementing != null) {
				CheckImplementingMethodConstraints (Parent, spec, MethodData.implementing);
			}
		}
Exemplo n.º 24
0
		public void AddCapturedThisField (EmitContext ec)
		{
			TypeExpr type_expr = new TypeExpression (ec.CurrentType, Location);
			Field f = AddCompilerGeneratedField ("<>f__this", type_expr);
			f.Define ();
			hoisted_this = new HoistedThis (this, f);

			// Inflated type instance has to be updated manually
			if (Instance.Type is InflatedTypeSpec) {
				var inflator = new TypeParameterInflator (this, Instance.Type, TypeParameterSpec.EmptyTypes, TypeSpec.EmptyTypes);
				Instance.Type.MemberCache.AddMember (f.Spec.InflateMember (inflator));

				inflator = new TypeParameterInflator (this, f.Parent.CurrentType, TypeParameterSpec.EmptyTypes, TypeSpec.EmptyTypes);
				f.Parent.CurrentType.MemberCache.AddMember (f.Spec.InflateMember (inflator));
			}
		}
Exemplo n.º 25
0
		public MethodSpec MakeGenericMethod (IMemberContext context, params TypeSpec[] targs)
		{
			if (targs == null)
				throw new ArgumentNullException ();
// TODO MemberCache
//			if (generic_intances != null && generic_intances.TryGetValue (targs, out ginstance))
//				return ginstance;

			//if (generic_intances == null)
			//    generic_intances = new Dictionary<TypeSpec[], Method> (TypeSpecArrayComparer.Default);

			var inflator = new TypeParameterInflator (context, DeclaringType, GenericDefinition.TypeParameters, targs);

			var inflated = (MethodSpec) MemberwiseClone ();
			inflated.declaringType = inflator.TypeInstance;
			inflated.returnType = inflator.Inflate (returnType);
			inflated.parameters = parameters.Inflate (inflator);
			inflated.targs = targs;
			inflated.constraints = TypeParameterSpec.InflateConstraints (inflator, constraints ?? GenericDefinition.TypeParameters);
			inflated.state |= StateFlags.PendingMakeMethod;

			//			if (inflated.parent == null)
			//				inflated.parent = parent;

			//generic_intances.Add (targs, inflated);
			return inflated;
		}
Exemplo n.º 26
0
		public override MemberSpec InflateMember (TypeParameterInflator inflator)
		{
			var es = (EventSpec) base.InflateMember (inflator);
			es.MemberType = inflator.Inflate (MemberType);
			return es;
		}
Exemplo n.º 27
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);
			}
		}
Exemplo n.º 28
0
        public override MemberSpec InflateMember(TypeParameterInflator inflator)
        {
            var tps = (TypeParameterSpec) MemberwiseClone ();
            tps.BaseType = inflator.Inflate (BaseType);
            if (ifaces != null) {
                tps.ifaces = new TypeSpec[ifaces.Count];
                for (int i = 0; i < ifaces.Count; ++i)
                    tps.ifaces[i] = 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]);
            }

            return tps;
        }