From db1df758b834822fd9006acf6860fd666380014c Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Tue, 9 Dec 2014 22:56:34 -0500 Subject: [PATCH] Debugger: Cleanups. SourceLanguage and friends: - Remove ParseTypeExpression from SourceLanguage, as its functionality can now properly be subsumed by the general expression parser, and simply becomes another result type thereof. CLanguageFamily/CLanguage/CppLanguage: - Remove IsModifierValid() hook, as this is all now handled internally in the expression parser. VariablesView: - Refactor to handle typecast requests via expression evaluation. Since this is done asynchronously, rework the logic to handle recognizing expression evaluation results that correspond to a requested cast, and handle accordingly. --- .../source_language/SourceLanguage.cpp | 8 - .../debugger/source_language/SourceLanguage.h | 4 - .../source_language/c_family/CLanguage.cpp | 10 -- .../source_language/c_family/CLanguage.h | 3 - .../c_family/CLanguageFamily.cpp | 127 --------------- .../c_family/CLanguageFamily.h | 7 - .../source_language/c_family/CppLanguage.cpp | 10 -- .../source_language/c_family/CppLanguage.h | 3 - .../gui/team_window/VariablesView.cpp | 146 ++++++++++++++---- .../gui/team_window/VariablesView.h | 5 + 10 files changed, 117 insertions(+), 206 deletions(-) diff --git a/src/apps/debugger/source_language/SourceLanguage.cpp b/src/apps/debugger/source_language/SourceLanguage.cpp index 6fb6604736..a5b3cbe15d 100644 --- a/src/apps/debugger/source_language/SourceLanguage.cpp +++ b/src/apps/debugger/source_language/SourceLanguage.cpp @@ -20,14 +20,6 @@ SourceLanguage::GetSyntaxHighlighter() const } -status_t -SourceLanguage::ParseTypeExpression(const BString& expression, - TeamTypeInformation* info, Type*& _resultType) const -{ - return B_NOT_SUPPORTED; -} - - status_t SourceLanguage::EvaluateExpression(const BString& expression, ValueNodeManager* manager, TeamTypeInformation* info, diff --git a/src/apps/debugger/source_language/SourceLanguage.h b/src/apps/debugger/source_language/SourceLanguage.h index ba18709b05..01292b2b5f 100644 --- a/src/apps/debugger/source_language/SourceLanguage.h +++ b/src/apps/debugger/source_language/SourceLanguage.h @@ -29,10 +29,6 @@ public: // returns a reference, // may return NULL, if not available - virtual status_t ParseTypeExpression(const BString& expression, - TeamTypeInformation* info, - Type*& _resultType) const; - virtual status_t EvaluateExpression(const BString& expression, ValueNodeManager* manager, TeamTypeInformation* info, diff --git a/src/apps/debugger/source_language/c_family/CLanguage.cpp b/src/apps/debugger/source_language/c_family/CLanguage.cpp index 27f063ef89..a1acaaf481 100644 --- a/src/apps/debugger/source_language/c_family/CLanguage.cpp +++ b/src/apps/debugger/source_language/c_family/CLanguage.cpp @@ -23,13 +23,3 @@ CLanguage::Name() const { return "C"; } - - -bool -CLanguage::IsModifierValid(char modifier) const -{ - if (modifier == '*') - return true; - - return false; -} diff --git a/src/apps/debugger/source_language/c_family/CLanguage.h b/src/apps/debugger/source_language/c_family/CLanguage.h index 959cda91fe..f0b27ed828 100644 --- a/src/apps/debugger/source_language/c_family/CLanguage.h +++ b/src/apps/debugger/source_language/c_family/CLanguage.h @@ -15,9 +15,6 @@ public: virtual ~CLanguage(); virtual const char* Name() const; - -protected: - virtual bool IsModifierValid(char modifier) const; }; diff --git a/src/apps/debugger/source_language/c_family/CLanguageFamily.cpp b/src/apps/debugger/source_language/c_family/CLanguageFamily.cpp index ea049fee1e..707c09d5a5 100644 --- a/src/apps/debugger/source_language/c_family/CLanguageFamily.cpp +++ b/src/apps/debugger/source_language/c_family/CLanguageFamily.cpp @@ -40,133 +40,6 @@ CLanguageFamily::GetSyntaxHighlighter() const } -status_t -CLanguageFamily::ParseTypeExpression(const BString& expression, - TeamTypeInformation* info, Type*& _resultType) const -{ - status_t result = B_OK; - Type* baseType = NULL; - - BString parsedName = expression; - BString baseTypeName; - BString arraySpecifier; - parsedName.RemoveAll(" "); - - int32 modifierIndex = -1; - modifierIndex = parsedName.FindFirst('*'); - if (modifierIndex == -1) - modifierIndex = parsedName.FindFirst('&'); - if (modifierIndex == -1) - modifierIndex = parsedName.FindFirst('['); - if (modifierIndex == -1) - modifierIndex = parsedName.Length(); - - parsedName.MoveInto(baseTypeName, 0, modifierIndex); - - modifierIndex = parsedName.FindFirst('['); - if (modifierIndex >= 0) { - parsedName.MoveInto(arraySpecifier, modifierIndex, - parsedName.Length() - modifierIndex); - } - - result = info->LookupTypeByName(baseTypeName, TypeLookupConstraints(), - baseType); - if (result != B_OK) - return result; - - BReference typeRef; - typeRef.SetTo(baseType, true); - - if (!parsedName.IsEmpty()) { - AddressType* derivedType = NULL; - // walk the list of modifiers trying to add each. - for (int32 i = 0; i < parsedName.Length(); i++) { - if (!IsModifierValid(parsedName[i])) - return B_BAD_VALUE; - - address_type_kind typeKind; - switch (parsedName[i]) { - case '*': - { - typeKind = DERIVED_TYPE_POINTER; - break; - } - case '&': - { - typeKind = DERIVED_TYPE_REFERENCE; - break; - } - default: - { - return B_BAD_VALUE; - } - - } - - if (derivedType == NULL) { - result = baseType->CreateDerivedAddressType(typeKind, - derivedType); - } else { - result = derivedType->CreateDerivedAddressType(typeKind, - derivedType); - } - - if (result != B_OK) - return result; - typeRef.SetTo(derivedType, true); - } - - _resultType = derivedType; - } else - _resultType = baseType; - - - if (!arraySpecifier.IsEmpty()) { - ArrayType* arrayType = NULL; - - int32 startIndex = 1; - do { - int32 size = strtoul(arraySpecifier.String() + startIndex, - NULL, 10); - if (size < 0) - return B_ERROR; - - if (arrayType == NULL) { - result = _resultType->CreateDerivedArrayType(0, size, true, - arrayType); - } else { - result = arrayType->CreateDerivedArrayType(0, size, true, - arrayType); - } - - if (result != B_OK) - return result; - - typeRef.SetTo(arrayType, true); - - startIndex = arraySpecifier.FindFirst('[', startIndex + 1); - - } while (startIndex >= 0); - - // since a C/C++ array is essentially pointer math, - // the resulting array has to be wrapped in a pointer to - // ensure the element addresses wind up being against the - // correct address. - AddressType* addressType = NULL; - result = arrayType->CreateDerivedAddressType(DERIVED_TYPE_POINTER, - addressType); - if (result != B_OK) - return result; - - _resultType = addressType; - } - - typeRef.Detach(); - - return result; -} - - status_t CLanguageFamily::EvaluateExpression(const BString& expression, ValueNodeManager* manager, TeamTypeInformation* info, diff --git a/src/apps/debugger/source_language/c_family/CLanguageFamily.h b/src/apps/debugger/source_language/c_family/CLanguageFamily.h index 9d656b0370..ad71e856dd 100644 --- a/src/apps/debugger/source_language/c_family/CLanguageFamily.h +++ b/src/apps/debugger/source_language/c_family/CLanguageFamily.h @@ -17,18 +17,11 @@ public: virtual SyntaxHighlighter* GetSyntaxHighlighter() const; - virtual status_t ParseTypeExpression(const BString& expression, - TeamTypeInformation* lookup, - Type*& _resultType) const; - virtual status_t EvaluateExpression(const BString& expression, ValueNodeManager* manager, TeamTypeInformation* info, ExpressionResult*& _output, ValueNode*& _neededNode); - -protected: - virtual bool IsModifierValid(char modifier) const = 0; }; diff --git a/src/apps/debugger/source_language/c_family/CppLanguage.cpp b/src/apps/debugger/source_language/c_family/CppLanguage.cpp index 201107f989..2885e7fa9c 100644 --- a/src/apps/debugger/source_language/c_family/CppLanguage.cpp +++ b/src/apps/debugger/source_language/c_family/CppLanguage.cpp @@ -23,13 +23,3 @@ CppLanguage::Name() const { return "C++"; } - - -bool -CppLanguage::IsModifierValid(char modifier) const -{ - if (modifier == '*' || modifier == '&') - return true; - - return false; -} diff --git a/src/apps/debugger/source_language/c_family/CppLanguage.h b/src/apps/debugger/source_language/c_family/CppLanguage.h index 9f303781c7..d163ed15d6 100644 --- a/src/apps/debugger/source_language/c_family/CppLanguage.h +++ b/src/apps/debugger/source_language/c_family/CppLanguage.h @@ -15,9 +15,6 @@ public: virtual ~CppLanguage(); virtual const char* Name() const; - -protected: - virtual bool IsModifierValid(char modifier) const; }; diff --git a/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp b/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp index 4837532f34..8ad4e3f0b0 100644 --- a/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp @@ -544,6 +544,34 @@ public: }; +// #pragma mark - VariablesExpressionInfo + + +class VariablesView::VariablesExpressionInfo : public ExpressionInfo { +public: + VariablesExpressionInfo(const BString& expression, ModelNode* node) + : + ExpressionInfo(expression), + fTargetNode(node) + { + fTargetNode->AcquireReference(); + } + + virtual ~VariablesExpressionInfo() + { + fTargetNode->ReleaseReference(); + } + + inline ModelNode* TargetNode() const + { + return fTargetNode; + } + +private: + ModelNode* fTargetNode; +}; + + // #pragma mark - VariableValueColumn @@ -1708,6 +1736,7 @@ VariablesView::VariablesView(Listener* listener) fExpressions(NULL), fExpressionChildren(10, false), fTableCellContextMenuTracker(NULL), + fPendingTypecastInfo(NULL), fFrameClearPending(false), fListener(listener) { @@ -1730,6 +1759,8 @@ VariablesView::~VariablesView() } delete fContainerListener; + if (fPendingTypecastInfo != NULL) + fPendingTypecastInfo->ReleaseReference(); } @@ -1848,44 +1879,27 @@ VariablesView::MessageReceived(BMessage* message) break; } - Type* type = NULL; - BString typeExpression = message->FindString("text"); - if (typeExpression.Length() == 0) - break; + BString typeExpression; + if (message->FindString("text", &typeExpression) == B_OK) { + if (typeExpression.IsEmpty()) + break; - FileSourceCode* code = fStackFrame->Function()->GetFunction() - ->GetSourceCode(); - if (code == NULL) - break; + if (fPendingTypecastInfo != NULL) + fPendingTypecastInfo->ReleaseReference(); - SourceLanguage* language = code->GetSourceLanguage(); - if (language == NULL) - break; + fPendingTypecastInfo = new(std::nothrow) + VariablesExpressionInfo(typeExpression, node); + if (fPendingTypecastInfo == NULL) { + // TODO: notify user + break; + } - if (language->ParseTypeExpression(typeExpression, - fThread->GetTeam()->DebugInfo(), type) != B_OK) { - BString errorMessage; - errorMessage.SetToFormat("Failed to resolve type %s", - typeExpression.String()); - BAlert* alert = new(std::nothrow) BAlert("Error", - errorMessage.String(), "Close"); - if (alert != NULL) - alert->Go(); + fPendingTypecastInfo->AddListener(this); + fListener->ExpressionEvaluationRequested(fPendingTypecastInfo, + fStackFrame, fThread); break; - } - - BReference typeRef(type, true); - ValueNode* valueNode = NULL; - if (TypeHandlerRoster::Default()->CreateValueNode( - node->NodeChild(), type, valueNode) != B_OK) { + } else break; - } - - typeRef.Detach(); - node->NodeChild()->SetNode(valueNode); - node->SetCastedType(type); - fVariableTableModel->NotifyNodeChanged(node); - break; } case MSG_TYPECAST_TO_ARRAY: { @@ -2071,7 +2085,17 @@ VariablesView::MessageReceived(BMessage* message) valueReference.SetTo(value, true); } - _AddExpressionNode(info, result, value); + VariablesExpressionInfo* variableInfo + = dynamic_cast(info); + if (variableInfo != NULL) { + if (fPendingTypecastInfo == variableInfo) { + _HandleTypecastResult(result, value); + fPendingTypecastInfo->ReleaseReference(); + fPendingTypecastInfo = NULL; + } + } else + _AddExpressionNode(info, result, value); + break; } case MSG_VALUE_NODE_CHANGED: @@ -2985,6 +3009,60 @@ VariablesView::_AddExpressionNode(ExpressionInfo* info, status_t result, } +void +VariablesView::_HandleTypecastResult(status_t result, ExpressionResult* value) +{ + BString errorMessage; + if (value == NULL) { + errorMessage.SetToFormat("Failed to evaluate expression \"%s\": %s (%" + B_PRId32 ")", fPendingTypecastInfo->Expression().String(), + strerror(result), result); + } else if (result != B_OK) { + BVariant valueData; + value->PrimitiveValue()->ToVariant(valueData); + + // usually, the evaluation can give us back an error message to + // specifically indicate why it failed. If it did, simply use + // the message directly, otherwise fall back to generating an error + // message based on the error code + if (valueData.Type() == B_STRING_TYPE) + errorMessage = valueData.ToString(); + else { + errorMessage.SetToFormat("Failed to evaluate expression \"%s\":" + " %s (%" B_PRId32 ")", + fPendingTypecastInfo->Expression().String(), strerror(result), + result); + } + + } else if (value->Kind() != EXPRESSION_RESULT_KIND_TYPE) { + errorMessage.SetToFormat("Expression \"%s\" does not evaluate to a" + " type.", fPendingTypecastInfo->Expression().String()); + } + + if (!errorMessage.IsEmpty()) { + BAlert* alert = new(std::nothrow) BAlert("Typecast error", + errorMessage, "Close"); + if (alert != NULL) + alert->Go(); + + return; + } + + Type* type = value->GetType(); + BReference typeRef(type); + ValueNode* valueNode = NULL; + ModelNode* node = fPendingTypecastInfo->TargetNode(); + if (TypeHandlerRoster::Default()->CreateValueNode(node->NodeChild(), type, + valueNode) != B_OK) { + return; + } + + node->NodeChild()->SetNode(valueNode); + node->SetCastedType(type); + fVariableTableModel->NotifyNodeChanged(node); +} + + status_t VariablesView::_GetTypeForTypeCode(int32 type, Type*& _resultType) const { diff --git a/src/apps/debugger/user_interface/gui/team_window/VariablesView.h b/src/apps/debugger/user_interface/gui/team_window/VariablesView.h index 5427740233..81568b8ce5 100644 --- a/src/apps/debugger/user_interface/gui/team_window/VariablesView.h +++ b/src/apps/debugger/user_interface/gui/team_window/VariablesView.h @@ -77,6 +77,7 @@ private: class VariableTableModel; class ContextMenu; class TableCellContextMenuTracker; + class VariablesExpressionInfo; typedef BObjectList ContextActionList; typedef BObjectList ExpressionInfoList; typedef BObjectList ExpressionChildList; @@ -121,6 +122,9 @@ private: void _AddExpressionNode(ExpressionInfo* info, status_t result, ExpressionResult* value); + void _HandleTypecastResult(status_t result, + ExpressionResult* value); + status_t _GetTypeForTypeCode(int32 typeCode, Type*& _resultType) const; @@ -135,6 +139,7 @@ private: ExpressionInfoTable* fExpressions; ExpressionChildList fExpressionChildren; TableCellContextMenuTracker* fTableCellContextMenuTracker; + VariablesExpressionInfo* fPendingTypecastInfo; bool fFrameClearPending; Listener* fListener; };