diff --git a/BeefLibs/Beefy2D/src/widgets/TabbedView.bf b/BeefLibs/Beefy2D/src/widgets/TabbedView.bf index 540a34ab..84904080 100644 --- a/BeefLibs/Beefy2D/src/widgets/TabbedView.bf +++ b/BeefLibs/Beefy2D/src/widgets/TabbedView.bf @@ -26,7 +26,6 @@ namespace Beefy.widgets public DragHelper mDragHelper ~ delete _; public Event mCloseClickedEvent ~ _.Dispose(); - delegate void Hey(); public float mWantWidth; public WidgetWindow mMouseDownWindow; diff --git a/IDE/Tests/CompileFail001/src/LocalVars.bf b/IDE/Tests/CompileFail001/src/LocalVars.bf index 07713fdd..707d2b2f 100644 --- a/IDE/Tests/CompileFail001/src/LocalVars.bf +++ b/IDE/Tests/CompileFail001/src/LocalVars.bf @@ -27,12 +27,19 @@ namespace IDETest b = a; } - public void For1(out int a) //FAIL + public void For1(out int a) { for (int b < 2) a = 9; } + public void For2(out int a) //FAIL + { + int b = 123; + for (int c < b) + a = 9; + } + public void Do1(out int a) //FAIL { int b = 123; diff --git a/IDE/src/IDEApp.bf b/IDE/src/IDEApp.bf index f421320b..84bfa0f4 100644 --- a/IDE/src/IDEApp.bf +++ b/IDE/src/IDEApp.bf @@ -9363,7 +9363,7 @@ namespace IDE { if (mBuildContext != null) { - if (mBuildContext.mScriptContext.mVars.TryGetValue(varName, var value)) + if (mBuildContext.mScriptContext.mVars.TryGetValue(varName, out value)) { if (value.VariantType == typeof(String)) { diff --git a/IDE/src/ScriptManager.bf b/IDE/src/ScriptManager.bf index 05df0640..23838d45 100644 --- a/IDE/src/ScriptManager.bf +++ b/IDE/src/ScriptManager.bf @@ -2447,7 +2447,7 @@ namespace IDE if (hasError) mScriptManager.Fail("Unexpected error at line {0} in {1}\n\t", lineIdx + 1, textPanel.mFilePath); else - mScriptManager.Fail("Expected error at line {0} in {1} but didn't encounter one\n\t", lineIdx + 1, textPanel.mFilePath); + mScriptManager.Fail("Expected error but didn't encounter one at line {0} in {1}\n\t", lineIdx + 1, textPanel.mFilePath); return; } } diff --git a/IDE/src/ui/BreakpointPanel.bf b/IDE/src/ui/BreakpointPanel.bf index 7630fe3c..63ab3a9b 100644 --- a/IDE/src/ui/BreakpointPanel.bf +++ b/IDE/src/ui/BreakpointPanel.bf @@ -475,6 +475,8 @@ namespace IDE.ui { if (val.StartsWith("!", StringComparison.Ordinal)) { + addr = 0; + byteCount = 0; String errorString = scope String(); DebugManager.GetFailString(val, evalStr, errorString); IDEApp.sApp.Fail(errorString); diff --git a/IDE/src/ui/SourceEditWidgetContent.bf b/IDE/src/ui/SourceEditWidgetContent.bf index 88af7db7..782a8b23 100644 --- a/IDE/src/ui/SourceEditWidgetContent.bf +++ b/IDE/src/ui/SourceEditWidgetContent.bf @@ -2447,7 +2447,7 @@ namespace IDE.ui if (stmtEndChar == '{') offsetLinePos++; } - else if (GetStatementRange(toLineStart, .AllowInnerMethodSelect, var stmtStartIdx, var stmtEndIdx, var stmtEndChar) == .Declaration) + else if (GetStatementRange(toLineStart, .AllowInnerMethodSelect, out stmtStartIdx, out stmtEndIdx, out stmtEndChar) == .Declaration) { if (stmtEndIdx <= toLineEnd) { diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 2895efa6..f0780129 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -254,7 +254,7 @@ void BfMethodState::LocalDefined(BfLocalVariable* localVar, int fieldIdx, BfLoca if (assignKind == BfLocalVarAssignKind_None) assignKind = ((deferredLocalAssignData != NULL) && (deferredLocalAssignData->mLeftBlock)) ? BfLocalVarAssignKind_Conditional : BfLocalVarAssignKind_Unconditional; - if (localVar->mAssignedKind == assignKind) + if (localVar->mAssignedKind >= assignKind) { // Leave it alone } @@ -262,11 +262,7 @@ void BfMethodState::LocalDefined(BfLocalVariable* localVar, int fieldIdx, BfLoca { if (fieldIdx >= 0) { - localVar->mUnassignedFieldFlags &= ~((int64)1 << fieldIdx); - /*if ((localVar->mResolvedTypeRef != NULL) && (localVar->mResolvedTypeRef->IsUnion())) - { - - }*/ + localVar->mUnassignedFieldFlags &= ~((int64)1 << fieldIdx); if (localVar->mUnassignedFieldFlags == 0) { if (localVar->mAssignedKind == BfLocalVarAssignKind_None) @@ -274,7 +270,7 @@ void BfMethodState::LocalDefined(BfLocalVariable* localVar, int fieldIdx, BfLoca } } else - { + { localVar->mAssignedKind = assignKind; } } @@ -282,16 +278,14 @@ void BfMethodState::LocalDefined(BfLocalVariable* localVar, int fieldIdx, BfLoca { BF_ASSERT(deferredLocalAssignData->mVarIdBarrier != -1); - BfAssignedLocal defineVal = {localVar, fieldIdx, assignKind}; - auto& assignedLocals = deferredLocalAssignData->mAssignedLocals; - if (!assignedLocals.Contains(defineVal)) - assignedLocals.push_back(defineVal); + BfAssignedLocal defineVal = {localVar, fieldIdx, assignKind}; + if (!deferredLocalAssignData->Contains(defineVal)) + deferredLocalAssignData->mAssignedLocals.push_back(defineVal); if (ifDeferredLocalAssignData != NULL) { - auto& assignedLocals = ifDeferredLocalAssignData->mAssignedLocals; - if (!assignedLocals.Contains(defineVal)) - assignedLocals.push_back(defineVal); + if (!ifDeferredLocalAssignData->Contains(defineVal)) + ifDeferredLocalAssignData->mAssignedLocals.push_back(defineVal); } } } @@ -13894,9 +13888,7 @@ void BfModule::MarkScopeLeft(BfScopeData* scopeData) if ((deferredLocalAssignData->mScopeData != NULL) && (deferredLocalAssignData->mScopeData->mScopeDepth == scopeData->mScopeDepth)) deferredLocalAssignData->mIsUnconditional = false; deferredLocalAssignData = deferredLocalAssignData->mChainedAssignData; - } - - + } } // When we leave a scope, mark those as assigned for deferred assignment purposes @@ -13913,8 +13905,10 @@ void BfModule::MarkScopeLeft(BfScopeData* scopeData) hadAssignment = true; } if (!hadAssignment) + { localDef->mHadExitBeforeAssign = true; - mCurMethodState->LocalDefined(localDef); + mCurMethodState->LocalDefined(localDef); + } } } } diff --git a/IDEHelper/Compiler/BfModule.h b/IDEHelper/Compiler/BfModule.h index e7931f9c..d581545f 100644 --- a/IDEHelper/Compiler/BfModule.h +++ b/IDEHelper/Compiler/BfModule.h @@ -350,6 +350,17 @@ public: mLeftBlock = false; } + bool Contains(const BfAssignedLocal& val) + { + for (int i = 0; i < (int)mAssignedLocals.mSize; i++) + { + auto& check = mAssignedLocals[i]; + if ((check.mLocalVar == val.mLocalVar) && (check.mLocalVarField == val.mLocalVarField) && (check.mAssignKind >= val.mAssignKind)) + return true; + } + return false; + } + void ExtendFrom(BfDeferredLocalAssignData* outerLocalAssignData, bool doChain = false); void BreakExtendChain(); void SetIntersection(const BfDeferredLocalAssignData& otherLocalAssignData); diff --git a/IDEHelper/Compiler/BfStmtEvaluator.cpp b/IDEHelper/Compiler/BfStmtEvaluator.cpp index 7520179b..b51038b7 100644 --- a/IDEHelper/Compiler/BfStmtEvaluator.cpp +++ b/IDEHelper/Compiler/BfStmtEvaluator.cpp @@ -5662,13 +5662,7 @@ void BfModule::DoForLess(BfForEachStatement* forEachStmt) auto isLet = BfNodeDynCast(forEachStmt->mVariableTypeRef) != 0; auto isVar = BfNodeDynCast(forEachStmt->mVariableTypeRef) != 0; - - BfDeferredLocalAssignData deferredLocalAssignData(mCurMethodState->mCurScope); - deferredLocalAssignData.mIsIfCondition = true; - deferredLocalAssignData.ExtendFrom(mCurMethodState->mDeferredLocalAssignData, true); - deferredLocalAssignData.mVarIdBarrier = mCurMethodState->GetRootMethodState()->mCurLocalVarId; - SetAndRestoreValue prevDLA(mCurMethodState->mDeferredLocalAssignData, &deferredLocalAssignData); - + BfTypedValue target; BfType* varType = NULL; bool didInference = false; @@ -5695,6 +5689,13 @@ void BfModule::DoForLess(BfForEachStatement* forEachStmt) if (varType == NULL) varType = GetPrimitiveType(BfTypeCode_IntPtr); + + BfDeferredLocalAssignData deferredLocalAssignData(mCurMethodState->mCurScope); + deferredLocalAssignData.mIsIfCondition = true; + deferredLocalAssignData.ExtendFrom(mCurMethodState->mDeferredLocalAssignData, true); + deferredLocalAssignData.mVarIdBarrier = mCurMethodState->GetRootMethodState()->mCurLocalVarId; + SetAndRestoreValue prevDLA(mCurMethodState->mDeferredLocalAssignData, &deferredLocalAssignData); + deferredLocalAssignData.mIsIfCondition = false; // The "extend chain" is only valid for the conditional -- since that expression may contain unconditionally executed and @@ -5813,6 +5814,18 @@ void BfModule::DoForLess(BfForEachStatement* forEachStmt) mCurMethodState->SetHadReturn(false); mCurMethodState->mLeftBlockUncond = false; mCurMethodState->mLeftBlockCond = false; + + bool definitelyExecuted = false; + if (target.mValue.IsConst()) + { + auto constant = mBfIRBuilder->GetConstant(target.mValue); + if (constant->mInt32 > 0) + definitelyExecuted = true; + } + + prevDLA.Restore(); + if (definitelyExecuted) + mCurMethodState->ApplyDeferredLocalAssignData(deferredLocalAssignData); RestoreScopeState(); }