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:
parent
f83875e8ad
commit
980fc63b74
2 changed files with 31 additions and 31 deletions
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue