parent
b8fa1a4e8a
commit
73385468ec
@ -1,184 +0,0 @@ |
||||
'use strict' |
||||
var remixLib = require('remix-lib') |
||||
var EventManager = remixLib.EventManager |
||||
var yo = require('yo-yo') |
||||
|
||||
var csjs = require('csjs-inject') |
||||
var styleGuide = require('../../../../ui/styles-guide/theme-chooser') |
||||
var styles = styleGuide.chooser() |
||||
|
||||
var css = csjs` |
||||
.buttons { |
||||
display: flex; |
||||
flex-wrap: wrap; |
||||
} |
||||
.stepButtons { |
||||
width: 100%; |
||||
display: flex; |
||||
justify-content: center; |
||||
} |
||||
.stepButton { |
||||
${styles.rightPanel.debuggerTab.button_Debugger} |
||||
} |
||||
.jumpButtons { |
||||
width: 100%; |
||||
display: flex; |
||||
justify-content: center; |
||||
} |
||||
.jumpButton { |
||||
${styles.rightPanel.debuggerTab.button_Debugger} |
||||
} |
||||
.navigator { |
||||
color: ${styles.rightPanel.debuggerTab.text_Primary}; |
||||
} |
||||
.navigator:hover { |
||||
color: ${styles.rightPanel.debuggerTab.button_Debugger_icon_HoverColor}; |
||||
} |
||||
` |
||||
|
||||
function ButtonNavigator (_parent, _traceManager) { |
||||
this.event = new EventManager() |
||||
this.intoBackDisabled = true |
||||
this.overBackDisabled = true |
||||
this.intoForwardDisabled = true |
||||
this.overForwardDisabled = true |
||||
this.jumpOutDisabled = true |
||||
this.jumpNextBreakpointDisabled = true |
||||
this.jumpPreviousBreakpointDisabled = true |
||||
|
||||
this.traceManager = _traceManager |
||||
this.currentCall = null |
||||
this.revertionPoint = null |
||||
|
||||
_parent.event.register('indexChanged', this, (index) => { |
||||
if (!this.view) return |
||||
if (index < 0) return |
||||
if (_parent.currentStepIndex !== index) return |
||||
|
||||
this.traceManager.buildCallPath(index, (error, callsPath) => { |
||||
if (error) { |
||||
console.log(error) |
||||
resetWarning(this) |
||||
} else { |
||||
this.currentCall = callsPath[callsPath.length - 1] |
||||
if (this.currentCall.reverted) { |
||||
this.revertionPoint = this.currentCall.return |
||||
this.view.querySelector('#reverted').style.display = 'block' |
||||
this.view.querySelector('#reverted #outofgas').style.display = this.currentCall.outOfGas ? 'inline' : 'none' |
||||
this.view.querySelector('#reverted #parenthasthrown').style.display = 'none' |
||||
} else { |
||||
var k = callsPath.length - 2 |
||||
while (k >= 0) { |
||||
var parent = callsPath[k] |
||||
if (parent.reverted) { |
||||
this.revertionPoint = parent.return |
||||
this.view.querySelector('#reverted').style.display = 'block' |
||||
this.view.querySelector('#reverted #parenthasthrown').style.display = parent ? 'inline' : 'none' |
||||
this.view.querySelector('#reverted #outofgas').style.display = 'none' |
||||
return |
||||
} |
||||
k-- |
||||
} |
||||
resetWarning(this) |
||||
} |
||||
} |
||||
}) |
||||
}) |
||||
|
||||
this.view |
||||
} |
||||
|
||||
module.exports = ButtonNavigator |
||||
|
||||
ButtonNavigator.prototype.render = function () { |
||||
var self = this |
||||
var view = yo`<div class="${css.buttons}">
|
||||
<div class="${css.stepButtons}"> |
||||
<button id='overback' title='Step over back' class='${css.navigator} ${css.stepButton} fa fa-reply' onclick=${function () { self.event.trigger('stepOverBack') }} disabled=${this.overBackDisabled} ></button> |
||||
<button id='intoback' title='Step back' class='${css.navigator} ${css.stepButton} fa fa-level-up' onclick=${function () { self.event.trigger('stepIntoBack') }} disabled=${this.intoBackDisabled} ></button> |
||||
<button id='intoforward' title='Step into' class='${css.navigator} ${css.stepButton} fa fa-level-down' onclick=${function () { self.event.trigger('stepIntoForward') }} disabled=${this.intoForwardDisabled} ></button> |
||||
<button id='overforward' title='Step over forward' class='${css.navigator} ${css.stepButton} fa fa-share' onclick=${function () { self.event.trigger('stepOverForward') }} disabled=${this.overForwardDisabled} ></button> |
||||
</div> |
||||
|
||||
<div class="${css.jumpButtons}"> |
||||
<button id='jumppreviousbreakpoint' title='Jump to the previous breakpoint' class='${css.navigator} ${css.jumpButton} fa fa-step-backward' onclick=${function () { self.event.trigger('jumpPreviousBreakpoint') }} disabled=${this.jumpPreviousBreakpointDisabled} ></button> |
||||
<button id='jumpout' title='Jump out' class='${css.navigator} ${css.jumpButton} fa fa-eject' onclick=${function () { self.event.trigger('jumpOut') }} disabled=${this.jumpOutDisabled} ></button> |
||||
<button id='jumpnextbreakpoint' title='Jump to the next breakpoint' class='${css.navigator} ${css.jumpButton} fa fa-step-forward' onclick=${function () { self.event.trigger('jumpNextBreakpoint') }} disabled=${this.jumpNextBreakpointDisabled} ></button> |
||||
</div> |
||||
<div id='reverted' style="display:none"> |
||||
<button id='jumptoexception' title='Jump to exception' class='${css.navigator} ${css.button} fa fa-exclamation-triangle' onclick=${function () { self.event.trigger('jumpToException', [self.revertionPoint]) }} disabled=${this.jumpOutDisabled} > |
||||
</button> |
||||
<span>State changes made during this call will be reverted.</span> |
||||
<span id='outofgas' style="display:none">This call will run out of gas.</span> |
||||
<span id='parenthasthrown' style="display:none">The parent call will throw an exception</span> |
||||
</div> |
||||
</div>` |
||||
if (!this.view) { |
||||
this.view = view |
||||
} |
||||
return view |
||||
} |
||||
|
||||
ButtonNavigator.prototype.reset = function () { |
||||
this.intoBackDisabled = true |
||||
this.overBackDisabled = true |
||||
this.intoForwardDisabled = true |
||||
this.overForwardDisabled = true |
||||
this.jumpOutDisabled = true |
||||
this.jumpNextBreakpointDisabled = true |
||||
this.jumpPreviousBreakpointDisabled = true |
||||
resetWarning(this) |
||||
} |
||||
|
||||
ButtonNavigator.prototype.stepChanged = function (step) { |
||||
this.intoBackDisabled = step <= 0 |
||||
this.overBackDisabled = step <= 0 |
||||
if (!this.traceManager) { |
||||
this.intoForwardDisabled = true |
||||
this.overForwardDisabled = true |
||||
} else { |
||||
var self = this |
||||
this.traceManager.getLength(function (error, length) { |
||||
if (error) { |
||||
self.reset() |
||||
console.log(error) |
||||
} else { |
||||
self.jumpNextBreakpointDisabled = step >= length - 1 |
||||
self.jumpPreviousBreakpointDisabled = step <= 0 |
||||
self.intoForwardDisabled = step >= length - 1 |
||||
self.overForwardDisabled = step >= length - 1 |
||||
var stepOut = self.traceManager.findStepOut(step) |
||||
self.jumpOutDisabled = stepOut === step |
||||
} |
||||
self.updateAll() |
||||
}) |
||||
} |
||||
this.updateAll() |
||||
} |
||||
|
||||
ButtonNavigator.prototype.updateAll = function () { |
||||
this.updateDisabled('intoback', this.intoBackDisabled) |
||||
this.updateDisabled('overback', this.overBackDisabled) |
||||
this.updateDisabled('overforward', this.overForwardDisabled) |
||||
this.updateDisabled('intoforward', this.intoForwardDisabled) |
||||
this.updateDisabled('jumpout', this.jumpOutDisabled) |
||||
this.updateDisabled('jumptoexception', this.jumpOutDisabled) |
||||
this.updateDisabled('jumpnextbreakpoint', this.jumpNextBreakpointDisabled) |
||||
this.updateDisabled('jumppreviousbreakpoint', this.jumpPreviousBreakpointDisabled) |
||||
} |
||||
|
||||
ButtonNavigator.prototype.updateDisabled = function (id, disabled) { |
||||
if (disabled) { |
||||
document.getElementById(id).setAttribute('disabled', true) |
||||
} else { |
||||
document.getElementById(id).removeAttribute('disabled') |
||||
} |
||||
} |
||||
|
||||
function resetWarning (self) { |
||||
self.view.querySelector('#reverted #outofgas').style.display = 'none' |
||||
self.view.querySelector('#reverted #parenthasthrown').style.display = 'none' |
||||
self.view.querySelector('#reverted').style.display = 'none' |
||||
} |
||||
|
||||
module.exports = ButtonNavigator |
@ -1,33 +0,0 @@ |
||||
'use strict' |
||||
var DropdownPanel = require('./DropdownPanel') |
||||
var yo = require('yo-yo') |
||||
|
||||
function CalldataPanel (_parentUI, _traceManager) { |
||||
this._parentUI = _parentUI |
||||
this.traceManager = _traceManager |
||||
this.basicPanel = new DropdownPanel('Call Data', {json: true}) |
||||
this.init() |
||||
} |
||||
|
||||
CalldataPanel.prototype.render = function () { |
||||
return yo`<div id='calldatapanel' >${this.basicPanel.render()}</div>` |
||||
} |
||||
|
||||
CalldataPanel.prototype.init = function () { |
||||
var self = this |
||||
this._parentUI.event.register('indexChanged', this, function (index) { |
||||
if (index < 0) return |
||||
if (self._parentUI.currentStepIndex !== index) return |
||||
|
||||
self.traceManager.getCallDataAt(index, function (error, calldata) { |
||||
if (error) { |
||||
self.basicPanel.update({}) |
||||
console.log(error) |
||||
} else if (self._parentUI.currentStepIndex === index) { |
||||
self.basicPanel.update(calldata) |
||||
} |
||||
}) |
||||
}) |
||||
} |
||||
|
||||
module.exports = CalldataPanel |
@ -1,33 +0,0 @@ |
||||
'use strict' |
||||
var DropdownPanel = require('./DropdownPanel') |
||||
var yo = require('yo-yo') |
||||
|
||||
function CallstackPanel (_parent, _traceManager) { |
||||
this.parent = _parent |
||||
this.traceManager = _traceManager |
||||
this.basicPanel = new DropdownPanel('Call Stack', {json: true}) |
||||
this.init() |
||||
} |
||||
|
||||
CallstackPanel.prototype.render = function () { |
||||
return yo`<div id='callstackpanel' >${this.basicPanel.render()}</div>` |
||||
} |
||||
|
||||
CallstackPanel.prototype.init = function () { |
||||
var self = this |
||||
this.parent.event.register('indexChanged', this, function (index) { |
||||
if (index < 0) return |
||||
if (self.parent.currentStepIndex !== index) return |
||||
|
||||
self.traceManager.getCallStackAt(index, function (error, callstack) { |
||||
if (error) { |
||||
console.log(error) |
||||
self.basicPanel.update({}) |
||||
} else if (self.parent.currentStepIndex === index) { |
||||
self.basicPanel.update(callstack) |
||||
} |
||||
}) |
||||
}) |
||||
} |
||||
|
||||
module.exports = CallstackPanel |
@ -1,88 +0,0 @@ |
||||
'use strict' |
||||
var style = require('./styles/basicStyles') |
||||
var yo = require('yo-yo') |
||||
var remixLib = require('remix-lib') |
||||
var DropdownPanel = require('./DropdownPanel') |
||||
var EventManager = remixLib.EventManager |
||||
var csjs = require('csjs-inject') |
||||
var styleGuide = require('../../../../ui/styles-guide/theme-chooser') |
||||
var styles = styleGuide.chooser() |
||||
|
||||
var css = csjs` |
||||
.instructions { |
||||
${styles.rightPanel.debuggerTab.box_Debugger} |
||||
overflow-y: scroll; |
||||
max-height: 150px; |
||||
} |
||||
` |
||||
function CodeListView (_parent, _codeManager) { |
||||
this.event = new EventManager() |
||||
this.parent = _parent |
||||
this.codeManager = _codeManager |
||||
this.code |
||||
this.address |
||||
this.codeView |
||||
this.itemSelected |
||||
this.basicPanel = new DropdownPanel('Instructions', {json: false, displayContentOnly: true}) |
||||
this.basicPanel.event.register('hide', () => { |
||||
this.event.trigger('hide', []) |
||||
}) |
||||
this.basicPanel.event.register('show', () => { |
||||
this.event.trigger('show', []) |
||||
}) |
||||
this.init() |
||||
} |
||||
|
||||
CodeListView.prototype.render = function () { |
||||
return yo`<div id='asmcodes' >${this.basicPanel.render({height: style.instructionsList.height})}</div>` |
||||
} |
||||
|
||||
CodeListView.prototype.init = function () { |
||||
var self = this |
||||
this.codeManager.event.register('changed', this, this.changed) |
||||
this.parent.event.register('traceUnloaded', this, function () { |
||||
self.changed([], '', -1) |
||||
}) |
||||
} |
||||
|
||||
CodeListView.prototype.indexChanged = function (index) { |
||||
if (index >= 0) { |
||||
if (this.itemSelected) { |
||||
this.itemSelected.removeAttribute('selected') |
||||
this.itemSelected.removeAttribute('style') |
||||
if (this.itemSelected.firstChild) { |
||||
this.itemSelected.firstChild.removeAttribute('style') |
||||
} |
||||
} |
||||
this.itemSelected = this.codeView.children[index] |
||||
this.itemSelected.setAttribute('style', 'background-color: ' + styles.rightPanel.debuggerTab.text_BgHighlight) |
||||
this.itemSelected.setAttribute('selected', 'selected') |
||||
if (this.itemSelected.firstChild) { |
||||
this.itemSelected.firstChild.setAttribute('style', 'margin-left: 2px') |
||||
} |
||||
this.codeView.scrollTop = this.itemSelected.offsetTop - parseInt(this.codeView.offsetTop) |
||||
} |
||||
} |
||||
|
||||
CodeListView.prototype.changed = function (code, address, index) { |
||||
if (this.address !== address) { |
||||
this.code = code |
||||
this.address = address |
||||
this.codeView = this.renderAssemblyItems() |
||||
this.basicPanel.setContent(this.codeView) |
||||
} |
||||
this.indexChanged(index) |
||||
} |
||||
|
||||
CodeListView.prototype.renderAssemblyItems = function () { |
||||
if (this.code) { |
||||
var codeView = this.code.map(function (item, i) { |
||||
return yo`<div key=${i} value=${i}><span>${item}</span></div>` |
||||
}) |
||||
return yo`<div class=${css.instructions} id='asmitems' ref='itemsList'>
|
||||
${codeView} |
||||
</div>` |
||||
} |
||||
} |
||||
|
||||
module.exports = CodeListView |
@ -1,208 +0,0 @@ |
||||
'use strict' |
||||
var yo = require('yo-yo') |
||||
const copy = require('clipboard-copy') |
||||
var remixLib = require('remix-lib') |
||||
var TreeView = require('../../../../ui/TreeView') // TODO setup a direct reference to the UI components
|
||||
var EventManager = remixLib.EventManager |
||||
|
||||
var csjs = require('csjs-inject') |
||||
var styleGuide = require('../../../../ui/styles-guide/theme-chooser') |
||||
var styles = styleGuide.chooser() |
||||
|
||||
var css = csjs` |
||||
.title { |
||||
margin-top: 10px; |
||||
${styles.rightPanel.debuggerTab.dropdown_Debugger}; |
||||
display: flex; |
||||
align-items: center; |
||||
} |
||||
.name { |
||||
font-weight: bold; |
||||
} |
||||
.nameDetail { |
||||
font-weight: bold; |
||||
margin-left: 3px; |
||||
} |
||||
.icon { |
||||
color: ${styles.rightPanel.debuggerTab.button_Debugger_icon_Color}; |
||||
margin-right: 5%; |
||||
} |
||||
.eyeButton { |
||||
margin: 3px; |
||||
} |
||||
.eyeButton:hover { |
||||
color: ${styles.rightPanel.debuggerTab.button_Debugger_icon_HoverColor}; |
||||
} |
||||
.dropdownpanel { |
||||
${styles.rightPanel.debuggerTab.dropdown_Debugger}; |
||||
width: 100%; |
||||
} |
||||
.dropdownrawcontent { |
||||
padding: 2px; |
||||
word-break: break-all; |
||||
} |
||||
.message { |
||||
padding: 2px; |
||||
word-break: break-all; |
||||
} |
||||
.refresh { |
||||
display: none; |
||||
margin-left: 4px; |
||||
margin-top: 4px;
|
||||
animation: spin 2s linear infinite; |
||||
} |
||||
` |
||||
|
||||
function DropdownPanel (_name, _opts) { |
||||
this.event = new EventManager() |
||||
if (!_opts) { |
||||
_opts = {} |
||||
} |
||||
this.name = _name |
||||
this.header = '' |
||||
this.json = _opts.json |
||||
this.displayContentOnly = _opts.displayContentOnly |
||||
if (this.json) { |
||||
this.treeView = new TreeView(_opts) |
||||
} |
||||
this.view |
||||
} |
||||
|
||||
DropdownPanel.prototype.setMessage = function (message) { |
||||
if (this.view) { |
||||
this.view.querySelector('.dropdownpanel .dropdownrawcontent').style.display = 'none' |
||||
this.view.querySelector('.dropdownpanel .dropdowncontent').style.display = 'none' |
||||
this.view.querySelector('.dropdownpanel .fa-refresh').style.display = 'none' |
||||
this.message(message) |
||||
} |
||||
} |
||||
|
||||
DropdownPanel.prototype.setLoading = function () { |
||||
if (this.view) { |
||||
this.view.querySelector('.dropdownpanel .dropdownrawcontent').style.display = 'none' |
||||
this.view.querySelector('.dropdownpanel .dropdowncontent').style.display = 'none' |
||||
this.view.querySelector('.dropdownpanel .fa-refresh').style.display = 'inline-block' |
||||
this.message('') |
||||
} |
||||
} |
||||
|
||||
DropdownPanel.prototype.setUpdating = function () { |
||||
if (this.view) { |
||||
this.view.querySelector('.dropdownpanel .dropdowncontent').style.color = styles.appProperties.greyedText_color |
||||
} |
||||
} |
||||
|
||||
DropdownPanel.prototype.update = function (_data, _header) { |
||||
if (this.view) { |
||||
this.view.querySelector('.dropdownpanel .fa-refresh').style.display = 'none' |
||||
this.view.querySelector('.dropdownpanel .dropdowncontent').style.display = 'block' |
||||
this.view.querySelector('.dropdownpanel .dropdowncontent').style.color = styles.appProperties.mainText_Color |
||||
this.view.querySelector('.dropdownpanel .dropdownrawcontent').innerText = JSON.stringify(_data, null, '\t') |
||||
if (!this.displayContentOnly) { |
||||
this.view.querySelector('.title div.btn').style.display = 'block' |
||||
this.view.querySelector('.title span').innerText = _header || ' ' |
||||
} |
||||
this.message('') |
||||
if (this.json) { |
||||
this.treeView.update(_data) |
||||
} |
||||
} |
||||
} |
||||
|
||||
DropdownPanel.prototype.setContent = function (node) { |
||||
if (this.view) { |
||||
var parent = this.view.querySelector('.dropdownpanel div.dropdowncontent') |
||||
parent.replaceChild(node, parent.firstElementChild) |
||||
} |
||||
} |
||||
|
||||
DropdownPanel.prototype.render = function (overridestyle) { |
||||
var content = yo`<div>Empty</div>` |
||||
if (this.json) { |
||||
content = this.treeView.render({}) |
||||
} |
||||
overridestyle === undefined ? {} : overridestyle |
||||
var self = this |
||||
var title = !self.displayContentOnly ? yo`<div class="${css.title} title">
|
||||
<div class="${css.icon} fa fa-caret-right" onclick=${function () { self.toggle() }} ></div> |
||||
<div class="${css.name}" onclick=${function () { self.toggle() }} >${this.name}</div><span class="${css.nameDetail}" onclick=${function () { self.toggle() }} ></span> |
||||
<div onclick=${function () { self.copyClipboard() }} title='raw' class="${css.eyeButton} btn fa fa-clipboard"></div> |
||||
</div>` : yo`<div></div>` |
||||
|
||||
var contentNode = yo`<div class='dropdownpanel' style='display:none'>
|
||||
<i class="${css.refresh} fa fa-refresh" aria-hidden="true"></i> |
||||
<div class='dropdowncontent'>${content}</div> |
||||
<div class='dropdownrawcontent' style='display:none'></div> |
||||
<div class='message' style='display:none'></div> |
||||
</div>` |
||||
var view = yo` |
||||
<div> |
||||
<style> |
||||
@-moz-keyframes spin { |
||||
to { -moz-transform: rotate(359deg); } |
||||
} |
||||
@-webkit-keyframes spin { |
||||
to { -webkit-transform: rotate(359deg); } |
||||
} |
||||
@keyframes spin { |
||||
to {transform:rotate(359deg);} |
||||
} |
||||
</style> |
||||
${title} |
||||
${contentNode} |
||||
</div>` |
||||
if (!this.view) { |
||||
this.view = view |
||||
} |
||||
if (self.displayContentOnly) contentNode.style.display = 'block' |
||||
return view |
||||
} |
||||
|
||||
DropdownPanel.prototype.copyClipboard = function () { |
||||
var content = this.view.querySelector('.dropdownpanel .dropdownrawcontent') |
||||
if (content) copy(content.innerText ? content.innerText : content.textContent) |
||||
} |
||||
|
||||
DropdownPanel.prototype.toggle = function () { |
||||
var el = this.view.querySelector('.dropdownpanel') |
||||
var caret = this.view.querySelector('.title').firstElementChild |
||||
if (el.style.display === '') { |
||||
el.style.display = 'none' |
||||
caret.className = `${css.icon} fa fa-caret-right` |
||||
this.event.trigger('hide', []) |
||||
} else { |
||||
el.style.display = '' |
||||
caret.className = `${css.icon} fa fa-caret-down` |
||||
this.event.trigger('show', []) |
||||
} |
||||
} |
||||
|
||||
DropdownPanel.prototype.hide = function () { |
||||
if (this.view && !this.displayContentOnly) { |
||||
var caret = this.view.querySelector('.title').firstElementChild |
||||
var el = this.view.querySelector('.dropdownpanel') |
||||
el.style.display = 'none' |
||||
caret.className = `${css.icon} fa fa-caret-right` |
||||
this.event.trigger('hide', []) |
||||
} |
||||
} |
||||
|
||||
DropdownPanel.prototype.show = function () { |
||||
if (this.view && !this.displayContentOnly) { |
||||
var caret = this.view.querySelector('.title').firstElementChild |
||||
var el = this.view.querySelector('.dropdownpanel') |
||||
el.style.display = '' |
||||
caret.className = `${css.icon} fa fa-caret-down` |
||||
this.event.trigger('show', []) |
||||
} |
||||
} |
||||
|
||||
DropdownPanel.prototype.message = function (message) { |
||||
if (this.view) { |
||||
var mes = this.view.querySelector('.dropdownpanel .message') |
||||
mes.innerText = message |
||||
mes.style.display = (message === '') ? 'none' : 'block' |
||||
} |
||||
} |
||||
|
||||
module.exports = DropdownPanel |
@ -1,210 +0,0 @@ |
||||
'use strict' |
||||
var TxBrowser = require('./TxBrowser') |
||||
var StepManager = require('./StepManager') |
||||
var remixLib = require('remix-lib') |
||||
var TraceManager = remixLib.trace.TraceManager |
||||
var VmDebugger = require('./VmDebugger') |
||||
var init = remixLib.init |
||||
var executionContext = remixLib.execution.executionContext |
||||
var EventManager = remixLib.EventManager |
||||
var yo = require('yo-yo') |
||||
var csjs = require('csjs-inject') |
||||
var Web3Providers = remixLib.vm.Web3Providers |
||||
var DummyProvider = remixLib.vm.DummyProvider |
||||
var CodeManager = remixLib.code.CodeManager |
||||
var remixDebug = require('remix-debug') |
||||
var SolidityProxy = remixDebug.SolidityDecoder.SolidityProxy |
||||
var InternalCallTree = remixDebug.SolidityDecoder.InternalCallTree |
||||
|
||||
var css = csjs` |
||||
.statusMessage { |
||||
margin-left: 15px; |
||||
} |
||||
.innerShift { |
||||
padding: 2px; |
||||
margin-left: 10px; |
||||
} |
||||
` |
||||
|
||||
function Ethdebugger (opts) { |
||||
this.opts = opts || {} |
||||
if (!this.opts.compilationResult) this.opts.compilationResult = () => { return null } |
||||
|
||||
var self = this |
||||
this.event = new EventManager() |
||||
|
||||
this.currentStepIndex = -1 |
||||
this.tx |
||||
this.statusMessage = '' |
||||
|
||||
this.view |
||||
this.web3Providers = new Web3Providers() |
||||
this.addProvider('DUMMYWEB3', new DummyProvider()) |
||||
this.switchProvider('DUMMYWEB3') |
||||
this.traceManager = new TraceManager() |
||||
this.codeManager = new CodeManager(this.traceManager) |
||||
this.solidityProxy = new SolidityProxy(this.traceManager, this.codeManager) |
||||
|
||||
var callTree = new InternalCallTree(this.event, this.traceManager, this.solidityProxy, this.codeManager, { includeLocalVariables: true }) |
||||
this.callTree = callTree // TODO: currently used by browser solidity, we should improve the API
|
||||
|
||||
this.event.register('indexChanged', this, function (index) { |
||||
self.codeManager.resolveStep(index, self.tx) |
||||
}) |
||||
|
||||
this.txBrowser = new TxBrowser(this) |
||||
this.txBrowser.event.register('newTxLoading', this, function () { |
||||
self.unLoad() |
||||
}) |
||||
this.txBrowser.event.register('newTraceRequested', this, function (blockNumber, txIndex, tx) { |
||||
console.dir('newTraceRequestd') |
||||
console.dir(arguments) |
||||
self.startDebugging(blockNumber, txIndex, tx) |
||||
}) |
||||
this.txBrowser.event.register('unloadRequested', this, function (blockNumber, txIndex, tx) { |
||||
self.unLoad() |
||||
}) |
||||
this.stepManager = new StepManager(this, this.traceManager) |
||||
this.stepManager.event.register('stepChanged', this, function (stepIndex) { |
||||
self.stepChanged(stepIndex) |
||||
}) |
||||
this.vmDebugger = new VmDebugger(this, this.traceManager, this.codeManager, this.solidityProxy, callTree) |
||||
|
||||
this.codeManager.event.register('changed', this, (code, address, instIndex) => { |
||||
this.callTree.sourceLocationTracker.getSourceLocationFromVMTraceIndex(address, this.currentStepIndex, this.solidityProxy.contracts, (error, sourceLocation) => { |
||||
if (!error) { |
||||
this.event.trigger('sourceLocationChanged', [sourceLocation]) |
||||
} |
||||
}) |
||||
}) |
||||
} |
||||
|
||||
Ethdebugger.prototype.setManagers = function () { |
||||
this.traceManager = new TraceManager({web3: this.web3}) |
||||
this.codeManager = new CodeManager(this.traceManager) |
||||
this.solidityProxy = new SolidityProxy(this.traceManager, this.codeManager) |
||||
this.storageResolver = null |
||||
var callTree = new InternalCallTree(this.event, this.traceManager, this.solidityProxy, this.codeManager, { includeLocalVariables: true }) |
||||
this.callTree = callTree // TODO: currently used by browser solidity, we should improve the API
|
||||
this.vmDebugger = new VmDebugger(this, this.traceManager, this.codeManager, this.solidityProxy, callTree) |
||||
|
||||
this.callTree = new InternalCallTree(this.event, this.traceManager, this.solidityProxy, this.codeManager, { includeLocalVariables: true }) |
||||
} |
||||
|
||||
Ethdebugger.prototype.setBreakpointManager = function (breakpointManager) { |
||||
this.breakpointManager = breakpointManager |
||||
} |
||||
|
||||
Ethdebugger.prototype.web3 = function () { |
||||
return global.web3 |
||||
} |
||||
|
||||
Ethdebugger.prototype.addProvider = function (type, obj) { |
||||
this.web3Providers.addProvider(type, obj) |
||||
this.event.trigger('providerAdded', [type]) |
||||
} |
||||
|
||||
Ethdebugger.prototype.updateWeb3Reference = function () { |
||||
if (!this.txBrowser) return |
||||
this.txBrowser.web3 = this.web3 |
||||
} |
||||
|
||||
Ethdebugger.prototype.switchProvider = function (type) { |
||||
var self = this |
||||
this.web3Providers.get(type, function (error, obj) { |
||||
if (error) { |
||||
console.log('provider ' + type + ' not defined') |
||||
} else { |
||||
self.web3 = obj |
||||
self.setManagers() |
||||
self.updateWeb3Reference() |
||||
executionContext.detectNetwork((error, network) => { |
||||
if (error || !network) { |
||||
global.web3Debug = obj |
||||
} else { |
||||
var webDebugNode = init.web3DebugNode(network.name) |
||||
global.web3Debug = !webDebugNode ? obj : webDebugNode |
||||
} |
||||
self.updateWeb3Reference() |
||||
}) |
||||
self.event.trigger('providerChanged', [type]) |
||||
} |
||||
}) |
||||
} |
||||
|
||||
Ethdebugger.prototype.setCompilationResult = function (compilationResult) { |
||||
if (compilationResult && compilationResult.sources && compilationResult.contracts) { |
||||
this.solidityProxy.reset(compilationResult) |
||||
} else { |
||||
this.solidityProxy.reset({}) |
||||
} |
||||
} |
||||
|
||||
Ethdebugger.prototype.debug = function (tx) { |
||||
this.setCompilationResult(this.opts.compilationResult()) |
||||
if (tx instanceof Object) { |
||||
this.txBrowser.load(tx.hash) |
||||
} else if (tx instanceof String) { |
||||
this.txBrowser.load(tx) |
||||
} |
||||
} |
||||
|
||||
Ethdebugger.prototype.render = function () { |
||||
var view = yo`<div>
|
||||
<div class="${css.innerShift}"> |
||||
${this.txBrowser.render()} |
||||
${this.vmDebugger.renderHead()} |
||||
${this.stepManager.render()} |
||||
</div> |
||||
<div class="${css.statusMessage}" >${this.statusMessage}</div> |
||||
${this.vmDebugger.render()} |
||||
</div>` |
||||
if (!this.view) { |
||||
this.view = view |
||||
} |
||||
return view |
||||
} |
||||
|
||||
Ethdebugger.prototype.unLoad = function () { |
||||
this.traceManager.init() |
||||
this.codeManager.clear() |
||||
this.stepManager.reset() |
||||
this.event.trigger('traceUnloaded') |
||||
} |
||||
|
||||
Ethdebugger.prototype.stepChanged = function (stepIndex) { |
||||
this.currentStepIndex = stepIndex |
||||
this.event.trigger('indexChanged', [stepIndex]) |
||||
} |
||||
|
||||
Ethdebugger.prototype.startDebugging = function (blockNumber, txIndex, tx) { |
||||
console.dir('startDebugging') |
||||
console.dir(arguments) |
||||
if (this.traceManager.isLoading) { |
||||
return |
||||
} |
||||
this.setCompilationResult(this.opts.compilationResult()) |
||||
this.statusMessage = 'Loading trace...' |
||||
yo.update(this.view, this.render()) |
||||
console.log('loading trace...') |
||||
this.tx = tx |
||||
var self = this |
||||
console.dir('resolving a trace with tx: ') |
||||
console.dir(tx) |
||||
this.traceManager.resolveTrace(tx, function (error, result) { |
||||
console.log('trace loaded ' + result) |
||||
if (result) { |
||||
self.statusMessage = '' |
||||
yo.update(self.view, self.render()) |
||||
self.event.trigger('newTraceLoaded', [self.traceManager.trace]) |
||||
if (self.breakpointManager && self.breakpointManager.hasBreakpoint()) { |
||||
self.breakpointManager.jumpNextBreakpoint(0, false) |
||||
} |
||||
} else { |
||||
self.statusMessage = error ? error.message : 'Trace not loaded' |
||||
yo.update(self.view, self.render()) |
||||
} |
||||
}) |
||||
} |
||||
|
||||
module.exports = Ethdebugger |
@ -1,72 +0,0 @@ |
||||
'use strict' |
||||
var DropdownPanel = require('./DropdownPanel') |
||||
var remixDebug = require('remix-debug') |
||||
var StorageViewer = remixDebug.storage.StorageViewer |
||||
var yo = require('yo-yo') |
||||
|
||||
function FullStoragesChanges (_parent, _traceManager) { |
||||
this.storageResolver = null |
||||
this.parent = _parent |
||||
this.debugger = _parent.debugger |
||||
this.traceManager = _traceManager |
||||
this.addresses = [] |
||||
this.view |
||||
this.traceLength |
||||
this.basicPanel = new DropdownPanel('Full Storages Changes', {json: true}) |
||||
this.init() |
||||
} |
||||
|
||||
FullStoragesChanges.prototype.render = function () { |
||||
var view = yo`<div id='fullstorageschangespanel' >${this.basicPanel.render()}</div>` |
||||
if (!this.view) { |
||||
this.view = view |
||||
} |
||||
return view |
||||
} |
||||
|
||||
FullStoragesChanges.prototype.init = function () { |
||||
var self = this |
||||
this.debugger.event.register('newTraceLoaded', this, function (length) { |
||||
self.panels = [] |
||||
self.traceManager.getAddresses(function (error, addresses) { |
||||
if (!error) { |
||||
self.addresses = addresses |
||||
self.basicPanel.update({}) |
||||
} |
||||
}) |
||||
|
||||
self.traceManager.getLength(function (error, length) { |
||||
if (!error) { |
||||
self.traceLength = length |
||||
} |
||||
}) |
||||
}) |
||||
|
||||
this.debugger.event.register('indexChanged', this, function (index) { |
||||
if (index < 0) return |
||||
if (self.parent.currentStepIndex !== index) return |
||||
if (!self.storageResolver) return |
||||
|
||||
if (index === self.traceLength - 1) { |
||||
var storageJSON = {} |
||||
for (var k in self.addresses) { |
||||
var address = self.addresses[k] |
||||
var storageViewer = new StorageViewer({ |
||||
stepIndex: self.parent.currentStepIndex, |
||||
tx: self.parent.tx, |
||||
address: address |
||||
}, self.storageResolver, self.traceManager) |
||||
storageViewer.storageRange(function (error, result) { |
||||
if (!error) { |
||||
storageJSON[address] = result |
||||
self.basicPanel.update(storageJSON) |
||||
} |
||||
}) |
||||
} |
||||
} else { |
||||
self.basicPanel.update({}) |
||||
} |
||||
}) |
||||
} |
||||
|
||||
module.exports = FullStoragesChanges |
@ -1,39 +0,0 @@ |
||||
'use strict' |
||||
var DropdownPanel = require('./DropdownPanel') |
||||
var remixLib = require('remix-lib') |
||||
var ui = remixLib.helpers.ui |
||||
var yo = require('yo-yo') |
||||
|
||||
function MemoryPanel (_parent, _traceManager) { |
||||
this.parent = _parent |
||||
this.traceManager = _traceManager |
||||
this.basicPanel = new DropdownPanel('Memory', { |
||||
json: true, |
||||
css: { |
||||
'font-family': 'monospace' |
||||
}}) |
||||
this.init() |
||||
} |
||||
|
||||
MemoryPanel.prototype.render = function () { |
||||
return yo`<div id='memorypanel' >${this.basicPanel.render()}</div>` |
||||
} |
||||
|
||||
MemoryPanel.prototype.init = function () { |
||||
var self = this |
||||
this.parent.event.register('indexChanged', this, function (index) { |
||||
if (index < 0) return |
||||
if (self.parent.currentStepIndex !== index) return |
||||
|
||||
self.traceManager.getMemoryAt(index, function (error, memory) { |
||||
if (error) { |
||||
console.log(error) |
||||
self.basicPanel.update({}) |
||||
} else if (self.parent.currentStepIndex === index) { |
||||
self.basicPanel.update(ui.formatMemory(memory, 16)) |
||||
} |
||||
}) |
||||
}) |
||||
} |
||||
|
||||
module.exports = MemoryPanel |
@ -1,75 +0,0 @@ |
||||
'use strict' |
||||
var remixLib = require('remix-lib') |
||||
var EventManager = remixLib.EventManager |
||||
var yo = require('yo-yo') |
||||
|
||||
class Slider { |
||||
constructor (_traceManager, _stepOverride) { |
||||
this.event = new EventManager() |
||||
this.traceManager = _traceManager |
||||
this.max |
||||
this.disabled = true |
||||
this.view |
||||
this.solidityMode = false |
||||
this.stepOverride = _stepOverride |
||||
|
||||
this.previousValue = null |
||||
} |
||||
|
||||
render () { |
||||
var self = this |
||||
var view = yo`<div>
|
||||
<input |
||||
id='slider' |
||||
style='width: 100%' |
||||
type='range' |
||||
min=0 |
||||
max=${this.max} |
||||
value=0 |
||||
onchange=${function () { self.onChange() }} |
||||
oninput=${function () { self.onChange() }} |
||||
disabled=${this.disabled} /> |
||||
</div>` |
||||
if (!this.view) { |
||||
this.view = view |
||||
} |
||||
return view |
||||
} |
||||
|
||||
init (length) { |
||||
var slider = this.view.querySelector('#slider') |
||||
slider.setAttribute('max', length - 1) |
||||
this.max = length - 1 |
||||
this.updateDisabled(length === 0) |
||||
this.disabled = length === 0 |
||||
this.setValue(0) |
||||
} |
||||
|
||||
onChange (event) { |
||||
var value = parseInt(this.view.querySelector('#slider').value) |
||||
if (this.stepOverride) { |
||||
var correctedValue = this.stepOverride(value) |
||||
if (correctedValue !== value) { |
||||
this.setValue(correctedValue) |
||||
value = correctedValue |
||||
} |
||||
} |
||||
if (value === this.previousValue) return |
||||
this.previousValue = value |
||||
this.event.trigger('moved', [value]) |
||||
} |
||||
|
||||
setValue (value) { |
||||
this.view.querySelector('#slider').value = value |
||||
} |
||||
|
||||
updateDisabled (disabled) { |
||||
if (disabled) { |
||||
this.view.querySelector('#slider').setAttribute('disabled', true) |
||||
} else { |
||||
this.view.querySelector('#slider').removeAttribute('disabled') |
||||
} |
||||
} |
||||
} |
||||
|
||||
module.exports = Slider |
@ -1,83 +0,0 @@ |
||||
'use strict' |
||||
var DropdownPanel = require('./DropdownPanel') |
||||
var remixDebug = require('remix-debug') |
||||
var localDecoder = remixDebug.SolidityDecoder.localDecoder |
||||
var solidityTypeFormatter = require('./SolidityTypeFormatter') |
||||
var StorageViewer = remixDebug.storage.StorageViewer |
||||
var yo = require('yo-yo') |
||||
|
||||
class SolidityLocals { |
||||
|
||||
constructor (_parent, _traceManager, _internalTreeCall) { |
||||
this.parent = _parent |
||||
this.internalTreeCall = _internalTreeCall |
||||
this.storageResolver = null |
||||
this.traceManager = _traceManager |
||||
this.basicPanel = new DropdownPanel('Solidity Locals', { |
||||
json: true, |
||||
formatSelf: solidityTypeFormatter.formatSelf, |
||||
extractData: solidityTypeFormatter.extractData |
||||
}) |
||||
this.init() |
||||
this.view |
||||
} |
||||
|
||||
render () { |
||||
this.view = yo`<div id='soliditylocals' >
|
||||
${this.basicPanel.render()} |
||||
</div>` |
||||
return this.view |
||||
} |
||||
|
||||
init () { |
||||
var decodeTimeout = null |
||||
this.parent.event.register('sourceLocationChanged', this, (sourceLocation) => { |
||||
if (!this.storageResolver) { |
||||
this.basicPanel.setMessage('storage not ready') |
||||
return |
||||
} |
||||
if (decodeTimeout) { |
||||
window.clearTimeout(decodeTimeout) |
||||
} |
||||
this.basicPanel.setUpdating() |
||||
decodeTimeout = setTimeout(() => { |
||||
decode(this, sourceLocation) |
||||
}, 500) |
||||
}) |
||||
} |
||||
} |
||||
|
||||
function decode (self, sourceLocation) { |
||||
self.basicPanel.setMessage('') |
||||
self.traceManager.waterfall([ |
||||
self.traceManager.getStackAt, |
||||
self.traceManager.getMemoryAt, |
||||
self.traceManager.getCurrentCalledAddressAt], |
||||
self.parent.currentStepIndex, |
||||
(error, result) => { |
||||
if (!error) { |
||||
var stack = result[0].value |
||||
var memory = result[1].value |
||||
try { |
||||
var storageViewer = new StorageViewer({ |
||||
stepIndex: self.parent.currentStepIndex, |
||||
tx: self.parent.tx, |
||||
address: result[2].value |
||||
}, self.storageResolver, self.traceManager) |
||||
localDecoder.solidityLocals(self.parent.currentStepIndex, self.internalTreeCall, stack, memory, storageViewer, sourceLocation).then((locals) => { |
||||
if (!locals.error) { |
||||
self.basicPanel.update(locals) |
||||
} |
||||
if (!Object.keys(locals).length) { |
||||
self.basicPanel.setMessage('no locals') |
||||
} |
||||
}) |
||||
} catch (e) { |
||||
self.basicPanel.setMessage(e.message) |
||||
} |
||||
} else { |
||||
console.log(error) |
||||
} |
||||
}) |
||||
} |
||||
module.exports = SolidityLocals |
@ -1,103 +0,0 @@ |
||||
'use strict' |
||||
var DropdownPanel = require('./DropdownPanel') |
||||
var remixDebug = require('remix-debug') |
||||
var stateDecoder = remixDebug.SolidityDecoder.stateDecoder |
||||
var solidityTypeFormatter = require('./SolidityTypeFormatter') |
||||
var StorageViewer = remixDebug.storage.StorageViewer |
||||
var yo = require('yo-yo') |
||||
|
||||
function SolidityState (_parent, _traceManager, _codeManager, _solidityProxy) { |
||||
this.storageResolver = null |
||||
this.parent = _parent |
||||
this.traceManager = _traceManager |
||||
this.codeManager = _codeManager |
||||
this.solidityProxy = _solidityProxy |
||||
this.basicPanel = new DropdownPanel('Solidity State', { |
||||
json: true, |
||||
formatSelf: solidityTypeFormatter.formatSelf, |
||||
extractData: solidityTypeFormatter.extractData |
||||
}) |
||||
this.init() |
||||
this.view |
||||
this.stateVariablesByAddresses = {} |
||||
_parent.event.register('traceUnloaded', () => { this.stateVariablesByAddresses = {} }) |
||||
_parent.event.register('newTraceLoaded', () => { this.stateVariablesByAddresses = {} }) |
||||
} |
||||
|
||||
SolidityState.prototype.render = function () { |
||||
if (!this.view) { |
||||
this.view = yo`<div id='soliditystate' >
|
||||
${this.basicPanel.render()} |
||||
</div>` |
||||
} |
||||
return this.view |
||||
} |
||||
|
||||
SolidityState.prototype.init = function () { |
||||
var self = this |
||||
var decodeTimeout = null |
||||
this.parent.event.register('indexChanged', this, function (index) { |
||||
if (index < 0) { |
||||
self.basicPanel.setMessage('invalid step index') |
||||
return |
||||
} |
||||
|
||||
if (self.parent.currentStepIndex !== index) return |
||||
if (!self.solidityProxy.loaded()) { |
||||
self.basicPanel.setMessage('no source has been specified') |
||||
return |
||||
} |
||||
|
||||
if (!self.storageResolver) { |
||||
return |
||||
} |
||||
if (decodeTimeout) { |
||||
window.clearTimeout(decodeTimeout) |
||||
} |
||||
self.basicPanel.setUpdating() |
||||
decodeTimeout = setTimeout(() => { |
||||
decode(self, index) |
||||
}, 500) |
||||
}) |
||||
} |
||||
|
||||
function decode (self, index) { |
||||
self.traceManager.getCurrentCalledAddressAt(self.parent.currentStepIndex, (error, address) => { |
||||
if (error) { |
||||
self.basicPanel.update({}) |
||||
console.log(error) |
||||
} else { |
||||
if (self.stateVariablesByAddresses[address]) { |
||||
extractStateVariables(self, self.stateVariablesByAddresses[address], address) |
||||
} else { |
||||
self.solidityProxy.extractStateVariablesAt(index, function (error, stateVars) { |
||||
if (error) { |
||||
self.basicPanel.update({}) |
||||
console.log(error) |
||||
} else { |
||||
self.stateVariablesByAddresses[address] = stateVars |
||||
extractStateVariables(self, stateVars, address) |
||||
} |
||||
}) |
||||
} |
||||
} |
||||
}) |
||||
} |
||||
|
||||
function extractStateVariables (self, stateVars, address) { |
||||
var storageViewer = new StorageViewer({ |
||||
stepIndex: self.parent.currentStepIndex, |
||||
tx: self.parent.tx, |
||||
address: address |
||||
}, self.storageResolver, self.traceManager) |
||||
stateDecoder.decodeState(stateVars, storageViewer).then((result) => { |
||||
self.basicPanel.setMessage('') |
||||
if (!result.error) { |
||||
self.basicPanel.update(result) |
||||
} else { |
||||
self.basicPanel.setMessage(result.error) |
||||
} |
||||
}) |
||||
} |
||||
|
||||
module.exports = SolidityState |
@ -1,71 +0,0 @@ |
||||
'use strict' |
||||
var yo = require('yo-yo') |
||||
var BN = require('ethereumjs-util').BN |
||||
|
||||
module.exports = { |
||||
formatSelf: formatSelf, |
||||
extractData: extractData |
||||
} |
||||
|
||||
function formatSelf (key, data) { |
||||
var style = fontColor(data) |
||||
var keyStyle = data.isProperty ? 'color:#847979' : '' |
||||
if (data.type === 'string') { |
||||
data.self = JSON.stringify(data.self) |
||||
} |
||||
return yo`<label style=${keyStyle}>${key}: <label style=${style}>${data.self}</label><label style='font-style:italic'> ${data.isProperty || !data.type ? '' : ' ' + data.type}</label></label>` |
||||
} |
||||
|
||||
function extractData (item, parent, key) { |
||||
var ret = {} |
||||
if (item.isProperty) { |
||||
return item |
||||
} |
||||
if (item.type.lastIndexOf(']') === item.type.length - 1) { |
||||
ret.children = (item.value || []).map(function (item, index) { |
||||
return {key: index, value: item} |
||||
}) |
||||
ret.children.unshift({ |
||||
key: 'length', |
||||
value: { |
||||
self: (new BN(item.length.replace('0x', ''), 16)).toString(10), |
||||
type: 'uint', |
||||
isProperty: true |
||||
} |
||||
}) |
||||
ret.isArray = true |
||||
ret.self = parent.isArray ? '' : item.type |
||||
} else if (item.type.indexOf('struct') === 0) { |
||||
ret.children = Object.keys((item.value || {})).map(function (key) { |
||||
return {key: key, value: item.value[key]} |
||||
}) |
||||
ret.self = item.type |
||||
ret.isStruct = true |
||||
} else if (item.type.indexOf('mapping') === 0) { |
||||
ret.children = Object.keys((item.value || {})).map(function (key) { |
||||
return {key: key, value: item.value[key]} |
||||
}) |
||||
ret.isMapping = true |
||||
ret.self = item.type |
||||
} else { |
||||
ret.children = null |
||||
ret.self = item.value |
||||
ret.type = item.type |
||||
} |
||||
return ret |
||||
} |
||||
|
||||
function fontColor (data) { |
||||
var color = '#124B46' |
||||
if (data.isArray || data.isStruct || data.isMapping) { |
||||
color = '#847979' |
||||
} else if (data.type.indexOf('uint') === 0 || |
||||
data.type.indexOf('int') === 0 || |
||||
data.type.indexOf('bool') === 0 || |
||||
data.type.indexOf('enum') === 0) { |
||||
color = '#0F0CE9' |
||||
} else if (data.type === 'string') { |
||||
color = '#E91E0C' |
||||
} |
||||
return 'color:' + color |
||||
} |
@ -1,33 +0,0 @@ |
||||
'use strict' |
||||
var DropdownPanel = require('./DropdownPanel') |
||||
var yo = require('yo-yo') |
||||
|
||||
function StackPanel (_parent, _traceManager) { |
||||
this.parent = _parent |
||||
this.traceManager = _traceManager |
||||
this.basicPanel = new DropdownPanel('Stack', {json: true, displayContentOnly: false}) |
||||
this.init() |
||||
} |
||||
|
||||
StackPanel.prototype.render = function () { |
||||
return yo`<div id='stackpanel' >${this.basicPanel.render()}</div>` |
||||
} |
||||
|
||||
StackPanel.prototype.init = function () { |
||||
var self = this |
||||
this.parent.event.register('indexChanged', this, function (index) { |
||||
if (index < 0) return |
||||
if (self.parent.currentStepIndex !== index) return |
||||
|
||||
self.traceManager.getStackAt(index, function (error, stack) { |
||||
if (error) { |
||||
self.basicPanel.update({}) |
||||
console.log(error) |
||||
} else if (self.parent.currentStepIndex === index) { |
||||
self.basicPanel.update(stack) |
||||
} |
||||
}) |
||||
}) |
||||
} |
||||
|
||||
module.exports = StackPanel |
@ -1,101 +0,0 @@ |
||||
'use strict' |
||||
var yo = require('yo-yo') |
||||
var DropdownPanel = require('./DropdownPanel') |
||||
|
||||
function StepDetail (_parentUI, _traceManager) { |
||||
this.debugger = _parentUI.debugger |
||||
this.parentUI = _parentUI |
||||
this.traceManager = _traceManager |
||||
|
||||
this.basicPanel = new DropdownPanel('Step detail', {json: true, displayContentOnly: true}) |
||||
|
||||
this.detail = initDetail() |
||||
this.view |
||||
this.init() |
||||
} |
||||
|
||||
StepDetail.prototype.render = function () { |
||||
return yo`<div id='stepdetail' >${this.basicPanel.render()}</div>` |
||||
} |
||||
|
||||
StepDetail.prototype.init = function () { |
||||
var self = this |
||||
this.debugger.event.register('traceUnloaded', this, function () { |
||||
self.detail = initDetail() |
||||
self.basicPanel.update(self.detail) |
||||
}) |
||||
|
||||
this.debugger.event.register('newTraceLoaded', this, function () { |
||||
self.detail = initDetail() |
||||
self.basicPanel.update(self.detail) |
||||
}) |
||||
|
||||
this.parentUI.event.register('indexChanged', this, function (index) { |
||||
if (index < 0) return |
||||
|
||||
self.detail['vm trace step'] = index |
||||
|
||||
self.traceManager.getCurrentStep(index, function (error, step) { |
||||
if (error) { |
||||
console.log(error) |
||||
self.detail['execution step'] = '-' |
||||
} else { |
||||
self.detail['execution step'] = step |
||||
} |
||||
self.basicPanel.update(self.detail) |
||||
}) |
||||
|
||||
self.traceManager.getMemExpand(index, function (error, addmem) { |
||||
if (error) { |
||||
console.log(error) |
||||
self.detail['add memory'] = '-' |
||||
} else { |
||||
self.detail['add memory'] = addmem |
||||
} |
||||
self.basicPanel.update(self.detail) |
||||
}) |
||||
|
||||
self.traceManager.getStepCost(index, function (error, gas) { |
||||
if (error) { |
||||
console.log(error) |
||||
self.detail.gas = '-' |
||||
} else { |
||||
self.detail.gas = gas |
||||
} |
||||
self.basicPanel.update(self.detail) |
||||
}) |
||||
|
||||
self.traceManager.getCurrentCalledAddressAt(index, function (error, address) { |
||||
if (error) { |
||||
console.log(error) |
||||
self.detail['loaded address'] = '-' |
||||
} else { |
||||
self.detail['loaded address'] = address |
||||
} |
||||
self.basicPanel.update(self.detail) |
||||
}) |
||||
|
||||
self.traceManager.getRemainingGas(index, function (error, remaingas) { |
||||
if (error) { |
||||
console.log(error) |
||||
self.detail['remaining gas'] = '-' |
||||
} else { |
||||
self.detail['remaining gas'] = remaingas |
||||
} |
||||
self.basicPanel.update(self.detail) |
||||
}) |
||||
}) |
||||
} |
||||
|
||||
module.exports = StepDetail |
||||
|
||||
function initDetail () { |
||||
return { |
||||
'vm trace step': '-', |
||||
'execution step': '-', |
||||
'add memory': '', |
||||
'gas': '', |
||||
'remaining gas': '-', |
||||
'loaded address': '-' |
||||
} |
||||
} |
@ -1,205 +0,0 @@ |
||||
'use strict' |
||||
var ButtonNavigator = require('./ButtonNavigator') |
||||
var Slider = require('./Slider') |
||||
var remixLib = require('remix-lib') |
||||
var EventManager = remixLib.EventManager |
||||
var yo = require('yo-yo') |
||||
var util = remixLib.util |
||||
|
||||
function StepManager (_parent, _traceManager) { |
||||
this.event = new EventManager() |
||||
this.parent = _parent.debugger |
||||
this.traceManager = _traceManager |
||||
this.sourceMapByAddress = {} |
||||
this.solidityMode = false |
||||
|
||||
var self = this |
||||
this.parent.event.register('newTraceLoaded', this, function () { |
||||
if (!this.slider) return |
||||
self.traceManager.getLength(function (error, length) { |
||||
if (error) { |
||||
console.log(error) |
||||
} else { |
||||
self.slider.init(length) |
||||
self.init() |
||||
} |
||||
}) |
||||
}) |
||||
|
||||
this.slider = new Slider(this.traceManager, (step) => { |
||||
return this.solidityMode ? this.resolveToReducedTrace(step, 0) : step |
||||
}) |
||||
this.slider.event.register('moved', this, function (step) { |
||||
self.sliderMoved(step) |
||||
}) |
||||
|
||||
this.parent.callTree.event.register('callTreeReady', () => { |
||||
if (!this.slider) return |
||||
if (this.parent.callTree.functionCallStack.length) { |
||||
this.jumpTo(this.parent.callTree.functionCallStack[0]) |
||||
} |
||||
}) |
||||
|
||||
this.buttonNavigator = new ButtonNavigator(_parent, this.traceManager) |
||||
this.buttonNavigator.event.register('stepIntoBack', this, function () { |
||||
self.stepIntoBack() |
||||
}) |
||||
this.buttonNavigator.event.register('stepIntoForward', this, function () { |
||||
self.stepIntoForward() |
||||
}) |
||||
this.buttonNavigator.event.register('stepOverBack', this, function () { |
||||
self.stepOverBack() |
||||
}) |
||||
this.buttonNavigator.event.register('stepOverForward', this, function () { |
||||
self.stepOverForward() |
||||
}) |
||||
this.buttonNavigator.event.register('jumpOut', this, function () { |
||||
self.jumpOut() |
||||
}) |
||||
this.buttonNavigator.event.register('jumpToException', this, function (exceptionIndex) { |
||||
self.jumpTo(exceptionIndex) |
||||
}) |
||||
this.buttonNavigator.event.register('jumpNextBreakpoint', (exceptionIndex) => { |
||||
self.parent.breakpointManager.jumpNextBreakpoint(_parent.currentStepIndex, true) |
||||
}) |
||||
this.buttonNavigator.event.register('jumpPreviousBreakpoint', (exceptionIndex) => { |
||||
self.parent.breakpointManager.jumpPreviousBreakpoint(_parent.currentStepIndex, true) |
||||
}) |
||||
} |
||||
|
||||
StepManager.prototype.remove = function () { |
||||
// used to stop listenning on event. bad and should be "refactored"
|
||||
this.slider.view = null |
||||
this.slider = null |
||||
this.buttonNavigator.view = null |
||||
this.buttonNavigator = null |
||||
} |
||||
|
||||
StepManager.prototype.resolveToReducedTrace = function (value, incr) { |
||||
if (this.parent.callTree.reducedTrace.length) { |
||||
var nextSource = util.findClosestIndex(value, this.parent.callTree.reducedTrace) |
||||
nextSource = nextSource + incr |
||||
if (nextSource <= 0) { |
||||
nextSource = 0 |
||||
} else if (nextSource > this.parent.callTree.reducedTrace.length) { |
||||
nextSource = this.parent.callTree.reducedTrace.length - 1 |
||||
} |
||||
return this.parent.callTree.reducedTrace[nextSource] |
||||
} |
||||
return value |
||||
} |
||||
|
||||
StepManager.prototype.render = function () { |
||||
return yo`<div>
|
||||
${this.slider.render()} |
||||
${this.buttonNavigator.render()} |
||||
</div>` |
||||
} |
||||
|
||||
StepManager.prototype.reset = function () { |
||||
this.slider.setValue(0) |
||||
this.currentStepIndex = 0 |
||||
this.buttonNavigator.reset() |
||||
} |
||||
|
||||
StepManager.prototype.init = function () { |
||||
this.slider.setValue(0) |
||||
this.changeState(0) |
||||
} |
||||
|
||||
StepManager.prototype.newTraceAvailable = function () { |
||||
this.init() |
||||
} |
||||
|
||||
StepManager.prototype.jumpTo = function (step) { |
||||
if (!this.traceManager.inRange(step)) { |
||||
return |
||||
} |
||||
this.slider.setValue(step) |
||||
this.changeState(step) |
||||
} |
||||
|
||||
StepManager.prototype.sliderMoved = function (step) { |
||||
if (!this.traceManager.inRange(step)) { |
||||
return |
||||
} |
||||
this.changeState(step) |
||||
} |
||||
|
||||
StepManager.prototype.stepIntoForward = function () { |
||||
if (!this.traceManager.isLoaded()) { |
||||
return |
||||
} |
||||
var step = this.currentStepIndex |
||||
if (this.solidityMode) { |
||||
step = this.resolveToReducedTrace(step, 1) |
||||
} else { |
||||
step += 1 |
||||
} |
||||
if (!this.traceManager.inRange(step)) { |
||||
return |
||||
} |
||||
this.slider.setValue(step) |
||||
this.changeState(step) |
||||
} |
||||
|
||||
StepManager.prototype.stepIntoBack = function () { |
||||
if (!this.traceManager.isLoaded()) { |
||||
return |
||||
} |
||||
var step = this.currentStepIndex |
||||
if (this.solidityMode) { |
||||
step = this.resolveToReducedTrace(step, -1) |
||||
} else { |
||||
step -= 1 |
||||
} |
||||
if (!this.traceManager.inRange(step)) { |
||||
return |
||||
} |
||||
this.slider.setValue(step) |
||||
this.changeState(step) |
||||
} |
||||
|
||||
StepManager.prototype.stepOverForward = function () { |
||||
if (!this.traceManager.isLoaded()) { |
||||
return |
||||
} |
||||
var step = this.traceManager.findStepOverForward(this.currentStepIndex) |
||||
if (this.solidityMode) { |
||||
step = this.resolveToReducedTrace(step, 1) |
||||
} |
||||
this.slider.setValue(step) |
||||
this.changeState(step) |
||||
} |
||||
|
||||
StepManager.prototype.stepOverBack = function () { |
||||
if (!this.traceManager.isLoaded()) { |
||||
return |
||||
} |
||||
var step = this.traceManager.findStepOverBack(this.currentStepIndex) |
||||
if (this.solidityMode) { |
||||
step = this.resolveToReducedTrace(step, -1) |
||||
} |
||||
this.slider.setValue(step) |
||||
this.changeState(step) |
||||
} |
||||
|
||||
StepManager.prototype.jumpOut = function () { |
||||
if (!this.traceManager.isLoaded()) { |
||||
return |
||||
} |
||||
var step = this.traceManager.findStepOut(this.currentStepIndex) |
||||
if (this.solidityMode) { |
||||
step = this.resolveToReducedTrace(step, 0) |
||||
} |
||||
this.slider.setValue(step) |
||||
this.changeState(step) |
||||
} |
||||
|
||||
StepManager.prototype.changeState = function (step) { |
||||
this.currentStepIndex = step |
||||
this.buttonNavigator.stepChanged(step) |
||||
this.event.trigger('stepChanged', [step]) |
||||
} |
||||
|
||||
module.exports = StepManager |
@ -1,50 +0,0 @@ |
||||
'use strict' |
||||
var DropdownPanel = require('./DropdownPanel') |
||||
var remixDebug = require('remix-debug') |
||||
var StorageViewer = remixDebug.storage.StorageViewer |
||||
var yo = require('yo-yo') |
||||
|
||||
function StoragePanel (_parent, _traceManager) { |
||||
this.parent = _parent |
||||
this.storageResolver = null |
||||
this.traceManager = _traceManager |
||||
this.basicPanel = new DropdownPanel('Storage', {json: true}) |
||||
this.init() |
||||
this.disabled = false |
||||
} |
||||
|
||||
StoragePanel.prototype.render = function () { |
||||
return yo`<div id='storagepanel' >${this.basicPanel.render()}</div>` |
||||
} |
||||
|
||||
StoragePanel.prototype.init = function () { |
||||
var self = this |
||||
this.parent.event.register('indexChanged', this, function (index) { |
||||
if (self.disabled) return |
||||
if (index < 0) return |
||||
if (self.parent.currentStepIndex !== index) return |
||||
if (!self.storageResolver) return |
||||
|
||||
this.traceManager.getCurrentCalledAddressAt(index, (error, address) => { |
||||
if (!error) { |
||||
var storageViewer = new StorageViewer({ |
||||
stepIndex: self.parent.currentStepIndex, |
||||
tx: self.parent.tx, |
||||
address: address |
||||
}, self.storageResolver, self.traceManager) |
||||
|
||||
storageViewer.storageRange((error, storage) => { |
||||
if (error) { |
||||
console.log(error) |
||||
self.basicPanel.update({}) |
||||
} else if (self.parent.currentStepIndex === index) { |
||||
var header = storageViewer.isComplete(address) ? 'completely loaded' : 'partially loaded...' |
||||
self.basicPanel.update(storage, header) |
||||
} |
||||
}) |
||||
} |
||||
}) |
||||
}) |
||||
} |
||||
|
||||
module.exports = StoragePanel |
@ -1,206 +0,0 @@ |
||||
var remixLib = require('remix-lib') |
||||
var EventManager = remixLib.EventManager |
||||
var traceHelper = remixLib.helpers.trace |
||||
var yo = require('yo-yo') |
||||
var init = remixLib.init |
||||
var csjs = require('csjs-inject') |
||||
var styleGuide = require('../../../../ui/styles-guide/theme-chooser') |
||||
var styles = styleGuide.chooser() |
||||
|
||||
var css = csjs` |
||||
.container { |
||||
display: flex; |
||||
flex-direction: column; |
||||
} |
||||
.txContainer { |
||||
display: flex; |
||||
flex-direction: column; |
||||
} |
||||
.txinputs { |
||||
width: 100%; |
||||
display: flex; |
||||
justify-content: center; |
||||
} |
||||
.txinput { |
||||
${styles.rightPanel.debuggerTab.input_Debugger} |
||||
margin: 3px; |
||||
width: inherit; |
||||
} |
||||
.txbuttons { |
||||
width: 100%; |
||||
display: flex; |
||||
justify-content: center; |
||||
} |
||||
.txbutton { |
||||
${styles.rightPanel.debuggerTab.button_Debugger} |
||||
width: inherit; |
||||
} |
||||
.txbuttonstart { |
||||
${styles.rightPanel.debuggerTab.button_Debugger} |
||||
} |
||||
.txbutton:hover { |
||||
color: ${styles.rightPanel.debuggerTab.button_Debugger_icon_HoverColor}; |
||||
} |
||||
.vmargin { |
||||
margin-top: 10px; |
||||
margin-bottom: 10px; |
||||
} |
||||
` |
||||
function TxBrowser (_parent, opts) { |
||||
this.event = new EventManager() |
||||
|
||||
this.blockNumber |
||||
this.txNumber |
||||
this.view |
||||
this.displayConnectionSetting = opts.displayConnectionSetting |
||||
this.web3 = opts.web3 |
||||
var self = this |
||||
_parent.event.register('providerChanged', this, function (provider) { |
||||
self.setDefaultValues() |
||||
if (self.view) { |
||||
yo.update(self.view, self.render()) |
||||
} |
||||
}) |
||||
} |
||||
|
||||
// creation 0xa9619e1d0a35b2c1d686f5b661b3abd87f998d2844e8e9cc905edb57fc9ce349
|
||||
// invokation 0x71a6d583d16d142c5c3e8903060e8a4ee5a5016348a9448df6c3e63b68076ec4 0xcda2b2835add61af54cf83bd076664d98d7908c6cd98d86423b3b48d8b8e51ff
|
||||
// test:
|
||||
// creation: 0x72908de76f99fca476f9e3a3b5d352f350a98cd77d09cebfc59ffe32a6ecaa0b
|
||||
// invokation: 0x20ef65b8b186ca942fcccd634f37074dde49b541c27994fc7596740ef44cfd51
|
||||
|
||||
TxBrowser.prototype.setDefaultValues = function () { |
||||
this.connectInfo = '' |
||||
if (this.view) { |
||||
yo.update(this.view, this.render()) |
||||
} |
||||
} |
||||
|
||||
TxBrowser.prototype.submit = function (tx) { |
||||
var self = this |
||||
self.event.trigger('newTxLoading', [this.blockNumber, this.txNumber]) |
||||
if (tx) { |
||||
return self.update(null, tx) |
||||
} |
||||
if (!this.txNumber) { |
||||
self.update('no tx index or tx hash to look for') |
||||
return |
||||
} |
||||
try { |
||||
if (this.txNumber.indexOf('0x') !== -1) { |
||||
self.web3.eth.getTransaction(this.txNumber, function (error, result) { |
||||
self.update(error, result) |
||||
}) |
||||
} else { |
||||
self.web3.eth.getTransactionFromBlock(this.blockNumber, this.txNumber, function (error, result) { |
||||
self.update(error, result) |
||||
}) |
||||
} |
||||
} catch (e) { |
||||
self.update(e.message) |
||||
} |
||||
} |
||||
|
||||
TxBrowser.prototype.update = function (error, tx) { |
||||
var info = {} |
||||
if (error) { |
||||
this.view.querySelector('#error').innerHTML = error |
||||
} else { |
||||
if (tx) { |
||||
this.view.querySelector('#error').innerHTML = '' |
||||
if (!tx.to) { |
||||
tx.to = traceHelper.contractCreationToken('0') |
||||
} |
||||
info.from = tx.from |
||||
info.to = tx.to |
||||
info.hash = tx.hash |
||||
this.event.trigger('newTraceRequested', [this.blockNumber, this.txNumber, tx]) |
||||
} else { |
||||
var mes = '<not found>' |
||||
info.from = mes |
||||
info.to = mes |
||||
info.hash = mes |
||||
this.view.querySelector('#error').innerHTML = 'Cannot find transaction with reference. Block number: ' + this.blockNumber + '. Transaction index/hash: ' + this.txNumber |
||||
} |
||||
} |
||||
} |
||||
|
||||
TxBrowser.prototype.updateWeb3Url = function (newhost) { |
||||
init.setProvider(global.web3, newhost) |
||||
var self = this |
||||
this.checkWeb3(function (error, block) { |
||||
if (!error) { |
||||
self.connectInfo = 'Connected to ' + global.web3.currentProvider.host + '. Current block number: ' + block |
||||
} else { |
||||
self.connectInfo = 'Unable to connect to ' + global.web3.currentProvider.host + '. ' + error.message |
||||
} |
||||
yo.update(self.view, self.render()) |
||||
}) |
||||
} |
||||
|
||||
TxBrowser.prototype.checkWeb3 = function (callback) { |
||||
try { |
||||
global.web3.eth.getBlockNumber(function (error, block) { |
||||
callback(error, block) |
||||
}) |
||||
} catch (e) { |
||||
console.log(e) |
||||
callback(e.message, null) |
||||
} |
||||
} |
||||
|
||||
TxBrowser.prototype.updateBlockN = function (ev) { |
||||
this.blockNumber = ev.target.value |
||||
} |
||||
|
||||
TxBrowser.prototype.updateTxN = function (ev) { |
||||
this.txNumber = ev.target.value |
||||
} |
||||
|
||||
TxBrowser.prototype.load = function (txHash, tx) { |
||||
this.txNumber = txHash |
||||
this.submit(tx) |
||||
} |
||||
|
||||
TxBrowser.prototype.unload = function (txHash) { |
||||
this.event.trigger('unloadRequested') |
||||
this.init() |
||||
} |
||||
|
||||
TxBrowser.prototype.init = function (ev) { |
||||
this.setDefaultValues() |
||||
} |
||||
|
||||
TxBrowser.prototype.connectionSetting = function () { |
||||
if (this.displayConnectionSetting) { |
||||
var self = this |
||||
return yo`<div class="${css.vmargin}"><span>Node URL: </span><input onkeyup=${function () { self.updateWeb3Url(arguments[0].target.value) }} value=${global.web3.currentProvider ? global.web3.currentProvider.host : ' - none - '} type='text' />
|
||||
<span>${this.connectInfo}</span></div>` |
||||
} else { |
||||
return '' |
||||
} |
||||
} |
||||
|
||||
TxBrowser.prototype.render = function () { |
||||
var self = this |
||||
var view = yo`<div class="${css.container}">
|
||||
${this.connectionSetting()} |
||||
<div class="${css.txContainer}"> |
||||
<div class="${css.txinputs}"> |
||||
<input class="${css.txinput}" onkeyup=${function () { self.updateBlockN(arguments[0]) }} type='text' placeholder=${'Block number'} /> |
||||
<input class="${css.txinput}" id='txinput' onkeyup=${function () { self.updateTxN(arguments[0]) }} type='text' placeholder=${'Transaction index or hash'} /> |
||||
</div> |
||||
<div class="${css.txbuttons}"> |
||||
<button id='load' class='${css.txbutton}' title='start debugging' onclick=${function () { self.submit() }}>Start debugging</button> |
||||
<button id='unload' class='${css.txbutton}' title='stop debugging' onclick=${function () { self.unload() }}>Stop</button> |
||||
</div> |
||||
</div> |
||||
<span id='error'></span> |
||||
</div>` |
||||
if (!this.view) { |
||||
this.view = view |
||||
} |
||||
return view |
||||
} |
||||
|
||||
module.exports = TxBrowser |
@ -1,126 +0,0 @@ |
||||
'use strict' |
||||
var csjs = require('csjs-inject') |
||||
var CodeListView = require('./CodeListView') |
||||
var CalldataPanel = require('./CalldataPanel') |
||||
var MemoryPanel = require('./MemoryPanel') |
||||
var CallstackPanel = require('./CallstackPanel') |
||||
var StackPanel = require('./StackPanel') |
||||
var StoragePanel = require('./StoragePanel') |
||||
var FullStoragesChangesPanel = require('./FullStoragesChanges') |
||||
var StepDetail = require('./StepDetail') |
||||
var DropdownPanel = require('./DropdownPanel') |
||||
var SolidityState = require('./SolidityState') |
||||
var SolidityLocals = require('./SolidityLocals') |
||||
var remixDebug = require('remix-debug') |
||||
var StorageResolver = remixDebug.storage.StorageResolver |
||||
var yo = require('yo-yo') |
||||
|
||||
var css = csjs` |
||||
.asmCode { |
||||
float: left; |
||||
width: 50%; |
||||
} |
||||
.stepDetail { |
||||
} |
||||
.vmheadView { |
||||
margin-top:10px; |
||||
} |
||||
` |
||||
|
||||
function VmDebugger (_parentUI, _traceManager, _codeManager, _solidityProxy, _callTree) { |
||||
let _parent = _parentUI.debugger |
||||
var self = this |
||||
this.view |
||||
this.asmCode = new CodeListView(_parent, _codeManager) |
||||
this.stackPanel = new StackPanel(_parentUI, _traceManager) |
||||
this.storagePanel = new StoragePanel(_parentUI, _traceManager) |
||||
this.memoryPanel = new MemoryPanel(_parentUI, _traceManager) |
||||
this.calldataPanel = new CalldataPanel(_parentUI, _traceManager) |
||||
this.callstackPanel = new CallstackPanel(_parentUI, _traceManager) |
||||
this.stepDetail = new StepDetail(_parentUI, _traceManager) |
||||
this.solidityState = new SolidityState(_parentUI, _traceManager, _codeManager, _solidityProxy) |
||||
this.solidityLocals = new SolidityLocals(_parentUI, _traceManager, _callTree) |
||||
|
||||
/* Return values - */ |
||||
this.returnValuesPanel = new DropdownPanel('Return Value', {json: true}) |
||||
this.returnValuesPanel.data = {} |
||||
_parentUI.event.register('indexChanged', this.returnValuesPanel, function (index) { |
||||
if (!self.view) return |
||||
var innerself = this |
||||
_traceManager.getReturnValue(index, function (error, returnValue) { |
||||
if (error) { |
||||
innerself.update([error]) |
||||
} else if (_parentUI.currentStepIndex === index) { |
||||
innerself.update([returnValue]) |
||||
} |
||||
}) |
||||
}) |
||||
/* Return values - */ |
||||
|
||||
this.fullStoragesChangesPanel = new FullStoragesChangesPanel(_parentUI, _traceManager) |
||||
|
||||
_parent.event.register('newTraceLoaded', this, function () { |
||||
if (!self.view) return |
||||
var storageResolver = new StorageResolver({web3: _parent.web3}) |
||||
self.storagePanel.storageResolver = storageResolver |
||||
self.solidityState.storageResolver = storageResolver |
||||
self.solidityLocals.storageResolver = storageResolver |
||||
self.fullStoragesChangesPanel.storageResolver = storageResolver |
||||
self.asmCode.basicPanel.show() |
||||
self.stackPanel.basicPanel.show() |
||||
self.storagePanel.basicPanel.show() |
||||
self.memoryPanel.basicPanel.show() |
||||
self.calldataPanel.basicPanel.show() |
||||
self.callstackPanel.basicPanel.show() |
||||
}) |
||||
_parent.event.register('traceUnloaded', this, function () { |
||||
if (!self.view) return |
||||
}) |
||||
_parent.callTree.event.register('callTreeReady', () => { |
||||
if (!self.view) return |
||||
if (_parent.callTree.reducedTrace.length) { |
||||
self.solidityLocals.basicPanel.show() |
||||
self.solidityState.basicPanel.show() |
||||
} |
||||
}) |
||||
} |
||||
|
||||
VmDebugger.prototype.renderHead = function () { |
||||
var headView = yo`<div id='vmheadView' class=${css.vmheadView}>
|
||||
<div> |
||||
<div class=${css.asmCode}>${this.asmCode.render()}</div> |
||||
<div class=${css.stepDetail}>${this.stepDetail.render()}</div> |
||||
</div> |
||||
</div>` |
||||
if (!this.headView) { |
||||
this.headView = headView |
||||
} |
||||
return headView |
||||
} |
||||
|
||||
VmDebugger.prototype.remove = function () { |
||||
// used to stop listenning on event. bad and should be "refactored"
|
||||
this.view = null |
||||
} |
||||
|
||||
VmDebugger.prototype.render = function () { |
||||
var view = yo`<div id='vmdebugger'>
|
||||
<div> |
||||
${this.solidityLocals.render()} |
||||
${this.solidityState.render()} |
||||
${this.stackPanel.render()} |
||||
${this.memoryPanel.render()} |
||||
${this.storagePanel.render()} |
||||
${this.callstackPanel.render()} |
||||
${this.calldataPanel.render()} |
||||
${this.returnValuesPanel.render()} |
||||
${this.fullStoragesChangesPanel.render()} |
||||
</div> |
||||
</div>` |
||||
if (!this.view) { |
||||
this.view = view |
||||
} |
||||
return view |
||||
} |
||||
|
||||
module.exports = VmDebugger |
Loading…
Reference in new issue