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; }
public override MemberSpec InflateMember (TypeParameterInflator inflator) { var fs = (FieldSpec) base.InflateMember (inflator); fs.memberType = inflator.Inflate (memberType); return fs; }
public TypeParameterInflator (TypeParameterInflator nested, TypeSpec type) : this (type, nested.tparams, nested.targs) { }
public override MemberSpec InflateMember (TypeParameterInflator inflator) { var spec = (IndexerSpec) base.InflateMember (inflator); spec.parameters = parameters.Inflate (inflator); return spec; }
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; }
// // 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; }
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; }
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 ()); } } } }
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; }
public override MemberSpec InflateMember (TypeParameterInflator inflator) { var tps = (TypeParameterSpec) MemberwiseClone (); InflateConstraints (inflator, tps); return tps; }
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); } } } }
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]); } }
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; }
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); }
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; } } }
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; }
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; }
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; }
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; }
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); } }
public override MemberSpec InflateMember (TypeParameterInflator inflator) { var ps = (PropertySpec) base.InflateMember (inflator); ps.memberType = inflator.Inflate (memberType); return ps; }
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 ()); } } } }
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); } }
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)); } }
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; }
public override MemberSpec InflateMember (TypeParameterInflator inflator) { var es = (EventSpec) base.InflateMember (inflator); es.MemberType = inflator.Inflate (MemberType); return es; }
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); } }
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; }