protected override Expression CreateExpressionTree (ResolveContext ec, TypeSpec delegate_type) { if (ec.IsInProbingMode) return this; BlockContext bc = new BlockContext (ec.MemberContext, ec.ConstructorBlock, ec.BuiltinTypes.Void) { CurrentAnonymousMethod = ec.CurrentAnonymousMethod }; Expression args = Parameters.CreateExpressionTree (bc, loc); Expression expr = Block.CreateExpressionTree (ec); if (expr == null) return null; Arguments arguments = new Arguments (2); arguments.Add (new Argument (expr)); arguments.Add (new Argument (args)); return CreateExpressionFactoryCall (ec, "Lambda", new TypeArguments (new TypeExpression (delegate_type, loc)), arguments); }
protected abstract Expression CreateCallSiteBinder(ResolveContext ec, Arguments args, bool isSet);
public override Expression CreateExpressionTree (ResolveContext ec) { BlockContext bc = new BlockContext (ec.MemberContext, Block, ReturnType); Expression args = parameters.CreateExpressionTree (bc, loc); Expression expr = Block.CreateExpressionTree (ec); if (expr == null) return null; Arguments arguments = new Arguments (2); arguments.Add (new Argument (expr)); arguments.Add (new Argument (args)); return CreateExpressionFactoryCall (ec, "Lambda", new TypeArguments (new TypeExpression (type, loc)), arguments); }
public DynamicExpressionStatement(IDynamicBinder binder, Arguments args, Location loc) { this.binder = binder; this.arguments = args; this.loc = loc; }
protected DynamicMemberAssignable(Arguments args, Location loc) : base(null, args, loc) { base.binder = this; }
public ArrayInitializer CreateDynamicBinderArguments (ResolveContext rc) { Location loc = Location.Null; var all = new ArrayInitializer (args.Count, loc); MemberAccess binder = DynamicExpressionStatement.GetBinderNamespace (loc); foreach (Argument a in args) { Arguments dargs = new Arguments (2); // CSharpArgumentInfoFlags.None = 0 const string info_flags_enum = "CSharpArgumentInfoFlags"; Expression info_flags = new IntLiteral (rc.BuiltinTypes, 0, loc); if (a.Expr is Constant) { info_flags = new Binary (Binary.Operator.BitwiseOr, info_flags, new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "Constant", loc)); } else if (a.ArgType == Argument.AType.Ref) { info_flags = new Binary (Binary.Operator.BitwiseOr, info_flags, new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "IsRef", loc)); info_flags = new Binary (Binary.Operator.BitwiseOr, info_flags, new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "UseCompileTimeType", loc)); } else if (a.ArgType == Argument.AType.Out) { info_flags = new Binary (Binary.Operator.BitwiseOr, info_flags, new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "IsOut", loc)); info_flags = new Binary (Binary.Operator.BitwiseOr, info_flags, new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "UseCompileTimeType", loc)); } else if (a.ArgType == Argument.AType.DynamicTypeName) { info_flags = new Binary (Binary.Operator.BitwiseOr, info_flags, new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "IsStaticType", loc)); } var arg_type = a.Expr.Type; if (arg_type.BuiltinType != BuiltinTypeSpec.Type.Dynamic && arg_type != InternalType.NullLiteral) { MethodGroupExpr mg = a.Expr as MethodGroupExpr; if (mg != null) { rc.Report.Error (1976, a.Expr.Location, "The method group `{0}' cannot be used as an argument of dynamic operation. Consider using parentheses to invoke the method", mg.Name); } else if (arg_type == InternalType.AnonymousMethod) { rc.Report.Error (1977, a.Expr.Location, "An anonymous method or lambda expression cannot be used as an argument of dynamic operation. Consider using a cast"); } else if (arg_type.Kind == MemberKind.Void || arg_type == InternalType.Arglist || arg_type.IsPointer) { rc.Report.Error (1978, a.Expr.Location, "An expression of type `{0}' cannot be used as an argument of dynamic operation", arg_type.GetSignatureForError ()); } info_flags = new Binary (Binary.Operator.BitwiseOr, info_flags, new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "UseCompileTimeType", loc)); } string named_value; NamedArgument na = a as NamedArgument; if (na != null) { info_flags = new Binary (Binary.Operator.BitwiseOr, info_flags, new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "NamedArgument", loc)); named_value = na.Name; } else { named_value = null; } dargs.Add (new Argument (info_flags)); dargs.Add (new Argument (new StringLiteral (rc.BuiltinTypes, named_value, loc))); all.Add (new Invocation (new MemberAccess (new MemberAccess (binder, "CSharpArgumentInfo", loc), "Create", loc), dargs)); } return all; }
public Arguments Clone (CloneContext ctx) { Arguments cloned = new Arguments (args.Count); foreach (Argument a in args) cloned.Add (a.Clone (ctx)); return cloned; }
public DynamicInvocation(ATypeNameExpression member, Arguments args, Location loc) : base(null, args, loc) { base.binder = this; this.member = member; }
public static DynamicInvocation CreateSpecialNameInvoke(ATypeNameExpression member, Arguments args, Location loc) { return(new DynamicInvocation(member, args, loc) { flags = CSharpBinderFlags.InvokeSpecialName }); }
public DynamicIndexBinder(Arguments args, Location loc) : base(args, loc) { }
public DynamicIndexBinder(CSharpBinderFlags flags, Arguments args, Location loc) : this(args, loc) { base.flags = flags; }
public DynamicConstructorBinder(TypeSpec type, Arguments args, Location loc) : base(null, args, loc) { this.type = type; base.binder = this; }
public IsEvent(string name, Arguments args, Location loc) : base(null, args, loc) { this.name = name; binder = this; }
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)) { 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; } } Expression target = new DelegateInvocation(new MemberAccess(site_field_expr, "Target", loc).Resolve(bc), args, false, loc).Resolve(bc); if (target != null) { target.Emit(ec); } } }
public ArgumentsOrdered (Arguments args) : base (args.Count) { AddRange (args); ordered = new List<MovableArgument> (); }
public Expression CreateCallSiteBinder(ResolveContext ec, Arguments args) { Arguments binder_args = new Arguments(member != null ? 5 : 3); bool is_member_access = member is MemberAccess; CSharpBinderFlags call_flags; if (!is_member_access && member is SimpleName) { call_flags = CSharpBinderFlags.InvokeSimpleName; is_member_access = true; } else { call_flags = 0; } binder_args.Add(new Argument(new BinderFlags(call_flags, this))); if (is_member_access) { binder_args.Add(new Argument(new StringLiteral(ec.BuiltinTypes, member.Name, member.Location))); } if (member != null && member.HasTypeArguments) { TypeArguments ta = member.TypeArguments; if (ta.Resolve(ec, false)) { var targs = new ArrayInitializer(ta.Count, loc); foreach (TypeSpec t in ta.Arguments) { targs.Add(new TypeOf(t, loc)); } binder_args.Add(new Argument(new ImplicitlyTypedArrayCreation(targs, loc))); } } else if (is_member_access) { binder_args.Add(new Argument(new NullLiteral(loc))); } binder_args.Add(new Argument(new TypeOf(ec.CurrentType, loc))); Expression real_args; if (args == null) { // Cannot be null because .NET trips over real_args = new ArrayCreation( new MemberAccess(GetBinderNamespace(loc), "CSharpArgumentInfo", loc), new ArrayInitializer(0, loc), loc); } else { real_args = new ImplicitlyTypedArrayCreation(args.CreateDynamicBinderArguments(ec), loc); } binder_args.Add(new Argument(real_args)); return(new Invocation(GetBinder(is_member_access ? "InvokeMember" : "Invoke", loc), binder_args)); }
public void AddRange (Arguments args) { this.args.AddRange (args.args); }
public DynamicMemberBinder(string name, Arguments args, Location loc) : base(args, loc) { this.name = name; }
public static Arguments CreateForExpressionTree (ResolveContext ec, Arguments args, params Expression[] e) { Arguments all = new Arguments ((args == null ? 0 : args.Count) + e.Length); for (int i = 0; i < e.Length; ++i) { if (e [i] != null) all.Add (new Argument (e[i])); } if (args != null) { foreach (Argument a in args.args) { Expression tree_arg = a.CreateExpressionTree (ec); if (tree_arg != null) all.Add (new Argument (tree_arg)); } } return all; }
public DynamicMemberBinder(string name, CSharpBinderFlags flags, Arguments args, Location loc) : this(name, args, loc) { base.flags = flags; }
public static System.Linq.Expressions.Expression[] MakeExpression (Arguments args, BuilderContext ctx) { if (args == null || args.Count == 0) return null; var exprs = new System.Linq.Expressions.Expression [args.Count]; for (int i = 0; i < exprs.Length; ++i) { Argument a = args.args [i]; exprs[i] = a.Expr.MakeExpression (ctx); } return exprs; }
public DynamicUnaryConversion(string name, Arguments args, Location loc) : base(null, args, loc) { this.name = name; base.binder = this; }