From 9dcef0489e544e13fc8ce4b92923ebe48b66f861 Mon Sep 17 00:00:00 2001 From: Rene Gollent Date: Mon, 15 Dec 2014 17:14:33 -0500 Subject: [PATCH] Debugger: Cleanups. Get rid of ExpressionEvaluationWindow. - When asking to evaluate an expression via the Tools menu, we now bring up a prompt window the same as the one used to add a watch expression. This in turn works exactly the same as the latter, except an additional flag is sent indicating that the expression in question should not be persisted. As such, the results are shown in the variables view, with all the capabilities that allows, but also without the expression following the function as a watch expression would. --- src/apps/debugger/Jamfile | 1 - .../ExpressionEvaluationWindow.cpp | 219 ------------------ .../team_window/ExpressionEvaluationWindow.h | 69 ------ .../team_window/ExpressionPromptWindow.cpp | 15 +- .../gui/team_window/ExpressionPromptWindow.h | 6 +- .../gui/team_window/TeamWindow.cpp | 52 ++--- .../gui/team_window/TeamWindow.h | 2 - .../gui/team_window/VariablesView.cpp | 73 ++++-- .../gui/team_window/VariablesView.h | 2 + 9 files changed, 79 insertions(+), 360 deletions(-) delete mode 100644 src/apps/debugger/user_interface/gui/team_window/ExpressionEvaluationWindow.cpp delete mode 100644 src/apps/debugger/user_interface/gui/team_window/ExpressionEvaluationWindow.h diff --git a/src/apps/debugger/Jamfile b/src/apps/debugger/Jamfile index 970a315f4e..678dea3ecc 100644 --- a/src/apps/debugger/Jamfile +++ b/src/apps/debugger/Jamfile @@ -275,7 +275,6 @@ Application Debugger : BreakpointListView.cpp BreakpointsView.cpp ConsoleOutputView.cpp - ExpressionEvaluationWindow.cpp ExpressionPromptWindow.cpp ImageFunctionsView.cpp ImageListView.cpp diff --git a/src/apps/debugger/user_interface/gui/team_window/ExpressionEvaluationWindow.cpp b/src/apps/debugger/user_interface/gui/team_window/ExpressionEvaluationWindow.cpp deleted file mode 100644 index 51a8b7b988..0000000000 --- a/src/apps/debugger/user_interface/gui/team_window/ExpressionEvaluationWindow.cpp +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright 2014, Rene Gollent, rene@gollent.com. - * Distributed under the terms of the MIT License. - */ -#include "ExpressionEvaluationWindow.h" - -#include -#include -#include -#include -#include -#include -#include - -#include "AutoLocker.h" - -#include "IntegerValue.h" -#include "MessageCodes.h" -#include "SourceLanguage.h" -#include "StackFrame.h" -#include "SyntheticPrimitiveType.h" -#include "Thread.h" -#include "UiUtils.h" -#include "UserInterface.h" - - -ExpressionEvaluationWindow::ExpressionEvaluationWindow( - SourceLanguage* language, StackFrame* frame, ::Thread* thread, - UserInterfaceListener* listener, BHandler* target) - : - BWindow(BRect(), "Evaluate Expression", B_FLOATING_WINDOW, - B_AUTO_UPDATE_SIZE_LIMITS | B_CLOSE_ON_ESCAPE), - fLanguage(language), - fExpressionInfo(NULL), - fExpressionInput(NULL), - fExpressionOutput(NULL), - fEvaluateButton(NULL), - fListener(listener), - fStackFrame(frame), - fThread(thread), - fCloseTarget(target) -{ - fLanguage->AcquireReference(); - - if (fStackFrame != NULL) - fStackFrame->AcquireReference(); - - if (fThread != NULL) - fThread->AcquireReference(); -} - - -ExpressionEvaluationWindow::~ExpressionEvaluationWindow() -{ - fLanguage->ReleaseReference(); - - if (fStackFrame != NULL) - fStackFrame->ReleaseReference(); - - if (fThread != NULL) - fThread->ReleaseReference(); - - fExpressionInfo->ReleaseReference(); -} - - -ExpressionEvaluationWindow* -ExpressionEvaluationWindow::Create(SourceLanguage* language, StackFrame* frame, - ::Thread* thread, UserInterfaceListener* listener, BHandler* target) -{ - ExpressionEvaluationWindow* self = new ExpressionEvaluationWindow(language, - frame, thread, listener, target); - - try { - self->_Init(); - } catch (...) { - delete self; - throw; - } - - return self; - -} - - -void -ExpressionEvaluationWindow::_Init() -{ - fExpressionInfo = new ExpressionInfo; - fExpressionInfo->AddListener(this); - - fExpressionInput = new BTextControl("Expression:", NULL, - new BMessage(MSG_EVALUATE_EXPRESSION)); - BLayoutItem* labelItem = fExpressionInput->CreateLabelLayoutItem(); - BLayoutItem* inputItem = fExpressionInput->CreateTextViewLayoutItem(); - inputItem->SetExplicitMinSize(BSize(200.0, B_SIZE_UNSET)); - inputItem->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, B_SIZE_UNSET)); - labelItem->View()->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); - - fExpressionOutput = new BStringView("ExpressionOutputView", NULL); - fExpressionOutput->SetExplicitMaxSize(BSize(B_SIZE_UNLIMITED, - B_SIZE_UNSET)); - - BLayoutBuilder::Group<>(this, B_VERTICAL) - .SetInsets(B_USE_DEFAULT_SPACING) - .AddGroup(B_HORIZONTAL, 4.0f) - .Add(labelItem) - .Add(inputItem) - .End() - .AddGroup(B_HORIZONTAL, 4.0f) - .Add(new BStringView("OutputLabelView", "Result:")) - .Add(fExpressionOutput) - .End() - .AddGroup(B_HORIZONTAL, 4.0f) - .AddGlue() - .Add((fEvaluateButton = new BButton("Evaluate", - new BMessage(MSG_EVALUATE_EXPRESSION)))) - .End(); - - fExpressionInput->SetTarget(this); - fEvaluateButton->SetTarget(this); - fEvaluateButton->MakeDefault(true); - fExpressionInput->TextView()->MakeFocus(true); -} - - -void -ExpressionEvaluationWindow::ExpressionEvaluated(ExpressionInfo* info, - status_t result, ExpressionResult* value) -{ - BMessage message(MSG_EXPRESSION_EVALUATED); - message.AddInt32("result", result); - BReference reference; - if (value != NULL) { - message.AddPointer("value", value); - reference.SetTo(value); - } - - if (PostMessage(&message) == B_OK) - reference.Detach(); -} - - -void -ExpressionEvaluationWindow::Show() -{ - CenterOnScreen(); - BWindow::Show(); -} - - -bool -ExpressionEvaluationWindow::QuitRequested() -{ - BMessenger messenger(fCloseTarget); - messenger.SendMessage(MSG_EXPRESSION_WINDOW_CLOSED); - - return BWindow::QuitRequested(); -} - - -void -ExpressionEvaluationWindow::MessageReceived(BMessage* message) -{ - switch (message->what) { - case MSG_EVALUATE_EXPRESSION: - { - if (fExpressionInput->TextView()->TextLength() == 0) - break; - - fExpressionInfo->SetTo(fExpressionInput->Text()); - - fListener->ExpressionEvaluationRequested(fLanguage, - fExpressionInfo, fStackFrame, fThread); - break; - } - case MSG_EXPRESSION_EVALUATED: - { - ExpressionResult* value = NULL; - BReference reference; - if (message->FindPointer("value", - reinterpret_cast(&value)) == B_OK) { - reference.SetTo(value, true); - } - - BString outputText; - if (value != NULL) { - if (value->Kind() == EXPRESSION_RESULT_KIND_PRIMITIVE) { - Value* primitive = value->PrimitiveValue(); - if (dynamic_cast(primitive) != NULL) { - BVariant variantValue; - primitive->ToVariant(variantValue); - primitive->ToString(outputText); - outputText.SetToFormat("%#" B_PRIx64 " (%s)", - variantValue.ToUInt64(), outputText.String()); - } else - primitive->ToString(outputText); - } else { - outputText.SetToFormat("Unsupported result type: %d", - value->Kind()); - } - } else { - status_t result; - if (message->FindInt32("result", &result) != B_OK) - result = B_ERROR; - - outputText.SetToFormat("Failed to evaluate expression: %s", - strerror(result)); - } - - fExpressionOutput->SetText(outputText); - break; - } - default: - BWindow::MessageReceived(message); - break; - } - -} diff --git a/src/apps/debugger/user_interface/gui/team_window/ExpressionEvaluationWindow.h b/src/apps/debugger/user_interface/gui/team_window/ExpressionEvaluationWindow.h deleted file mode 100644 index e985667b96..0000000000 --- a/src/apps/debugger/user_interface/gui/team_window/ExpressionEvaluationWindow.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2014, Rene Gollent, rene@gollent.com. - * Distributed under the terms of the MIT License. - */ -#ifndef EXPRESSION_EVALUATION_WINDOW_H -#define EXPRESSION_EVALUATION_WINDOW_H - - -#include - -#include "ExpressionInfo.h" - - -class BButton; -class BStringView; -class BTextControl; -class Thread; -class SourceLanguage; -class StackFrame; -class UserInterfaceListener; - - -class ExpressionEvaluationWindow : public BWindow, - private ExpressionInfo::Listener -{ -public: - ExpressionEvaluationWindow( - SourceLanguage* language, - StackFrame* frame, - ::Thread* thread, - UserInterfaceListener* listener, - BHandler* target); - - ~ExpressionEvaluationWindow(); - - static ExpressionEvaluationWindow* Create( - SourceLanguage* language, - StackFrame* frame, - ::Thread* thread, - UserInterfaceListener* listener, - BHandler* target); - // throws - - - virtual void MessageReceived(BMessage* message); - - virtual void Show(); - virtual bool QuitRequested(); - -private: - void _Init(); - - // ExpressionInfo::Listener - virtual void ExpressionEvaluated(ExpressionInfo* info, - status_t result, ExpressionResult* value); - -private: - SourceLanguage* fLanguage; - ExpressionInfo* fExpressionInfo; - BTextControl* fExpressionInput; - BStringView* fExpressionOutput; - BButton* fEvaluateButton; - UserInterfaceListener* fListener; - StackFrame* fStackFrame; - ::Thread* fThread; - BHandler* fCloseTarget; -}; - -#endif // EXPRESSION_EVALUATION_WINDOW_H diff --git a/src/apps/debugger/user_interface/gui/team_window/ExpressionPromptWindow.cpp b/src/apps/debugger/user_interface/gui/team_window/ExpressionPromptWindow.cpp index 7e59844ee4..6c142b5873 100644 --- a/src/apps/debugger/user_interface/gui/team_window/ExpressionPromptWindow.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/ExpressionPromptWindow.cpp @@ -13,15 +13,16 @@ ExpressionPromptWindow::ExpressionPromptWindow(BHandler* addTarget, - BHandler* closeTarget) + BHandler* closeTarget, bool isPersistent) : - BWindow(BRect(), "Add Expression", B_FLOATING_WINDOW, - B_AUTO_UPDATE_SIZE_LIMITS | B_CLOSE_ON_ESCAPE), + BWindow(BRect(), isPersistent ? "Add Expression" : "Evaluate Expression", + B_FLOATING_WINDOW, B_AUTO_UPDATE_SIZE_LIMITS | B_CLOSE_ON_ESCAPE), fExpressionInput(NULL), fCancelButton(NULL), fAddButton(NULL), fAddTarget(addTarget), - fCloseTarget(closeTarget) + fCloseTarget(closeTarget), + fPersistentExpression(isPersistent) { } @@ -32,10 +33,11 @@ ExpressionPromptWindow::~ExpressionPromptWindow() ExpressionPromptWindow* -ExpressionPromptWindow::Create(BHandler* addTarget, BHandler* closeTarget) +ExpressionPromptWindow::Create(BHandler* addTarget, BHandler* closeTarget, + bool isPersistent) { ExpressionPromptWindow* self = new ExpressionPromptWindow(addTarget, - closeTarget); + closeTarget, isPersistent); try { self->_Init(); @@ -108,6 +110,7 @@ ExpressionPromptWindow::MessageReceived(BMessage* message) { BMessage addMessage(MSG_EXPRESSION_PROMPT_WINDOW_CLOSED); addMessage.AddString("expression", fExpressionInput->Text()); + addMessage.AddBool("persistent", fPersistentExpression); addMessage.AddMessenger("target", BMessenger(fAddTarget)); BMessenger(fCloseTarget).SendMessage(&addMessage); diff --git a/src/apps/debugger/user_interface/gui/team_window/ExpressionPromptWindow.h b/src/apps/debugger/user_interface/gui/team_window/ExpressionPromptWindow.h index ce18792f55..ca5b43a636 100644 --- a/src/apps/debugger/user_interface/gui/team_window/ExpressionPromptWindow.h +++ b/src/apps/debugger/user_interface/gui/team_window/ExpressionPromptWindow.h @@ -17,12 +17,13 @@ class ExpressionPromptWindow : public BWindow { public: ExpressionPromptWindow(BHandler* addTarget, - BHandler* closeTarget); + BHandler* closeTarget, bool isPersistent); ~ExpressionPromptWindow(); static ExpressionPromptWindow* Create(BHandler* addTarget, - BHandler* closeTarget); + BHandler* closeTarget, + bool isPersistent); // throws @@ -40,6 +41,7 @@ private: BButton* fAddButton; BHandler* fAddTarget; BHandler* fCloseTarget; + bool fPersistentExpression; }; #endif // EXPRESSION_PROMPT_WINDOW_H diff --git a/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp b/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp index 0f8f101fda..7dbb0f9ca6 100644 --- a/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/TeamWindow.cpp @@ -41,7 +41,6 @@ #include "CpuState.h" #include "DisassembledCode.h" #include "BreakpointEditWindow.h" -#include "ExpressionEvaluationWindow.h" #include "ExpressionPromptWindow.h" #include "FileSourceCode.h" #include "GuiSettingsUtils.h" @@ -142,7 +141,6 @@ TeamWindow::TeamWindow(::Team* team, UserInterfaceListener* listener) fBreakConditionConfigWindow(NULL), fBreakpointEditWindow(NULL), fInspectorWindow(NULL), - fExpressionWindow(NULL), fExpressionPromptWindow(NULL), fFilePanel(NULL), fActiveSourceWorker(-1) @@ -170,9 +168,9 @@ TeamWindow::~TeamWindow() if (fInspectorWindow->Lock()) fInspectorWindow->Quit(); } - if (fExpressionWindow != NULL) { - if (fExpressionWindow->Lock()) - fExpressionWindow->Quit(); + if (fExpressionPromptWindow != NULL) { + if (fExpressionPromptWindow->Lock()) + fExpressionPromptWindow->Quit(); } fTeam->RemoveListener(this); @@ -348,39 +346,12 @@ TeamWindow::MessageReceived(BMessage* message) } case MSG_SHOW_EXPRESSION_WINDOW: - { - if (fExpressionWindow != NULL) { - AutoLocker lock(fExpressionWindow); - if (lock.IsLocked()) - fExpressionWindow->Activate(true); - } else { - try { - SourceLanguage* language = NULL; - if (_GetActiveSourceLanguage(language) != B_OK) - break; - - BReference languageReference(language, - true); - fExpressionWindow = ExpressionEvaluationWindow::Create( - language, fActiveStackFrame, fActiveThread, fListener, - this); - if (fExpressionWindow != NULL) - fExpressionWindow->Show(); - } catch (...) { - // TODO: notify user - } - } - break; - } - case MSG_EXPRESSION_WINDOW_CLOSED: - { - fExpressionWindow = NULL; - break; - } case MSG_SHOW_EXPRESSION_PROMPT_WINDOW: { BHandler* addTarget; - if (message->FindPointer("target", + if (message->what == MSG_SHOW_EXPRESSION_WINDOW) + addTarget = fVariablesView; + else if (message->FindPointer("target", reinterpret_cast(&addTarget)) != B_OK) { break; } @@ -391,8 +362,13 @@ TeamWindow::MessageReceived(BMessage* message) fExpressionPromptWindow->Activate(true); } else { try { + // if the request was initiated via the evaluate + // expression top level menu item, then this evaluation + // should not be persisted. + bool persistentExpression = + message->what == MSG_SHOW_EXPRESSION_PROMPT_WINDOW; fExpressionPromptWindow = ExpressionPromptWindow::Create( - addTarget, this); + addTarget, this, persistentExpression); if (fExpressionPromptWindow != NULL) fExpressionPromptWindow->Show(); } catch (...) { @@ -401,6 +377,7 @@ TeamWindow::MessageReceived(BMessage* message) } break; } + case MSG_EXPRESSION_WINDOW_CLOSED: case MSG_EXPRESSION_PROMPT_WINDOW_CLOSED: { fExpressionPromptWindow = NULL; @@ -410,8 +387,11 @@ TeamWindow::MessageReceived(BMessage* message) if (message->FindString("expression", &expression) == B_OK && message->FindMessenger("target", &targetMessenger) == B_OK) { + BMessage addMessage(MSG_ADD_NEW_EXPRESSION); addMessage.AddString("expression", expression); + addMessage.AddBool("persistent", message->FindBool( + "persistent")); targetMessenger.SendMessage(&addMessage); } diff --git a/src/apps/debugger/user_interface/gui/team_window/TeamWindow.h b/src/apps/debugger/user_interface/gui/team_window/TeamWindow.h index d42dec4916..d9f5dfa7e9 100644 --- a/src/apps/debugger/user_interface/gui/team_window/TeamWindow.h +++ b/src/apps/debugger/user_interface/gui/team_window/TeamWindow.h @@ -34,7 +34,6 @@ class BTabView; class ConsoleOutputView; class BreakConditionConfigWindow; class BreakpointEditWindow; -class ExpressionEvaluationWindow; class ExpressionPromptWindow; class Image; class InspectorWindow; @@ -231,7 +230,6 @@ private: BreakConditionConfigWindow* fBreakConditionConfigWindow; BreakpointEditWindow* fBreakpointEditWindow; InspectorWindow* fInspectorWindow; - ExpressionEvaluationWindow* fExpressionWindow; ExpressionPromptWindow* fExpressionPromptWindow; GuiTeamUiSettings fUiSettings; BFilePanel* fFilePanel; 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 45c6ddd897..0b58a6954c 100644 --- a/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp @@ -1740,6 +1740,7 @@ VariablesView::VariablesView(Listener* listener) fExpressionChildren(10, false), fTableCellContextMenuTracker(NULL), fPendingTypecastInfo(NULL), + fTemporaryExpression(NULL), fFrameClearPending(false), fListener(listener) { @@ -1764,6 +1765,9 @@ VariablesView::~VariablesView() delete fContainerListener; if (fPendingTypecastInfo != NULL) fPendingTypecastInfo->ReleaseReference(); + + if (fTemporaryExpression != NULL) + fTemporaryExpression->ReleaseReference(); } @@ -2060,8 +2064,11 @@ VariablesView::MessageReceived(BMessage* message) if (message->FindString("expression", &expression) != B_OK) break; + bool persistentExpression = message->FindBool("persistent"); + ExpressionInfo* info; - status_t error = _AddExpression(expression, info); + status_t error = _AddExpression(expression, persistentExpression, + info); if (error != B_OK) { // TODO: notify user of failure break; @@ -2096,8 +2103,13 @@ VariablesView::MessageReceived(BMessage* message) fPendingTypecastInfo->ReleaseReference(); fPendingTypecastInfo = NULL; } - } else + } else { _AddExpressionNode(info, result, value); + if (info == fTemporaryExpression) { + info->ReleaseReference(); + fTemporaryExpression = NULL; + } + } break; } @@ -2828,29 +2840,33 @@ VariablesView::_CopyVariableValueToClipboard() status_t -VariablesView::_AddExpression(const char* expression, ExpressionInfo*& _info) +VariablesView::_AddExpression(const char* expression, + bool persistentExpression, ExpressionInfo*& _info) { - // if our stack frame doesn't have an associated function, - // we can't add an expression - FunctionInstance* function = fStackFrame->Function(); - if (function == NULL) - return B_NOT_ALLOWED; + ExpressionInfoEntry* entry = NULL; + if (persistentExpression) { + // if our stack frame doesn't have an associated function, + // we can't add an expression + FunctionInstance* function = fStackFrame->Function(); + if (function == NULL) + return B_NOT_ALLOWED; - FunctionID* id = function->GetFunctionID(); - if (id == NULL) - return B_NO_MEMORY; - - BReference idReference(id, true); - - ExpressionInfoEntry* entry = fExpressions->Lookup(FunctionKey(id)); - if (entry == NULL) { - entry = new(std::nothrow) ExpressionInfoEntry(id); - if (entry == NULL) + FunctionID* id = function->GetFunctionID(); + if (id == NULL) return B_NO_MEMORY; - status_t error = fExpressions->Insert(entry); - if (error != B_OK) { - delete entry; - return error; + + BReference idReference(id, true); + + entry = fExpressions->Lookup(FunctionKey(id)); + if (entry == NULL) { + entry = new(std::nothrow) ExpressionInfoEntry(id); + if (entry == NULL) + return B_NO_MEMORY; + status_t error = fExpressions->Insert(entry); + if (error != B_OK) { + delete entry; + return error; + } } } @@ -2861,8 +2877,11 @@ VariablesView::_AddExpression(const char* expression, ExpressionInfo*& _info) BReference infoReference(info, true); - if (!entry->AddItem(info)) - return B_NO_MEMORY; + if (persistentExpression) { + if (!entry->AddItem(info)) + return B_NO_MEMORY; + } else + fTemporaryExpression = info; info->AddListener(this); infoReference.Detach(); @@ -2926,6 +2945,7 @@ void VariablesView::_AddExpressionNode(ExpressionInfo* info, status_t result, ExpressionResult* value) { + bool temporaryExpression = (info == fTemporaryExpression); Variable* variable = NULL; BReference variableReference; BVariant valueData; @@ -2990,9 +3010,12 @@ VariablesView::_AddExpressionNode(ExpressionInfo* info, status_t result, child->Node()->SetLocationAndValue(NULL, explicitValue, B_OK); } - if (fExpressionChildren.AddItem(child)) { + if (temporaryExpression || fExpressionChildren.AddItem(child)) { child->AcquireReference(); + if (temporaryExpression) + return; + // attempt to restore our newly added node's view state, // if applicable. FunctionID* functionID = fStackFrame->Function() 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 81568b8ce5..b19ed15b6c 100644 --- a/src/apps/debugger/user_interface/gui/team_window/VariablesView.h +++ b/src/apps/debugger/user_interface/gui/team_window/VariablesView.h @@ -114,6 +114,7 @@ private: void _CopyVariableValueToClipboard(); status_t _AddExpression(const char* expression, + bool persistentExpression, ExpressionInfo*& _info); void _RemoveExpression(ModelNode* node); @@ -140,6 +141,7 @@ private: ExpressionChildList fExpressionChildren; TableCellContextMenuTracker* fTableCellContextMenuTracker; VariablesExpressionInfo* fPendingTypecastInfo; + ExpressionInfo* fTemporaryExpression; bool fFrameClearPending; Listener* fListener; };