public EXPRUSERLOGOP CreateUserLogOp(CType pType, EXPR pCallTF, EXPRCALL pCallOp) { Debug.Assert(pCallTF != null); Debug.Assert(pCallOp != null); Debug.Assert(pCallOp.GetOptionalArguments() != null); Debug.Assert(pCallOp.GetOptionalArguments().isLIST()); Debug.Assert(pCallOp.GetOptionalArguments().asLIST().GetOptionalElement() != null); EXPRUSERLOGOP rval = new EXPRUSERLOGOP(); EXPR leftChild = pCallOp.GetOptionalArguments().asLIST().GetOptionalElement(); Debug.Assert(leftChild != null); if (leftChild.isWRAP()) { // In the EE case, we don't create WRAPEXPRs. leftChild = leftChild.asWRAP().GetOptionalExpression(); Debug.Assert(leftChild != null); } rval.kind = ExpressionKind.EK_USERLOGOP; rval.type = pType; rval.flags = EXPRFLAG.EXF_ASSGOP; rval.TrueFalseCall = pCallTF; rval.OperatorCall = pCallOp; rval.FirstOperandToExamine = leftChild; Debug.Assert(rval != null); return(rval); }
public EXPRUSERLOGOP CreateUserLogOpError(CType pType, EXPR pCallTF, EXPRCALL pCallOp) { EXPRUSERLOGOP rval = CreateUserLogOp(pType, pCallTF, pCallOp); rval.SetError(); return(rval); }
public EXPRCALL CreateCall(EXPRFLAG nFlags, CType pType, EXPR pOptionalArguments, EXPRMEMGRP pMemberGroup, MethWithInst MWI) { Debug.Assert(0 == (nFlags & ~( EXPRFLAG.EXF_NEWOBJCALL | EXPRFLAG.EXF_CONSTRAINED | EXPRFLAG.EXF_BASECALL | EXPRFLAG.EXF_NEWSTRUCTASSG | EXPRFLAG.EXF_IMPLICITSTRUCTASSG | EXPRFLAG.EXF_MASK_ANY ) )); EXPRCALL rval = new EXPRCALL(); rval.kind = ExpressionKind.EK_CALL; rval.type = pType; rval.flags = nFlags; rval.SetOptionalArguments(pOptionalArguments); rval.SetMemberGroup(pMemberGroup); rval.nubLiftKind = NullableCallLiftKind.NotLifted; rval.castOfNonLiftedResultToLiftedType = null; rval.mwi = MWI; Debug.Assert(rval != null); return (rval); }
public EXPRCALL BindNew(EXPR pExprSrc) { Debug.Assert(pExprSrc != null); NullableType pNubSourceType = GetSymbolLoader().GetTypeManager().GetNullable(pExprSrc.type); AggregateType pSourceType = pNubSourceType.GetAts(GetErrorContext()); if (pSourceType == null) { MethWithInst mwi = new MethWithInst(null, null); EXPRMEMGRP pMemGroup = GetExprFactory().CreateMemGroup(pExprSrc, mwi); EXPRCALL rval = GetExprFactory().CreateCall(0, pNubSourceType, null, pMemGroup, null); rval.SetError(); return(rval); } // UNDONE: move this to transform pass MethodSymbol meth = GetSymbolLoader().getBSymmgr().methNubCtor; if (meth == null) { meth = GetSymbolLoader().getPredefinedMembers().GetMethod(PREDEFMETH.PM_G_OPTIONAL_CTOR); GetSymbolLoader().getBSymmgr().methNubCtor = meth; } MethWithInst methwithinst = new MethWithInst(meth, pSourceType, BSYMMGR.EmptyTypeArray()); EXPRMEMGRP memgroup = GetExprFactory().CreateMemGroup(null, methwithinst); EXPRCALL pExprRes = GetExprFactory().CreateCall(EXPRFLAG.EXF_NEWOBJCALL | EXPRFLAG.EXF_CANTBENULL, pNubSourceType, pExprSrc, memgroup, methwithinst); if (meth == null) { pExprRes.SetError(); } return(pExprRes); }
public static bool IsNullableConstructor(EXPR expr) { Debug.Assert(expr != null); if (!expr.isCALL()) { return(false); } EXPRCALL pCall = expr.asCALL(); if (pCall.GetMemberGroup().GetOptionalObject() != null) { return(false); } MethodSymbol meth = pCall.mwi.Meth(); if (meth == null) { return(false); } return(meth.IsNullableConstructor()); }
public EXPRCALL CreateCall(EXPRFLAG nFlags, CType pType, EXPR pOptionalArguments, EXPRMEMGRP pMemberGroup, MethWithInst MWI) { Debug.Assert(0 == (nFlags & ~( EXPRFLAG.EXF_NEWOBJCALL | EXPRFLAG.EXF_CONSTRAINED | EXPRFLAG.EXF_BASECALL | EXPRFLAG.EXF_NEWSTRUCTASSG | EXPRFLAG.EXF_IMPLICITSTRUCTASSG | EXPRFLAG.EXF_MASK_ANY ) )); EXPRCALL rval = new EXPRCALL(); rval.kind = ExpressionKind.EK_CALL; rval.type = pType; rval.flags = nFlags; rval.SetOptionalArguments(pOptionalArguments); rval.SetMemberGroup(pMemberGroup); rval.nubLiftKind = NullableCallLiftKind.NotLifted; rval.castOfNonLiftedResultToLiftedType = null; rval.mwi = MWI; Debug.Assert(rval != null); return(rval); }
///////////////////////////////////////////////////////////////////////////////// private ExpressionEXPR GenerateUnaryOperator(EXPRCALL pExpr) { PREDEFMETH pm = pExpr.PredefinedMethod; Expression arg = GetExpression(pExpr.GetOptionalArguments()); switch (pm) { case PREDEFMETH.PM_EXPRESSION_NOT: return new ExpressionEXPR(Expression.Not(arg)); case PREDEFMETH.PM_EXPRESSION_NEGATE: return new ExpressionEXPR(Expression.Negate(arg)); case PREDEFMETH.PM_EXPRESSION_NEGATECHECKED: return new ExpressionEXPR(Expression.NegateChecked(arg)); default: Debug.Assert(false, "Invalid Predefined Method in GenerateUnaryOperator"); throw Error.InternalCompilerError(); } }
///////////////////////////////////////////////////////////////////////////////// private ExpressionEXPR GenerateUserDefinedUnaryOperator(EXPRCALL pExpr) { PREDEFMETH pm = pExpr.PredefinedMethod; EXPRLIST list = pExpr.GetOptionalArguments().asLIST(); Expression arg = GetExpression(list.GetOptionalElement()); MethodInfo methodInfo = GetMethodInfoFromExpr(list.GetOptionalNextListNode().asMETHODINFO()); switch (pm) { case PREDEFMETH.PM_EXPRESSION_NOT_USER_DEFINED: return new ExpressionEXPR(Expression.Not(arg, methodInfo)); case PREDEFMETH.PM_EXPRESSION_NEGATE_USER_DEFINED: return new ExpressionEXPR(Expression.Negate(arg, methodInfo)); case PREDEFMETH.PM_EXPRESSION_UNARYPLUS_USER_DEFINED: return new ExpressionEXPR(Expression.UnaryPlus(arg, methodInfo)); case PREDEFMETH.PM_EXPRESSION_NEGATECHECKED_USER_DEFINED: return new ExpressionEXPR(Expression.NegateChecked(arg, methodInfo)); default: Debug.Assert(false, "Invalid Predefined Method in GenerateUserDefinedUnaryOperator"); throw Error.InternalCompilerError(); } }
///////////////////////////////////////////////////////////////////////////////// private ExpressionEXPR GenerateBinaryOperator(EXPRCALL pExpr) { Expression arg1 = GetExpression(pExpr.GetOptionalArguments().asLIST().GetOptionalElement()); Expression arg2 = GetExpression(pExpr.GetOptionalArguments().asLIST().GetOptionalNextListNode()); switch (pExpr.PredefinedMethod) { case PREDEFMETH.PM_EXPRESSION_ADD: return new ExpressionEXPR(Expression.Add(arg1, arg2)); case PREDEFMETH.PM_EXPRESSION_AND: return new ExpressionEXPR(Expression.And(arg1, arg2)); case PREDEFMETH.PM_EXPRESSION_DIVIDE: return new ExpressionEXPR(Expression.Divide(arg1, arg2)); case PREDEFMETH.PM_EXPRESSION_EQUAL: return new ExpressionEXPR(Expression.Equal(arg1, arg2)); case PREDEFMETH.PM_EXPRESSION_EXCLUSIVEOR: return new ExpressionEXPR(Expression.ExclusiveOr(arg1, arg2)); case PREDEFMETH.PM_EXPRESSION_GREATERTHAN: return new ExpressionEXPR(Expression.GreaterThan(arg1, arg2)); case PREDEFMETH.PM_EXPRESSION_GREATERTHANOREQUAL: return new ExpressionEXPR(Expression.GreaterThanOrEqual(arg1, arg2)); case PREDEFMETH.PM_EXPRESSION_LEFTSHIFT: return new ExpressionEXPR(Expression.LeftShift(arg1, arg2)); case PREDEFMETH.PM_EXPRESSION_LESSTHAN: return new ExpressionEXPR(Expression.LessThan(arg1, arg2)); case PREDEFMETH.PM_EXPRESSION_LESSTHANOREQUAL: return new ExpressionEXPR(Expression.LessThanOrEqual(arg1, arg2)); case PREDEFMETH.PM_EXPRESSION_MODULO: return new ExpressionEXPR(Expression.Modulo(arg1, arg2)); case PREDEFMETH.PM_EXPRESSION_MULTIPLY: return new ExpressionEXPR(Expression.Multiply(arg1, arg2)); case PREDEFMETH.PM_EXPRESSION_NOTEQUAL: return new ExpressionEXPR(Expression.NotEqual(arg1, arg2)); case PREDEFMETH.PM_EXPRESSION_OR: return new ExpressionEXPR(Expression.Or(arg1, arg2)); case PREDEFMETH.PM_EXPRESSION_RIGHTSHIFT: return new ExpressionEXPR(Expression.RightShift(arg1, arg2)); case PREDEFMETH.PM_EXPRESSION_SUBTRACT: return new ExpressionEXPR(Expression.Subtract(arg1, arg2)); case PREDEFMETH.PM_EXPRESSION_ORELSE: return new ExpressionEXPR(Expression.OrElse(arg1, arg2)); case PREDEFMETH.PM_EXPRESSION_ANDALSO: return new ExpressionEXPR(Expression.AndAlso(arg1, arg2)); // Checked case PREDEFMETH.PM_EXPRESSION_ADDCHECKED: return new ExpressionEXPR(Expression.AddChecked(arg1, arg2)); case PREDEFMETH.PM_EXPRESSION_MULTIPLYCHECKED: return new ExpressionEXPR(Expression.MultiplyChecked(arg1, arg2)); case PREDEFMETH.PM_EXPRESSION_SUBTRACTCHECKED: return new ExpressionEXPR(Expression.SubtractChecked(arg1, arg2)); default: Debug.Assert(false, "Invalid Predefined Method in GenerateBinaryOperator"); throw Error.InternalCompilerError(); } }
///////////////////////////////////////////////////////////////////////////////// private ExpressionEXPR GenerateUserDefinedBinaryOperator(EXPRCALL pExpr) { EXPRLIST list = pExpr.GetOptionalArguments().asLIST(); Expression arg1 = GetExpression(list.GetOptionalElement()); Expression arg2 = GetExpression(list.GetOptionalNextListNode().asLIST().GetOptionalElement()); list = list.GetOptionalNextListNode().asLIST(); MethodInfo methodInfo; bool bIsLifted = false; if (list.GetOptionalNextListNode().isLIST()) { EXPRCONSTANT isLifted = list.GetOptionalNextListNode().asLIST().GetOptionalElement().asCONSTANT(); bIsLifted = isLifted.getVal().iVal == 1; methodInfo = GetMethodInfoFromExpr(list.GetOptionalNextListNode().asLIST().GetOptionalNextListNode().asMETHODINFO()); } else { methodInfo = GetMethodInfoFromExpr(list.GetOptionalNextListNode().asMETHODINFO()); } switch (pExpr.PredefinedMethod) { case PREDEFMETH.PM_EXPRESSION_ADD_USER_DEFINED: return new ExpressionEXPR(Expression.Add(arg1, arg2, methodInfo)); case PREDEFMETH.PM_EXPRESSION_AND_USER_DEFINED: return new ExpressionEXPR(Expression.And(arg1, arg2, methodInfo)); case PREDEFMETH.PM_EXPRESSION_DIVIDE_USER_DEFINED: return new ExpressionEXPR(Expression.Divide(arg1, arg2, methodInfo)); case PREDEFMETH.PM_EXPRESSION_EQUAL_USER_DEFINED: return new ExpressionEXPR(Expression.Equal(arg1, arg2, bIsLifted, methodInfo)); case PREDEFMETH.PM_EXPRESSION_EXCLUSIVEOR_USER_DEFINED: return new ExpressionEXPR(Expression.ExclusiveOr(arg1, arg2, methodInfo)); case PREDEFMETH.PM_EXPRESSION_GREATERTHAN_USER_DEFINED: return new ExpressionEXPR(Expression.GreaterThan(arg1, arg2, bIsLifted, methodInfo)); case PREDEFMETH.PM_EXPRESSION_GREATERTHANOREQUAL_USER_DEFINED: return new ExpressionEXPR(Expression.GreaterThanOrEqual(arg1, arg2, bIsLifted, methodInfo)); case PREDEFMETH.PM_EXPRESSION_LEFTSHIFT_USER_DEFINED: return new ExpressionEXPR(Expression.LeftShift(arg1, arg2, methodInfo)); case PREDEFMETH.PM_EXPRESSION_LESSTHAN_USER_DEFINED: return new ExpressionEXPR(Expression.LessThan(arg1, arg2, bIsLifted, methodInfo)); case PREDEFMETH.PM_EXPRESSION_LESSTHANOREQUAL_USER_DEFINED: return new ExpressionEXPR(Expression.LessThanOrEqual(arg1, arg2, bIsLifted, methodInfo)); case PREDEFMETH.PM_EXPRESSION_MODULO_USER_DEFINED: return new ExpressionEXPR(Expression.Modulo(arg1, arg2, methodInfo)); case PREDEFMETH.PM_EXPRESSION_MULTIPLY_USER_DEFINED: return new ExpressionEXPR(Expression.Multiply(arg1, arg2, methodInfo)); case PREDEFMETH.PM_EXPRESSION_NOTEQUAL_USER_DEFINED: return new ExpressionEXPR(Expression.NotEqual(arg1, arg2, bIsLifted, methodInfo)); case PREDEFMETH.PM_EXPRESSION_OR_USER_DEFINED: return new ExpressionEXPR(Expression.Or(arg1, arg2, methodInfo)); case PREDEFMETH.PM_EXPRESSION_RIGHTSHIFT_USER_DEFINED: return new ExpressionEXPR(Expression.RightShift(arg1, arg2, methodInfo)); case PREDEFMETH.PM_EXPRESSION_SUBTRACT_USER_DEFINED: return new ExpressionEXPR(Expression.Subtract(arg1, arg2, methodInfo)); case PREDEFMETH.PM_EXPRESSION_ORELSE_USER_DEFINED: return new ExpressionEXPR(Expression.OrElse(arg1, arg2, methodInfo)); case PREDEFMETH.PM_EXPRESSION_ANDALSO_USER_DEFINED: return new ExpressionEXPR(Expression.AndAlso(arg1, arg2, methodInfo)); // Checked case PREDEFMETH.PM_EXPRESSION_ADDCHECKED_USER_DEFINED: return new ExpressionEXPR(Expression.AddChecked(arg1, arg2, methodInfo)); case PREDEFMETH.PM_EXPRESSION_MULTIPLYCHECKED_USER_DEFINED: return new ExpressionEXPR(Expression.MultiplyChecked(arg1, arg2, methodInfo)); case PREDEFMETH.PM_EXPRESSION_SUBTRACTCHECKED_USER_DEFINED: return new ExpressionEXPR(Expression.SubtractChecked(arg1, arg2, methodInfo)); default: Debug.Assert(false, "Invalid Predefined Method in GenerateUserDefinedBinaryOperator"); throw Error.InternalCompilerError(); } }
public EXPRUSERLOGOP CreateUserLogOp(CType pType, EXPR pCallTF, EXPRCALL pCallOp) { Debug.Assert(pCallTF != null); Debug.Assert(pCallOp != null); Debug.Assert(pCallOp.GetOptionalArguments() != null); Debug.Assert(pCallOp.GetOptionalArguments().isLIST()); Debug.Assert(pCallOp.GetOptionalArguments().asLIST().GetOptionalElement() != null); EXPRUSERLOGOP rval = new EXPRUSERLOGOP(); EXPR leftChild = pCallOp.GetOptionalArguments().asLIST().GetOptionalElement(); Debug.Assert(leftChild != null); if (leftChild.isWRAP()) { // In the EE case, we don't create WRAPEXPRs. leftChild = leftChild.asWRAP().GetOptionalExpression(); Debug.Assert(leftChild != null); } rval.kind = ExpressionKind.EK_USERLOGOP; rval.type = pType; rval.flags = EXPRFLAG.EXF_ASSGOP; rval.TrueFalseCall = pCallTF; rval.OperatorCall = pCallOp; rval.FirstOperandToExamine = leftChild; Debug.Assert(rval != null); return (rval); }
///////////////////////////////////////////////////////////////////////////////// private ExpressionEXPR GenerateAssignment(EXPRCALL pExpr) { EXPRLIST list = pExpr.GetOptionalArguments().asLIST(); return new ExpressionEXPR(Expression.Assign( GetExpression(list.GetOptionalElement()), GetExpression(list.GetOptionalNextListNode()))); }
public EXPRUSERLOGOP CreateUserLogOpError(CType pType, EXPR pCallTF, EXPRCALL pCallOp) { EXPRUSERLOGOP rval = CreateUserLogOp(pType, pCallTF, pCallOp); rval.SetError(); return rval; }
protected virtual EXPR VisitCALL(EXPRCALL pExpr) { return VisitEXPR(pExpr); }
///////////////////////////////////////////////////////////////////////////////// private ExpressionEXPR GenerateProperty(EXPRCALL pExpr) { EXPRLIST list = pExpr.asCALL().GetOptionalArguments().asLIST(); EXPR instance = list.GetOptionalElement(); EXPRPropertyInfo propinfo = list.GetOptionalNextListNode().isLIST() ? list.GetOptionalNextListNode().asLIST().GetOptionalElement().asPropertyInfo() : list.GetOptionalNextListNode().asPropertyInfo(); EXPRARRINIT arguments = list.GetOptionalNextListNode().isLIST() ? list.GetOptionalNextListNode().asLIST().GetOptionalNextListNode().asARRINIT() : null; PropertyInfo p = GetPropertyInfoFromExpr(propinfo); if (p == null) { Debug.Assert(false, "How did we get a prop that doesn't have a propinfo?"); throw Error.InternalCompilerError(); } if (arguments == null) { return new ExpressionEXPR(Expression.Property(GetExpression(instance), p)); } return new ExpressionEXPR(Expression.Property(GetExpression(instance), p, GetArgumentsFromArrayInit(arguments))); }
private EXPR BindUserBoolOp(ExpressionKind kind, EXPRCALL pCall) { RETAILVERIFY(pCall != null); RETAILVERIFY(pCall.mwi.Meth() != null); RETAILVERIFY(pCall.GetOptionalArguments() != null); Debug.Assert(kind == ExpressionKind.EK_LOGAND || kind == ExpressionKind.EK_LOGOR); CType typeRet = pCall.type; Debug.Assert(pCall.mwi.Meth().Params.size == 2); if (!GetTypes().SubstEqualTypes(typeRet, pCall.mwi.Meth().Params.Item(0), typeRet) || !GetTypes().SubstEqualTypes(typeRet, pCall.mwi.Meth().Params.Item(1), typeRet)) { MethWithInst mwi = new MethWithInst(null, null); EXPRMEMGRP pMemGroup = GetExprFactory().CreateMemGroup(null, mwi); EXPRCALL pCallTF = GetExprFactory().CreateCall(0, null, null, pMemGroup, null); pCallTF.SetError(); GetErrorContext().Error(ErrorCode.ERR_BadBoolOp, pCall.mwi); return GetExprFactory().CreateUserLogOpError(typeRet, pCallTF, pCall); } Debug.Assert(pCall.GetOptionalArguments().isLIST()); EXPR pExpr = pCall.GetOptionalArguments().asLIST().GetOptionalElement(); EXPR pExprWrap = WrapShortLivedExpression(pExpr); pCall.GetOptionalArguments().asLIST().SetOptionalElement(pExprWrap); // Reflection load the true and false methods. SymbolLoader.RuntimeBinderSymbolTable.PopulateSymbolTableWithName(SpecialNames.CLR_True, null, pExprWrap.type.AssociatedSystemType); SymbolLoader.RuntimeBinderSymbolTable.PopulateSymbolTableWithName(SpecialNames.CLR_False, null, pExprWrap.type.AssociatedSystemType); EXPR pCallT = bindUDUnop(ExpressionKind.EK_TRUE, pExprWrap); EXPR pCallF = bindUDUnop(ExpressionKind.EK_FALSE, pExprWrap); if (pCallT == null || pCallF == null) { EXPR pCallTorF = pCallT != null ? pCallT : pCallF; if (pCallTorF == null) { MethWithInst mwi = new MethWithInst(null, null); EXPRMEMGRP pMemGroup = GetExprFactory().CreateMemGroup(null, mwi); pCallTorF = GetExprFactory().CreateCall(0, null, pExprWrap, pMemGroup, null); pCall.SetError(); } GetErrorContext().Error(ErrorCode.ERR_MustHaveOpTF, typeRet); return GetExprFactory().CreateUserLogOpError(typeRet, pCallTorF, pCall); } pCallT = mustConvert(pCallT, GetReqPDT(PredefinedType.PT_BOOL)); pCallF = mustConvert(pCallF, GetReqPDT(PredefinedType.PT_BOOL)); return GetExprFactory().CreateUserLogOp(typeRet, kind == ExpressionKind.EK_LOGAND ? pCallF : pCallT, pCall); }
///////////////////////////////////////////////////////////////////////////////// private ExpressionEXPR GenerateConvert(EXPRCALL pExpr) { PREDEFMETH pm = pExpr.PredefinedMethod; Expression e; Type t; if (pm == PREDEFMETH.PM_EXPRESSION_CONVERT_USER_DEFINED || pm == PREDEFMETH.PM_EXPRESSION_CONVERTCHECKED_USER_DEFINED) { // If we have a user defined conversion, then we'll have the object // as the first element, and another list as a second element. This list // contains a TYPEOF as the first element, and the METHODINFO for the call // as the second. EXPRLIST list = pExpr.asCALL().GetOptionalArguments().asLIST(); EXPRLIST list2 = list.GetOptionalNextListNode().asLIST(); e = GetExpression(list.GetOptionalElement()); t = list2.GetOptionalElement().asTYPEOF().SourceType.type.AssociatedSystemType; if (e.Type.MakeByRefType() == t) { // We're trying to convert from a type to its by ref type. Don't do that. return new ExpressionEXPR(e); } Debug.Assert((pExpr.flags & EXPRFLAG.EXF_UNBOXRUNTIME) == 0); MethodInfo m = GetMethodInfoFromExpr(list2.GetOptionalNextListNode().asMETHODINFO()); if (pm == PREDEFMETH.PM_EXPRESSION_CONVERT_USER_DEFINED) { return new ExpressionEXPR(Expression.Convert(e, t, m)); } return new ExpressionEXPR(Expression.ConvertChecked(e, t, m)); } else { Debug.Assert(pm == PREDEFMETH.PM_EXPRESSION_CONVERT || pm == PREDEFMETH.PM_EXPRESSION_CONVERTCHECKED); // If we have a standard conversion, then we'll have some object as // the first list element (ie a WRAP or a CALL), and then a TYPEOF // as the second list element. EXPRLIST list = pExpr.asCALL().GetOptionalArguments().asLIST(); e = GetExpression(list.GetOptionalElement()); t = list.GetOptionalNextListNode().asTYPEOF().SourceType.type.AssociatedSystemType; if (e.Type.MakeByRefType() == t) { // We're trying to convert from a type to its by ref type. Don't do that. return new ExpressionEXPR(e); } if ((pExpr.flags & EXPRFLAG.EXF_UNBOXRUNTIME) != 0) { // If we want to unbox this thing, return that instead of the convert. return new ExpressionEXPR(Expression.Unbox(e, t)); } if (pm == PREDEFMETH.PM_EXPRESSION_CONVERT) { return new ExpressionEXPR(Expression.Convert(e, t)); } return new ExpressionEXPR(Expression.ConvertChecked(e, t)); } }
///////////////////////////////////////////////////////////////////////////////// private ExpressionEXPR GenerateArrayIndex(EXPRCALL pExpr) { // We have two possibilities here - we're either a single index array, in which // case we'll be PM_EXPRESSION_ARRAYINDEX, or we have multiple dimensions, // in which case we are PM_EXPRESSION_ARRAYINDEX2. // // Our arguments then, are: object, index or object, indices. EXPRLIST list = pExpr.GetOptionalArguments().asLIST(); Expression obj = GetExpression(list.GetOptionalElement()); Expression[] indices; if (pExpr.PredefinedMethod == PREDEFMETH.PM_EXPRESSION_ARRAYINDEX) { indices = new Expression[] { GetExpression(list.GetOptionalNextListNode()) }; } else { Debug.Assert(pExpr.PredefinedMethod == PREDEFMETH.PM_EXPRESSION_ARRAYINDEX2); indices = GetArgumentsFromArrayInit(list.GetOptionalNextListNode().asARRINIT()); } return new ExpressionEXPR(Expression.ArrayAccess(obj, indices)); }
///////////////////////////////////////////////////////////////////////////////// private ExpressionEXPR GenerateCall(EXPRCALL pExpr) { // Our arguments are: object, methodinfo, parameters. // The object is either an EXPRWRAP of a CALL, or a CALL that is a PM_CONVERT, whose // argument is the WRAP of a CALL. Deal with that first. EXPRMETHODINFO methinfo; EXPRARRINIT arrinit; EXPRLIST list = pExpr.GetOptionalArguments().asLIST(); if (list.GetOptionalNextListNode().isLIST()) { methinfo = list.GetOptionalNextListNode().asLIST().GetOptionalElement().asMETHODINFO(); arrinit = list.GetOptionalNextListNode().asLIST().GetOptionalNextListNode().asARRINIT(); } else { methinfo = list.GetOptionalNextListNode().asMETHODINFO(); arrinit = null; } Expression obj = null; MethodInfo m = GetMethodInfoFromExpr(methinfo); Expression[] arguments = GetArgumentsFromArrayInit(arrinit); if (m == null) { Debug.Assert(false, "How did we get a call that doesn't have a methodinfo?"); throw Error.InternalCompilerError(); } // The DLR is expecting the instance for a static invocation to be null. If we have // an instance method, fetch the object. if (!m.IsStatic) { obj = GetExpression(pExpr.GetOptionalArguments().asLIST().GetOptionalElement()); } return new ExpressionEXPR(Expression.Call(obj, m, arguments)); }
///////////////////////////////////////////////////////////////////////////////// private ExpressionEXPR GenerateLambda(EXPRCALL pExpr) { // We always call Lambda(body, arrayinit) where the arrayinit // is the initialization of the parameters. ExpressionEXPR body = Visit(pExpr.GetOptionalArguments().asLIST().GetOptionalElement()) as ExpressionEXPR; Expression e = body.Expression; /* * // Do we need to do this? if (e.Type.IsValueType) { // If we have a value type, convert it to object so that boxing // can happen. e = Expression.Convert(body.Expression, typeof(object)); } * */ return new ExpressionEXPR(e); }
///////////////////////////////////////////////////////////////////////////////// protected override EXPR VisitCALL(EXPRCALL pExpr) { if (pExpr.PredefinedMethod != PREDEFMETH.PM_FIRST) { switch (pExpr.PredefinedMethod) { case PREDEFMETH.PM_EXPRESSION_LAMBDA: return GenerateLambda(pExpr); case PREDEFMETH.PM_EXPRESSION_CALL: return GenerateCall(pExpr); case PREDEFMETH.PM_EXPRESSION_ARRAYINDEX: case PREDEFMETH.PM_EXPRESSION_ARRAYINDEX2: return GenerateArrayIndex(pExpr); 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(pExpr); case PREDEFMETH.PM_EXPRESSION_PROPERTY: return GenerateProperty(pExpr); case PREDEFMETH.PM_EXPRESSION_FIELD: return GenerateField(pExpr); case PREDEFMETH.PM_EXPRESSION_INVOKE: return GenerateInvoke(pExpr); case PREDEFMETH.PM_EXPRESSION_NEW: return GenerateNew(pExpr); case PREDEFMETH.PM_EXPRESSION_ADD: case PREDEFMETH.PM_EXPRESSION_AND: 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_NOTEQUAL: case PREDEFMETH.PM_EXPRESSION_OR: case PREDEFMETH.PM_EXPRESSION_RIGHTSHIFT: case PREDEFMETH.PM_EXPRESSION_SUBTRACT: case PREDEFMETH.PM_EXPRESSION_ORELSE: case PREDEFMETH.PM_EXPRESSION_ANDALSO: // Checked case PREDEFMETH.PM_EXPRESSION_ADDCHECKED: case PREDEFMETH.PM_EXPRESSION_MULTIPLYCHECKED: case PREDEFMETH.PM_EXPRESSION_SUBTRACTCHECKED: return GenerateBinaryOperator(pExpr); case PREDEFMETH.PM_EXPRESSION_ADD_USER_DEFINED: case PREDEFMETH.PM_EXPRESSION_AND_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_NOTEQUAL_USER_DEFINED: case PREDEFMETH.PM_EXPRESSION_OR_USER_DEFINED: case PREDEFMETH.PM_EXPRESSION_RIGHTSHIFT_USER_DEFINED: case PREDEFMETH.PM_EXPRESSION_SUBTRACT_USER_DEFINED: case PREDEFMETH.PM_EXPRESSION_ORELSE_USER_DEFINED: case PREDEFMETH.PM_EXPRESSION_ANDALSO_USER_DEFINED: // Checked case PREDEFMETH.PM_EXPRESSION_ADDCHECKED_USER_DEFINED: case PREDEFMETH.PM_EXPRESSION_MULTIPLYCHECKED_USER_DEFINED: case PREDEFMETH.PM_EXPRESSION_SUBTRACTCHECKED_USER_DEFINED: return GenerateUserDefinedBinaryOperator(pExpr); case PREDEFMETH.PM_EXPRESSION_NEGATE: case PREDEFMETH.PM_EXPRESSION_NOT: case PREDEFMETH.PM_EXPRESSION_NEGATECHECKED: return GenerateUnaryOperator(pExpr); case PREDEFMETH.PM_EXPRESSION_UNARYPLUS_USER_DEFINED: case PREDEFMETH.PM_EXPRESSION_NEGATE_USER_DEFINED: case PREDEFMETH.PM_EXPRESSION_NOT_USER_DEFINED: case PREDEFMETH.PM_EXPRESSION_NEGATECHECKED_USER_DEFINED: return GenerateUserDefinedUnaryOperator(pExpr); case PREDEFMETH.PM_EXPRESSION_CONSTANT_OBJECT_TYPE: return GenerateConstantType(pExpr); case PREDEFMETH.PM_EXPRESSION_ASSIGN: return GenerateAssignment(pExpr); default: Debug.Assert(false, "Invalid Predefined Method in VisitCALL"); throw Error.InternalCompilerError(); } } return pExpr; }
protected override EXPR VisitCALL(EXPRCALL expr) { Debug.Assert(expr != null); Debug.Assert(alwaysRewrite || currentAnonMeth != null); switch (expr.nubLiftKind) { default: break; case NullableCallLiftKind.NullableIntermediateConversion: case NullableCallLiftKind.NullableConversion: case NullableCallLiftKind.NullableConversionConstructor: return GenerateConversion(expr.GetOptionalArguments(), expr.type, expr.isChecked()); case NullableCallLiftKind.NotLiftedIntermediateConversion: case NullableCallLiftKind.UserDefinedConversion: return GenerateUserDefinedConversion(expr.GetOptionalArguments(), expr.type, expr.mwi); } if (expr.mwi.Meth().IsConstructor()) { return GenerateConstructor(expr); } EXPRMEMGRP memberGroup = expr.GetMemberGroup(); if (memberGroup.isDelegate()) { return GenerateDelegateInvoke(expr); } EXPR pObject; if (expr.mwi.Meth().isStatic || expr.GetMemberGroup().GetOptionalObject() == null) { pObject = GetExprFactory().CreateNull(); } else { pObject = expr.GetMemberGroup().GetOptionalObject(); // If we have, say, an int? which is the object of a call to ToString // then we do NOT want to generate ((object)i).ToString() because that // will convert a null-valued int? to a null object. Rather what we want // to do is box it to a ValueType and call ValueType.ToString. // // To implement this we say that if the object of the call is an implicit boxing cast // then just generate the object, not the cast. If the cast is explicit in the // source code then it will be an EXPLICITCAST and we will visit it normally. // // It might be better to rewrite the expression tree API so that it // can handle in the general case all implicit boxing conversions. Right now it // requires that all arguments to a call that need to be boxed be explicitly boxed. if (pObject != null && pObject.isCAST() && pObject.asCAST().IsBoxingCast()) { pObject = pObject.asCAST().GetArgument(); } pObject = Visit(pObject); } EXPR methodInfo = GetExprFactory().CreateMethodInfo(expr.mwi); EXPR args = GenerateArgsList(expr.GetOptionalArguments()); EXPR Params = GenerateParamsArray(args, PredefinedType.PT_EXPRESSION); PREDEFMETH pdm = PREDEFMETH.PM_EXPRESSION_CALL; Debug.Assert(!expr.mwi.Meth().isVirtual || expr.GetMemberGroup().GetOptionalObject() != null); return GenerateCall(pdm, pObject, methodInfo, Params); }
protected virtual EXPR GenerateConstructor(EXPRCALL expr) { Debug.Assert(expr != null); Debug.Assert(expr.mwi.Meth().IsConstructor()); // Realize a call to new DELEGATE(obj, FUNCPTR) as though it actually was // (DELEGATE)CreateDelegate(typeof(DELEGATE), obj, GetMethInfoFromHandle(FUNCPTR)) if (IsDelegateConstructorCall(expr)) { return GenerateDelegateConstructor(expr); } EXPR constructorInfo = GetExprFactory().CreateMethodInfo(expr.mwi); EXPR args = GenerateArgsList(expr.GetOptionalArguments()); EXPR Params = GenerateParamsArray(args, PredefinedType.PT_EXPRESSION); if (expr.type.IsAggregateType() && expr.type.AsAggregateType().getAggregate().IsAnonymousType()) { EXPR members = GenerateMembersArray(expr.type.AsAggregateType(), PredefinedType.PT_METHODINFO); return GenerateCall(PREDEFMETH.PM_EXPRESSION_NEW_MEMBERS, constructorInfo, Params, members); } else { return GenerateCall(PREDEFMETH.PM_EXPRESSION_NEW, constructorInfo, Params); } }
///////////////////////////////////////////////////////////////////////////////// private ExpressionEXPR GenerateField(EXPRCALL pExpr) { EXPRLIST list = pExpr.asCALL().GetOptionalArguments().asLIST(); Type t = list.GetOptionalNextListNode().asFIELDINFO().FieldType().AssociatedSystemType; FieldInfo f = list.GetOptionalNextListNode().asFIELDINFO().Field().AssociatedFieldInfo; // This is to ensure that for embedded nopia types, we have the // appropriate local type from the member itself; this is possible // because nopia types are not generic or nested. if (!t.GetTypeInfo().IsGenericType && !t.GetTypeInfo().IsNested) { t = f.DeclaringType; } // Now find the generic'ed one if we're generic. if (t.GetTypeInfo().IsGenericType) { f = t.GetField(f.Name, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static); } return new ExpressionEXPR(Expression.Field(GetExpression(list.GetOptionalElement()), f)); }
protected virtual EXPR VisitCALL(EXPRCALL pExpr) { return(VisitEXPR(pExpr)); }
/*************************************************************************************************** * Called by BindImplicitConversion when the destination type is Nullable<T>. The following * conversions are handled by this method: * * For S in { object, ValueType, interfaces implemented by underlying type} there is an explicit * unboxing conversion S => T? * System.Enum => T? there is an unboxing conversion if T is an enum type * null => T? implemented as default(T?) * * Implicit T?* => T?+ implemented by either wrapping or calling GetValueOrDefault the * appropriate number of times. * If imp/exp S => T then imp/exp S => T?+ implemented by converting to T then wrapping the * appropriate number of times. * If imp/exp S => T then imp/exp S?+ => T?+ implemented by calling GetValueOrDefault (m-1) times * then calling HasValue, producing a null if it returns false, otherwise calling Value, * converting to T then wrapping the appropriate number of times. * * The 3 rules above can be summarized with the following recursive rules: * * If imp/exp S => T? then imp/exp S? => T? implemented as * qs.HasValue ? (T?)(qs.Value) : default(T?) * If imp/exp S => T then imp/exp S => T? implemented as new T?((T)s) * * This method also handles calling bindUserDefinedConverion. This method does NOT handle * the following conversions: * * Implicit boxing conversion from S? to { object, ValueType, Enum, ifaces implemented by S }. (Handled by BindImplicitConversion.) * If imp/exp S => T then explicit S?+ => T implemented by calling Value the appropriate number * of times. (Handled by BindExplicitConversion.) * * The recursive equivalent is: * * If imp/exp S => T and T is not nullable then explicit S? => T implemented as qs.Value * * Some nullable conversion are NOT standard conversions. In particular, if S => T is implicit * then S? => T is not standard. Similarly if S => T is not implicit then S => T? is not standard. ***************************************************************************************************/ private bool BindNubConversion(NullableType nubDst) { // This code assumes that STANDARD and ISEXPLICIT are never both set. // bindUserDefinedConversion should ensure this! Debug.Assert(0 != (~flags & (CONVERTTYPE.STANDARD | CONVERTTYPE.ISEXPLICIT))); Debug.Assert(exprSrc == null || exprSrc.type == typeSrc); Debug.Assert(!needsExprDest || exprSrc != null); Debug.Assert(typeSrc != nubDst); // BindImplicitConversion should have taken care of this already. AggregateType atsDst = nubDst.GetAts(GetErrorContext()); if (atsDst == null) { return(false); } // Check for the unboxing conversion. This takes precedence over the wrapping conversions. if (GetSymbolLoader().HasBaseConversion(nubDst.GetUnderlyingType(), typeSrc) && !CConversions.FWrappingConv(typeSrc, nubDst)) { // These should be different! Fix the caller if typeSrc is an AggregateType of Nullable. Debug.Assert(atsDst != typeSrc); // typeSrc is a base type of the destination nullable type so there is an explicit // unboxing conversion. if (0 == (flags & CONVERTTYPE.ISEXPLICIT)) { return(false); } if (needsExprDest) { binder.bindSimpleCast(exprSrc, exprTypeDest, out exprDest, EXPRFLAG.EXF_UNBOX); } return(true); } int cnubDst; int cnubSrc; CType typeDstBase = nubDst.StripNubs(out cnubDst); EXPRCLASS exprTypeDstBase = GetExprFactory().MakeClass(typeDstBase); CType typeSrcBase = typeSrc.StripNubs(out cnubSrc); ConversionFunc pfn = (flags & CONVERTTYPE.ISEXPLICIT) != 0 ? (ConversionFunc)binder.BindExplicitConversion : (ConversionFunc)binder.BindImplicitConversion; if (cnubSrc == 0) { Debug.Assert(typeSrc == typeSrcBase); // The null type can be implicitly converted to T? as the default value. if (typeSrc.IsNullType()) { // If we have the constant null, generate it as a default value of T?. If we have // some crazy expression which has been determined to be always null, like (null??null) // keep it in its expression form and transform it in the nullable rewrite pass. if (needsExprDest) { if (exprSrc.isCONSTANT_OK()) { exprDest = GetExprFactory().CreateZeroInit(nubDst); } else { exprDest = GetExprFactory().CreateCast(0x00, typeDest, exprSrc); } } return(true); } EXPR exprTmp = exprSrc; // If there is an implicit/explicit S => T then there is an implicit/explicit S => T? if (typeSrc == typeDstBase || pfn(exprSrc, typeSrc, exprTypeDstBase, nubDst, needsExprDest, out exprTmp, flags | CONVERTTYPE.NOUDC)) { if (needsExprDest) { // UNDONE: This is a premature realization of the nullable conversion as // UNDONE: a constructor. Rather than flagging this, can we simply emit it // UNDONE: as a cast node and have the operator rewrite pass turn it into // UNDONE: a constructor call? EXPRUSERDEFINEDCONVERSION exprUDC = exprTmp.kind == ExpressionKind.EK_USERDEFINEDCONVERSION ? exprTmp.asUSERDEFINEDCONVERSION() : null; if (exprUDC != null) { exprTmp = exprUDC.UserDefinedCall; } // This logic is left over from the days when T?? was legal. However there are error/LAF cases that necessitates the loop. // typeSrc is not nullable so just wrap the required number of times. For legal code (cnubDst <= 0). for (int i = 0; i < cnubDst; i++) { exprTmp = binder.BindNubNew(exprTmp); exprTmp.asCALL().nubLiftKind = NullableCallLiftKind.NullableConversionConstructor; } if (exprUDC != null) { exprUDC.UserDefinedCall = exprTmp; exprUDC.setType((CType)exprTmp.type); exprTmp = exprUDC; } Debug.Assert(exprTmp.type == nubDst); exprDest = exprTmp; } return(true); } // No builtin conversion. Maybe there is a user defined conversion.... return(0 == (flags & CONVERTTYPE.NOUDC) && binder.bindUserDefinedConversion(exprSrc, typeSrc, nubDst, needsExprDest, out exprDest, 0 == (flags & CONVERTTYPE.ISEXPLICIT))); } // Both are Nullable so there is only a conversion if there is a conversion between the base types. // That is, if there is an implicit/explicit S => T then there is an implicit/explicit S?+ => T?+. if (typeSrcBase != typeDstBase && !pfn(null, typeSrcBase, exprTypeDstBase, nubDst, false, out exprDest, flags | CONVERTTYPE.NOUDC)) { // No builtin conversion. Maybe there is a user defined conversion.... return(0 == (flags & CONVERTTYPE.NOUDC) && binder.bindUserDefinedConversion(exprSrc, typeSrc, nubDst, needsExprDest, out exprDest, 0 == (flags & CONVERTTYPE.ISEXPLICIT))); } if (needsExprDest) { MethWithInst mwi = new MethWithInst(null, null); EXPRMEMGRP pMemGroup = GetExprFactory().CreateMemGroup(null, mwi); EXPRCALL exprDst = GetExprFactory().CreateCall(0, nubDst, exprSrc, pMemGroup, null); // Here we want to first check whether or not the conversions work on the base types. EXPR arg1 = binder.mustCast(exprSrc, typeSrcBase); EXPRCLASS arg2 = GetExprFactory().MakeClass(typeDstBase); bool convertible; if (0 != (flags & CONVERTTYPE.ISEXPLICIT)) { convertible = binder.BindExplicitConversion(arg1, arg1.type, arg2, typeDstBase, out arg1, flags | CONVERTTYPE.NOUDC); } else { convertible = binder.BindImplicitConversion(arg1, arg1.type, arg2, typeDstBase, out arg1, flags | CONVERTTYPE.NOUDC); } if (!convertible) { VSFAIL("bind(Im|Ex)plicitConversion failed unexpectedly"); return(false); } exprDst.castOfNonLiftedResultToLiftedType = binder.mustCast(arg1, nubDst, 0); exprDst.nubLiftKind = NullableCallLiftKind.NullableConversion; exprDst.pConversions = exprDst.castOfNonLiftedResultToLiftedType; exprDest = exprDst; } return(true); }
///////////////////////////////////////////////////////////////////////////////// private ExpressionEXPR GenerateInvoke(EXPRCALL pExpr) { EXPRLIST list = pExpr.asCALL().GetOptionalArguments().asLIST(); return new ExpressionEXPR(Expression.Invoke( GetExpression(list.GetOptionalElement()), GetArgumentsFromArrayInit(list.GetOptionalNextListNode().asARRINIT()))); }
protected virtual EXPR GenerateDelegateInvoke(EXPRCALL expr) { Debug.Assert(expr != null); EXPRMEMGRP memberGroup = expr.GetMemberGroup(); Debug.Assert(memberGroup.isDelegate()); EXPR oldObject = memberGroup.GetOptionalObject(); Debug.Assert(oldObject != null); EXPR pObject = Visit(oldObject); EXPR args = GenerateArgsList(expr.GetOptionalArguments()); EXPR Params = GenerateParamsArray(args, PredefinedType.PT_EXPRESSION); return GenerateCall(PREDEFMETH.PM_EXPRESSION_INVOKE, pObject, Params); }
///////////////////////////////////////////////////////////////////////////////// private ExpressionEXPR GenerateNew(EXPRCALL pExpr) { EXPRLIST list = pExpr.asCALL().GetOptionalArguments().asLIST(); var constructor = GetConstructorInfoFromExpr(list.GetOptionalElement().asMETHODINFO()); var arguments = GetArgumentsFromArrayInit(list.GetOptionalNextListNode().asARRINIT()); return new ExpressionEXPR(Expression.New(constructor, arguments)); }
protected virtual EXPR GenerateDelegateConstructor(EXPRCALL expr) { // In: // // new DELEGATE(obj, &FUNC) // // Out: // // Cast( // Call( // null, // (MethodInfo)GetMethodFromHandle(&CreateDelegate), // new Expression[3]{ // Constant(typeof(DELEGATE)), // transformed-object, // Constant((MethodInfo)GetMethodFromHandle(&FUNC)}), // typeof(DELEGATE)) // Debug.Assert(expr != null); Debug.Assert(expr.mwi.Meth().IsConstructor()); Debug.Assert(expr.type.isDelegateType()); Debug.Assert(expr.GetOptionalArguments() != null); Debug.Assert(expr.GetOptionalArguments().isLIST()); EXPRLIST origArgs = expr.GetOptionalArguments().asLIST(); EXPR target = origArgs.GetOptionalElement(); Debug.Assert(origArgs.GetOptionalNextListNode().kind == ExpressionKind.EK_FUNCPTR); EXPRFUNCPTR funcptr = origArgs.GetOptionalNextListNode().asFUNCPTR(); MethodSymbol createDelegateMethod = GetPreDefMethod(PREDEFMETH.PM_METHODINFO_CREATEDELEGATE_TYPE_OBJECT); AggregateType delegateType = GetSymbolLoader().GetOptPredefTypeErr(PredefinedType.PT_DELEGATE, true); MethWithInst mwi = new MethWithInst(createDelegateMethod, delegateType); EXPR instance = GenerateConstant(GetExprFactory().CreateMethodInfo(funcptr.mwi)); EXPR methinfo = GetExprFactory().CreateMethodInfo(mwi); EXPR param1 = GenerateConstant(CreateTypeOf(expr.type)); EXPR param2 = Visit(target); EXPR paramsList = GetExprFactory().CreateList(param1, param2); EXPR Params = GenerateParamsArray(paramsList, PredefinedType.PT_EXPRESSION); EXPR call = GenerateCall(PREDEFMETH.PM_EXPRESSION_CALL, instance, methinfo, Params); EXPR pTypeOf = CreateTypeOf(expr.type); return GenerateCall(PREDEFMETH.PM_EXPRESSION_CONVERT, call, pTypeOf); }
///////////////////////////////////////////////////////////////////////////////// private ExpressionEXPR GenerateConstantType(EXPRCALL pExpr) { EXPRLIST list = pExpr.GetOptionalArguments().asLIST(); return new ExpressionEXPR( Expression.Constant( GetObject(list.GetOptionalElement()), list.GetOptionalNextListNode().asTYPEOF().SourceType.type.AssociatedSystemType)); }