internal MSAst.Expression TransformAndDynamicConvert(Expression expression, Type/*!*/ type) {
Debug.Assert(expression != null);
MSAst.Expression res = expression;
// Do we need conversion?
if (!CanAssign(type, expression.Type)) {
// ensure we're reduced before we check for dynamic expressions.
var reduced = expression.Reduce();
if (reduced is LightDynamicExpression) {
reduced = reduced.Reduce();
}
// Add conversion step to the AST
MSAst.DynamicExpression ae = reduced as MSAst.DynamicExpression;
ReducableDynamicExpression rde = reduced as ReducableDynamicExpression;
if ((ae != null && ae.Binder is PythonBinaryOperationBinder) ||
(rde != null && rde.Binder is PythonBinaryOperationBinder)) {
// create a combo site which does the conversion
PythonBinaryOperationBinder binder;
IList<MSAst.Expression> args;
if (ae != null) {
binder = (PythonBinaryOperationBinder)ae.Binder;
args = ArrayUtils.ToArray(ae.Arguments);
} else {
binder = (PythonBinaryOperationBinder)rde.Binder;
args = rde.Args;
}
ParameterMappingInfo[] infos = new ParameterMappingInfo[args.Count];
for (int i = 0; i < infos.Length; i++) {
infos[i] = ParameterMappingInfo.Parameter(i);
}
res = Expression.Dynamic(
GlobalParent.PyContext.BinaryOperationRetType(
binder,
GlobalParent.PyContext.Convert(
type,
ConversionResultKind.ExplicitCast
)
),
type,
args
);
} else {
res = GlobalParent.Convert(
type,
ConversionResultKind.ExplicitCast,
reduced
);
}
}
return res;
}