diff --git a/BeefySysLib/platform/win/Platform.cpp b/BeefySysLib/platform/win/Platform.cpp index b2bd5ab7..2238d677 100644 --- a/BeefySysLib/platform/win/Platform.cpp +++ b/BeefySysLib/platform/win/Platform.cpp @@ -2193,7 +2193,7 @@ BFP_EXPORT void BFP_CALLTYPE BfpThread_GetIntRegisters(BfpThread* thread, intptr { CONTEXT ctx; memset(&ctx, 0, sizeof(CONTEXT)); - ctx.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS; + ctx.ContextFlags = CONTEXT_INTEGER | CONTEXT_CONTROL; BOOL success = ::GetThreadContext((HANDLE)thread, &ctx); if (!success) { diff --git a/BeefySysLib/util/BeefPerf.cpp b/BeefySysLib/util/BeefPerf.cpp index f0f24075..e972a387 100644 --- a/BeefySysLib/util/BeefPerf.cpp +++ b/BeefySysLib/util/BeefPerf.cpp @@ -34,7 +34,7 @@ typedef fd_set FD_SET; USING_NS_BF; // All DLLs must use the same ABI version -#define BP_ABI_VERSION 2 +#define BP_ABI_VERSION 3 BpManager* BpManager::sBpManager = NULL; static bool gOwnsBpManager = false; @@ -665,6 +665,7 @@ BpManager::BpManager() : mShutdownEvent(true), mTLSDtor(&FlsFreeFunc) mSocket = INVALID_SOCKET; mConnectState = BpConnectState_NotConnected; mThread = NULL; + mThreadId = 0; mCurTick = 0; mCurThreadId = 0; mOutBlockSizeLeft = 0; @@ -890,6 +891,8 @@ void BpManager::FinishWorkThread() void BpManager::ThreadProc() { + BfpThread_SetName(NULL, "BeefPerf", NULL); + if (!Connect()) { mConnectState = BpConnectState_Failed; @@ -1482,7 +1485,7 @@ BpResult BpManager::Init(const char* serverName, const char* sessionName) mRootCmdTarget.Init(); - mThread = BfpThread_Create(ThreadProcThunk, (void*)this, 64 * 1024, BfpThreadCreateFlag_StackSizeReserve); + mThread = BfpThread_Create(ThreadProcThunk, (void*)this, 64 * 1024, BfpThreadCreateFlag_StackSizeReserve, &mThreadId); return BpResult_Ok; } diff --git a/BeefySysLib/util/BeefPerf.h b/BeefySysLib/util/BeefPerf.h index 951c891b..b08f42fc 100644 --- a/BeefySysLib/util/BeefPerf.h +++ b/BeefySysLib/util/BeefPerf.h @@ -195,6 +195,7 @@ public: #endif SOCKET mSocket; BfpThread* mThread; + BfpThreadId mThreadId; String mServerName; String mSessionName; String mSessionID; diff --git a/IDE/src/Compiler/BfParser.bf b/IDE/src/Compiler/BfParser.bf index 297cfff1..7d6e6137 100644 --- a/IDE/src/Compiler/BfParser.bf +++ b/IDE/src/Compiler/BfParser.bf @@ -39,7 +39,7 @@ namespace IDE.Compiler GetFixits, GetTypeDefList, GetTypeDefInto, - GetVarType + GetResultString } public class ResolveParams @@ -62,6 +62,7 @@ namespace IDE.Compiler public int32 mOutLineChar; public String mNavigationData ~ delete _; public String mAutocompleteInfo ~ delete _; + public String mResultString ~ delete _; public WaitEvent mWaitEvent ~ delete _; public BfPassInstance mPassInstance ~ delete _; diff --git a/IDE/src/ui/DisassemblyPanel.bf b/IDE/src/ui/DisassemblyPanel.bf index e60e8909..aa5b0536 100644 --- a/IDE/src/ui/DisassemblyPanel.bf +++ b/IDE/src/ui/DisassemblyPanel.bf @@ -1335,7 +1335,7 @@ namespace IDE.ui else { mHoverWatch = new HoverWatch(); - if (mHoverWatch.Show(this, x, y, debugExpr)) + if (mHoverWatch.Show(this, x, y, debugExpr, debugExpr)) { mHoverWatch.mOpenMousePos = DarkTooltipManager.sLastRelMousePos; mHoverWatch.mEvalString.Set(debugExpr); // Set to old debugStr for comparison diff --git a/IDE/src/ui/HoverWatch.bf b/IDE/src/ui/HoverWatch.bf index 409a1015..2b683f78 100644 --- a/IDE/src/ui/HoverWatch.bf +++ b/IDE/src/ui/HoverWatch.bf @@ -63,7 +63,7 @@ namespace IDE.ui if (mColumnIdx == 0) { var hoverListView = (HoverListView)mListView; - if ((mWatchEntry.mResultType == WatchResultType.TypeClass) || (mWatchEntry.mResultType == WatchResultType.TypeValueType)) + if ((mWatchEntry.mResultType.HasFlag(WatchResultType.TypeClass)) || (mWatchEntry.mResultType.HasFlag(WatchResultType.TypeValueType))) return false; return mouseX < LabelX + hoverListView.mFont.GetWidth(mLabel) + GS!(2); } @@ -226,8 +226,9 @@ namespace IDE.ui } } + public String mDisplayString = new String() ~ delete _; + public String mOrigEvalString = new String() ~ delete _; public String mEvalString = new String() ~ delete _; - public String mOrigEvalString = new String() ~ delete _; public TextPanel mTextPanel; public HoverListView mListView; public Point mOpenMousePos; @@ -1382,7 +1383,7 @@ namespace IDE.ui theEvent.mHandled = true; } - public HoverListViewItem Eval(String evalString, bool isPending) + public HoverListViewItem Eval(String displayString, String evalString, bool isPending) { Debug.Assert(evalString != null); mOrigEvalString.Set(evalString); @@ -1390,7 +1391,7 @@ namespace IDE.ui mListView = CreateListView(); else mListView.GetRoot().Clear(); - return DoListViewItem(mListView, null, evalString, evalString, isPending); + return DoListViewItem(mListView, null, displayString, evalString, isPending); } public void SetListView(HoverListView listView) @@ -1405,7 +1406,7 @@ namespace IDE.ui Close(); } - public bool Show(TextPanel textPanel, float x, float y, String evalString) + public bool Show(TextPanel textPanel, float x, float y, String displayString, String evalString) { if (mIsShown) Clear(); @@ -1434,6 +1435,11 @@ namespace IDE.ui if (mTextPanel.mHoverWatch != null) Debug.Assert(mTextPanel.mHoverWatch == this); mTextPanel.mHoverWatch = this; + if (displayString == null) + mDisplayString.Clear(); + else + mDisplayString.Set(displayString); + if (evalString == null) mEvalString.Clear(); else @@ -1447,7 +1453,7 @@ namespace IDE.ui if (evalString != null) { - if (Eval(evalString, false).Failed) + if (Eval(displayString, evalString, false).Failed) { if (mListView.mParent != null) mListView.RemoveSelf(); @@ -1529,7 +1535,7 @@ namespace IDE.ui widgetWindow.mRootWidget = null; // Detach root //Debug.WriteLine("Hoverwatch showing"); mClosed = false; - Show(sourceViewPanel, mOrigX, mOrigY, mOrigEvalString); + Show(sourceViewPanel, mOrigX, mOrigY, mDisplayString, mOrigEvalString); sourceViewPanel.mHoverWatch = this; for (int32 listIdx = 0; listIdx < openYList.Count; listIdx++) diff --git a/IDE/src/ui/ImmediateWidget.bf b/IDE/src/ui/ImmediateWidget.bf index 176bb119..0f72e6e3 100644 --- a/IDE/src/ui/ImmediateWidget.bf +++ b/IDE/src/ui/ImmediateWidget.bf @@ -198,7 +198,7 @@ namespace IDE.ui hoverWatch.mAllowSideEffects = true; hoverWatch.mOrigEvalString.Set(mImmediateWidget.mResultHoverWatch.mOrigEvalString); hoverWatch.SetListView(mImmediateWidget.mResultHoverWatch.mListView); - hoverWatch.Show(mImmediateWidget.mPanel, mX + GS!(2), mY + GS!(3), null); + hoverWatch.Show(mImmediateWidget.mPanel, mX + GS!(2), mY + GS!(3), null, null); hoverWatch.mRehupEvent.Add(new () => { mImmediateWidget.RehupResult(); @@ -316,7 +316,7 @@ namespace IDE.ui { // Is a continuation if (mLastEvalString != null) - result = mResultHoverWatch.Eval(mLastEvalString, true); + result = mResultHoverWatch.Eval(mLastEvalString, mLastEvalString, true); gApp.mIsImmediateDebugExprEval = true; } else @@ -341,7 +341,7 @@ namespace IDE.ui gApp.mScriptManager.QueueCommands(StringView(cmdText, 1), "Immediate", .NoLines | .NoWait); } else - result = mResultHoverWatch.Eval(cmdText, false); + result = mResultHoverWatch.Eval(cmdText, cmdText, false); mLastTextVersionId = mEditWidgetContent.mData.mCurTextVersionId; gApp.mIsImmediateDebugExprEval = true; } diff --git a/IDE/src/ui/LeakWidget.bf b/IDE/src/ui/LeakWidget.bf index 928ce2ed..6fd99514 100644 --- a/IDE/src/ui/LeakWidget.bf +++ b/IDE/src/ui/LeakWidget.bf @@ -67,7 +67,7 @@ namespace IDE.ui //hoverWatch.SetListView(mImmediateWidget.mResultHoverWatch.mListView); //hoverWatch.Show(mTextPanel, mX + 2, mY + 3, evalStr); hoverWatch.mOpenMousePos = DarkTooltipManager.sLastRelMousePos; - hoverWatch.Show(mOutputPanel, mX, mY, evalStr); + hoverWatch.Show(mOutputPanel, mX, mY, evalStr, evalStr); mOutputPanel.mHoverWatch = hoverWatch; } } diff --git a/IDE/src/ui/SourceViewPanel.bf b/IDE/src/ui/SourceViewPanel.bf index 61641bdb..41098d98 100644 --- a/IDE/src/ui/SourceViewPanel.bf +++ b/IDE/src/ui/SourceViewPanel.bf @@ -1609,9 +1609,9 @@ namespace IDE.ui { resolveParams.mNavigationData = new String(autocompleteInfo); } - else if (resolveType == ResolveType.GetVarType) + else if (resolveType == ResolveType.GetResultString) { - resolveParams.mTypeDef = new String(autocompleteInfo); + resolveParams.mResultString = new String(autocompleteInfo); } else if (resolveType == ResolveType.GetCurrentLocation) { @@ -4819,7 +4819,33 @@ namespace IDE.ui if (debugExpr != null) triedShow = true; - if ((debugExpr == null) || (isOverMessage) || (!mHoverWatch.Show(this, x, y, debugExpr))) + bool didShow = false; + //if ((debugExpr == "var") || (debugExpr == "let")) + + String origDebugExpr = null; + + if ((debugExpr != null) || (isOverMessage)) + { + let resolveParams = scope ResolveParams(); + resolveParams.mOverrideCursorPos = (int32)textIdx; + Classify(ResolveType.GetResultString, resolveParams); + if (!String.IsNullOrEmpty(resolveParams.mResultString)) + { + origDebugExpr = scope:: String(); + origDebugExpr.Set(debugExpr); + + debugExpr.Set(resolveParams.mResultString); + } + + if (!triedShow) + { + mHoverWatch.Show(this, x, y, debugExpr, debugExpr); + triedShow = true; + } + } + + if ((!didShow) && + ((debugExpr == null) || (isOverMessage) || (!mHoverWatch.Show(this, x, y, origDebugExpr ?? debugExpr, debugExpr)))) { #if IDE_C_SUPPORT if ((mIsClang) && (textIdx != -1)) @@ -4918,7 +4944,7 @@ namespace IDE.ui if (showMouseoverString != null) { triedShow = true; - mHoverWatch.Show(this, x, y, showMouseoverString); + mHoverWatch.Show(this, x, y, showMouseoverString, showMouseoverString); if (debugExpr != null) mHoverWatch.mEvalString.Set(debugExpr); // Set to old debugStr for comparison } @@ -4928,25 +4954,6 @@ namespace IDE.ui } if (!hasHoverWatchOpen) mHoverWatch.mOpenMousePos = DarkTooltipManager.sLastRelMousePos; - - if ((debugExpr == "var") || (debugExpr == "let")) - { - let resolveParams = scope ResolveParams(); - resolveParams.mOverrideCursorPos = (int32)textIdx; - Classify(ResolveType.GetVarType, resolveParams); - if (resolveParams.mTypeDef != null) - { - debugExpr.Set(resolveParams.mTypeDef); - if (!debugExpr.IsEmpty) - debugExpr.Insert(0, ":"); - } - - if (!triedShow) - { - mHoverWatch.Show(this, x, y, debugExpr); - triedShow = true; - } - } } // Not used? diff --git a/IDE/src/ui/ThreadPanel.bf b/IDE/src/ui/ThreadPanel.bf index 8046eef0..6df86193 100644 --- a/IDE/src/ui/ThreadPanel.bf +++ b/IDE/src/ui/ThreadPanel.bf @@ -128,7 +128,7 @@ namespace IDE.ui { base.MouseDown(x, y, btn, btnCount); - if (x >= mListView.mParent.mWidth - LabelX - GS!(34)) + if ((x >= mListView.mParent.mWidth - LabelX - GS!(34)) && (mParentItem != null)) { PopupCallStackPanel(); } diff --git a/IDE/src/ui/WatchPanel.bf b/IDE/src/ui/WatchPanel.bf index 92cec606..c089ee88 100644 --- a/IDE/src/ui/WatchPanel.bf +++ b/IDE/src/ui/WatchPanel.bf @@ -16,16 +16,16 @@ namespace IDE.ui { public enum WatchResultType { - None, - Value, - Int, - MM128, - Object, - Pointer, - TypeClass, - TypeValueType, - Namespace, - Text + None = 0, + Value = 1, + Int = 2, + MM128 = 4, + Object = 8, + Pointer = 0x10, + TypeClass = 0x20, + TypeValueType = 0x40, + Namespace = 0x80, + Text = 0x100 } public class WatchEntry @@ -54,6 +54,18 @@ namespace IDE.ui public int32 mSeriesFirstVersion = -1; public int32 mSeriesVersion = -1; + public bool IsConstant + { + get + { + if (mEvalStr.IsEmpty) + return true; + if (mEvalStr[0].IsNumber) + return true; + return false; + } + } + public bool ParseCmd(List cmd) { switch (scope String(cmd[0])) @@ -62,25 +74,25 @@ namespace IDE.ui switch (scope String(cmd[1])) { case "object": - mResultType = WatchResultType.Object; + mResultType |= WatchResultType.Object; return true; case "pointer": - mResultType = WatchResultType.Pointer; + mResultType |= WatchResultType.Pointer; return true; case "class": - mResultType = WatchResultType.TypeClass; + mResultType |= WatchResultType.TypeClass; return true; case "valuetype": - mResultType = WatchResultType.TypeValueType; + mResultType |= WatchResultType.TypeValueType; return true; case "namespace": - mResultType = WatchResultType.Namespace; + mResultType |= WatchResultType.Namespace; return true; case "int": - mResultType = WatchResultType.Int; + mResultType |= WatchResultType.Int; return true; case "mm128": - mResultType = WatchResultType.MM128; + mResultType |= WatchResultType.MM128; return true; } break; @@ -1131,26 +1143,26 @@ namespace IDE.ui { imageIdx = .RedDot; } - else if (mWatchEntry.mResultType == WatchResultType.Object) + else if (mWatchEntry.mResultType.HasFlag(WatchResultType.Object)) { if (mWatchEntry.mIsDeleted) imageIdx = .IconObjectDeleted; else imageIdx = .IconObject; } - else if (mWatchEntry.mResultType == WatchResultType.TypeClass) + else if (mWatchEntry.mResultType.HasFlag(WatchResultType.TypeClass)) { imageIdx = .Type_Class; } - else if (mWatchEntry.mResultType == WatchResultType.TypeValueType) + else if (mWatchEntry.mResultType.HasFlag(WatchResultType.TypeValueType)) { imageIdx = .Type_ValueType; } - else if (mWatchEntry.mResultType == WatchResultType.Namespace) + else if (mWatchEntry.mResultType.HasFlag(WatchResultType.Namespace)) { imageIdx = .Namespace; } - else if (mWatchEntry.mResultType == WatchResultType.Pointer) + else if (mWatchEntry.mResultType.HasFlag(WatchResultType.Pointer)) { imageIdx = .IconPointer; } @@ -2587,9 +2599,9 @@ namespace IDE.ui public static bool AddDisplayTypeMenu(String label, Menu menu, WatchResultType watchResultType, String referenceId, bool includeDefault) { - bool isInt = watchResultType == WatchResultType.Int; - bool isMM128 = watchResultType == WatchResultType.MM128; - bool canSetFormat = isInt || isMM128; + bool hasInt = watchResultType.HasFlag(WatchResultType.Int); + bool hasMM128 = watchResultType.HasFlag(WatchResultType.MM128); + bool canSetFormat = hasInt || hasMM128; var debugger = IDEApp.sApp.mDebugger; DebugManager.IntDisplayType intDisplayType; @@ -2606,7 +2618,7 @@ namespace IDE.ui Menu parentItem = menu.AddItem(label); //anItem.mIconImage = DarkTheme.sDarkTheme.GetImage(DarkTheme.ImageIdx.Check); - if (isInt) + if (hasInt) { for (DebugManager.IntDisplayType i = default; i < DebugManager.IntDisplayType.COUNT; i++) { @@ -2622,8 +2634,9 @@ namespace IDE.ui new () => SetDisplayType(referenceId, toType, mmDisplayType)); } } - else if (isMM128) - { + + if (hasMM128) + { for (DebugManager.MmDisplayType i = default; i < DebugManager.MmDisplayType.COUNT; i++) { var toType = i; @@ -2677,49 +2690,52 @@ namespace IDE.ui if (watchEntry.mReferenceId != null) AddDisplayTypeMenu("Watch Display", menu, listViewItem.mWatchEntry.mResultType, watchEntry.mReferenceId, true); - anItem = menu.AddItem("Break When Value Changes"); - if (watchEntry.mMemoryBreakpointAddr == 0) + if (!watchEntry.IsConstant) { - anItem.mOnMenuItemSelected.Add(new (evt) => - { - String evalStr = scope String(); - CompactChildExpression(listViewItem, evalStr); - evalStr.Insert(0, "&"); - gApp.mBreakpointPanel.CreateMemoryBreakpoint(evalStr); - gApp.MarkDirty(); - }); - } - else - { - anItem.mIconImage = DarkTheme.sDarkTheme.GetImage(.Check); - anItem.mOnMenuItemSelected.Add(new (evt) => - { - for (int breakIdx < gApp.mDebugger.mBreakpointList.Count) + anItem = menu.AddItem("Break When Value Changes"); + if (watchEntry.mMemoryBreakpointAddr == 0) + { + anItem.mOnMenuItemSelected.Add(new (evt) => { - let breakpoint = gApp.mDebugger.mBreakpointList[breakIdx]; - if (breakpoint.mMemoryAddress == watchEntry.mMemoryBreakpointAddr) + String evalStr = scope String(); + CompactChildExpression(listViewItem, evalStr); + evalStr.Insert(0, "&"); + gApp.mBreakpointPanel.CreateMemoryBreakpoint(evalStr); + gApp.MarkDirty(); + }); + } + else + { + anItem.mIconImage = DarkTheme.sDarkTheme.GetImage(.Check); + anItem.mOnMenuItemSelected.Add(new (evt) => + { + for (int breakIdx < gApp.mDebugger.mBreakpointList.Count) { - gApp.mDebugger.DeleteBreakpoint(breakpoint); - gApp.RefreshWatches(); - breakIdx--; + let breakpoint = gApp.mDebugger.mBreakpointList[breakIdx]; + if (breakpoint.mMemoryAddress == watchEntry.mMemoryBreakpointAddr) + { + gApp.mDebugger.DeleteBreakpoint(breakpoint); + gApp.RefreshWatches(); + breakIdx--; + } } - } - }); + }); - let configItem = menu.AddItem("Configure Breakpoint"); - configItem.mOnMenuItemSelected.Add(new (evt) => - { - for (int breakIdx < gApp.mDebugger.mBreakpointList.Count) + let configItem = menu.AddItem("Configure Breakpoint"); + configItem.mOnMenuItemSelected.Add(new (evt) => { - let breakpoint = gApp.mDebugger.mBreakpointList[breakIdx]; - if (breakpoint.mMemoryAddress == watchEntry.mMemoryBreakpointAddr) + for (int breakIdx < gApp.mDebugger.mBreakpointList.Count) { - ConditionDialog dialog = new ConditionDialog(); - dialog.Init(breakpoint); - dialog.PopupWindow(listView.mWidgetWindow); + let breakpoint = gApp.mDebugger.mBreakpointList[breakIdx]; + if (breakpoint.mMemoryAddress == watchEntry.mMemoryBreakpointAddr) + { + ConditionDialog dialog = new ConditionDialog(); + dialog.Init(breakpoint); + dialog.PopupWindow(listView.mWidgetWindow); + } } - } - }); + }); + } } if (watchEntry.mResultType == .Pointer) diff --git a/IDEHelper/Compiler/BfAst.cpp b/IDEHelper/Compiler/BfAst.cpp index bb1fde95..0918d2af 100644 --- a/IDEHelper/Compiler/BfAst.cpp +++ b/IDEHelper/Compiler/BfAst.cpp @@ -1543,7 +1543,7 @@ const char* Beefy::BfGetOpName(BfBinaryOp binOp) case BfBinaryOp_Add: return "+"; case BfBinaryOp_Subtract: return "-"; case BfBinaryOp_Multiply: return "*"; - case BfBinaryOp_Divide: return "\\"; + case BfBinaryOp_Divide: return "/"; case BfBinaryOp_Modulus: return "%"; case BfBinaryOp_BitwiseAnd: return "&"; case BfBinaryOp_BitwiseOr: return "|"; diff --git a/IDEHelper/Compiler/BfAutoComplete.cpp b/IDEHelper/Compiler/BfAutoComplete.cpp index cb5d1291..2a316ea7 100644 --- a/IDEHelper/Compiler/BfAutoComplete.cpp +++ b/IDEHelper/Compiler/BfAutoComplete.cpp @@ -460,6 +460,9 @@ void BfAutoComplete::AddMethod(BfMethodDeclaration* methodDecl, const StringImpl void BfAutoComplete::AddTypeDef(BfTypeDef* typeDef, const StringImpl& filter, bool onlyAttribute) { + if (typeDef->mTypeDeclaration == NULL) + return; + StringT<64> name(typeDef->mName->ToString()); if (name == "@") return; @@ -576,6 +579,11 @@ void BfAutoComplete::AddTypeMembers(BfTypeInstance* typeInst, bool addStatic, bo auto activeTypeDef = mModule->GetActiveTypeDef(); + if ((addStatic) && (mModule->mCurMethodInstance == NULL) && (typeInst->IsEnum())) + { + AddEntry(AutoCompleteEntry("valuetype", "_"), filter); + } + #define CHECK_STATIC(staticVal) ((staticVal && addStatic) || (!staticVal && addNonStatic)) mModule->PopulateType(typeInst, BfPopulateType_Data); @@ -2178,13 +2186,41 @@ void BfAutoComplete::CheckVarResolution(BfAstNode* varTypeRef, BfType* resolvedT } } - if (mResolveType == BfResolveType_GetVarType) + if (mResolveType == BfResolveType_GetResultString) { - mVarTypeName = mModule->TypeToString(resolvedType); + mResultString = ":"; + mResultString += mModule->TypeToString(resolvedType); } } } +void BfAutoComplete::CheckResult(BfAstNode* node, const BfTypedValue& typedValue) +{ + if (mResolveType != BfResolveType_GetResultString) + return; + + if (!IsAutocompleteNode(node)) + return; + + if (!typedValue.mValue.IsConst()) + return; + + if (typedValue.mType->IsPointer()) + return; + if (typedValue.mType->IsObject()) + return; + + auto constant = mModule->mBfIRBuilder->GetConstant(typedValue.mValue); + if (BfIRConstHolder::IsInt(constant->mTypeCode)) + { + mResultString = StrFormat("%lld", constant->mInt64); + } + else if (BfIRConstHolder::IsFloat(constant->mTypeCode)) + { + mResultString = StrFormat("%f", constant->mDouble); + } +} + void BfAutoComplete::CheckLocalDef(BfIdentifierNode* identifierNode, BfLocalVariable* varDecl) { CheckLocalRef(identifierNode, varDecl); diff --git a/IDEHelper/Compiler/BfAutoComplete.h b/IDEHelper/Compiler/BfAutoComplete.h index 03cc28d8..4925d84b 100644 --- a/IDEHelper/Compiler/BfAutoComplete.h +++ b/IDEHelper/Compiler/BfAutoComplete.h @@ -170,7 +170,7 @@ public: MethodMatchInfo* mMethodMatchInfo; bool mIsCapturingMethodMatchInfo; String mDefaultSelection; - String mVarTypeName; + String mResultString; String mDocumentationEntryName; BfAstNode* mGetDefinitionNode; BfResolveType mResolveType; @@ -238,6 +238,7 @@ public: void CheckMethod(BfMethodDeclaration* methodDeclaration, bool isLocalMethod); void CheckProperty(BfPropertyDeclaration* propertyDeclaration); void CheckVarResolution(BfAstNode* varTypeRef, BfType* resolvedTypeRef); + void CheckResult(BfAstNode* node, const BfTypedValue& typedValue); void CheckLocalDef(BfIdentifierNode* identifierNode, BfLocalVariable* varDecl); void CheckLocalRef(BfIdentifierNode* identifierNode, BfLocalVariable* varDecl); void CheckFieldRef(BfIdentifierNode* identifierNode, BfFieldInstance* fieldInst); @@ -246,6 +247,7 @@ public: bool CheckFixit(BfAstNode* node); void FixitAddMember(BfTypeInstance* typeInst, BfType* fieldType, const StringImpl& fieldName, bool isStatic, BfTypeInstance* referencedFrom); + }; NS_BF_END \ No newline at end of file diff --git a/IDEHelper/Compiler/BfCompiler.cpp b/IDEHelper/Compiler/BfCompiler.cpp index b40ab0fc..c690f9fc 100644 --- a/IDEHelper/Compiler/BfCompiler.cpp +++ b/IDEHelper/Compiler/BfCompiler.cpp @@ -3393,7 +3393,7 @@ void BfCompiler::VisitSourceExteriorNodes() auto _CheckParser = [&](BfParser* parser) { - if (parser->mNextRevision != NULL) + while (parser->mNextRevision != NULL) parser = parser->mNextRevision; if (parser->mAwaitingDelete) return; @@ -3819,19 +3819,34 @@ void BfCompiler::ProcessAutocompleteTempType() } } - if ((autoComplete->mIsGetDefinition) && (fieldDef->mFieldDeclaration != NULL) && (autoComplete->IsAutocompleteNode(fieldDef->mFieldDeclaration->mNameNode))) + if (((autoComplete->mIsGetDefinition) || (autoComplete->mResolveType == BfResolveType_GetResultString)) && + (fieldDef->mFieldDeclaration != NULL) && (autoComplete->IsAutocompleteNode(fieldDef->mFieldDeclaration->mNameNode))) { for (int i = 0; i < (int)actualTypeDef->mFields.size(); i++) { auto actualFieldDef = actualTypeDef->mFields[i]; if (actualFieldDef->mName == fieldDef->mName) { - autoComplete->mDefType = actualTypeDef; - autoComplete->mDefField = actualFieldDef; + if (autoComplete->mIsGetDefinition) + { + autoComplete->mDefType = actualTypeDef; + autoComplete->mDefField = actualFieldDef; - autoComplete->SetDefinitionLocation(fieldDef->mFieldDeclaration->mNameNode); - autoComplete->mInsertStartIdx = fieldDef->mFieldDeclaration->mNameNode->GetSrcStart(); - autoComplete->mInsertEndIdx = fieldDef->mFieldDeclaration->mNameNode->GetSrcEnd(); + autoComplete->SetDefinitionLocation(fieldDef->mFieldDeclaration->mNameNode); + autoComplete->mInsertStartIdx = fieldDef->mFieldDeclaration->mNameNode->GetSrcStart(); + autoComplete->mInsertEndIdx = fieldDef->mFieldDeclaration->mNameNode->GetSrcEnd(); + } + else if (autoComplete->mResolveType == BfResolveType_GetResultString) + { + auto fieldInstance = &typeInst->mFieldInstances[actualFieldDef->mIdx]; + if (fieldInstance->mConstIdx != -1) + { + auto constant = typeInst->mConstHolder->GetConstantById(fieldInstance->mConstIdx); + auto retVal = module->ConstantToCurrent(constant, typeInst->mConstHolder, typeInst); + BfTypedValue typedValue = BfTypedValue(retVal, typeInst); + autoComplete->CheckResult(fieldDef->GetRefNode(), typedValue); + } + } break; } } @@ -3847,7 +3862,7 @@ void BfCompiler::ProcessAutocompleteTempType() { module->ResolveConstField(typeInst, NULL, fieldDef); } - + if (fieldDef->mInitializer == NULL) { if (BfNodeIsA(fieldDef->mTypeRef)) @@ -6682,9 +6697,9 @@ void BfCompiler::GenerateAutocompleteInfo() if (autoComplete->mResolveType == BfResolveType_GetNavigationData) return; // Already handled - if (autoComplete->mResolveType == BfResolveType_GetVarType) + if (autoComplete->mResolveType == BfResolveType_GetResultString) { - autoCompleteResultString = autoComplete->mVarTypeName; + autoCompleteResultString = autoComplete->mResultString; return; } diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index 8336c4af..dbbf6884 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -2940,6 +2940,40 @@ BfTypedValue BfExprEvaluator::LookupIdentifier(BfAstNode* refNode, const StringI } } + if ((mModule->mCurMethodInstance == NULL) && (mModule->mCurTypeInstance->IsEnum())) + { + if (findName == "_") + { + BfFieldDef* resolvingFieldDef = NULL; + auto checkTypeState = mModule->mContext->mCurTypeState; + while (checkTypeState != NULL) + { + if (checkTypeState->mCurFieldDef != NULL) + { + if (checkTypeState->mTypeInstance == mModule->mCurTypeInstance) + resolvingFieldDef = checkTypeState->mCurFieldDef; + } + checkTypeState = checkTypeState->mPrevState; + } + + if ((resolvingFieldDef != NULL) && (resolvingFieldDef->mIdx > 0)) + { + auto enumType = mModule->mCurTypeInstance; + if (!enumType->mFieldInstances.IsEmpty()) + { + auto fieldInstance = &mModule->mCurTypeInstance->mFieldInstances[resolvingFieldDef->mIdx - 1]; + if ((fieldInstance->mConstIdx != -1) && + (fieldInstance->mResolvedType == mModule->mCurTypeInstance)) + { + auto foreignConst = enumType->mConstHolder->GetConstantById(fieldInstance->mConstIdx); + auto retVal = mModule->ConstantToCurrent(foreignConst, enumType->mConstHolder, enumType); + return BfTypedValue(retVal, enumType); + } + } + } + } + } + BfTypedValue thisValue = mModule->GetThis(); bool forcedIFaceLookup = false; diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index f80fb158..8941211b 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -3523,14 +3523,26 @@ BfTypedValue BfModule::GetFieldInitializerValue(BfFieldInstance* fieldInstance, else if (fieldDef->mIsConst) { BfTypeState typeState; + typeState.mTypeInstance = mCurTypeInstance; typeState.mCurTypeDef = fieldDef->mDeclaringType; + typeState.mCurFieldDef = fieldDef; SetAndRestoreValue prevTypeState(mContext->mCurTypeState, &typeState); BfConstResolver constResolver(this); if (fieldType->IsVar()) return constResolver.Resolve(initializer); else - return constResolver.Resolve(initializer, fieldType); + { + BfConstResolveFlags resolveFlags = BfConstResolveFlag_None; + if ((mCompiler->mResolvePassData != NULL) && (mCurTypeInstance->IsEnum()) && (fieldDef->IsEnumCaseEntry()) && + (mCompiler->mResolvePassData->mAutoCompleteTempTypes.Contains(fieldDef->mDeclaringType))) + { + // We avoid doing the cast here because the value we're typing may not be in the range of the current + // auto-created underlying type and it will cause an 'error flash'. We defer errors until the full resolve for that purpose + resolveFlags = BfConstResolveFlag_NoCast; + } + return constResolver.Resolve(initializer, fieldType, resolveFlags); + } } if (fieldType->IsVar()) diff --git a/IDEHelper/Compiler/BfModuleTypeUtils.cpp b/IDEHelper/Compiler/BfModuleTypeUtils.cpp index 238cbf8f..90dd0454 100644 --- a/IDEHelper/Compiler/BfModuleTypeUtils.cpp +++ b/IDEHelper/Compiler/BfModuleTypeUtils.cpp @@ -2964,18 +2964,40 @@ bool BfModule::DoPopulateType(BfType* resolvedTypeRef, BfPopulateType populateTy } } - for (auto& fieldInstanceRef : typeInstance->mFieldInstances) + /// { - auto fieldInstance = &fieldInstanceRef; - if (!fieldInstance->mFieldIncluded) - continue; - auto fieldDef = fieldInstance->GetFieldDef(); - if (fieldDef == NULL) - continue; - if ((fieldInstance->mConstIdx == -1) && (fieldDef->mIsConst)) - { - SetAndRestoreValue prevTypeRef(mContext->mCurTypeState->mCurFieldDef, fieldDef); - typeInstance->mModule->ResolveConstField(typeInstance, fieldInstance, fieldDef); + Dictionary valueMap; + + for (auto& fieldInstanceRef : typeInstance->mFieldInstances) + { + auto fieldInstance = &fieldInstanceRef; + if (!fieldInstance->mFieldIncluded) + continue; + auto fieldDef = fieldInstance->GetFieldDef(); + if (fieldDef == NULL) + continue; + if ((fieldInstance->mConstIdx == -1) && (fieldDef->mIsConst)) + { + SetAndRestoreValue prevTypeRef(mContext->mCurTypeState->mCurFieldDef, fieldDef); + typeInstance->mModule->ResolveConstField(typeInstance, fieldInstance, fieldDef); + + auto underlyingType = fieldInstance->mResolvedType->GetUnderlyingType(); + if ((fieldDef->IsEnumCaseEntry()) && (fieldInstance->mConstIdx != -1) && (underlyingType->IsIntegral())) + { + auto foreignConst = typeInstance->mConstHolder->GetConstantById(fieldInstance->mConstIdx); + BfFieldDef** fieldDefPtr; + if (valueMap.TryAdd(foreignConst->mInt64, NULL, &fieldDefPtr)) + { + *fieldDefPtr = fieldDef; + } + else + { + auto error = Warn(0, StrFormat("Enum value '%lld' for field '%s' is not unique", foreignConst->mInt64, fieldDef->mName.c_str()), fieldDef->GetRefNode(), true); + if (error != NULL) + mCompiler->mPassInstance->MoreInfo(StrFormat("This value was previously used for field '%s'", (*fieldDefPtr)->mName.c_str()), (*fieldDefPtr)->GetRefNode()); + } + } + } } } @@ -8997,7 +9019,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp if (explicitCast) { // TypedPrimitive -> Primitive - if ((typedVal.mType->IsTypedPrimitive()) && (toType->IsPrimitiveType())) + if ((typedVal.mType->IsTypedPrimitive()) && (!typedVal.mType->IsFunction()) && (toType->IsPrimitiveType())) { auto fromTypedPrimitiveType = typedVal.mType->ToTypeInstance(); auto primTypedVal = BfTypedValue(typedVal.mValue, fromTypedPrimitiveType->mFieldInstances.back().mResolvedType, typedVal.IsAddr()); @@ -9006,7 +9028,7 @@ BfIRValue BfModule::CastToValue(BfAstNode* srcNode, BfTypedValue typedVal, BfTyp } // TypedPrimitive -> TypedPrimitive - if ((typedVal.mType->IsTypedPrimitive()) && (toType->IsTypedPrimitive())) + if ((typedVal.mType->IsTypedPrimitive()) && (!typedVal.mType->IsFunction()) && (toType->IsTypedPrimitive())) { auto fromTypedPrimitiveType = typedVal.mType->ToTypeInstance(); auto toTypedPrimitiveType = toType->ToTypeInstance(); diff --git a/IDEHelper/Compiler/BfResolvePass.h b/IDEHelper/Compiler/BfResolvePass.h index e4906843..71180746 100644 --- a/IDEHelper/Compiler/BfResolvePass.h +++ b/IDEHelper/Compiler/BfResolvePass.h @@ -20,7 +20,7 @@ enum BfResolveType BfResolveType_GetFixits, BfResolveType_GetTypeDefList, BfResolveType_GetTypeDefInto, - BfResolveType_GetVarType, + BfResolveType_GetResultString, }; class BfLocalVariable; diff --git a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp index 92f2337e..6687f90b 100644 --- a/IDEHelper/Compiler/BfResolvedTypeUtils.cpp +++ b/IDEHelper/Compiler/BfResolvedTypeUtils.cpp @@ -2198,7 +2198,7 @@ int BfResolvedTypeSet::Hash(BfType* type, LookupContext* ctx, bool allowRef) else if (type->IsConstExprValue()) { BfConstExprValueType* constExprValueType = (BfConstExprValueType*)type; - int hashVal = ((int)constExprValueType->mValue.mTypeCode << 17) ^ (constExprValueType->mValue.mInt32 << 3) ^ HASH_CONSTTYPE; + int hashVal = (constExprValueType->mValue.mInt32 << 17) ^ HASH_CONSTTYPE; int elemHash = Hash(constExprValueType->mType, ctx); hashVal = ((hashVal ^ elemHash) << 5) - hashVal; return hashVal; @@ -2897,8 +2897,7 @@ bool BfResolvedTypeSet::Equals(BfType* lhs, BfType* rhs, LookupContext* ctx) BfConstExprValueType* lhsConstExprValueType = (BfConstExprValueType*)lhs; BfConstExprValueType* rhsConstExprValueType = (BfConstExprValueType*)rhs; - return (lhsConstExprValueType->mType == rhsConstExprValueType->mType) && - (lhsConstExprValueType->mValue.mTypeCode == rhsConstExprValueType->mValue.mTypeCode) && + return (lhsConstExprValueType->mType == rhsConstExprValueType->mType) && (lhsConstExprValueType->mValue.mInt64 == rhsConstExprValueType->mValue.mInt64); } else diff --git a/IDEHelper/Compiler/BfStmtEvaluator.cpp b/IDEHelper/Compiler/BfStmtEvaluator.cpp index f5478505..9516abd7 100644 --- a/IDEHelper/Compiler/BfStmtEvaluator.cpp +++ b/IDEHelper/Compiler/BfStmtEvaluator.cpp @@ -1404,11 +1404,8 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD { unresolvedType = ResolveTypeRef(varDecl->mTypeRef, BfPopulateType_Data, (BfResolveTypeRefFlags)(BfResolveTypeRefFlag_NoResolveGenericParam | BfResolveTypeRefFlag_AllowRef)); if (unresolvedType == NULL) - unresolvedType = mContext->mBfObjectType; // Fake an object - //resolvedType = ResolveGenericType(unresolvedType); - resolvedType = unresolvedType; - if (unresolvedType == NULL) - resolvedType = mContext->mBfObjectType; // Fake an object + unresolvedType = GetPrimitiveType(BfTypeCode_Var); + resolvedType = unresolvedType; } auto _CheckConst = [&] @@ -1417,7 +1414,7 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD { auto constant = mBfIRBuilder->GetConstant(initValue.mValue); - // NullPtr is standin for GlobalVar during autocomplete + // NullPtr is stand-in for GlobalVar during autocomplete if ((constant->mConstType == BfConstType_GlobalVar) || (constant->mTypeCode == BfTypeCode_NullPtr)) { @@ -3114,7 +3111,7 @@ void BfModule::VisitCodeBlock(BfBlock* block) if ((!autoComplete->mIsAutoComplete) || (autoComplete->mResolveType == BfResolveType_GetCurrentLocation) || (autoComplete->mResolveType == BfResolveType_GetFixits) || - (autoComplete->mResolveType == BfResolveType_GetVarType) || + (autoComplete->mResolveType == BfResolveType_GetResultString) || (autoComplete->mResolveType == BfResolveType_GetSymbolInfo) || (autoComplete->mResolveType == BfResolveType_ShowFileSymbolReferences)) wantsAllLocalMethods = false;