#include "BfDeferEvalChecker.h" USING_NS_BF; BfDeferEvalChecker::BfDeferEvalChecker() { mNeedsDeferEval = false; } void BfDeferEvalChecker::Visit(BfAstNode* attribExpr) { mNeedsDeferEval = false; } void BfDeferEvalChecker::Visit(BfLiteralExpression* literalExpr) { switch (literalExpr->mValue.mTypeCode) { case BfTypeCode_Boolean: case BfTypeCode_Char8: case BfTypeCode_Int8: case BfTypeCode_UInt8: case BfTypeCode_Int16: case BfTypeCode_UInt16: case BfTypeCode_Int32: case BfTypeCode_UInt32: case BfTypeCode_Int64: case BfTypeCode_UInt64: case BfTypeCode_IntPtr: case BfTypeCode_UIntPtr: case BfTypeCode_IntUnknown: case BfTypeCode_UIntUnknown: mNeedsDeferEval = true; break; default: mNeedsDeferEval = false; } } void BfDeferEvalChecker::Visit(BfCastExpression* castExpr) { if (auto namedTypeRef = BfNodeDynCastExact(castExpr->mTypeRef)) { if (namedTypeRef->ToString() == "ExpectedType") { mNeedsDeferEval = true; } } else if (auto dotTypeRef = BfNodeDynCastExact(castExpr->mTypeRef)) { mNeedsDeferEval = true; } } void BfDeferEvalChecker::Visit(BfParenthesizedExpression* parenExpr) { VisitChild(parenExpr->mExpression); } void BfDeferEvalChecker::Visit(BfTupleExpression* tupleExpr) { bool needDeferEval = false; for (auto element : tupleExpr->mValues) { VisitChild(element); needDeferEval |= mNeedsDeferEval; } mNeedsDeferEval = needDeferEval; } void BfDeferEvalChecker::Visit(BfMemberReferenceExpression* memberRefExpr) { // Dotted name? mNeedsDeferEval = (memberRefExpr->mTarget == NULL); } void BfDeferEvalChecker::Visit(BfInvocationExpression* invocationExpr) { VisitChild(invocationExpr->mTarget); } void BfDeferEvalChecker::Visit(BfConditionalExpression* condExpr) { VisitChild(condExpr->mTrueExpression); bool prev = mNeedsDeferEval; VisitChild(condExpr->mFalseExpression); mNeedsDeferEval |= prev; } void BfDeferEvalChecker::Visit(BfUnaryOperatorExpression* unaryOpExpr) { switch (unaryOpExpr->mOp) { case BfUnaryOp_Negate: case BfUnaryOp_Positive: case BfUnaryOp_InvertBits: VisitChild(unaryOpExpr->mExpression); break; // case BfUnaryOp_Params: // mNeedsDeferEval = true; // break; default: mNeedsDeferEval = false; } } void BfDeferEvalChecker::Visit(BfObjectCreateExpression * objCreateExpr) { if (objCreateExpr->mTypeRef != NULL) { if (objCreateExpr->mTypeRef->IsExact()) mNeedsDeferEval = true; } } void BfDeferEvalChecker::Visit(BfBinaryOperatorExpression* binOpExpr) { switch (binOpExpr->mOp) { case BfBinaryOp_Add: case BfBinaryOp_Subtract: case BfBinaryOp_Multiply: case BfBinaryOp_Divide: case BfBinaryOp_Modulus: case BfBinaryOp_BitwiseAnd: case BfBinaryOp_BitwiseOr: case BfBinaryOp_ExclusiveOr: case BfBinaryOp_LeftShift: case BfBinaryOp_RightShift: case BfBinaryOp_GreaterThan: case BfBinaryOp_LessThan: case BfBinaryOp_GreaterThanOrEqual: case BfBinaryOp_LessThanOrEqual: { VisitChild(binOpExpr->mLeft); bool prev = mNeedsDeferEval; VisitChild(binOpExpr->mRight); mNeedsDeferEval |= prev; } break; default: mNeedsDeferEval = false; } } void BfDeferEvalChecker::Visit(BfDefaultExpression* defaultExpr) { if (defaultExpr->mTypeRef == NULL) mNeedsDeferEval = true; }