Browse Source

HackStudio: Remove "evaluate expression" dialog

This was built on Web::InProcessWebView which is going to be removed.
Since this feature wasn't really used or maintained, let's just remove
it for now, and it can be resurrected on top of OutOfProcessWebView if
someone finds it useful enough to do that work.
Andreas Kling 3 years ago
parent
commit
e076f9997f

+ 0 - 3
Userland/DevTools/HackStudio/CMakeLists.txt

@@ -18,11 +18,8 @@ set(SOURCES
     Debugger/BacktraceModel.cpp
     Debugger/DebugInfoWidget.cpp
     Debugger/Debugger.cpp
-    Debugger/DebuggerGlobalJSObject.cpp
-    Debugger/DebuggerVariableJSObject.cpp
     Debugger/DisassemblyModel.cpp
     Debugger/DisassemblyWidget.cpp
-    Debugger/EvaluateExpressionDialog.cpp
     Debugger/RegistersModel.cpp
     Debugger/VariablesModel.cpp
     Dialogs/Git/GitCommitDialog.cpp

+ 0 - 115
Userland/DevTools/HackStudio/Debugger/DebuggerGlobalJSObject.cpp

@@ -1,115 +0,0 @@
-/*
- * Copyright (c) 2021, Hunter Salyer <thefalsehonesty@gmail.com>
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
-
-#include "DebuggerGlobalJSObject.h"
-#include "Debugger.h"
-#include "DebuggerVariableJSObject.h"
-#include <LibJS/Runtime/Completion.h>
-#include <LibJS/Runtime/Object.h>
-#include <LibJS/Runtime/ProxyObject.h>
-
-namespace HackStudio {
-
-DebuggerGlobalJSObject::DebuggerGlobalJSObject()
-{
-    auto regs = Debugger::the().session()->get_registers();
-    auto lib = Debugger::the().session()->library_at(regs.ip());
-    if (!lib)
-        return;
-    m_variables = lib->debug_info->get_variables_in_current_scope(regs);
-}
-
-JS::ThrowCompletionOr<JS::Value> DebuggerGlobalJSObject::internal_get(JS::PropertyKey const& property_key, JS::Value receiver) const
-{
-    if (m_variables.is_empty() || !property_key.is_string())
-        return Base::internal_get(property_key, receiver);
-
-    auto it = m_variables.find_if([&](auto& variable) {
-        return variable->name == property_key.as_string();
-    });
-    if (it.is_end())
-        return Base::internal_get(property_key, receiver);
-    auto& target_variable = **it;
-    auto js_value = debugger_to_js(target_variable);
-    if (js_value.has_value())
-        return js_value.value();
-    auto error_string = String::formatted("Variable {} of type {} is not convertible to a JS Value", property_key.as_string(), target_variable.type_name);
-    return vm().throw_completion<JS::TypeError>(const_cast<DebuggerGlobalJSObject&>(*this), move(error_string));
-}
-
-JS::ThrowCompletionOr<bool> DebuggerGlobalJSObject::internal_set(JS::PropertyKey const& property_key, JS::Value value, JS::Value receiver)
-{
-    if (m_variables.is_empty() || !property_key.is_string())
-        return Base::internal_set(property_key, value, receiver);
-
-    auto it = m_variables.find_if([&](auto& variable) {
-        return variable->name == property_key.as_string();
-    });
-    if (it.is_end())
-        return Base::internal_set(property_key, value, receiver);
-    auto& target_variable = **it;
-    auto debugger_value = js_to_debugger(value, target_variable);
-    if (debugger_value.has_value())
-        return Debugger::the().session()->poke(target_variable.location_data.address, debugger_value.value());
-    auto error_string = String::formatted("Cannot convert JS value {} to variable {} of type {}", value.to_string_without_side_effects(), property_key.as_string(), target_variable.type_name);
-    return vm().throw_completion<JS::TypeError>(const_cast<DebuggerGlobalJSObject&>(*this), move(error_string));
-}
-
-Optional<JS::Value> DebuggerGlobalJSObject::debugger_to_js(Debug::DebugInfo::VariableInfo const& variable) const
-{
-    if (variable.location_type != Debug::DebugInfo::VariableInfo::LocationType::Address)
-        return {};
-
-    auto variable_address = variable.location_data.address;
-
-    if (variable.is_enum_type() || variable.type_name == "int") {
-        auto value = Debugger::the().session()->peek(variable_address);
-        VERIFY(value.has_value());
-        return JS::Value((i32)value.value());
-    }
-
-    if (variable.type_name == "char") {
-        auto value = Debugger::the().session()->peek(variable_address);
-        VERIFY(value.has_value());
-        return JS::Value((char)value.value());
-    }
-
-    if (variable.type_name == "bool") {
-        auto value = Debugger::the().session()->peek(variable_address);
-        VERIFY(value.has_value());
-        return JS::Value(value.value() != 0);
-    }
-
-    auto* object = DebuggerVariableJSObject::create(const_cast<DebuggerGlobalJSObject&>(*this), variable);
-    for (auto& member : variable.members) {
-        auto member_value = debugger_to_js(member);
-        if (!member_value.has_value())
-            continue;
-        object->define_direct_property(member.name, member_value.value(), JS::default_attributes);
-    }
-
-    return JS::Value(object);
-}
-
-Optional<u32> DebuggerGlobalJSObject::js_to_debugger(JS::Value value, Debug::DebugInfo::VariableInfo const& variable) const
-{
-    if (value.is_string() && variable.type_name == "char") {
-        auto string = value.as_string().string();
-        if (string.length() != 1)
-            return {};
-        return string[0];
-    }
-
-    if (value.is_number() && (variable.is_enum_type() || variable.type_name == "int"))
-        return value.as_u32();
-
-    if (value.is_boolean() && variable.type_name == "bool")
-        return value.as_bool();
-
-    return {};
-}
-
-}

+ 0 - 34
Userland/DevTools/HackStudio/Debugger/DebuggerGlobalJSObject.h

@@ -1,34 +0,0 @@
-/*
- * Copyright (c) 2021, Hunter Salyer <thefalsehonesty@gmail.com>
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
-
-#pragma once
-
-#include <AK/Weakable.h>
-#include <LibDebug/DebugInfo.h>
-#include <LibJS/Runtime/Completion.h>
-#include <LibJS/Runtime/GlobalObject.h>
-
-namespace HackStudio {
-
-class DebuggerGlobalJSObject final
-    : public JS::GlobalObject
-    , public Weakable<DebuggerGlobalJSObject> {
-    JS_OBJECT(DebuggerGlobalJSObject, JS::GlobalObject);
-
-public:
-    DebuggerGlobalJSObject();
-
-    virtual JS::ThrowCompletionOr<JS::Value> internal_get(JS::PropertyKey const&, JS::Value receiver) const override;
-    virtual JS::ThrowCompletionOr<bool> internal_set(JS::PropertyKey const&, JS::Value value, JS::Value receiver) override;
-
-    Optional<JS::Value> debugger_to_js(Debug::DebugInfo::VariableInfo const&) const;
-    Optional<u32> js_to_debugger(JS::Value value, Debug::DebugInfo::VariableInfo const&) const;
-
-private:
-    NonnullOwnPtrVector<Debug::DebugInfo::VariableInfo> m_variables;
-};
-
-}

+ 0 - 58
Userland/DevTools/HackStudio/Debugger/DebuggerVariableJSObject.cpp

@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 2021, Matthew Olsson <matthewcolsson@gmail.com>
- * Copyright (c) 2021, Hunter Salyer <thefalsehonesty@gmail.com>
- * Copyright (c) 2022, the SerenityOS developers.
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
-
-#include "DebuggerVariableJSObject.h"
-#include "Debugger.h"
-#include <LibJS/Runtime/Completion.h>
-#include <LibJS/Runtime/Error.h>
-#include <LibJS/Runtime/PrimitiveString.h>
-#include <LibJS/Runtime/PropertyKey.h>
-
-namespace HackStudio {
-
-DebuggerVariableJSObject* DebuggerVariableJSObject::create(DebuggerGlobalJSObject& global_object, Debug::DebugInfo::VariableInfo const& variable_info)
-{
-    return global_object.heap().allocate<DebuggerVariableJSObject>(global_object, variable_info, *global_object.object_prototype());
-}
-
-DebuggerVariableJSObject::DebuggerVariableJSObject(Debug::DebugInfo::VariableInfo const& variable_info, JS::Object& prototype)
-    : JS::Object(prototype)
-    , m_variable_info(variable_info)
-{
-}
-
-JS::ThrowCompletionOr<bool> DebuggerVariableJSObject::internal_set(const JS::PropertyKey& property_key, JS::Value value, JS::Value)
-{
-    auto& vm = this->vm();
-
-    if (!property_key.is_string())
-        return vm.throw_completion<JS::TypeError>(global_object(), String::formatted("Invalid variable name {}", property_key.to_string()));
-
-    auto name = property_key.as_string();
-    auto it = m_variable_info.members.find_if([&](auto& variable) {
-        return variable->name == name;
-    });
-
-    if (it.is_end())
-        return vm.throw_completion<JS::TypeError>(global_object(), String::formatted("Variable of type {} has no property {}", m_variable_info.type_name, property_key));
-
-    auto& member = **it;
-    auto new_value = debugger_object().js_to_debugger(value, member);
-    if (!new_value.has_value())
-        return vm.throw_completion<JS::TypeError>(global_object(), String::formatted("Cannot convert JS value {} to variable {} of type {}", value.to_string_without_side_effects(), name, member.type_name));
-
-    Debugger::the().session()->poke(member.location_data.address, new_value.value());
-    return true;
-}
-
-DebuggerGlobalJSObject& DebuggerVariableJSObject::debugger_object() const
-{
-    return static_cast<DebuggerGlobalJSObject&>(global_object());
-}
-
-}

+ 0 - 38
Userland/DevTools/HackStudio/Debugger/DebuggerVariableJSObject.h

@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2021, Matthew Olsson <matthewcolsson@gmail.com>
- * Copyright (c) 2021, Hunter Salyer <thefalsehonesty@gmail.com>
- * Copyright (c) 2022, the SerenityOS developers.
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
-
-#pragma once
-
-#include "DebuggerGlobalJSObject.h"
-#include <AK/StringView.h>
-#include <LibDebug/DebugInfo.h>
-#include <LibJS/Runtime/Completion.h>
-#include <LibJS/Runtime/Object.h>
-
-namespace HackStudio {
-
-class DebuggerVariableJSObject final : public JS::Object {
-    using Base = JS::Object;
-
-public:
-    static DebuggerVariableJSObject* create(DebuggerGlobalJSObject&, Debug::DebugInfo::VariableInfo const& variable_info);
-
-    DebuggerVariableJSObject(Debug::DebugInfo::VariableInfo const& variable_info, JS::Object& prototype);
-    virtual ~DebuggerVariableJSObject() override = default;
-
-    virtual StringView class_name() const override { return m_variable_info.type_name; }
-
-    JS::ThrowCompletionOr<bool> internal_set(JS::PropertyKey const&, JS::Value value, JS::Value receiver) override;
-
-private:
-    DebuggerGlobalJSObject& debugger_object() const;
-
-    Debug::DebugInfo::VariableInfo const& m_variable_info;
-};
-
-}

+ 0 - 147
Userland/DevTools/HackStudio/Debugger/EvaluateExpressionDialog.cpp

@@ -1,147 +0,0 @@
-/*
- * Copyright (c) 2021, Hunter Salyer <thefalsehonesty@gmail.com>
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
-
-#include "EvaluateExpressionDialog.h"
-#include "DebuggerGlobalJSObject.h"
-#include <LibGUI/BoxLayout.h>
-#include <LibGUI/Button.h>
-#include <LibGUI/TextBox.h>
-#include <LibGUI/Widget.h>
-#include <LibGfx/FontDatabase.h>
-#include <LibJS/Interpreter.h>
-#include <LibJS/MarkupGenerator.h>
-#include <LibJS/Parser.h>
-#include <LibJS/SyntaxHighlighter.h>
-#include <LibWeb/DOM/DocumentType.h>
-
-namespace HackStudio {
-
-static JS::VM& global_vm()
-{
-    static RefPtr<JS::VM> vm;
-    if (!vm)
-        vm = JS::VM::create();
-    return *vm;
-}
-
-EvaluateExpressionDialog::EvaluateExpressionDialog(Window* parent_window)
-    : Dialog(parent_window)
-    , m_interpreter(JS::Interpreter::create<DebuggerGlobalJSObject>(global_vm()))
-{
-    set_title("Evaluate Expression");
-    set_icon(parent_window->icon());
-    build(parent_window);
-}
-
-void EvaluateExpressionDialog::build(Window* parent_window)
-{
-    auto& widget = set_main_widget<GUI::Widget>();
-
-    int width = max(parent_window->width() / 2, 150);
-    int height = max(parent_window->height() * (2 / 3), 350);
-
-    set_rect(x(), y(), width, height);
-
-    widget.set_layout<GUI::VerticalBoxLayout>();
-    widget.set_fill_with_background_color(true);
-
-    widget.layout()->set_margins(6);
-    widget.layout()->set_spacing(6);
-
-    m_text_editor = widget.add<GUI::TextBox>();
-    m_text_editor->set_fixed_height(19);
-    m_text_editor->set_syntax_highlighter(make<JS::SyntaxHighlighter>());
-    m_text_editor->set_font(Gfx::FontDatabase::default_fixed_width_font());
-    m_text_editor->set_history_enabled(true);
-
-    auto base_document = Web::DOM::Document::create();
-    base_document->append_child(adopt_ref(*new Web::DOM::DocumentType(base_document)));
-    auto html_element = base_document->create_element("html").release_value();
-    base_document->append_child(html_element);
-    auto head_element = base_document->create_element("head").release_value();
-    html_element->append_child(head_element);
-    auto body_element = base_document->create_element("body").release_value();
-    html_element->append_child(body_element);
-    m_output_container = body_element;
-
-    m_output_view = widget.add<Web::InProcessWebView>();
-    m_output_view->set_document(base_document);
-
-    auto& button_container_outer = widget.add<GUI::Widget>();
-    button_container_outer.set_fixed_height(20);
-    button_container_outer.set_layout<GUI::VerticalBoxLayout>();
-
-    auto& button_container_inner = button_container_outer.add<GUI::Widget>();
-    button_container_inner.set_layout<GUI::HorizontalBoxLayout>();
-    button_container_inner.layout()->set_spacing(6);
-    button_container_inner.layout()->set_margins({ 4, 0, 4 });
-    button_container_inner.layout()->add_spacer();
-
-    m_evaluate_button = button_container_inner.add<GUI::Button>();
-    m_evaluate_button->set_fixed_height(20);
-    m_evaluate_button->set_text("Evaluate");
-    m_evaluate_button->on_click = [this](auto) {
-        handle_evaluation(m_text_editor->text());
-    };
-
-    m_close_button = button_container_inner.add<GUI::Button>();
-    m_close_button->set_fixed_height(20);
-    m_close_button->set_text("Close");
-    m_close_button->on_click = [this](auto) {
-        done(ExecOK);
-    };
-
-    m_text_editor->on_return_pressed = [this] {
-        m_evaluate_button->click();
-    };
-    m_text_editor->on_escape_pressed = [this] {
-        m_close_button->click();
-    };
-    m_text_editor->set_focus(true);
-}
-
-void EvaluateExpressionDialog::handle_evaluation(String const& expression)
-{
-    m_output_container->remove_all_children();
-    m_output_view->update();
-
-    auto script_or_error = JS::Script::parse(expression, m_interpreter->realm());
-
-    StringBuilder output_html;
-    auto result = JS::ThrowCompletionOr<JS::Value> { JS::js_undefined() };
-    if (script_or_error.is_error()) {
-        auto error = script_or_error.error()[0];
-        auto hint = error.source_location_hint(expression);
-        if (!hint.is_empty())
-            output_html.append(String::formatted("<pre>{}</pre>", escape_html_entities(hint)));
-        result = m_interpreter->vm().throw_completion<JS::SyntaxError>(m_interpreter->global_object(), error.to_string());
-    } else {
-        result = m_interpreter->run(script_or_error.value());
-    }
-
-    if (result.is_error()) {
-        output_html.append("Uncaught exception: ");
-        auto error = *result.throw_completion().value();
-        if (error.is_object())
-            output_html.append(JS::MarkupGenerator::html_from_error(error.as_object()));
-        else
-            output_html.append(JS::MarkupGenerator::html_from_value(error));
-        set_output(output_html.string_view());
-        return;
-    }
-
-    set_output(JS::MarkupGenerator::html_from_value(result.value()));
-}
-
-void EvaluateExpressionDialog::set_output(StringView html)
-{
-    auto paragraph = m_output_container->document().create_element("p").release_value();
-    paragraph->set_inner_html(html);
-
-    m_output_container->append_child(paragraph);
-}
-
-}

+ 0 - 32
Userland/DevTools/HackStudio/Debugger/EvaluateExpressionDialog.h

@@ -1,32 +0,0 @@
-/*
- * Copyright (c) 2021, Hunter Salyer <thefalsehonesty@gmail.com>
- *
- * SPDX-License-Identifier: BSD-2-Clause
- */
-
-#pragma once
-
-#include <LibGUI/Dialog.h>
-#include <LibWeb/InProcessWebView.h>
-
-namespace HackStudio {
-
-class EvaluateExpressionDialog : public GUI::Dialog {
-    C_OBJECT(EvaluateExpressionDialog);
-
-private:
-    explicit EvaluateExpressionDialog(Window* parent_window);
-
-    void build(Window* parent_window);
-    void handle_evaluation(String const& expression);
-    void set_output(StringView html);
-
-    NonnullOwnPtr<JS::Interpreter> m_interpreter;
-    RefPtr<GUI::TextBox> m_text_editor;
-    RefPtr<Web::InProcessWebView> m_output_view;
-    RefPtr<Web::DOM::Element> m_output_container;
-    RefPtr<GUI::Button> m_evaluate_button;
-    RefPtr<GUI::Button> m_close_button;
-};
-
-}

+ 0 - 8
Userland/DevTools/HackStudio/Editor.cpp

@@ -7,7 +7,6 @@
 
 #include "Editor.h"
 #include "Debugger/Debugger.h"
-#include "Debugger/EvaluateExpressionDialog.h"
 #include "EditorWrapper.h"
 #include "HackStudio.h"
 #include "Language.h"
@@ -56,11 +55,6 @@ Editor::Editor()
     create_tokens_info_timer();
 
     set_document(CodeDocument::create());
-    m_evaluate_expression_action = GUI::Action::create("Evaluate expression", { Mod_Ctrl, Key_E }, [this](auto&) {
-        VERIFY(is_program_running());
-        auto dialog = EvaluateExpressionDialog::construct(window());
-        dialog->exec();
-    });
     m_move_execution_to_line_action = GUI::Action::create("Set execution point to line", [this](auto&) {
         VERIFY(is_program_running());
         auto success = Debugger::the().set_execution_position(currently_open_file(), cursor().line());
@@ -73,7 +67,6 @@ Editor::Editor()
 
     set_debug_mode(false);
 
-    add_custom_context_menu_action(*m_evaluate_expression_action);
     add_custom_context_menu_action(*m_move_execution_to_line_action);
 
     set_gutter_visible(true);
@@ -722,7 +715,6 @@ void Editor::handle_function_parameters_hint_request()
 
 void Editor::set_debug_mode(bool enabled)
 {
-    m_evaluate_expression_action->set_enabled(enabled);
     m_move_execution_to_line_action->set_enabled(enabled);
 }
 

+ 0 - 1
Userland/DevTools/HackStudio/Editor.h

@@ -120,7 +120,6 @@ private:
     bool m_hovering_editor { false };
     bool m_hovering_clickable { false };
     bool m_autocomplete_in_focus { false };
-    RefPtr<GUI::Action> m_evaluate_expression_action;
     RefPtr<GUI::Action> m_move_execution_to_line_action;
     RefPtr<Core::Timer> m_tokens_info_timer; // Used for querying language server for syntax highlighting info
     OwnPtr<LanguageClient> m_language_client;