diff --git a/mix/AssemblyDebuggerControl.cpp b/mix/AssemblyDebuggerControl.cpp index 528d965c3..53d5e068f 100644 --- a/mix/AssemblyDebuggerControl.cpp +++ b/mix/AssemblyDebuggerControl.cpp @@ -55,7 +55,7 @@ QString toQString(dev::u256 _value) return QString::fromStdString(s.str()); } -AssemblyDebuggerControl::AssemblyDebuggerControl(AppContext* _context): Extension(_context, ExtensionDisplayBehavior::ModalDialog) +AssemblyDebuggerControl::AssemblyDebuggerControl(AppContext* _context): Extension(_context, ExtensionDisplayBehavior::RightView) { qRegisterMetaType("QVariableDefinition*"); qRegisterMetaType("QVariableDefinitionList*"); @@ -128,7 +128,7 @@ void AssemblyDebuggerControl::callContract(TransactionSettings _tr, dev::Address { auto compilerRes = m_ctx->codeModel()->code(); if (!compilerRes->successfull()) - m_ctx->displayMessageDialog("debugger","compilation failed"); + return; else { ContractCallDataEncoder c; @@ -194,10 +194,11 @@ void AssemblyDebuggerControl::updateGUI(bool _success, DebuggingStatusResult con m_appEngine->rootContext()->setContextProperty("humanReadableExecutionCode", QVariant::fromValue(std::get<0>(_code))); m_appEngine->rootContext()->setContextProperty("bytesCodeMapping", QVariant::fromValue(std::get<1>(_code))); m_appEngine->rootContext()->setContextProperty("contractCallReturnParameters", QVariant::fromValue(new QVariableDefinitionList(_returnParam))); - this->addContentOn(this); } - else - m_ctx->displayMessageDialog(QApplication::tr("debugger"), QApplication::tr("compilation failed")); + + QVariant returnValue; + QObject* debugPanel = m_view->findChild("debugPanel", Qt::FindChildrenRecursively); + QMetaObject::invokeMethod(debugPanel, "init", Q_RETURN_ARG(QVariant, returnValue)); } void AssemblyDebuggerControl::runTransaction(TransactionSettings const& _tr) diff --git a/mix/CodeEditorExtensionManager.cpp b/mix/CodeEditorExtensionManager.cpp index b7e5680ff..31f9b480d 100644 --- a/mix/CodeEditorExtensionManager.cpp +++ b/mix/CodeEditorExtensionManager.cpp @@ -80,9 +80,9 @@ void CodeEditorExtensionManager::initExtension(std::shared_ptr _ext) try { if (_ext->getDisplayBehavior() == ExtensionDisplayBehavior::RightView) - _ext->addContentOn(m_rightView); + _ext->addTabOn(m_rightView); if (_ext->getDisplayBehavior() == ExtensionDisplayBehavior::HeaderView) - _ext->addContentOn(m_headerView); + _ext->addTabOn(m_headerView); } catch (...) { diff --git a/mix/CodeModel.cpp b/mix/CodeModel.cpp index bafc42faa..ff468ff18 100644 --- a/mix/CodeModel.cpp +++ b/mix/CodeModel.cpp @@ -1,18 +1,18 @@ /* - This file is part of cpp-ethereum. + This file is part of cpp-ethereum. - cpp-ethereum is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. - cpp-ethereum is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + cpp-ethereum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with cpp-ethereum. If not, see . + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . */ /** @file CodeModel.cpp * @author Arkadiy Paronyan arkadiy@ethdev.com diff --git a/mix/CodeModel.h b/mix/CodeModel.h index c33110226..8cccd1943 100644 --- a/mix/CodeModel.h +++ b/mix/CodeModel.h @@ -1,18 +1,18 @@ /* - This file is part of cpp-ethereum. + This file is part of cpp-ethereum. - cpp-ethereum is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. - cpp-ethereum is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + cpp-ethereum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with cpp-ethereum. If not, see . + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see . */ /** @file CodeModel.h * @author Arkadiy Paronyan arkadiy@ethdev.com @@ -60,6 +60,8 @@ class CompilationResult : public QObject { Q_OBJECT Q_PROPERTY(QContractDefinition* contract READ contract) + Q_PROPERTY(QString compilerMessage READ compilerMessage CONSTANT) + Q_PROPERTY(bool successfull READ successfull CONSTANT) public: /// Empty compilation result constructor diff --git a/mix/ConstantCompilationControl.cpp b/mix/ConstantCompilationControl.cpp index 8543eeb26..a7326170c 100644 --- a/mix/ConstantCompilationControl.cpp +++ b/mix/ConstantCompilationControl.cpp @@ -37,11 +37,12 @@ using namespace dev::mix; ConstantCompilationControl::ConstantCompilationControl(AppContext* _context): Extension(_context, ExtensionDisplayBehavior::HeaderView) { connect(_context->codeModel(), &CodeModel::compilationComplete, this, &ConstantCompilationControl::update); + _context->appEngine()->rootContext()->setContextProperty("constantCompilation", this); } QString ConstantCompilationControl::contentUrl() const { - return QStringLiteral("qrc:/qml/BasicContent.qml"); + return QStringLiteral("qrc:/qml/CompilationStatus.qml"); } QString ConstantCompilationControl::title() const @@ -53,30 +54,19 @@ void ConstantCompilationControl::start() const { } -void ConstantCompilationControl::update() +CompilationResult* ConstantCompilationControl::result() const { - auto result = m_ctx->codeModel()->code(); + return m_ctx->codeModel()->code(); +} - QObject* status = m_view->findChild("status", Qt::FindChildrenRecursively); - QObject* content = m_view->findChild("content", Qt::FindChildrenRecursively); - if (result->successfull()) - { - status->setProperty("text", "succeeded"); - status->setProperty("color", "green"); - content->setProperty("text", result->assemblyCode()); - } - else - { - status->setProperty("text", "failure"); - status->setProperty("color", "red"); - content->setProperty("text", result->compilerMessage()); - } +void ConstantCompilationControl::update() +{ + QObject* ctrl = m_view->findChild("constantCompilationStatus", Qt::FindChildrenRecursively); + QMetaObject::invokeMethod(ctrl, "update"); } void ConstantCompilationControl::resetOutPut() { QObject* status = m_view->findChild("status", Qt::FindChildrenRecursively); - QObject* content = m_view->findChild("content", Qt::FindChildrenRecursively); status->setProperty("text", ""); - content->setProperty("text", ""); } diff --git a/mix/ConstantCompilationControl.h b/mix/ConstantCompilationControl.h index fa056424e..8acde4f09 100644 --- a/mix/ConstantCompilationControl.h +++ b/mix/ConstantCompilationControl.h @@ -20,6 +20,7 @@ #pragma once #include "Extension.h" +#include "CodeModel.h" namespace dev { @@ -32,6 +33,7 @@ namespace mix class ConstantCompilationControl: public Extension { Q_OBJECT + Q_PROPERTY(CompilationResult* result READ result CONSTANT) public: ConstantCompilationControl(AppContext* _appContext); @@ -39,6 +41,7 @@ public: void start() const override; QString title() const override; QString contentUrl() const override; + CompilationResult* result() const; private: void resetOutPut(); diff --git a/mix/DebuggingStateWrapper.cpp b/mix/DebuggingStateWrapper.cpp index 72bb02ecd..95e7991ed 100644 --- a/mix/DebuggingStateWrapper.cpp +++ b/mix/DebuggingStateWrapper.cpp @@ -66,43 +66,46 @@ std::tuple, QQMLMap*> DebuggingStateWrapper::getHumanReadableCod return std::make_tuple(codeStr, QPointer(new QQMLMap(codeMapping))); } -QString DebuggingStateWrapper::gasLeft() +QString DebuggingStateWrapper::gasCost() { std::ostringstream ss; - ss << std::dec << (m_state.gas - m_state.gasCost); + ss << std::dec << m_state.gasCost; return QString::fromStdString(ss.str()); } -QString DebuggingStateWrapper::gasCost() +QString DebuggingStateWrapper::gas() { std::ostringstream ss; - ss << std::dec << m_state.gasCost; + ss << std::dec << m_state.gas; return QString::fromStdString(ss.str()); } -QString DebuggingStateWrapper::gas() +QString DebuggingStateWrapper::newMemSize() { std::ostringstream ss; - ss << std::dec << m_state.gas; + ss << std::dec << m_state.newMemSize; return QString::fromStdString(ss.str()); } -QString DebuggingStateWrapper::debugStack() +QStringList DebuggingStateWrapper::debugStack() { - QString stack; + QStringList stack; for (auto i: m_state.stack) - stack.prepend(QString::fromStdString(prettyU256(i)) + "\n"); + stack.append(QString::fromStdString(prettyU256(i))); return stack; } -QString DebuggingStateWrapper::debugStorage() +QStringList DebuggingStateWrapper::debugStorage() { - std::stringstream s; + QStringList storage; for (auto const& i: m_state.storage) + { + std::stringstream s; s << "@" << prettyU256(i.first) << " " << prettyU256(i.second); - - return QString::fromStdString(s.str()); + storage.append(QString::fromStdString(s.str())); + } + return storage; } QString DebuggingStateWrapper::debugMemory() @@ -136,6 +139,13 @@ QString DebuggingStateWrapper::headerInfo() return QString::fromStdString(ss.str()); } +QString DebuggingStateWrapper::instruction() +{ + std::ostringstream ss; + ss << dev::eth::instructionInfo(m_state.inst).name; + return QString::fromStdString(ss.str()); +} + QString DebuggingStateWrapper::endOfDebug() { if (m_state.gasCost > m_state.gas) diff --git a/mix/DebuggingStateWrapper.h b/mix/DebuggingStateWrapper.h index bf3efe34d..902986570 100644 --- a/mix/DebuggingStateWrapper.h +++ b/mix/DebuggingStateWrapper.h @@ -115,13 +115,14 @@ class DebuggingStateWrapper: public QObject Q_PROPERTY(int curPC READ curPC CONSTANT) Q_PROPERTY(QString gasCost READ gasCost CONSTANT) Q_PROPERTY(QString gas READ gas CONSTANT) - Q_PROPERTY(QString gasLeft READ gasLeft CONSTANT) - Q_PROPERTY(QString debugStack READ debugStack CONSTANT) - Q_PROPERTY(QString debugStorage READ debugStorage CONSTANT) + Q_PROPERTY(QString instruction READ instruction CONSTANT) + Q_PROPERTY(QStringList debugStack READ debugStack CONSTANT) + Q_PROPERTY(QStringList debugStorage READ debugStorage CONSTANT) Q_PROPERTY(QString debugMemory READ debugMemory CONSTANT) Q_PROPERTY(QString debugCallData READ debugCallData CONSTANT) Q_PROPERTY(QString headerInfo READ headerInfo CONSTANT) Q_PROPERTY(QString endOfDebug READ endOfDebug CONSTANT) + Q_PROPERTY(QString newMemSize READ newMemSize CONSTANT) Q_PROPERTY(QStringList levels READ levels CONSTANT) public: @@ -137,9 +138,9 @@ public: /// Get gas used. QString gas(); /// Get stack. - QString debugStack(); + QStringList debugStack(); /// Get storage. - QString debugStorage(); + QStringList debugStorage(); /// Get memory. QString debugMemory(); /// Get call data. @@ -148,6 +149,10 @@ public: QString headerInfo(); /// get end of debug information. QString endOfDebug(); + /// Get the new memory size. + QString newMemSize(); + /// Get current instruction + QString instruction(); /// Get all previous steps. QStringList levels(); /// Get the current processed machine state. diff --git a/mix/qml.qrc b/mix/qml.qrc index 7e731b6f4..f39442cef 100644 --- a/mix/qml.qrc +++ b/mix/qml.qrc @@ -12,5 +12,24 @@ qml/AlertMessageDialog.qml qml/StateDialog.qml qml/StateList.qml + qml/CompilationStatus.qml + qml/js/main.js + qml/img/jumpintoback.png + qml/img/jumpintoforward.png + qml/img/jumpoutback.png + qml/img/jumpoutforward.png + qml/img/jumpoverback.png + qml/img/jumpoverforward.png + qml/ImageButton.qml + qml/DataDump.qml + qml/Storage.qml + qml/StepActionImage.qml + qml/img/jumpintobackdisabled.png + qml/img/jumpintoforwarddisabled.png + qml/img/jumpoutbackdisabled.png + qml/img/jumpoutforwarddisabled.png + qml/img/jumpoverbackdisabled.png + qml/DebugBasicInfo.qml + qml/js/ErrorLocationFormater.js diff --git a/mix/qml/CompilationStatus.qml b/mix/qml/CompilationStatus.qml index ff31dc86f..424e4a3dd 100644 --- a/mix/qml/CompilationStatus.qml +++ b/mix/qml/CompilationStatus.qml @@ -1,35 +1,97 @@ import QtQuick 2.2 import QtQuick.Controls 1.1 +import "js/ErrorLocationFormater.js" as ErrorLocationFormater Rectangle { + id: constantCompilationStatus + objectName: "constantCompilationStatus" + function update() + { + if (constantCompilation.result.successfull) + { + image.state = ""; + status.state = ""; + status.text = qsTr("Compile without errors."); + logslink.visible = false; + } + else + { + image.state = "error"; + status.state = "error"; + var errorInfo = ErrorLocationFormater.extractErrorInfo(constantCompilation.result.compilerMessage, true); + status.text = errorInfo.errorLocation + " " + errorInfo.errorDetail; + logslink.visible = true; + } + } + anchors.fill: parent - width: parent.width - height: parent.height - color: "lightgray" - Text { - font.pointSize: 9 - anchors.left: parent.left - anchors.top: parent.top - anchors.topMargin: 3 - anchors.leftMargin: 3 - height: 9 - font.family: "Monospace" - objectName: "status" - id: status + gradient: Gradient { + GradientStop { position: 0.0; color: "#f1f1f1" } + GradientStop { position: 1.0; color: "#d9d7da" } } - TextArea { - readOnly: true - anchors.left: parent.left - anchors.leftMargin: 10 - anchors.top: status.bottom - anchors.topMargin: 3 - font.pointSize: 9 - font.family: "Monospace" - height: parent.height * 0.8 - width: parent.width - 20 - wrapMode: Text.Wrap - backgroundVisible: false - objectName: "content" - id: content + Rectangle { + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + anchors.topMargin: 10 + anchors.bottomMargin: 10 + radius: 3 + width: 500 + height: 30 + color: "#fffcd5" + Row { + anchors.horizontalCenter: parent.horizontalCenter + anchors.verticalCenter: parent.verticalCenter + spacing: 5 + Image + { + source: "qrc:/qml/img/compilsuceeded.png" + id: image + states:[ + State { + name: "error" + PropertyChanges { + target: image + source: "qrc:/qml/img/compilfailed.png" + } + } + ] + } + + Text { + font.pointSize: 10 + height: 9 + font.family: "sans serif" + objectName: "status" + id: status + states:[ + State { + name: "error" + PropertyChanges { + target: status + color: "red" + } + } + ] + } + + Text { + + visible: false + font.pointSize: 9 + height: 9 + text: qsTr("See log.") + font.family: "Monospace" + objectName: "status" + id: logslink + color: "#8c8a74" + MouseArea { + anchors.fill: parent + onClicked: { + mainContent.ensureRightView(); + debugModel.debugDeployment(); + } + } + } + } } } diff --git a/mix/qml/DataDump.qml b/mix/qml/DataDump.qml index 4c91ca022..85732fbca 100644 --- a/mix/qml/DataDump.qml +++ b/mix/qml/DataDump.qml @@ -2,118 +2,89 @@ import QtQuick 2.2 import QtQuick.Controls 1.1 import QtQuick.Layouts 1.0 import QtQuick.Controls.Styles 1.1 -import CodeEditorExtensionManager 1.0 -Rectangle { - objectName: "mainContent" - signal keyPressed(variant event) - focus: true - Keys.enabled: true - Keys.onPressed: - { - root.keyPressed(event.key); - } - anchors.fill: parent - id: root +ColumnLayout { + property variant content; + property string title; + height: 250 - function ensureRightView() - { - if (!rightView.visible) - { - rightView.show(); + RowLayout { + + Image { + source: "qrc:/qml/img/jumpoverback.png" + width: 15 + sourceSize.width: 15 + id: imgArrow } - } - CodeEditorExtensionManager { - headerView: headerPaneTabs; - rightView: rightPaneTabs; - editor: codeEditor - } + Text { + color: "#8b8b8b" + text: title + id: listTitle + } - GridLayout - { - anchors.fill: parent - rows: 2 - flow: GridLayout.TopToBottom - columnSpacing: 0 - rowSpacing: 0 - Rectangle { - Layout.row: 0 - Layout.fillWidth: true - Layout.preferredHeight: 50 - id: headerView - TabView { - id: headerPaneTabs - tabsVisible: false - antialiasing: true - anchors.fill: parent - style: TabViewStyle { - frameOverlap: 1 - tab: Rectangle {} - frame: Rectangle {} - } + MouseArea + { + anchors.fill: parent + onClicked: { + if (listContainer.state === "collapsed") + listContainer.state = ""; + else + listContainer.state = "collapsed"; } } + } - SplitView { - resizing: false - Layout.row: 1 - orientation: Qt.Horizontal; - Layout.fillWidth: true - Layout.preferredHeight: root.height - headerView.height; - Rectangle { - id: editorRect; - height: parent.height; - width: parent.width; - TextArea { - id: codeEditor - anchors.fill: parent; - font.family: "Monospace" - font.pointSize: 12 - backgroundVisible: true; - textColor: "white" - tabChangesFocus: false - style: TextAreaStyle { - backgroundColor: "black" - } - Keys.onPressed: { - if (event.key === Qt.Key_Tab) { - codeEditor.insert(codeEditor.cursorPosition, "\t"); - event.accepted = true; - } - } - } + Rectangle + { + Layout.fillWidth: true + transitions: [ + Transition { + NumberAnimation { target: listContainer; property: "opacity"; duration: 400 } + NumberAnimation { target: listContainer; property: "height"; duration: 400 } + NumberAnimation { target: listContainer.parent; property: "height"; duration: 400 } + NumberAnimation { target: dumpList; property: "opacity"; duration: 400 } + NumberAnimation { target: dumpList; property: "height"; duration: 400 } } - Rectangle { - visible: false; - id: rightView; - property real panelRelWidth: 0.38 - function show() { - visible = true; - editorRect.width = parent.width * (1 - 0.38) - codeEditor.focus = false; - rightPaneTabs.focus = true; + ] + states: [ + State { + name: "collapsed" + PropertyChanges { + target: listContainer + height: 0 + opacity: 0 + } + PropertyChanges { + target: listContainer.parent + height: 20 } - height: parent.height; - width: Layout.minimumWidth - Layout.minimumWidth: parent.width * 0.38 - Rectangle { - anchors.fill: parent; - id: rightPaneView - TabView { - id: rightPaneTabs - tabsVisible: false - antialiasing: true - anchors.fill: parent - style: TabViewStyle { - frameOverlap: 1 - tab: Rectangle {} - frame: Rectangle {} - } - } + PropertyChanges { + target: dumpList + height: 0 + opacity: 0 } } + ] + id: listContainer + //border.width: 3 + //border.color: "#deddd9" + anchors.top: listTitle.bottom + height: 223 + anchors.topMargin: 5 + width: parent.width + color: "transparent" + TextArea { + readOnly: true + anchors.top: parent.top + anchors.left: parent.left + anchors.topMargin: 5 + anchors.leftMargin: 5 + width: parent.width + height: parent.height + id: dumpList + text: content } } } diff --git a/mix/qml/DebugBasicInfo.qml b/mix/qml/DebugBasicInfo.qml index 206100c7b..5cfea55ac 100644 --- a/mix/qml/DebugBasicInfo.qml +++ b/mix/qml/DebugBasicInfo.qml @@ -3,36 +3,107 @@ import QtQuick.Controls 1.1 import QtQuick.Layouts 1.0 import QtQuick.Controls.Styles 1.1 -Item { - id: button +ColumnLayout { + property string currentStep + property string mem + property string stepCost + property string gasSpent + spacing: 0 + RowLayout { + width: parent.width + height: parent.height / 4 + Rectangle { + width: parent.width / 2 + height: parent.height + color: "#e5e5e5" + Text + { + font.pixelSize: 12 + anchors.centerIn: parent + color: "#a2a2a2" + text: qsTr("Current step") + font.family: "Sans Serif" + } + } + Text + { + font.pixelSize: 13 + id: currentStepValue + text: currentStep + } + } - signal clicked - signal pressed - signal released + RowLayout { + width: parent.width + height: parent.height / 4 + Rectangle { + width: parent.width / 2 + height: parent.height + color: "#e5e5e5" + Text + { + font.pixelSize: 12 + anchors.centerIn: parent + color: "#a2a2a2" + text: qsTr("Adding memory") + font.family: "Sans Serif" + } + } - width: sprite.width - height: sprite.height + Text + { + font.pixelSize: 13 + id: memValue + text: mem + } + } + RowLayout { + width: parent.width + height: parent.height / 4 + Rectangle { + width: parent.width / 2 + height: parent.height + color: "#e5e5e5" + Text + { + font.pixelSize: 12 + anchors.centerIn: parent + color: "#a2a2a2" + text: qsTr("Step cost") + font.family: "Sans Serif" + } + } + Text + { + font.pixelSize: 13 + id: stepCostValue + text: stepCost + } + } - MouseArea { - id: mouseArea - enabled: button.enabled - anchors.fill: button - hoverEnabled: true - - onClicked: button.clicked() - onPressed: button.pressed() - onReleased: button.released() - } - - onClicked: { - } - - onPressed: { - opacity = 0.5 - } - - onReleased: { - opacity = 1.0 - } + RowLayout { + width: parent.width + height: parent.height / 4 + Rectangle { + width: parent.width / 2 + height: parent.height + color: "#e5e5e5" + Text + { + font.pixelSize: 12 + anchors.centerIn: parent + color: "#a2a2a2" + text: qsTr("Total gas spent") + font.family: "Sans Serif" + } + } + Text + { + font.pixelSize: 13 + id: gasSpentValue + text: gasSpent + } + } } + diff --git a/mix/qml/Debugger.qml b/mix/qml/Debugger.qml index 056126e16..f1c06c157 100644 --- a/mix/qml/Debugger.qml +++ b/mix/qml/Debugger.qml @@ -4,266 +4,329 @@ import QtQuick.Controls 1.1 import QtQuick.Dialogs 1.1 import QtQuick.Layouts 1.1 import "js/Debugger.js" as Debugger +import "js/ErrorLocationFormater.js" as ErrorLocationFormater Rectangle { + id: debugPanel + objectName: "debugPanel" anchors.fill: parent; - color: "lightgrey" - Component.onCompleted: Debugger.init(); - Rectangle { - color: "transparent" - id: headerInfo - anchors.horizontalCenter: parent.horizontalCenter - width: parent.width - height: 60 - anchors.top: parent.top - Column { - width: parent.width - height: parent.height - Rectangle { - color: "transparent" - width: parent.width - height: 30 - Label { - anchors.centerIn: parent - font.family: "Verdana" - font.pointSize: 9 - font.italic: true - id: headerInfoLabel - } - } - Rectangle { - color: "transparent" - width: parent.width - anchors.horizontalCenter: parent.horizontalCenter - height: 30 - ListView { - orientation: ListView.Horizontal - anchors.centerIn: parent; - width: parent.width - id: headerReturnList - delegate: renderDelegateReturnValues - } - Component { - id: renderDelegateReturnValues - Item { - id: wrapperItem - width: 80 - Text { - anchors.centerIn: parent - text: variable.declaration.name + " = " + variable.value - font.pointSize: 9 - } - } - } - } - } - } + color: "#ededed" - Keys.onPressed: { + Keys.onPressed: + { if (event.key === Qt.Key_F10) Debugger.moveSelection(1); else if (event.key === Qt.Key_F9) Debugger.moveSelection(-1); } - Rectangle { - color: "transparent" - id: stateListContainer - focus: true - anchors.topMargin: 10 - anchors.top: headerInfo.bottom - anchors.left: parent.left - height: parent.height - 70 - width: parent.width * 0.5 + function init() + { + if (constantCompilation.result.successfull) + { + Debugger.init(); + debugScrollArea.visible = true; + compilationErrorArea.visible = false; + machineStates.visible = true; + } + else + { + debugScrollArea.visible = false; + compilationErrorArea.visible = true; + machineStates.visible = false; + console.log(constantCompilation.result.compilerMessage); + var errorInfo = ErrorLocationFormater.extractErrorInfo(constantCompilation.result.compilerMessage, false); + errorLocation.text = errorInfo.errorLocation; + errorDetail.text = errorInfo.errorDetail; + errorLine.text = errorInfo.errorLine; + } + forceActiveFocus(); + } - ListView { + Rectangle + { + visible: false; + id: compilationErrorArea + width: parent.width - 20 + height: 500 + color: "#ededed" + anchors.left: parent.left + anchors.top: parent.top + anchors.margins: 10 + ColumnLayout + { + width: parent.width anchors.top: parent.top - height: parent.height * 0.60 - width: 200 - anchors.horizontalCenter: parent.horizontalCenter - id: statesList - model: humanReadableExecutionCode - delegate: renderDelegate - highlight: highlightBar - highlightFollowsCurrentItem: true - } + spacing: 25 + RowLayout + { + height: 100 + Image { + id: compileFailed + source: "qrc:/qml/img/compilfailed.png" + } + ColumnLayout + { + Text { + color: "red" + id: errorLocation + } + Text { + color: "#4a4a4a" + id: errorDetail + } + } + } - Component { - id: highlightBar - Rectangle { - height: statesList.currentItem.height - width: statesList.currentItem.width - border.color: "orange" - border.width: 1 - Behavior on y { SpringAnimation { spring: 2; damping: 0.1 } } + Rectangle + { + width: parent.width - 6 + height: 2 + color: "#d0d0d0" } - } - Component { - id: renderDelegate - Item { - id: wrapperItem - height: 20 - width: parent.width - Text { - anchors.centerIn: parent - text: line - font.pointSize: 9 + RowLayout + { + Text + { + color: "#4a4a4a" + id: errorLine } } } + } - Rectangle { - id: callStackPanel - anchors.top: statesList.bottom - height: parent.height * 0.35 - width: parent.width + + Flickable { + id: debugScrollArea + flickableDirection: Flickable.VerticalFlick + anchors.fill: parent + contentHeight: machineStates.height + contentWidth: machineStates.width + + GridLayout + { + property int sideMargin: 10 + id: machineStates + anchors.top: parent.top anchors.topMargin: 15 - color: "transparent" - Label { - id: callStackLabel - anchors.bottomMargin: 10 - horizontalAlignment: "AlignHCenter" - font.family: "Verdana" - font.pointSize: 8 - font.letterSpacing: 2 - width: parent.width - height: 15 - text: qsTr("callstack") - } + anchors.left: parent.left; + anchors.leftMargin: machineStates.sideMargin + anchors.right: parent.right; + anchors.rightMargin: machineStates.sideMargin + flow: GridLayout.TopToBottom + //columnSpacing: 7 + rowSpacing: 15 + RowLayout { + // step button + slider + spacing: 10 + height: 27 + width: debugPanel.width + RowLayout { + id: jumpButtons + spacing: 15 + width: 250 + height: parent.height + + StepActionImage + { + id: jumpoutbackaction; + source: "qrc:/qml/img/jumpoutback.png" + disableStateImg: "qrc:/qml/img/jumpoutbackdisabled.png" + onClicked: Debugger.stepOutBack() + } - ListView { - height: parent.height - 15 - width: 200 - anchors.top: callStackLabel.bottom - anchors.horizontalCenter: parent.horizontalCenter - id: levelList - delegate: Component { - Item { - Text { - font.family: "Verdana" - font.pointSize: 8 - text: modelData + StepActionImage + { + id: jumpintobackaction + source: "qrc:/qml/img/jumpintoback.png" + disableStateImg: "qrc:/qml/img/jumpintobackdisabled.png" + onClicked: Debugger.stepIntoBack() + } + + StepActionImage + { + id: jumpoverbackaction + source: "qrc:/qml/img/jumpoverback.png" + disableStateImg: "qrc:/qml/img/jumpoverbackdisabled.png" + onClicked: Debugger.stepOverBack() + } + + StepActionImage + { + id: jumpoverforwardaction + source: "qrc:/qml/img/jumpoverforward.png" + disableStateImg: "qrc:/qml/img/jumpoverforwarddisabled.png" + onClicked: Debugger.stepOverForward() + } + + StepActionImage + { + id: jumpintoforwardaction + source: "qrc:/qml/img/jumpintoforward.png" + disableStateImg: "qrc:/qml/img/jumpintoforwarddisabled.png" + onClicked: Debugger.stepIntoForward() + } + + StepActionImage + { + id: jumpoutforwardaction + source: "qrc:/qml/img/jumpoutforward.png" + disableStateImg: "qrc:/qml/img/jumpoutforwarddisabled.png" + onClicked: Debugger.stepOutForward() + } + } + + Rectangle { + color: "transparent" + width: 250 + height: parent.height + Slider { + id: statesSlider + anchors.fill: parent + tickmarksEnabled: true + stepSize: 1.0 + height: parent.height + onValueChanged: Debugger.jumpTo(value); + style: SliderStyle { + groove: Rectangle { + implicitHeight: 3 + color: "#7da4cd" + radius: 8 + } + handle: Rectangle { + anchors.centerIn: parent + color: control.pressed ? "white" : "lightgray" + border.color: "gray" + border.width: 2 + implicitWidth: 10 + implicitHeight: 10 + radius: 12 + } } } } } - } - } - Rectangle { - color: "transparent" - anchors.topMargin: 5 - anchors.bottomMargin: 10 - anchors.rightMargin: 10 - height: parent.height - 30 - width: parent.width * 0.5 - anchors.right: parent.right - anchors.top: headerInfo.bottom - anchors.bottom: parent.bottom + RowLayout { + // Assembly code + width: debugPanel.width + height: 400 + spacing: 10 - Rectangle { - id: debugStack - anchors.top: parent.top - width: parent.width - height: parent.height * 0.25 - color: "transparent" - Label { - horizontalAlignment: "AlignHCenter" - font.family: "Verdana" - font.pointSize: 8 - width: parent.width - height: 15 - anchors.top : parent.top - text: qsTr("debug stack") - } - TextArea { - anchors.bottom: parent.bottom - width: parent.width - font.family: "Verdana" - font.pointSize: 8 - height: parent.height - 15 - id: debugStackTxt - readOnly: true; + Rectangle + { + width: 170 + height: parent.height + border.width: 3 + border.color: "#deddd9" + color: "white" + + ListView { + anchors.fill: parent + anchors.topMargin: 3 + anchors.bottomMargin: 3 + clip: true + id: statesList + delegate: renderDelegate + highlight: highlightBar + highlightFollowsCurrentItem: true + } + + Component { + id: highlightBar + Rectangle { + height: statesList.currentItem.height + width: statesList.currentItem.width + color: "#4b8fe2" + Behavior on y { SpringAnimation { spring: 2; damping: 0.1 } } + } + } + + Component { + id: renderDelegate + Item { + id: wrapperItem + height: 20 + width: parent.width + Text { + color: parent.ListView.isCurrentItem ? "white" : "black" + anchors.centerIn: parent + text: line + font.pointSize: 9 + } + } + } + } + + ColumnLayout { + width: 250 + height: parent.height + Rectangle { + // Info + width: parent.width + id: basicInfoColumn + height: 150 + color: "transparent" + DebugBasicInfo { + id: basicInfo + width: parent.width + height: parent.height + } + } + + Rectangle { + // Stack + height: 250 + width: parent.width + color: "transparent" + + Storage { + id: stack + width: parent.width + title : qsTr("Stack") + } + } + } } - } - Rectangle { - id: debugMemory - anchors.top: debugStack.bottom - width: parent.width - height: parent.height * 0.25 - color: "transparent" - Label { - horizontalAlignment: "AlignHCenter" - font.family: "Verdana" - font.pointSize: 8 - width: parent.width - height: 15 - anchors.top : parent.top - text: qsTr("debug memory") + Rectangle { + width: debugPanel.width - 2 * machineStates.sideMargin + height: 2; + color: "#e3e3e3" + radius: 3 } - TextArea { - anchors.bottom: parent.bottom - width: parent.width - font.family: "Verdana" - font.pointSize: 8 - height: parent.height - 15 - id: debugMemoryTxt - readOnly: true; + + Storage { + id: storage + width: debugPanel.width - 2 * machineStates.sideMargin + title : qsTr("Storage") } - } - Rectangle { - id: debugStorage - anchors.top: debugMemory.bottom - width: parent.width - height: parent.height * 0.25 - color: "transparent" - Label { - horizontalAlignment: "AlignHCenter" - font.family: "Verdana" - font.pointSize: 8 - width: parent.width - height: 15 - anchors.top : parent.top - text: qsTr("debug storage") + Rectangle { + width: debugPanel.width - 2 * machineStates.sideMargin + height: 2; + color: "#e3e3e3" + radius: 3 } - TextArea { - anchors.bottom: parent.bottom - width: parent.width - font.family: "Verdana" - font.pointSize: 8 - height: parent.height - 15 - id: debugStorageTxt - readOnly: true; + + Storage { + id: memoryDump + width: debugPanel.width - 2 * machineStates.sideMargin + title: qsTr("Memory Dump") } - } - Rectangle { - id: debugCallData - anchors.top: debugStorage.bottom - width: parent.width - height: parent.height * 0.25 - color: "transparent" - Label { - horizontalAlignment: "AlignHCenter" - font.family: "Verdana" - font.pointSize: 8 - width: parent.width - height: 15 - anchors.top : parent.top - text: qsTr("debug calldata") + Rectangle { + width: debugPanel.width - 2 * machineStates.sideMargin + height: 2; + color: "#e3e3e3" + radius: 3 } - TextArea { - anchors.bottom: parent.bottom - width: parent.width - height: parent.height - 15 - font.family: "Verdana" - font.pointSize: 8 - font.letterSpacing: 2 - id: debugCallDataTxt - readOnly: true; + + Storage { + id: callDataDump + width: debugPanel.width; + title: qsTr("Call data") } } } diff --git a/mix/qml/ImageButton.qml b/mix/qml/ImageButton.qml index 4c91ca022..206100c7b 100644 --- a/mix/qml/ImageButton.qml +++ b/mix/qml/ImageButton.qml @@ -2,118 +2,37 @@ import QtQuick 2.2 import QtQuick.Controls 1.1 import QtQuick.Layouts 1.0 import QtQuick.Controls.Styles 1.1 -import CodeEditorExtensionManager 1.0 -Rectangle { +Item { + id: button - objectName: "mainContent" - signal keyPressed(variant event) - focus: true - Keys.enabled: true - Keys.onPressed: - { - root.keyPressed(event.key); - } - anchors.fill: parent - id: root + signal clicked + signal pressed + signal released - function ensureRightView() - { - if (!rightView.visible) - { - rightView.show(); - } - } + width: sprite.width + height: sprite.height - CodeEditorExtensionManager { - headerView: headerPaneTabs; - rightView: rightPaneTabs; - editor: codeEditor - } - GridLayout - { - anchors.fill: parent - rows: 2 - flow: GridLayout.TopToBottom - columnSpacing: 0 - rowSpacing: 0 - Rectangle { - Layout.row: 0 - Layout.fillWidth: true - Layout.preferredHeight: 50 - id: headerView - TabView { - id: headerPaneTabs - tabsVisible: false - antialiasing: true - anchors.fill: parent - style: TabViewStyle { - frameOverlap: 1 - tab: Rectangle {} - frame: Rectangle {} - } - } - } + MouseArea { + id: mouseArea + enabled: button.enabled + anchors.fill: button + hoverEnabled: true - SplitView { - resizing: false - Layout.row: 1 - orientation: Qt.Horizontal; - Layout.fillWidth: true - Layout.preferredHeight: root.height - headerView.height; - Rectangle { - id: editorRect; - height: parent.height; - width: parent.width; - TextArea { - id: codeEditor - anchors.fill: parent; - font.family: "Monospace" - font.pointSize: 12 - backgroundVisible: true; - textColor: "white" - tabChangesFocus: false - style: TextAreaStyle { - backgroundColor: "black" - } - Keys.onPressed: { - if (event.key === Qt.Key_Tab) { - codeEditor.insert(codeEditor.cursorPosition, "\t"); - event.accepted = true; - } - } - } - } - Rectangle { - visible: false; - id: rightView; - property real panelRelWidth: 0.38 - function show() { - visible = true; - editorRect.width = parent.width * (1 - 0.38) - codeEditor.focus = false; - rightPaneTabs.focus = true; - } - height: parent.height; - width: Layout.minimumWidth - Layout.minimumWidth: parent.width * 0.38 - Rectangle { - anchors.fill: parent; - id: rightPaneView - TabView { - id: rightPaneTabs - tabsVisible: false - antialiasing: true - anchors.fill: parent - style: TabViewStyle { - frameOverlap: 1 - tab: Rectangle {} - frame: Rectangle {} - } - } - } - } - } - } + onClicked: button.clicked() + onPressed: button.pressed() + onReleased: button.released() + } + + onClicked: { + } + + onPressed: { + opacity = 0.5 + } + + onReleased: { + opacity = 1.0 + } } diff --git a/mix/qml/MainContent.qml b/mix/qml/MainContent.qml index 8669f191e..398ea6f47 100644 --- a/mix/qml/MainContent.qml +++ b/mix/qml/MainContent.qml @@ -5,6 +5,7 @@ import QtQuick.Controls.Styles 1.1 import CodeEditorExtensionManager 1.0 Rectangle { + objectName: "mainContent" signal keyPressed(variant event) focus: true @@ -14,69 +15,118 @@ Rectangle { root.keyPressed(event.key); } anchors.fill: parent - height: parent.height - width: parent.width; - id:root + id: root + + function ensureRightView() + { + if (!rightView.visible) + { + rightView.show(); + } + } + + function hideRightView() + { + if (rightView.visible) + { + rightView.hide(); + } + } CodeEditorExtensionManager { - headerView: headerView; - rightView: rightView; + headerView: headerPaneTabs; + rightView: rightPaneTabs; editor: codeEditor } - Column { - anchors.fill: parent; - anchors.horizontalCenter: parent.horizontalCenter - anchors.verticalCenter: parent.verticalCenter + GridLayout + { + anchors.fill: parent + rows: 2 + flow: GridLayout.TopToBottom + columnSpacing: 0 + rowSpacing: 0 Rectangle { + Layout.row: 0 + Layout.fillWidth: true + Layout.preferredHeight: 50 id: headerView - height: 50 - width: parent.width; + TabView { + id: headerPaneTabs + tabsVisible: false + antialiasing: true + anchors.fill: parent + style: TabViewStyle { + frameOverlap: 1 + tab: Rectangle {} + frame: Rectangle {} + } + } } - Row { - anchors.fill: parent; - anchors.horizontalCenter: parent.horizontalCenter - anchors.verticalCenter: parent.verticalCenter - SplitView { - orientation: Qt.Vertical; - anchors.fill: parent; - Rectangle { - id: editorRect; - height: parent.height; - width: parent.width /2; - TextArea { - id: codeEditor - height: parent.height - width: parent.width - font.family: "Monospace" - font.pointSize: 12 - anchors.centerIn: parent - tabChangesFocus: false - Keys.onPressed: { - if (event.key === Qt.Key_Tab) { - codeEditor.insert(codeEditor.cursorPosition, "\t"); - event.accepted = true; - } + + SplitView { + resizing: false + Layout.row: 1 + orientation: Qt.Horizontal; + Layout.fillWidth: true + Layout.preferredHeight: root.height - headerView.height; + Rectangle { + id: editorRect; + height: parent.height; + width: parent.width; + TextArea { + id: codeEditor + anchors.fill: parent; + font.family: "Monospace" + font.pointSize: 12 + backgroundVisible: true; + textColor: "white" + tabChangesFocus: false + style: TextAreaStyle { + backgroundColor: "black" + } + Keys.onPressed: { + if (event.key === Qt.Key_Tab) { + codeEditor.insert(codeEditor.cursorPosition, "\t"); + event.accepted = true; } - } + } + } + } + Rectangle { + + Keys.onEscapePressed: + { + hide(); + } + + visible: false; + id: rightView; + property real panelRelWidth: 0.38 + function show() { + visible = true; + editorRect.width = parent.width * (1 - 0.38) } + + function hide() { + visible = false; + editorRect.width = parent.width; + } + height: parent.height; + width: Layout.minimumWidth + Layout.minimumWidth: parent.width * 0.38 Rectangle { - id: rightView; - height: parent.height; - width: parent.width /2; - Rectangle { - id: debugWindow; - } - Rectangle { - anchors.right: parent.right - id: rightPaneView - width: parent.width * 0.2 - height: parent.height - Layout.minimumWidth: 20 - TabView { - id: rightPaneTabs - antialiasing: true - anchors.fill: parent + anchors.fill: parent; + id: rightPaneView + TabView { + id: rightPaneTabs + tabsVisible: false + antialiasing: true + anchors.fill: parent + style: TabViewStyle { + frameOverlap: 1 + tab: Rectangle {} + frame: Rectangle {} } } } diff --git a/mix/qml/StepActionImage.qml b/mix/qml/StepActionImage.qml index a4cae74ab..ec262b36e 100644 --- a/mix/qml/StepActionImage.qml +++ b/mix/qml/StepActionImage.qml @@ -3,93 +3,24 @@ import QtQuick.Controls 1.1 import QtQuick.Layouts 1.0 import QtQuick.Controls.Styles 1.1 -ColumnLayout { - property string title - property variant listModel; - height: 250 - - RowLayout { - - Image { - source: "qrc:/qml/img/jumpoverback.png" - width: 15 - sourceSize.width: 15 - id: storageImgArrow - - } - - Text { - anchors.left: storageImgArrow.right - color: "#8b8b8b" - text: title - id: storageListTitle - } - - MouseArea - { - anchors.fill: parent - onClicked: { - if (storageContainer.state == "collapsed") - storageContainer.state = ""; - else - storageContainer.state = "collapsed"; - } - } - } - - Rectangle +Image { + id: jumpintobackimg + property string disableStateImg + signal clicked + width: 15 + sourceSize.width: 15 + MouseArea { - Layout.fillWidth: true - states: [ - State { - name: "collapsed" - PropertyChanges { - target: storageContainer - height: 0 - opacity: 0 - visible: false - } - PropertyChanges { - target: storageContainer.parent - height: 20 - } - PropertyChanges { - target: storageList - height: 0 - opacity: 0 - visible: false - } - + anchors.fill: parent + onClicked: jumpintobackimg.clicked(); + } + states: [ + State { + name: "disabled" + PropertyChanges { + target: jumpintobackimg + source: disableStateImg } - ] - id: storageContainer - border.width: 3 - border.color: "#deddd9" - anchors.top: storageListTitle.bottom - height: 223 - anchors.topMargin: 5 - width: parent.width - ListView { - anchors.top: parent.top - anchors.left: parent.left - anchors.topMargin: 5 - anchors.leftMargin: 5 - width: parent.width - height: parent.height - id: storageList - model: listModel - delegate: - Component { - Item { - height: 20 - width: parent.width - Text { - color: "#8b8b8b" - text: modelData - font.pointSize: 9 - } - } - } } - } + ] } diff --git a/mix/qml/Storage.qml b/mix/qml/Storage.qml index f944a0f4d..b68f8bc12 100644 --- a/mix/qml/Storage.qml +++ b/mix/qml/Storage.qml @@ -3,96 +3,96 @@ import QtQuick.Controls 1.1 import QtQuick.Layouts 1.0 import QtQuick.Controls.Styles 1.1 - ColumnLayout { + property string title property variant listModel; - property string title; - height: 250 - //width: width //debugPanel.width - //anchors.left: machineStates.left - //anchors.right: machineStates.right - //anchors.leftMargin: machineStates.sideMargin - - RowLayout { + height: 20 Image { source: "qrc:/qml/img/jumpoverback.png" width: 15 sourceSize.width: 15 - id: imgArrow + id: storageImgArrow } Text { + anchors.left: storageImgArrow.right color: "#8b8b8b" text: title - id: listTitle + id: storageListTitle } MouseArea { anchors.fill: parent onClicked: { - if (listContainer.state === "collapsed") - listContainer.state = ""; + if (storageContainer.state == "collapsed") + storageContainer.state = ""; else - listContainer.state = "collapsed"; + storageContainer.state = "collapsed"; } } } - Rectangle + RowLayout { - Layout.fillWidth: true - states: [ - State { - name: "collapsed" - PropertyChanges { - target: listContainer - height: 0 - opacity: 0 - visible: false - } - PropertyChanges { - target: listContainer.parent - height: 20 + Rectangle + { + border.width: 3 + border.color: "#deddd9" + height: 223; + Layout.fillWidth: true + transitions: [ + Transition { + NumberAnimation { target: storageContainer; property: "visible"; duration: 400 } + NumberAnimation { target: storageContainer; property: "height"; duration: 400 } } - PropertyChanges { - target: dumpList - height: 0 - opacity: 0 - visible: false + ] + states: [ + State { + name: "collapsed" + PropertyChanges { + target: storageContainer + height: 0 + //opacity: 0 + visible: false + } + PropertyChanges { + target: storageContainer.parent + height: 20 + } } + ] + id: storageContainer + + anchors.top: storageListTitle.bottom - } - ] - id: listContainer - border.width: 3 - border.color: "#deddd9" - anchors.top: listTitle.bottom - height: 223 - anchors.topMargin: 5 - width: parent.width - ListView { - anchors.top: parent.top - anchors.left: parent.left anchors.topMargin: 5 - anchors.leftMargin: 5 width: parent.width - height: parent.height - id: dumpList - delegate: Component { - Item { - height: 20 - width: parent.width - Text { - color: "#8b8b8b" - text: modelData - font.pointSize: 9 - } - } - } + ListView { + anchors.top: parent.top + anchors.left: parent.left + anchors.topMargin: 5 + anchors.leftMargin: 5 + width: parent.width + height: parent.height + id: storageList + model: listModel + delegate: + Component { + Item { + height: 20 + width: parent.width + Text { + color: "#8b8b8b" + text: modelData + font.pointSize: 9 + } + } + } + } } } } diff --git a/mix/qml/js/Debugger.js b/mix/qml/js/Debugger.js index d516abde6..6ebec2299 100644 --- a/mix/qml/js/Debugger.js +++ b/mix/qml/js/Debugger.js @@ -4,11 +4,20 @@ //statesList => ListView var currentSelectedState = null; +var jumpStartingPoint = null; function init() { + statesSlider.maximumValue = debugStates.length - 1; + statesList.model = humanReadableExecutionCode; currentSelectedState = 0; select(currentSelectedState); - displayReturnValue(); + //displayReturnValue(); + + jumpoutbackaction.state = "disabled"; + jumpintobackaction.state = "disabled"; + jumpintoforwardaction.state = "disabled" + jumpoutforwardaction.state = "disabled" + } function moveSelection(incr) @@ -21,20 +30,37 @@ function moveSelection(incr) } else { - endOfDebug(); + //endOfDebug(); } + statesSlider.value = currentSelectedState; } } function select(stateIndex) { + var codeLine = codeStr(stateIndex); var state = debugStates[stateIndex]; - var codeStr = bytesCodeMapping.getValue(state.curPC); - highlightSelection(codeStr); + highlightSelection(codeLine); currentSelectedState = stateIndex; completeCtxInformation(state); - levelList.model = state.levels; - levelList.update(); + //levelList.model = state.levels; + //levelList.update(); + + if (state.instruction === "JUMP") + jumpintoforwardaction.state = ""; + else + jumpintoforwardaction.state = "disabled"; + + if (state.instruction === "JUMPDEST") + jumpintobackaction.state = ""; + else + jumpintobackaction.state = "disabled"; +} + +function codeStr(stateIndex) +{ + var state = debugStates[stateIndex]; + return bytesCodeMapping.getValue(state.curPC); } function highlightSelection(index) @@ -44,11 +70,15 @@ function highlightSelection(index) function completeCtxInformation(state) { - debugStackTxt.text = state.debugStack; - debugStorageTxt.text = state.debugStorage; - debugMemoryTxt.text = state.debugMemory; - debugCallDataTxt.text = state.debugCallData; - headerInfoLabel.text = state.headerInfo + basicInfo.currentStep = state.step; + basicInfo.mem = state.newMemSize + " " + qsTr("words"); + basicInfo.stepCost = state.gasCost; + basicInfo.gasSpent = debugStates[0].gas - state.gas; + // This is available in all editors. + stack.listModel = state.debugStack; + storage.listModel = state.debugStorage; + memoryDump.listModel = state.debugMemory; + callDataDump.listModel = state.debugCallData; } function endOfDebug() @@ -66,3 +96,86 @@ function displayReturnValue() headerReturnList.model = contractCallReturnParameters; headerReturnList.update(); } + +function stepOutBack() +{ + if (jumpStartingPoint != null) + { + select(jumpStartingPoint); + jumpStartingPoint = null; + jumpoutbackaction.state = "disabled"; + jumpoutforwardaction.state = "disabled"; + } +} + +function stepIntoBack() +{ + moveSelection(-1); +} + +function stepOverBack() +{ + var state = debugStates[currentSelectedState]; + if (state.instruction === "JUMPDEST") + { + for (var k = currentSelectedState; k > 0; k--) + { + var line = bytesCodeMapping.getValue(debugStates[k].curPC); + if (line === statesList.currentIndex - 2) + { + select(k); + break; + } + } + } + else + moveSelection(-1); +} + +function stepOverForward() +{ + var state = debugStates[currentSelectedState]; + if (state.instruction === "JUMP") + { + for (var k = currentSelectedState; k < debugStates.length; k++) + { + var line = bytesCodeMapping.getValue(debugStates[k].curPC); + if (line === statesList.currentIndex + 2) + { + select(k); + break; + } + } + } + else + moveSelection(1); +} + +function stepIntoForward() +{ + var state = debugStates[currentSelectedState]; + if (state.instruction === "JUMP") + { + jumpStartingPoint = currentSelectedState; + moveSelection(1); + jumpoutbackaction.state = ""; + jumpoutforwardaction.state = ""; + } +} + +function stepOutForward() +{ + if (jumpStartingPoint != null) + { + stepOutBack(); + stepOverForward(); + jumpoutbackaction.state = "disabled"; + jumpoutforwardaction.state = "disabled"; + } +} + +function jumpTo(value) +{ + currentSelectedState = value; + select(currentSelectedState); +} diff --git a/mix/qml/js/ErrorLocationFormater.js b/mix/qml/js/ErrorLocationFormater.js index 6ebec2299..8c83e6b15 100644 --- a/mix/qml/js/ErrorLocationFormater.js +++ b/mix/qml/js/ErrorLocationFormater.js @@ -1,181 +1,27 @@ -//humanReadableExecutionCode => contain human readable code. -//debugStates => contain all debug states. -//bytesCodeMapping => mapping between humanReadableExecutionCode and bytesCode. -//statesList => ListView - -var currentSelectedState = null; -var jumpStartingPoint = null; -function init() -{ - statesSlider.maximumValue = debugStates.length - 1; - statesList.model = humanReadableExecutionCode; - currentSelectedState = 0; - select(currentSelectedState); - //displayReturnValue(); - - jumpoutbackaction.state = "disabled"; - jumpintobackaction.state = "disabled"; - jumpintoforwardaction.state = "disabled" - jumpoutforwardaction.state = "disabled" - -} - -function moveSelection(incr) -{ - if (currentSelectedState + incr >= 0) - { - if (currentSelectedState + incr < debugStates.length) - { - select(currentSelectedState + incr); - } - else - { - //endOfDebug(); - } - statesSlider.value = currentSelectedState; - } -} - -function select(stateIndex) -{ - var codeLine = codeStr(stateIndex); - var state = debugStates[stateIndex]; - highlightSelection(codeLine); - currentSelectedState = stateIndex; - completeCtxInformation(state); - //levelList.model = state.levels; - //levelList.update(); - - if (state.instruction === "JUMP") - jumpintoforwardaction.state = ""; - else - jumpintoforwardaction.state = "disabled"; - - if (state.instruction === "JUMPDEST") - jumpintobackaction.state = ""; - else - jumpintobackaction.state = "disabled"; -} - -function codeStr(stateIndex) -{ - var state = debugStates[stateIndex]; - return bytesCodeMapping.getValue(state.curPC); -} - -function highlightSelection(index) -{ - statesList.currentIndex = index; -} - -function completeCtxInformation(state) -{ - basicInfo.currentStep = state.step; - basicInfo.mem = state.newMemSize + " " + qsTr("words"); - basicInfo.stepCost = state.gasCost; - basicInfo.gasSpent = debugStates[0].gas - state.gas; - // This is available in all editors. - stack.listModel = state.debugStack; - storage.listModel = state.debugStorage; - memoryDump.listModel = state.debugMemory; - callDataDump.listModel = state.debugCallData; -} - -function endOfDebug() +function formatLocation(raw, shortMessage) { - var state = debugStates[debugStates.length - 1]; - debugStorageTxt.text = ""; - debugCallDataTxt.text = ""; - debugStackTxt.text = ""; - debugMemoryTxt.text = state.endOfDebug; - headerInfoLabel.text = "EXIT | GAS: " + state.gasLeft; -} - -function displayReturnValue() -{ - headerReturnList.model = contractCallReturnParameters; - headerReturnList.update(); -} - -function stepOutBack() -{ - if (jumpStartingPoint != null) - { - select(jumpStartingPoint); - jumpStartingPoint = null; - jumpoutbackaction.state = "disabled"; - jumpoutforwardaction.state = "disabled"; - } -} - -function stepIntoBack() -{ - moveSelection(-1); -} - -function stepOverBack() -{ - var state = debugStates[currentSelectedState]; - if (state.instruction === "JUMPDEST") - { - for (var k = currentSelectedState; k > 0; k--) - { - var line = bytesCodeMapping.getValue(debugStates[k].curPC); - if (line === statesList.currentIndex - 2) - { - select(k); - break; - } - } - } + var splitted = raw.split(':'); + if (!shortMessage) + return qsTr("Error in line ") + splitted[1] + ", " + qsTr("character ") + splitted[2]; else - moveSelection(-1); + return "L" + splitted[1] + "," + "C" + splitted[2]; } -function stepOverForward() +function extractErrorInfo(raw, shortMessage) { - var state = debugStates[currentSelectedState]; - if (state.instruction === "JUMP") + var _return = {}; + var detail = raw.split('\n')[0]; + var reg = detail.match(/:\d+:\d+:/g); + if (reg !== null) { - for (var k = currentSelectedState; k < debugStates.length; k++) - { - var line = bytesCodeMapping.getValue(debugStates[k].curPC); - if (line === statesList.currentIndex + 2) - { - select(k); - break; - } - } + _return.errorLocation = ErrorLocationFormater.formatLocation(reg[0], shortMessage); + _return.errorDetail = detail.replace(reg[0], ""); } else - moveSelection(1); -} - -function stepIntoForward() -{ - var state = debugStates[currentSelectedState]; - if (state.instruction === "JUMP") { - jumpStartingPoint = currentSelectedState; - moveSelection(1); - jumpoutbackaction.state = ""; - jumpoutforwardaction.state = ""; + _return.errorLocation = ""; + _return.errorDetail = detail; } -} - -function stepOutForward() -{ - if (jumpStartingPoint != null) - { - stepOutBack(); - stepOverForward(); - jumpoutbackaction.state = "disabled"; - jumpoutforwardaction.state = "disabled"; - } -} - -function jumpTo(value) -{ - currentSelectedState = value; - select(currentSelectedState); + _return.errorLine = raw.split('\n')[1]; + return _return; } diff --git a/mix/qml/js/main.js b/mix/qml/js/main.js index d516abde6..e69de29bb 100644 --- a/mix/qml/js/main.js +++ b/mix/qml/js/main.js @@ -1,68 +0,0 @@ -//humanReadableExecutionCode => contain human readable code. -//debugStates => contain all debug states. -//bytesCodeMapping => mapping between humanReadableExecutionCode and bytesCode. -//statesList => ListView - -var currentSelectedState = null; -function init() -{ - currentSelectedState = 0; - select(currentSelectedState); - displayReturnValue(); -} - -function moveSelection(incr) -{ - if (currentSelectedState + incr >= 0) - { - if (currentSelectedState + incr < debugStates.length) - { - select(currentSelectedState + incr); - } - else - { - endOfDebug(); - } - } -} - -function select(stateIndex) -{ - var state = debugStates[stateIndex]; - var codeStr = bytesCodeMapping.getValue(state.curPC); - highlightSelection(codeStr); - currentSelectedState = stateIndex; - completeCtxInformation(state); - levelList.model = state.levels; - levelList.update(); -} - -function highlightSelection(index) -{ - statesList.currentIndex = index; -} - -function completeCtxInformation(state) -{ - debugStackTxt.text = state.debugStack; - debugStorageTxt.text = state.debugStorage; - debugMemoryTxt.text = state.debugMemory; - debugCallDataTxt.text = state.debugCallData; - headerInfoLabel.text = state.headerInfo -} - -function endOfDebug() -{ - var state = debugStates[debugStates.length - 1]; - debugStorageTxt.text = ""; - debugCallDataTxt.text = ""; - debugStackTxt.text = ""; - debugMemoryTxt.text = state.endOfDebug; - headerInfoLabel.text = "EXIT | GAS: " + state.gasLeft; -} - -function displayReturnValue() -{ - headerReturnList.model = contractCallReturnParameters; - headerReturnList.update(); -} diff --git a/mix/qml/main.qml b/mix/qml/main.qml index e44144f61..9aac44c45 100644 --- a/mix/qml/main.qml +++ b/mix/qml/main.qml @@ -15,7 +15,7 @@ ApplicationWindow { minimumHeight: 300 title: qsTr("mix") - menuBar: MenuBar { + /*menuBar: MenuBar { Menu { title: qsTr("File") MenuItem { @@ -28,15 +28,19 @@ ApplicationWindow { MenuItem { action: debugRunAction } MenuItem { action: debugResetStateAction } } - } + }*/ + Component.onCompleted: { setX(Screen.width / 2 - width / 2); setY(Screen.height / 2 - height / 2); } MainContent { + id: mainContent; + anchors.fill: parent } + ModalDialog { objectName: "dialog" id: dialog @@ -51,7 +55,10 @@ ApplicationWindow { id: debugRunAction text: "&Run" shortcut: "F5" - onTriggered: debugModel.debugDeployment(); + onTriggered: { + mainContent.ensureRightView(); + debugModel.debugDeployment(); + } } Action {