ExpressionTreeCallRewriter
using Microsoft.CSharp.RuntimeBinder.Semantics;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;
namespace Microsoft.CSharp.RuntimeBinder
{
internal sealed class ExpressionTreeCallRewriter : ExprVisitorBase
{
private sealed class ExpressionExpr : Expr
{
public readonly Expression Expression;
public ExpressionExpr(Expression e)
: base(ExpressionKind.NoOp)
{
Expression = e;
}
}
private readonly Dictionary<ExprCall, Expression> _DictionaryOfParameters;
private readonly Expression[] _ListOfParameters;
private int _currentParameterIndex;
private ExpressionTreeCallRewriter(Expression[] listOfParameters)
{
_DictionaryOfParameters = new Dictionary<ExprCall, Expression>();
_ListOfParameters = listOfParameters;
}
public static Expression Rewrite(ExprBinOp binOp, Expression[] listOfParameters)
{
ExpressionTreeCallRewriter expressionTreeCallRewriter = new ExpressionTreeCallRewriter(listOfParameters);
expressionTreeCallRewriter.Visit(binOp.OptionalLeftChild);
ExprCall pExpr = (ExprCall)binOp.OptionalRightChild;
ExpressionExpr expressionExpr = expressionTreeCallRewriter.Visit(pExpr) as ExpressionExpr;
return expressionExpr.Expression;
}
protected override Expr VisitSAVE(ExprBinOp pExpr)
{
ExprCall key = (ExprCall)pExpr.OptionalLeftChild;
Expression value = _ListOfParameters[_currentParameterIndex++];
_DictionaryOfParameters.Add(key, value);
return null;
}
protected override Expr VisitCALL(ExprCall pExpr)
{
if (pExpr.PredefinedMethod == PREDEFMETH.PM_COUNT)
return pExpr;
Expression e;
switch (pExpr.PredefinedMethod) {
case PREDEFMETH.PM_EXPRESSION_LAMBDA:
return GenerateLambda(pExpr);
case PREDEFMETH.PM_EXPRESSION_CALL:
e = GenerateCall(pExpr);
break;
case PREDEFMETH.PM_EXPRESSION_ARRAYINDEX:
case PREDEFMETH.PM_EXPRESSION_ARRAYINDEX2:
e = GenerateArrayIndex(pExpr);
break;
case PREDEFMETH.PM_EXPRESSION_CONVERT:
case PREDEFMETH.PM_EXPRESSION_CONVERT_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_CONVERTCHECKED:
case PREDEFMETH.PM_EXPRESSION_CONVERTCHECKED_USER_DEFINED:
e = GenerateConvert(pExpr);
break;
case PREDEFMETH.PM_EXPRESSION_PROPERTY:
e = GenerateProperty(pExpr);
break;
case PREDEFMETH.PM_EXPRESSION_FIELD:
e = GenerateField(pExpr);
break;
case PREDEFMETH.PM_EXPRESSION_INVOKE:
e = GenerateInvoke(pExpr);
break;
case PREDEFMETH.PM_EXPRESSION_NEW:
e = GenerateNew(pExpr);
break;
case PREDEFMETH.PM_EXPRESSION_ADD:
case PREDEFMETH.PM_EXPRESSION_ADDCHECKED:
case PREDEFMETH.PM_EXPRESSION_AND:
case PREDEFMETH.PM_EXPRESSION_ANDALSO:
case PREDEFMETH.PM_EXPRESSION_DIVIDE:
case PREDEFMETH.PM_EXPRESSION_EQUAL:
case PREDEFMETH.PM_EXPRESSION_EXCLUSIVEOR:
case PREDEFMETH.PM_EXPRESSION_GREATERTHAN:
case PREDEFMETH.PM_EXPRESSION_GREATERTHANOREQUAL:
case PREDEFMETH.PM_EXPRESSION_LEFTSHIFT:
case PREDEFMETH.PM_EXPRESSION_LESSTHAN:
case PREDEFMETH.PM_EXPRESSION_LESSTHANOREQUAL:
case PREDEFMETH.PM_EXPRESSION_MODULO:
case PREDEFMETH.PM_EXPRESSION_MULTIPLY:
case PREDEFMETH.PM_EXPRESSION_MULTIPLYCHECKED:
case PREDEFMETH.PM_EXPRESSION_NOTEQUAL:
case PREDEFMETH.PM_EXPRESSION_OR:
case PREDEFMETH.PM_EXPRESSION_ORELSE:
case PREDEFMETH.PM_EXPRESSION_RIGHTSHIFT:
case PREDEFMETH.PM_EXPRESSION_SUBTRACT:
case PREDEFMETH.PM_EXPRESSION_SUBTRACTCHECKED:
e = GenerateBinaryOperator(pExpr);
break;
case PREDEFMETH.PM_EXPRESSION_ADD_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_ADDCHECKED_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_AND_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_ANDALSO_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_DIVIDE_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_EQUAL_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_EXCLUSIVEOR_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_GREATERTHAN_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_GREATERTHANOREQUAL_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_LEFTSHIFT_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_LESSTHAN_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_LESSTHANOREQUAL_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_MODULO_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_MULTIPLY_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_MULTIPLYCHECKED_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_NOTEQUAL_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_OR_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_ORELSE_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_RIGHTSHIFT_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_SUBTRACT_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_SUBTRACTCHECKED_USER_DEFINED:
e = GenerateUserDefinedBinaryOperator(pExpr);
break;
case PREDEFMETH.PM_EXPRESSION_NEGATE:
case PREDEFMETH.PM_EXPRESSION_NEGATECHECKED:
case PREDEFMETH.PM_EXPRESSION_NOT:
e = GenerateUnaryOperator(pExpr);
break;
case PREDEFMETH.PM_EXPRESSION_UNARYPLUS_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_NEGATE_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_NEGATECHECKED_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_NOT_USER_DEFINED:
e = GenerateUserDefinedUnaryOperator(pExpr);
break;
case PREDEFMETH.PM_EXPRESSION_CONSTANT_OBJECT_TYPE:
e = GenerateConstantType(pExpr);
break;
case PREDEFMETH.PM_EXPRESSION_ASSIGN:
e = GenerateAssignment(pExpr);
break;
default:
throw Error.InternalCompilerError();
}
return new ExpressionExpr(e);
}
protected override Expr VisitWRAP(ExprWrap pExpr)
{
return new ExpressionExpr(GetExpression(pExpr));
}
private Expr GenerateLambda(ExprCall pExpr)
{
return Visit(((ExprList)pExpr.OptionalArguments).OptionalElement);
}
private Expression GenerateCall(ExprCall pExpr)
{
ExprList exprList = (ExprList)pExpr.OptionalArguments;
ExprList exprList2;
ExprMethodInfo exprMethodInfo;
ExprArrayInit arrinit;
if ((exprList2 = (exprList.OptionalNextListNode as ExprList)) != null) {
exprMethodInfo = (ExprMethodInfo)exprList2.OptionalElement;
arrinit = (ExprArrayInit)exprList2.OptionalNextListNode;
} else {
exprMethodInfo = (ExprMethodInfo)exprList.OptionalNextListNode;
arrinit = null;
}
Expression instance = null;
MethodInfo methodInfo = exprMethodInfo.MethodInfo;
Expression[] argumentsFromArrayInit = GetArgumentsFromArrayInit(arrinit);
if (methodInfo == (MethodInfo)null)
throw Error.InternalCompilerError();
if (!methodInfo.IsStatic)
instance = GetExpression(((ExprList)pExpr.OptionalArguments).OptionalElement);
return Expression.Call(instance, methodInfo, argumentsFromArrayInit);
}
private Expression GenerateArrayIndex(ExprCall pExpr)
{
ExprList exprList = (ExprList)pExpr.OptionalArguments;
Expression expression = GetExpression(exprList.OptionalElement);
Expression[] indexes = (pExpr.PredefinedMethod != PREDEFMETH.PM_EXPRESSION_ARRAYINDEX) ? GetArgumentsFromArrayInit((ExprArrayInit)exprList.OptionalNextListNode) : new Expression[1] {
GetExpression(exprList.OptionalNextListNode)
};
return Expression.ArrayAccess(expression, indexes);
}
private Expression GenerateConvert(ExprCall pExpr)
{
PREDEFMETH predefinedMethod = pExpr.PredefinedMethod;
Expression expression;
Type associatedSystemType;
if (predefinedMethod == PREDEFMETH.PM_EXPRESSION_CONVERT_USER_DEFINED || predefinedMethod == PREDEFMETH.PM_EXPRESSION_CONVERTCHECKED_USER_DEFINED) {
ExprList exprList = (ExprList)pExpr.OptionalArguments;
ExprList exprList2 = (ExprList)exprList.OptionalNextListNode;
expression = GetExpression(exprList.OptionalElement);
associatedSystemType = ((ExprTypeOf)exprList2.OptionalElement).SourceType.AssociatedSystemType;
if (expression.Type.MakeByRefType() == associatedSystemType)
return expression;
MethodInfo methodInfo = ((ExprMethodInfo)exprList2.OptionalNextListNode).MethodInfo;
if (predefinedMethod == PREDEFMETH.PM_EXPRESSION_CONVERT_USER_DEFINED)
return Expression.Convert(expression, associatedSystemType, methodInfo);
return Expression.ConvertChecked(expression, associatedSystemType, methodInfo);
}
ExprList exprList3 = (ExprList)pExpr.OptionalArguments;
expression = GetExpression(exprList3.OptionalElement);
associatedSystemType = ((ExprTypeOf)exprList3.OptionalNextListNode).SourceType.AssociatedSystemType;
if (expression.Type.MakeByRefType() == associatedSystemType)
return expression;
if ((pExpr.Flags & EXPRFLAG.EXF_USERCALLABLE) != 0)
return Expression.Unbox(expression, associatedSystemType);
if (predefinedMethod == PREDEFMETH.PM_EXPRESSION_CONVERT)
return Expression.Convert(expression, associatedSystemType);
return Expression.ConvertChecked(expression, associatedSystemType);
}
private Expression GenerateProperty(ExprCall pExpr)
{
ExprList exprList = (ExprList)pExpr.OptionalArguments;
Expr optionalElement = exprList.OptionalElement;
Expr optionalNextListNode = exprList.OptionalNextListNode;
ExprList exprList2;
ExprPropertyInfo exprPropertyInfo;
ExprArrayInit exprArrayInit;
if ((exprList2 = (optionalNextListNode as ExprList)) != null) {
exprPropertyInfo = (exprList2.OptionalElement as ExprPropertyInfo);
exprArrayInit = (exprList2.OptionalNextListNode as ExprArrayInit);
} else {
exprPropertyInfo = (optionalNextListNode as ExprPropertyInfo);
exprArrayInit = null;
}
PropertyInfo propertyInfo = exprPropertyInfo.PropertyInfo;
if (propertyInfo == (PropertyInfo)null)
throw Error.InternalCompilerError();
if (exprArrayInit == null)
return Expression.Property(GetExpression(optionalElement), propertyInfo);
return Expression.Property(GetExpression(optionalElement), propertyInfo, GetArgumentsFromArrayInit(exprArrayInit));
}
private Expression GenerateField(ExprCall pExpr)
{
ExprList exprList = (ExprList)pExpr.OptionalArguments;
ExprFieldInfo exprFieldInfo = (ExprFieldInfo)exprList.OptionalNextListNode;
Type type = exprFieldInfo.FieldType.AssociatedSystemType;
FieldInfo fieldInfo = exprFieldInfo.Field.AssociatedFieldInfo;
if (!type.IsGenericType && !type.IsNested)
type = fieldInfo.DeclaringType;
if (type.IsGenericType)
fieldInfo = type.GetField(fieldInfo.Name, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
return Expression.Field(GetExpression(exprList.OptionalElement), fieldInfo);
}
private Expression GenerateInvoke(ExprCall pExpr)
{
ExprList exprList = (ExprList)pExpr.OptionalArguments;
return Expression.Invoke(GetExpression(exprList.OptionalElement), GetArgumentsFromArrayInit(exprList.OptionalNextListNode as ExprArrayInit));
}
private Expression GenerateNew(ExprCall pExpr)
{
ExprList exprList = (ExprList)pExpr.OptionalArguments;
ConstructorInfo constructorInfo = ((ExprMethodInfo)exprList.OptionalElement).ConstructorInfo;
Expression[] argumentsFromArrayInit = GetArgumentsFromArrayInit(exprList.OptionalNextListNode as ExprArrayInit);
return Expression.New(constructorInfo, argumentsFromArrayInit);
}
private static Expression GenerateConstantType(ExprCall pExpr)
{
ExprList exprList = (ExprList)pExpr.OptionalArguments;
return Expression.Constant(exprList.OptionalElement.Object, ((ExprTypeOf)exprList.OptionalNextListNode).SourceType.AssociatedSystemType);
}
private Expression GenerateAssignment(ExprCall pExpr)
{
ExprList exprList = (ExprList)pExpr.OptionalArguments;
return Expression.Assign(GetExpression(exprList.OptionalElement), GetExpression(exprList.OptionalNextListNode));
}
private Expression GenerateBinaryOperator(ExprCall pExpr)
{
ExprList exprList = (ExprList)pExpr.OptionalArguments;
Expression expression = GetExpression(exprList.OptionalElement);
Expression expression2 = GetExpression(exprList.OptionalNextListNode);
switch (pExpr.PredefinedMethod) {
case PREDEFMETH.PM_EXPRESSION_ADD:
return Expression.Add(expression, expression2);
case PREDEFMETH.PM_EXPRESSION_AND:
return Expression.And(expression, expression2);
case PREDEFMETH.PM_EXPRESSION_DIVIDE:
return Expression.Divide(expression, expression2);
case PREDEFMETH.PM_EXPRESSION_EQUAL:
return Expression.Equal(expression, expression2);
case PREDEFMETH.PM_EXPRESSION_EXCLUSIVEOR:
return Expression.ExclusiveOr(expression, expression2);
case PREDEFMETH.PM_EXPRESSION_GREATERTHAN:
return Expression.GreaterThan(expression, expression2);
case PREDEFMETH.PM_EXPRESSION_GREATERTHANOREQUAL:
return Expression.GreaterThanOrEqual(expression, expression2);
case PREDEFMETH.PM_EXPRESSION_LEFTSHIFT:
return Expression.LeftShift(expression, expression2);
case PREDEFMETH.PM_EXPRESSION_LESSTHAN:
return Expression.LessThan(expression, expression2);
case PREDEFMETH.PM_EXPRESSION_LESSTHANOREQUAL:
return Expression.LessThanOrEqual(expression, expression2);
case PREDEFMETH.PM_EXPRESSION_MODULO:
return Expression.Modulo(expression, expression2);
case PREDEFMETH.PM_EXPRESSION_MULTIPLY:
return Expression.Multiply(expression, expression2);
case PREDEFMETH.PM_EXPRESSION_NOTEQUAL:
return Expression.NotEqual(expression, expression2);
case PREDEFMETH.PM_EXPRESSION_OR:
return Expression.Or(expression, expression2);
case PREDEFMETH.PM_EXPRESSION_RIGHTSHIFT:
return Expression.RightShift(expression, expression2);
case PREDEFMETH.PM_EXPRESSION_SUBTRACT:
return Expression.Subtract(expression, expression2);
case PREDEFMETH.PM_EXPRESSION_ORELSE:
return Expression.OrElse(expression, expression2);
case PREDEFMETH.PM_EXPRESSION_ANDALSO:
return Expression.AndAlso(expression, expression2);
case PREDEFMETH.PM_EXPRESSION_ADDCHECKED:
return Expression.AddChecked(expression, expression2);
case PREDEFMETH.PM_EXPRESSION_MULTIPLYCHECKED:
return Expression.MultiplyChecked(expression, expression2);
case PREDEFMETH.PM_EXPRESSION_SUBTRACTCHECKED:
return Expression.SubtractChecked(expression, expression2);
default:
throw Error.InternalCompilerError();
}
}
private Expression GenerateUserDefinedBinaryOperator(ExprCall pExpr)
{
ExprList exprList = (ExprList)pExpr.OptionalArguments;
Expression expression = GetExpression(exprList.OptionalElement);
Expression expression2 = GetExpression(((ExprList)exprList.OptionalNextListNode).OptionalElement);
exprList = (ExprList)exprList.OptionalNextListNode;
bool liftToNull = false;
ExprList exprList2;
MethodInfo methodInfo;
if ((exprList2 = (exprList.OptionalNextListNode as ExprList)) != null) {
ExprConstant exprConstant = (ExprConstant)exprList2.OptionalElement;
liftToNull = (exprConstant.Val.Int32Val == 1);
methodInfo = ((ExprMethodInfo)exprList2.OptionalNextListNode).MethodInfo;
} else
methodInfo = ((ExprMethodInfo)exprList.OptionalNextListNode).MethodInfo;
switch (pExpr.PredefinedMethod) {
case PREDEFMETH.PM_EXPRESSION_ADD_USER_DEFINED:
return Expression.Add(expression, expression2, methodInfo);
case PREDEFMETH.PM_EXPRESSION_AND_USER_DEFINED:
return Expression.And(expression, expression2, methodInfo);
case PREDEFMETH.PM_EXPRESSION_DIVIDE_USER_DEFINED:
return Expression.Divide(expression, expression2, methodInfo);
case PREDEFMETH.PM_EXPRESSION_EQUAL_USER_DEFINED:
return Expression.Equal(expression, expression2, liftToNull, methodInfo);
case PREDEFMETH.PM_EXPRESSION_EXCLUSIVEOR_USER_DEFINED:
return Expression.ExclusiveOr(expression, expression2, methodInfo);
case PREDEFMETH.PM_EXPRESSION_GREATERTHAN_USER_DEFINED:
return Expression.GreaterThan(expression, expression2, liftToNull, methodInfo);
case PREDEFMETH.PM_EXPRESSION_GREATERTHANOREQUAL_USER_DEFINED:
return Expression.GreaterThanOrEqual(expression, expression2, liftToNull, methodInfo);
case PREDEFMETH.PM_EXPRESSION_LEFTSHIFT_USER_DEFINED:
return Expression.LeftShift(expression, expression2, methodInfo);
case PREDEFMETH.PM_EXPRESSION_LESSTHAN_USER_DEFINED:
return Expression.LessThan(expression, expression2, liftToNull, methodInfo);
case PREDEFMETH.PM_EXPRESSION_LESSTHANOREQUAL_USER_DEFINED:
return Expression.LessThanOrEqual(expression, expression2, liftToNull, methodInfo);
case PREDEFMETH.PM_EXPRESSION_MODULO_USER_DEFINED:
return Expression.Modulo(expression, expression2, methodInfo);
case PREDEFMETH.PM_EXPRESSION_MULTIPLY_USER_DEFINED:
return Expression.Multiply(expression, expression2, methodInfo);
case PREDEFMETH.PM_EXPRESSION_NOTEQUAL_USER_DEFINED:
return Expression.NotEqual(expression, expression2, liftToNull, methodInfo);
case PREDEFMETH.PM_EXPRESSION_OR_USER_DEFINED:
return Expression.Or(expression, expression2, methodInfo);
case PREDEFMETH.PM_EXPRESSION_RIGHTSHIFT_USER_DEFINED:
return Expression.RightShift(expression, expression2, methodInfo);
case PREDEFMETH.PM_EXPRESSION_SUBTRACT_USER_DEFINED:
return Expression.Subtract(expression, expression2, methodInfo);
case PREDEFMETH.PM_EXPRESSION_ORELSE_USER_DEFINED:
return Expression.OrElse(expression, expression2, methodInfo);
case PREDEFMETH.PM_EXPRESSION_ANDALSO_USER_DEFINED:
return Expression.AndAlso(expression, expression2, methodInfo);
case PREDEFMETH.PM_EXPRESSION_ADDCHECKED_USER_DEFINED:
return Expression.AddChecked(expression, expression2, methodInfo);
case PREDEFMETH.PM_EXPRESSION_MULTIPLYCHECKED_USER_DEFINED:
return Expression.MultiplyChecked(expression, expression2, methodInfo);
case PREDEFMETH.PM_EXPRESSION_SUBTRACTCHECKED_USER_DEFINED:
return Expression.SubtractChecked(expression, expression2, methodInfo);
default:
throw Error.InternalCompilerError();
}
}
private Expression GenerateUnaryOperator(ExprCall pExpr)
{
PREDEFMETH predefinedMethod = pExpr.PredefinedMethod;
Expression expression = GetExpression(pExpr.OptionalArguments);
switch (predefinedMethod) {
case PREDEFMETH.PM_EXPRESSION_NOT:
return Expression.Not(expression);
case PREDEFMETH.PM_EXPRESSION_NEGATE:
return Expression.Negate(expression);
case PREDEFMETH.PM_EXPRESSION_NEGATECHECKED:
return Expression.NegateChecked(expression);
default:
throw Error.InternalCompilerError();
}
}
private Expression GenerateUserDefinedUnaryOperator(ExprCall pExpr)
{
PREDEFMETH predefinedMethod = pExpr.PredefinedMethod;
ExprList exprList = (ExprList)pExpr.OptionalArguments;
Expression expression = GetExpression(exprList.OptionalElement);
MethodInfo methodInfo = ((ExprMethodInfo)exprList.OptionalNextListNode).MethodInfo;
switch (predefinedMethod) {
case PREDEFMETH.PM_EXPRESSION_NOT_USER_DEFINED:
return Expression.Not(expression, methodInfo);
case PREDEFMETH.PM_EXPRESSION_NEGATE_USER_DEFINED:
return Expression.Negate(expression, methodInfo);
case PREDEFMETH.PM_EXPRESSION_UNARYPLUS_USER_DEFINED:
return Expression.UnaryPlus(expression, methodInfo);
case PREDEFMETH.PM_EXPRESSION_NEGATECHECKED_USER_DEFINED:
return Expression.NegateChecked(expression, methodInfo);
default:
throw Error.InternalCompilerError();
}
}
private Expression GetExpression(Expr pExpr)
{
ExprWrap exprWrap;
if ((exprWrap = (pExpr as ExprWrap)) != null)
return _DictionaryOfParameters[(ExprCall)exprWrap.OptionalExpression];
if (!(pExpr is ExprConstant)) {
ExprCall exprCall = (ExprCall)pExpr;
switch (exprCall.PredefinedMethod) {
case PREDEFMETH.PM_EXPRESSION_CALL:
return GenerateCall(exprCall);
case PREDEFMETH.PM_EXPRESSION_CONVERT:
case PREDEFMETH.PM_EXPRESSION_CONVERT_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_CONVERTCHECKED:
case PREDEFMETH.PM_EXPRESSION_CONVERTCHECKED_USER_DEFINED:
return GenerateConvert(exprCall);
case PREDEFMETH.PM_EXPRESSION_NEWARRAYINIT: {
ExprList exprList = (ExprList)exprCall.OptionalArguments;
return Expression.NewArrayInit(((ExprTypeOf)exprList.OptionalElement).SourceType.AssociatedSystemType, GetArgumentsFromArrayInit((ExprArrayInit)exprList.OptionalNextListNode));
}
case PREDEFMETH.PM_EXPRESSION_ARRAYINDEX:
case PREDEFMETH.PM_EXPRESSION_ARRAYINDEX2:
return GenerateArrayIndex(exprCall);
case PREDEFMETH.PM_EXPRESSION_NEW:
return GenerateNew(exprCall);
case PREDEFMETH.PM_EXPRESSION_PROPERTY:
return GenerateProperty(exprCall);
case PREDEFMETH.PM_EXPRESSION_FIELD:
return GenerateField(exprCall);
case PREDEFMETH.PM_EXPRESSION_CONSTANT_OBJECT_TYPE:
return GenerateConstantType(exprCall);
case PREDEFMETH.PM_EXPRESSION_ASSIGN:
return GenerateAssignment(exprCall);
case PREDEFMETH.PM_EXPRESSION_ADD:
case PREDEFMETH.PM_EXPRESSION_ADDCHECKED:
case PREDEFMETH.PM_EXPRESSION_AND:
case PREDEFMETH.PM_EXPRESSION_ANDALSO:
case PREDEFMETH.PM_EXPRESSION_DIVIDE:
case PREDEFMETH.PM_EXPRESSION_EQUAL:
case PREDEFMETH.PM_EXPRESSION_EXCLUSIVEOR:
case PREDEFMETH.PM_EXPRESSION_GREATERTHAN:
case PREDEFMETH.PM_EXPRESSION_GREATERTHANOREQUAL:
case PREDEFMETH.PM_EXPRESSION_LEFTSHIFT:
case PREDEFMETH.PM_EXPRESSION_LESSTHAN:
case PREDEFMETH.PM_EXPRESSION_LESSTHANOREQUAL:
case PREDEFMETH.PM_EXPRESSION_MODULO:
case PREDEFMETH.PM_EXPRESSION_MULTIPLY:
case PREDEFMETH.PM_EXPRESSION_MULTIPLYCHECKED:
case PREDEFMETH.PM_EXPRESSION_NOTEQUAL:
case PREDEFMETH.PM_EXPRESSION_OR:
case PREDEFMETH.PM_EXPRESSION_ORELSE:
case PREDEFMETH.PM_EXPRESSION_RIGHTSHIFT:
case PREDEFMETH.PM_EXPRESSION_SUBTRACT:
case PREDEFMETH.PM_EXPRESSION_SUBTRACTCHECKED:
return GenerateBinaryOperator(exprCall);
case PREDEFMETH.PM_EXPRESSION_ADD_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_ADDCHECKED_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_AND_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_ANDALSO_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_DIVIDE_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_EQUAL_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_EXCLUSIVEOR_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_GREATERTHAN_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_GREATERTHANOREQUAL_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_LEFTSHIFT_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_LESSTHAN_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_LESSTHANOREQUAL_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_MODULO_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_MULTIPLY_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_MULTIPLYCHECKED_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_NOTEQUAL_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_OR_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_ORELSE_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_RIGHTSHIFT_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_SUBTRACT_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_SUBTRACTCHECKED_USER_DEFINED:
return GenerateUserDefinedBinaryOperator(exprCall);
case PREDEFMETH.PM_EXPRESSION_NEGATE:
case PREDEFMETH.PM_EXPRESSION_NEGATECHECKED:
case PREDEFMETH.PM_EXPRESSION_NOT:
return GenerateUnaryOperator(exprCall);
case PREDEFMETH.PM_EXPRESSION_UNARYPLUS_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_NEGATE_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_NEGATECHECKED_USER_DEFINED:
case PREDEFMETH.PM_EXPRESSION_NOT_USER_DEFINED:
return GenerateUserDefinedUnaryOperator(exprCall);
default:
throw Error.InternalCompilerError();
}
}
return null;
}
private Expression[] GetArgumentsFromArrayInit(ExprArrayInit arrinit)
{
List<Expression> list = new List<Expression>();
if (arrinit != null) {
Expr expr = arrinit.OptionalArguments;
while (expr != null) {
ExprList exprList;
Expr pExpr;
if ((exprList = (expr as ExprList)) != null) {
pExpr = exprList.OptionalElement;
expr = exprList.OptionalNextListNode;
} else {
pExpr = expr;
expr = null;
}
list.Add(GetExpression(pExpr));
}
}
return list.ToArray();
}
}
}