1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-10 04:22:20 +02:00

Additional if variable restrictions

This commit is contained in:
Brian Fiete 2020-09-25 05:36:58 -07:00
parent f83875e8ad
commit 980fc63b74
2 changed files with 31 additions and 31 deletions

View file

@ -1409,6 +1409,11 @@ public:
{ {
return (srcPos >= mSrcStart + startAdd) && (srcPos < mSrcEnd + lenAdd); return (srcPos >= mSrcStart + startAdd) && (srcPos < mSrcEnd + lenAdd);
} }
bool Contains(BfAstNode* node)
{
return (node->mSrcStart >= mSrcStart) && (node->mSrcEnd <= mSrcEnd);
}
#endif #endif

View file

@ -2702,6 +2702,7 @@ void BfExprEvaluator::Visit(BfBlock* blockExpr)
bool BfExprEvaluator::CheckVariableDeclaration(BfAstNode* checkNode, bool requireSimpleIfExpr, bool exprMustBeTrue, bool silentFail) bool BfExprEvaluator::CheckVariableDeclaration(BfAstNode* checkNode, bool requireSimpleIfExpr, bool exprMustBeTrue, bool silentFail)
{ {
BfAstNode* checkChild = checkNode; BfAstNode* checkChild = checkNode;
bool childWasAndRHS = false;
bool foundIf = false; bool foundIf = false;
auto parentNodeEntry = mModule->mParentNodeEntry; auto parentNodeEntry = mModule->mParentNodeEntry;
@ -2712,7 +2713,20 @@ bool BfExprEvaluator::CheckVariableDeclaration(BfAstNode* checkNode, bool requir
checkChild = parentNodeEntry->mNode; checkChild = parentNodeEntry->mNode;
parentNodeEntry = parentNodeEntry->mPrev; parentNodeEntry = parentNodeEntry->mPrev;
} }
} }
auto _Fail = [&](const StringImpl& errorStr, BfAstNode* node)
{
if (!silentFail)
{
auto error = mModule->Fail(errorStr, node);
if ((error != NULL) && (node != checkNode))
{
mModule->mCompiler->mPassInstance->MoreInfo("See variable declaration", checkNode);
}
}
return false;
};
while (parentNodeEntry != NULL) while (parentNodeEntry != NULL)
{ {
@ -2723,41 +2737,20 @@ bool BfExprEvaluator::CheckVariableDeclaration(BfAstNode* checkNode, bool requir
if (binOpExpr->mOp == BfBinaryOp_ConditionalAnd) if (binOpExpr->mOp == BfBinaryOp_ConditionalAnd)
{ {
// This is always okay // This is always okay
childWasAndRHS = (binOpExpr->mRight != NULL) && (binOpExpr->mRight->Contains(checkChild));
} }
else if ((binOpExpr->mOp == BfBinaryOp_ConditionalOr) && (!exprMustBeTrue)) else if ((binOpExpr->mOp == BfBinaryOp_ConditionalOr) && (!exprMustBeTrue))
{ {
bool matches = false; if ((binOpExpr->mRight != NULL) & (binOpExpr->mRight->Contains(checkChild)))
auto checkRight = binOpExpr->mRight;
while (checkRight != NULL)
{ {
if (checkRight == checkChild) return _Fail("Conditional short-circuiting may skip variable initialization", binOpExpr->mOpToken);
{
matches = true;
break;
}
if (auto parenExpr = BfNodeDynCast<BfParenthesizedExpression>(checkRight))
checkRight = parenExpr->mExpression;
else
{
break;
}
}
if (matches)
{
if (!silentFail)
mModule->Fail("Conditional short-circuiting may skip variable initialization", binOpExpr->mOpToken);
return false;
} }
} }
else else
{ {
if (exprMustBeTrue) if (exprMustBeTrue)
{ {
if (!silentFail) return _Fail("Operator cannot be used with variable initialization", binOpExpr->mOpToken);
mModule->Fail("Operator cannot be used with variable initialization", binOpExpr->mOpToken);
return false;
} }
} }
} }
@ -2769,10 +2762,14 @@ bool BfExprEvaluator::CheckVariableDeclaration(BfAstNode* checkNode, bool requir
{ {
if (exprMustBeTrue) if (exprMustBeTrue)
{ {
if (!silentFail) return _Fail("Operator cannot be used with variable initialization", unaryOp->mOpToken);
mModule->Fail("Operator cannot be used with variable initialization", unaryOp->mOpToken);
return false; return false;
} }
if (childWasAndRHS)
{
return _Fail("Operator may allow conditional short-circuiting to skip variable initialization", unaryOp->mOpToken);
}
} }
else if (auto ifStmt = BfNodeDynCast<BfIfStatement>(checkParent)) else if (auto ifStmt = BfNodeDynCast<BfIfStatement>(checkParent))
{ {
@ -2784,9 +2781,7 @@ bool BfExprEvaluator::CheckVariableDeclaration(BfAstNode* checkNode, bool requir
{ {
if (requireSimpleIfExpr) if (requireSimpleIfExpr)
{ {
if (!silentFail) return _Fail("Variable declaration expression can only be contained in simple 'if' expressions", checkNode);
mModule->Fail("Variable declaration expression can only be contained in simple 'if' expressions", checkNode);
return false;
} }
break; break;
} }