| 16473 | } |
| 16474 | |
| 16475 | void BfModule::CheckVariableDef(BfLocalVariable* variableDef) |
| 16476 | { |
| 16477 | if (variableDef->mName.IsEmpty()) |
| 16478 | return; |
| 16479 | |
| 16480 | BfLocalVarEntry* localVarEntryPtr = NULL; |
| 16481 | if ((mCurMethodState != NULL) && (mCurMethodState->mLocalVarSet.TryGet(BfLocalVarEntry(variableDef), &localVarEntryPtr))) |
| 16482 | { |
| 16483 | auto checkLocal = localVarEntryPtr->mLocalVar; |
| 16484 | if ((checkLocal->mLocalVarIdx >= mCurMethodState->GetLocalStartIdx()) && (!checkLocal->mIsShadow)) |
| 16485 | { |
| 16486 | auto _Fail = [&](int warningNum, String str, BfAstNode* refNode) |
| 16487 | { |
| 16488 | BfError* error = Warn(warningNum, str, refNode); |
| 16489 | if ((checkLocal->mNameNode != NULL) && (error != NULL)) |
| 16490 | mCompiler->mPassInstance->MoreInfo("Previous declaration", checkLocal->mNameNode); |
| 16491 | }; |
| 16492 | |
| 16493 | auto checkScope = mCurMethodState->mCurScope; |
| 16494 | if (checkScope->mScopeKind == BfScopeKind_StatementTarget) |
| 16495 | checkScope = checkScope->mPrevScope; |
| 16496 | |
| 16497 | if (checkLocal->mIsImplicitParam) |
| 16498 | return; // Ignore 'redefinition' |
| 16499 | if (checkLocal->IsParam()) |
| 16500 | { |
| 16501 | if (variableDef->IsParam()) |
| 16502 | _Fail(4200, StrFormat("A parameter named '%s' has already been declared", variableDef->mName.c_str()), variableDef->mNameNode); |
| 16503 | else |
| 16504 | _Fail(4200, StrFormat("The name '%s' is already used by a parameter. Consider declaring 'var %s;' if you wish to make a mutable copy of that parameter.", variableDef->mName.c_str(), variableDef->mName.c_str()), variableDef->mNameNode); |
| 16505 | } |
| 16506 | else if (checkLocal->mLocalVarIdx < checkScope->mLocalVarStart) |
| 16507 | _Fail(4200, StrFormat("A variable named '%s' has already been declared in an outer scope", variableDef->mName.c_str()), variableDef->mNameNode); |
| 16508 | else |
| 16509 | _Fail(4200, StrFormat("A variable named '%s' has already been declared in this scope", variableDef->mName.c_str()), variableDef->mNameNode); |
| 16510 | return; |
| 16511 | } |
| 16512 | } |
| 16513 | } |
| 16514 | |
| 16515 | BfScopeData* BfModule::FindScope(BfAstNode* scopeName, BfMixinState* fromMixinState, bool allowAcrossDeferredBlock) |
| 16516 | { |
no test coverage detected