diff --git a/IDEHelper/Compiler/BfReducer.cpp b/IDEHelper/Compiler/BfReducer.cpp index a86c1a68..8b041e40 100644 --- a/IDEHelper/Compiler/BfReducer.cpp +++ b/IDEHelper/Compiler/BfReducer.cpp @@ -4451,8 +4451,15 @@ BfAstNode* BfReducer::CreateStatement(BfAstNode* node, CreateStmtFlags createStm { if (!IsSemicolon(nextNode)) { + bool doWarn = false; + // Why did we have this BfIdentifierNode check? It failed to throw an error on just things like "{ a }" - if (/*(origStmtNode->IsA()) || */(origStmtNode->IsA()) || (origStmtNode->IsA())) + if (origStmtNode->IsA()) + { + // These do require a semicolon + doWarn = true; + } + else if (/*(origStmtNode->IsA()) || */(origStmtNode->IsA()) || (origStmtNode->IsA())) return stmt; if (origStmtNode->IsA()) { @@ -4465,7 +4472,12 @@ BfAstNode* BfReducer::CreateStatement(BfAstNode* node, CreateStmtFlags createStm if (((createStmtFlags & CreateStmtFlags_AllowUnterminatedExpression) != 0) && (origStmtNode->IsA()) && (nextNode == NULL)) return stmt; - auto error = mPassInstance->FailAfterAt("Semicolon expected", node->GetSourceData(), stmt->GetSrcEnd() - 1); + BfError* error; + if (doWarn) + error = mPassInstance->WarnAfterAt(0, "Semicolon expected", node->GetSourceData(), stmt->GetSrcEnd() - 1); + else + error = mPassInstance->FailAfterAt("Semicolon expected", node->GetSourceData(), stmt->GetSrcEnd() - 1); + if ((error != NULL) && (mSource != NULL)) error->mProject = mSource->mProject; mPrevStmtHadError = true; diff --git a/IDEHelper/Compiler/BfSystem.cpp b/IDEHelper/Compiler/BfSystem.cpp index 6b8b370f..137e4a70 100644 --- a/IDEHelper/Compiler/BfSystem.cpp +++ b/IDEHelper/Compiler/BfSystem.cpp @@ -1701,6 +1701,48 @@ BfError* BfPassInstance::WarnAfter(int warningNumber, const StringImpl& warning, return WarnAt(warningNumber, warning, refNode->GetSourceData(), refNode->GetSrcEnd()); } +BfError* BfPassInstance::WarnAfterAt(int warningNumber, const StringImpl& error, BfSourceData* bfSource, int srcIdx) +{ + BP_ZONE("BfPassInstance::FailAfterAt"); + + mFailedIdx++; + if ((int)mErrors.size() >= sMaxErrors) + return NULL; + + auto bfParser = bfSource->ToParserData(); + if ((bfParser != NULL) && (warningNumber > 0) && (!bfParser->IsWarningEnabledAtSrcIndex(warningNumber, srcIdx))) + return NULL; + + if (!WantsRangeRecorded(bfParser, srcIdx, 1, false)) + return NULL; + + // Go to start of UTF8 chunk +// int startIdx = srcIdx; +// int spanLenth = 0; +// UTF8GetGraphemeClusterSpan(bfParser->mSrc, bfParser->mOrigSrcLength, srcIdx, startIdx, spanLenth); + + BfError* errorVal = new BfError(); + errorVal->mIsWarning = true; + errorVal->SetSource(this, bfSource); + errorVal->mIsAfter = true; + errorVal->mError = error; + errorVal->mSrcStart = srcIdx; + errorVal->mSrcEnd = srcIdx + 1; + FixSrcStartAndEnd(bfSource, errorVal->mSrcStart, errorVal->mSrcEnd); + mErrorSet.Add(BfErrorEntry(errorVal)); + mErrors.push_back(errorVal); + + mLastWasDisplayed = WantsRangeDisplayed(bfParser, srcIdx - 1, 2, false); + if (mLastWasDisplayed) + { + String errorStart = "WARNING"; + /*if ((int)mErrors.size() > 1) + errorStart += StrFormat(" #%d", mErrors.size());*/ + MessageAt(":warn", errorStart + ": " + error, bfParser, srcIdx + 1, 1); + } + return errorVal; +} + BfMoreInfo* BfPassInstance::MoreInfoAt(const StringImpl& info, BfSourceData* bfSource, int srcIdx, int srcLen, BfFailFlags flags) { if (!mLastWasDisplayed) diff --git a/IDEHelper/Compiler/BfSystem.h b/IDEHelper/Compiler/BfSystem.h index cec7a07d..f9df4b42 100644 --- a/IDEHelper/Compiler/BfSystem.h +++ b/IDEHelper/Compiler/BfSystem.h @@ -1375,6 +1375,7 @@ public: BfError* Warn(int warningNumber, const StringImpl& warning); BfError* Warn(int warningNumber, const StringImpl& warning, BfAstNode* refNode); BfError* WarnAfter(int warningNumber, const StringImpl& warning, BfAstNode* refNode); + BfError* WarnAfterAt(int warningNumber, const StringImpl& error, BfSourceData* bfSource, int srcIdx); BfMoreInfo* MoreInfoAt(const StringImpl& info, BfSourceData* bfSource, int srcIdx, int srcLen, BfFailFlags flags = BfFailFlag_None); BfMoreInfo* MoreInfo(const StringImpl& info, bool forceQueue = false);