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 (member.Name, member.Location))); if (member != null && member.HasTypeArguments) { TypeArguments ta = member.TypeArguments; if (ta.Resolve (ec)) { var targs = new ArrayInitializer (ta.Count, loc); foreach (TypeSpec t in ta.Arguments) targs.Add (new TypeOf (new TypeExpression (t, loc), 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 (new TypeExpression (ec.CurrentType, loc), 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 Expression CreateExpressionTree (BlockContext ec, Location loc) { var initializers = new ArrayInitializer (Count, loc); foreach (Parameter p in FixedParameters) { // // Each parameter expression is stored to local variable // to save some memory when referenced later. // StatementExpression se = new StatementExpression (p.CreateExpressionTreeVariable (ec), Location.Null); if (se.Resolve (ec)) { ec.CurrentBlock.AddScopeStatement (new TemporaryVariableReference.Declarator (p.ExpressionTreeVariableReference ())); ec.CurrentBlock.AddScopeStatement (se); } initializers.Add (p.ExpressionTreeVariableReference ()); } return new ArrayCreation ( Parameter.ResolveParameterExpressionType (ec, loc), initializers, loc); }
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 (0, loc); var constant = a.Expr as Constant; if (constant != null && constant.IsLiteral) { info_flags = new Binary (Binary.Operator.BitwiseOr, info_flags, new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "Constant", loc), 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), 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), 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), loc); } var arg_type = a.Expr.Type; if (arg_type != InternalType.Dynamic) { 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 == TypeManager.void_type || 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", TypeManager.CSharpName (arg_type)); } info_flags = new Binary (Binary.Operator.BitwiseOr, info_flags, new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "UseCompileTimeType", loc), 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), loc); named_value = na.Name; } else { named_value = null; } dargs.Add (new Argument (info_flags)); dargs.Add (new Argument (new StringLiteral (named_value, loc))); all.Add (new Invocation (new MemberAccess (new MemberAccess (binder, "CSharpArgumentInfo", loc), "Create", loc), dargs)); } return all; }
public ArrayInitializer CreateDynamicBinderArguments (ResolveContext rc) { Location loc = Location.Null; var all = new ArrayInitializer (args.Count, loc); MemberAccess binder = DynamicExpressionStatement.GetBinderNamespace (rc, 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)); } TypeSpec arg_type; if (rc.FileType == SourceFileType.PlayScript && a.Expr is ArrayInitializer || a.Expr is AsObjectInitializer) { if (a.Expr is ArrayInitializer) { arg_type = rc.Module.PredefinedTypes.AsArray.Resolve(); } else { arg_type = rc.Module.PredefinedTypes.AsObject.Resolve(); } } else { arg_type = a.Expr.Type; } if (arg_type.BuiltinType != BuiltinTypeSpec.Type.Dynamic && arg_type != InternalType.NullLiteral) { MethodGroupExpr mg = a.Expr as MethodGroupExpr; bool wasConverted = false; // In PlayScript, we try to implicity convert to dynamic, which handles conversions of method groups to delegates, and // anon methods to delegates. if (rc.FileType == SourceFileType.PlayScript && (mg != null || arg_type == InternalType.AnonymousMethod)) { var expr = Convert.ImplicitConversion (rc, a.Expr, rc.BuiltinTypes.Dynamic, loc); if (expr != null) { a.Expr = expr; arg_type = rc.BuiltinTypes.Dynamic; wasConverted = true; } } // Failed.. check the C# error if (!wasConverted) { 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 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(member.Name, member.Location))); } if (member != null && member.HasTypeArguments) { TypeArguments ta = member.TypeArguments; if (ta.Resolve(ec)) { var targs = new ArrayInitializer(ta.Count, loc); foreach (TypeSpec t in ta.Arguments) { targs.Add(new TypeOf(new TypeExpression(t, loc), 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(new TypeExpression(ec.CurrentType, loc), 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 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), 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), loc); info_flags = new Binary(Binary.Operator.BitwiseOr, info_flags, new MemberAccess(new MemberAccess(binder, info_flags_enum, loc), "UseCompileTimeType", loc), 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), loc); info_flags = new Binary(Binary.Operator.BitwiseOr, info_flags, new MemberAccess(new MemberAccess(binder, info_flags_enum, loc), "UseCompileTimeType", loc), 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), 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", TypeManager.CSharpName(arg_type)); } info_flags = new Binary(Binary.Operator.BitwiseOr, info_flags, new MemberAccess(new MemberAccess(binder, info_flags_enum, loc), "UseCompileTimeType", loc), 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), 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 ArrayInitializer CreateDynamicBinderArguments(ResolveContext rc) { Location loc = Location.Null; var all = new ArrayInitializer(args.Count, loc); MemberAccess binder = DynamicExpressionStatement.GetBinderNamespace(rc, 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)); } TypeSpec arg_type; if (rc.FileType == SourceFileType.PlayScript && a.Expr is ArrayInitializer || a.Expr is AsObjectInitializer) { if (a.Expr is ArrayInitializer) { arg_type = rc.Module.PredefinedTypes.AsArray.Resolve(); } else { arg_type = rc.Module.PredefinedTypes.AsExpandoObject.Resolve(); } } else { arg_type = a.Expr.Type; } if (arg_type.BuiltinType != BuiltinTypeSpec.Type.Dynamic && arg_type != InternalType.NullLiteral) { MethodGroupExpr mg = a.Expr as MethodGroupExpr; bool wasConverted = false; // In PlayScript, we try to implicity convert to dynamic, which handles conversions of method groups to delegates, and // anon methods to delegates. if (rc.FileType == SourceFileType.PlayScript && (mg != null || arg_type == InternalType.AnonymousMethod)) { var expr = Convert.ImplicitConversion(rc, a.Expr, rc.BuiltinTypes.Dynamic, loc); if (expr != null) { a.Expr = expr; arg_type = rc.BuiltinTypes.Dynamic; wasConverted = true; } } // Failed.. check the C# error if (!wasConverted) { 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); }