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