From 4f2c28862d97cf05e36e9e2cc4b1fb5a150fddb9 Mon Sep 17 00:00:00 2001 From: Brian Fiete Date: Tue, 31 Dec 2024 07:48:03 -0800 Subject: [PATCH] Debugger mouseover improvements --- IDE/src/ui/SourceViewPanel.bf | 16 ++- IDE/src/ui/WatchPanel.bf | 4 +- IDEHelper/Compiler/BfAutoComplete.cpp | 181 +++++++++++++++++-------- IDEHelper/Compiler/BfAutoComplete.h | 3 +- IDEHelper/Compiler/BfConstResolver.cpp | 4 +- IDEHelper/Compiler/BfExprEvaluator.cpp | 2 +- IDEHelper/Compiler/BfModule.cpp | 7 + IDEHelper/Compiler/BfStmtEvaluator.cpp | 5 + 8 files changed, 161 insertions(+), 61 deletions(-) diff --git a/IDE/src/ui/SourceViewPanel.bf b/IDE/src/ui/SourceViewPanel.bf index ac4362a0..bf6cc7ab 100644 --- a/IDE/src/ui/SourceViewPanel.bf +++ b/IDE/src/ui/SourceViewPanel.bf @@ -5645,8 +5645,22 @@ namespace IDE.ui if ((mHoverResolveTask == null) && ((debugExpr == null) || (!debugExpr.StartsWith(':')))) { + bool wantDebugEval = false; + if ((gApp.mDebugger.mIsRunning) && (!String.IsNullOrEmpty(debugExpr))) + { + wantDebugEval = true; + if (FilteredProjectSource != null) + { + // This is active Beef source + if ((debugExpr[0].IsNumber) || (debugExpr.StartsWith('\'')) || (debugExpr.StartsWith('"'))) + { + // Literal, don't debug eval + wantDebugEval = false; + } + } + } - if (((!gApp.mDebugger.mIsRunning) || (!mHoverWatch.HasDisplay)) && // Don't show extended information for debug watches + if (((!wantDebugEval) || (!mHoverWatch.HasDisplay)) && // Don't show extended information for debug watches (!handlingHoverResolveTask) && (ResolveCompiler != null) && (!ResolveCompiler.mThreadWorkerHi.mThreadRunning) && (gApp.mSettings.mEditorSettings.mHiliteCursorReferences) && (!gApp.mDeterministic)) { ResolveParams resolveParams = new .(); diff --git a/IDE/src/ui/WatchPanel.bf b/IDE/src/ui/WatchPanel.bf index 7c41a6e2..876c794f 100644 --- a/IDE/src/ui/WatchPanel.bf +++ b/IDE/src/ui/WatchPanel.bf @@ -2635,9 +2635,9 @@ namespace IDE.ui } var dispStr = scope String(); - dispStr.AppendF(mWatchSeriesInfo.mDisplayTemplate, params formatParams); + dispStr.AppendF(mWatchSeriesInfo.mDisplayTemplate, params formatParams).IgnoreError(); var evalStr = scope String(); - evalStr.AppendF(mWatchSeriesInfo.mEvalTemplate, params formatParams); + evalStr.AppendF(mWatchSeriesInfo.mEvalTemplate, params formatParams).IgnoreError(); watchListView.mWatchOwner.SetupListViewItem(curWatchListViewItem, dispStr, evalStr); curWatchListViewItem.mWatchEntry.mSeriesFirstVersion = mWatchSeriesInfo.mSeriesFirstVersion; diff --git a/IDEHelper/Compiler/BfAutoComplete.cpp b/IDEHelper/Compiler/BfAutoComplete.cpp index fccb5bdf..e100deb3 100644 --- a/IDEHelper/Compiler/BfAutoComplete.cpp +++ b/IDEHelper/Compiler/BfAutoComplete.cpp @@ -2957,30 +2957,85 @@ void BfAutoComplete::CheckVarResolution(BfAstNode* varTypeRef, BfType* resolvedT } } -void BfAutoComplete::CheckResult(BfAstNode* node, const BfTypedValue& typedValue) +class BfAutocompleteNodeChecker : public BfStructuralVisitor { +public: + BfAutoComplete* mAutoComplete; + bool mSelected; + +public: + BfAutocompleteNodeChecker(BfAutoComplete* autoComplete) + { + mAutoComplete = autoComplete; + mSelected = false; + } + + virtual void Visit(BfAstNode* bfAstNode) override + { + mSelected = mAutoComplete->IsAutocompleteNode(bfAstNode); + } + + virtual void Visit(BfBinaryOperatorExpression* binOpExpr) override + { + mSelected = mAutoComplete->IsAutocompleteNode(binOpExpr->mOpToken); + } + + virtual void Visit(BfUnaryOperatorExpression* unaryOpExpr) override + { + VisitChild(unaryOpExpr->mExpression); + } + + virtual void Visit(BfCastExpression* castExpr) override + { + VisitChild(castExpr->mExpression); + } + + virtual void Visit(BfLiteralExpression* literalExpr) override + { + mSelected = mAutoComplete->IsAutocompleteNode(literalExpr); + } + + virtual void Visit(BfIdentifierNode* identifierNode) override + { + mSelected = mAutoComplete->IsAutocompleteNode(identifierNode); + } + + virtual void Visit(BfMemberReferenceExpression* memberRefExpr) override + { + mSelected = mAutoComplete->IsAutocompleteNode(memberRefExpr->mMemberName); + } +}; + +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)) + BfAutocompleteNodeChecker autocompleteNodeChecker(this); + autocompleteNodeChecker.VisitChildNoRef(node); + if (!autocompleteNodeChecker.mSelected) + return; + + String constStr = ConstantToString(mModule->mBfIRBuilder, typedValue); + if (!constStr.IsEmpty()) { - mResultString = StrFormat(":%lld", constant->mInt64); + mResultString = ":"; + mResultString += constStr; + AddResultTypeKind(typedValue.mType); } - else if (BfIRConstHolder::IsFloat(constant->mTypeCode)) + else { - mResultString = StrFormat(":%f", constant->mDouble); + SetResultStringType(typedValue.mType); } } @@ -3041,7 +3096,7 @@ void BfAutoComplete::CheckLocalRef(BfAstNode* identifierNode, BfLocalVariable* v { String constStr; if (varDecl->mConstValue.IsConst()) - constStr = ConstantToString(mModule->mBfIRBuilder, varDecl->mConstValue); + constStr = ConstantToString(mModule->mBfIRBuilder, BfTypedValue(varDecl->mConstValue, varDecl->mResolvedType)); if (!constStr.IsEmpty()) { mResultString = constStr; @@ -3699,11 +3754,21 @@ String BfAutoComplete::FixitGetLocation(BfParserData* parser, int insertPos) return StrFormat("%s|%d:%d", parser->mFileName.c_str(), line, lineChar); } -String BfAutoComplete::ConstantToString(BfIRConstHolder* constHolder, BfIRValue id) +String BfAutoComplete::ConstantToString(BfIRConstHolder* constHolder, BfTypedValue typedValue) { + SetAndRestoreValue prevTypeInst(mModule->mCurTypeInstance, typedValue.mType->ToTypeInstance()); + SetAndRestoreValue prevMethodInst(mModule->mCurMethodInstance, NULL); + + BF_ASSERT(typedValue.mValue.IsConst()); + + String result; + result = "("; + result += mModule->TypeToString(typedValue.mType); + result += ")"; + char str[32]; - int stringId = mModule->GetStringPoolIdx(id, constHolder); + int stringId = mModule->GetStringPoolIdx(typedValue.mValue, constHolder); if (stringId != -1) { BfStringPoolEntry* entry; @@ -3716,49 +3781,52 @@ String BfAutoComplete::ConstantToString(BfIRConstHolder* constHolder, BfIRValue } } - auto constant = constHolder->GetConstant(id); + auto constant = constHolder->GetConstant(typedValue.mValue); switch (constant->mTypeCode) { case BfTypeCode_Boolean: - return StrFormat(":(bool) %s", constant->mBool ? "true" : "false"); - case BfTypeCode_UInt8: - return StrFormat(":(uint8) %llu", constant->mUInt64); - case BfTypeCode_UInt16: - return StrFormat(":(uint16) %llu", constant->mUInt64); - case BfTypeCode_UInt32: - return StrFormat(":(uint32) %llu", constant->mUInt64); - case BfTypeCode_UInt64: - return StrFormat(":(uint64) %llu", constant->mUInt64); - - case BfTypeCode_Int8: - return StrFormat(":(int8) %lld", constant->mInt64); - case BfTypeCode_Int16: - return StrFormat(":(int16) %lld", constant->mInt64); - case BfTypeCode_Int32: - return StrFormat(":(int32) %lld", constant->mInt64); - case BfTypeCode_Int64: - return StrFormat(":(int64) %lld", constant->mInt64); - - case BfTypeCode_Float: - { - ExactMinimalFloatToStr((float)constant->mDouble, str); - String result; - result += str; - result += "f"; - return result; - } - case BfTypeCode_Double: - { - ExactMinimalDoubleToStr(constant->mDouble, str); - String result; - result += str; - return result; - } - default: + result += StrFormat(" %s", constant->mBool ? "true" : "false"); break; + case BfTypeCode_UInt8: + result += StrFormat(" %llu", constant->mUInt64); + break; + case BfTypeCode_UInt16: + result += StrFormat(" %llu", constant->mUInt64); + break; + case BfTypeCode_UInt32: + result += StrFormat(" %llu", constant->mUInt64); + break; + case BfTypeCode_UInt64: + result += StrFormat(" %llu", constant->mUInt64); + break; + case BfTypeCode_Int8: + result += StrFormat(" %lld", constant->mInt64); + break; + case BfTypeCode_Int16: + result += StrFormat(" %lld", constant->mInt64); + break; + case BfTypeCode_Int32: + result += StrFormat(" %lld", constant->mInt64); + break; + case BfTypeCode_Int64: + result += StrFormat(" %lld", constant->mInt64); + break; + case BfTypeCode_Float: + ExactMinimalFloatToStr((float)constant->mDouble, str); + result += " "; + result += str; + result += "f"; + break; + case BfTypeCode_Double: + ExactMinimalDoubleToStr(constant->mDouble, str); + result += " "; + result += str; + break; + default: + return ""; } - return ""; + return result; } void BfAutoComplete::FixitAddMethod(BfTypeInstance* typeInst, const StringImpl& methodName, BfType* returnType, const BfTypeVector& paramTypes, bool wantStatic) @@ -3946,13 +4014,8 @@ void BfAutoComplete::FixitAddConstructor(BfTypeInstance *typeInstance) } } -void BfAutoComplete::SetResultStringType(BfType * type) +void BfAutoComplete::AddResultTypeKind(BfType* type) { - SetAndRestoreValue prevTypeInst(mModule->mCurTypeInstance, type->ToTypeInstance()); - SetAndRestoreValue prevMethodInst(mModule->mCurMethodInstance, NULL); - - mResultString = ":"; - mResultString += mModule->TypeToString(type); if (type->IsObject()) mResultString += "\n:type\tclass"; else if (type->IsInterface()) @@ -3963,6 +4026,16 @@ void BfAutoComplete::SetResultStringType(BfType * type) mResultString += "\n:type\tvaluetype"; } +void BfAutoComplete::SetResultStringType(BfType* type) +{ + SetAndRestoreValue prevTypeInst(mModule->mCurTypeInstance, type->ToTypeInstance()); + SetAndRestoreValue prevMethodInst(mModule->mCurMethodInstance, NULL); + + mResultString = ":"; + mResultString += mModule->TypeToString(type); + AddResultTypeKind(type); +} + void BfAutoComplete::FixitAddFullyQualify(BfAstNode* refNode, const StringImpl& findName, const SizedArrayImpl& foundList) { BfProtectionCheckFlags protectionCheckFlags = BfProtectionCheckFlag_None; diff --git a/IDEHelper/Compiler/BfAutoComplete.h b/IDEHelper/Compiler/BfAutoComplete.h index ff3c1fca..ecdc9563 100644 --- a/IDEHelper/Compiler/BfAutoComplete.h +++ b/IDEHelper/Compiler/BfAutoComplete.h @@ -244,7 +244,7 @@ public: void FixitGetParamString(const BfTypeVector& paramTypes, StringImpl& outStr); int FixitGetMemberInsertPos(BfTypeDef* typeDef); String FixitGetLocation(BfParserData* parserData, int insertPos); - String ConstantToString(BfIRConstHolder* constHolder, BfIRValue id); + String ConstantToString(BfIRConstHolder* constHolder, BfTypedValue typedValue); public: BfAutoComplete(BfResolveType resolveType = BfResolveType_Autocomplete, bool doFuzzyAutoComplete = false); @@ -283,6 +283,7 @@ public: void FixitAddConstructor(BfTypeInstance* typeInstance); void FixitAddFullyQualify(BfAstNode* refNode, const StringImpl& findName, const SizedArrayImpl& foundList); + void AddResultTypeKind(BfType* type); void SetResultStringType(BfType* type); }; diff --git a/IDEHelper/Compiler/BfConstResolver.cpp b/IDEHelper/Compiler/BfConstResolver.cpp index c6e87b45..e3b42a75 100644 --- a/IDEHelper/Compiler/BfConstResolver.cpp +++ b/IDEHelper/Compiler/BfConstResolver.cpp @@ -167,7 +167,7 @@ BfTypedValue BfConstResolver::Resolve(BfExpression* expr, BfType* wantType, BfCo } else { - mResult = mModule->Cast(expr, mResult, wantType, (BfCastFlags)(BfCastFlags_WantsConst | BfCastFlags_NoConversionOperator | (explicitCast ? BfCastFlags_Explicit : BfCastFlags_None))); + mResult = mModule->Cast(expr, mResult, wantType, (BfCastFlags)(BfCastFlags_WantsConst | (explicitCast ? BfCastFlags_Explicit : BfCastFlags_None))); } } @@ -399,7 +399,7 @@ bool BfConstResolver::PrepareMethodArguments(BfAstNode* targetSrc, BfMethodMatch if (argExpr != NULL) { - argValue = mModule->Cast(argExpr, argValue, wantType, (BfCastFlags)(BfCastFlags_WantsConst | BfCastFlags_NoConversionOperator)); + argValue = mModule->Cast(argExpr, argValue, wantType, (BfCastFlags)(BfCastFlags_WantsConst)); if (!argValue) return false; } diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index 617e24a1..a640ad59 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -5172,7 +5172,7 @@ BfTypedValue BfExprEvaluator::LoadField(BfAstNode* targetSrc, BfTypedValue targe if (fieldInstance->mConstIdx != -1) { - String constStr = autoComplete->ConstantToString(typeInstance->mConstHolder, BfIRValue(BfIRValueFlags_Const, fieldInstance->mConstIdx)); + String constStr = autoComplete->ConstantToString(typeInstance->mConstHolder, BfTypedValue(BfIRValue(BfIRValueFlags_Const, fieldInstance->mConstIdx), fieldInstance->mResolvedType)); if (!constStr.IsEmpty()) { autoComplete->mResultString += " = "; diff --git a/IDEHelper/Compiler/BfModule.cpp b/IDEHelper/Compiler/BfModule.cpp index 4676a821..2d68e7c2 100644 --- a/IDEHelper/Compiler/BfModule.cpp +++ b/IDEHelper/Compiler/BfModule.cpp @@ -4670,6 +4670,10 @@ BfTypedValue BfModule::GetFieldInitializerValue(BfFieldInstance* fieldInstance, if (mCompiler->mCeMachine->mExecuteId != ceExecuteId) fieldInstance->mHadConstEval = true; } + + if (auto autoComplete = mCompiler->GetAutoComplete()) + autoComplete->CheckResult(initializer, result); + return result; } } @@ -9240,6 +9244,9 @@ BfTypedValue BfModule::CreateValueFromExpression(BfExprEvaluator& exprEvaluator, if ((typedVal.mType->IsValueType()) && ((flags & BfEvalExprFlags_NoValueAddr) != 0)) typedVal = LoadValue(typedVal, 0, exprEvaluator.mIsVolatileReference); + if (auto autoComplete = mCompiler->GetAutoComplete()) + autoComplete->CheckResult(expr, typedVal); + return typedVal; } diff --git a/IDEHelper/Compiler/BfStmtEvaluator.cpp b/IDEHelper/Compiler/BfStmtEvaluator.cpp index f5c23244..e961ab4e 100644 --- a/IDEHelper/Compiler/BfStmtEvaluator.cpp +++ b/IDEHelper/Compiler/BfStmtEvaluator.cpp @@ -1778,6 +1778,11 @@ BfLocalVariable* BfModule::HandleVariableDeclaration(BfVariableDeclaration* varD resolvedType = initValue.mType; unresolvedType = resolvedType; } + + if (auto autoComplete = mCompiler->GetAutoComplete()) + { + autoComplete->CheckResult(varDecl->mInitializer, initValue); + } } if ((!handledVarInit) && (!isConst)) {