add new stepmanager and related files; move step manager out of old ui

pull/1/head
Iuri Matias 6 years ago committed by yann300
parent a47d7e824f
commit 9546b78ffa
  1. 31
      src/app/debugger/debuggerUI.js
  2. 184
      src/app/debugger/debuggerUI/ButtonNavigator.js
  3. 75
      src/app/debugger/debuggerUI/Slider.js
  4. 205
      src/app/debugger/debuggerUI/StepManager.js
  5. 15
      src/app/debugger/remix-debugger/src/ui/EthdebuggerUI.js

@ -2,6 +2,7 @@ var OldEthdebuggerUI = require('./remix-debugger/src/ui/EthdebuggerUI')
var Debugger = require('../debugger/debugger')
var SourceHighlighter = require('../editor/sourceHighlighter')
var TxBrowser = require('./debuggerUI/TxBrowser')
var StepManager = require('./debuggerUI/StepManager')
var remixLib = require('remix-lib')
var executionContext = remixLib.execution.executionContext
var traceHelper = remixLib.helpers.trace
@ -17,6 +18,8 @@ class DebuggerUI {
})
this.startTxBrowser()
// this.startStepManager()
this.stepManager = null
container.appendChild(this.debugger_ui.render())
@ -30,7 +33,7 @@ class DebuggerUI {
})
this.transactionDebugger.event.register('breakpointStep', function (step) {
self.debugger_ui.stepManager.jumpTo(step)
self.stepManager.jumpTo(step)
})
this.debugger_ui.event.register('indexChanged', function (index) {
@ -38,6 +41,10 @@ class DebuggerUI {
})
}
// startStepManager () {
// this.stepManager = null
// }
startTxBrowser () {
const self = this
let web3 = executionContext.web3()
@ -52,7 +59,7 @@ class DebuggerUI {
if (!tx.to) {
tx.to = traceHelper.contractCreationToken('0')
}
return self.debugger_ui.startDebugging(blockNumber, txNumber, tx)
return self.startDebugging(blockNumber, txNumber, tx)
}
try {
@ -60,13 +67,13 @@ class DebuggerUI {
return web3.eth.getTransaction(txNumber, function (error, result) {
let tx = result
txBrowser.update(error, result)
self.debugger_ui.startDebugging(blockNumber, txNumber, tx)
self.startDebugging(blockNumber, txNumber, tx)
})
}
web3.eth.getTransactionFromBlock(blockNumber, txNumber, function (error, result) {
let tx = result
txBrowser.update(error, result)
self.debugger_ui.startDebugging(blockNumber, txNumber, tx)
self.startDebugging(blockNumber, txNumber, tx)
})
} catch (e) {
self.update(e.message)
@ -92,6 +99,22 @@ class DebuggerUI {
return this.isActive
}
startDebugging (blockNumber, txNumber, tx) {
const self = this
let shouldOpenDebugger = this.debugger_ui.startDebugging(blockNumber, txNumber, tx)
if (!shouldOpenDebugger) return
this.stepManager = new StepManager(this.debugger_ui, this.transactionDebugger.debugger.traceManager)
this.stepManager.event.register('stepChanged', this, function (stepIndex) {
self.debugger_ui.stepChanged(stepIndex)
})
this.debugger_ui.stepManager = this.stepManager
this.debugger_ui.createAndAddVmDebugger()
this.transactionDebugger.debugger.debug(tx)
}
debug (txHash) {
const self = this
this.transactionDebugger.debug(txHash, (error, tx) => {

@ -0,0 +1,184 @@
'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

@ -0,0 +1,75 @@
'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

@ -0,0 +1,205 @@
'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,6 +1,6 @@
'use strict'
// var TxBrowser = require('./TxBrowser')
var StepManager = require('./StepManager')
// var StepManager = require('./StepManager')
var VmDebugger = require('./VmDebugger')
var yo = require('yo-yo')
@ -91,16 +91,11 @@ EthdebuggerUI.prototype.stepChanged = function (stepIndex) {
EthdebuggerUI.prototype.startDebugging = function (blockNumber, txIndex, tx) {
const self = this
if (this.debugger.traceManager.isLoading) {
return
return false
}
this.tx = tx
this.stepManager = new StepManager(this, this.debugger.traceManager)
this.stepManager.event.register('stepChanged', this, function (stepIndex) {
self.stepChanged(stepIndex)
})
this.debugger.codeManager.event.register('changed', this, (code, address, instIndex) => {
self.debugger.callTree.sourceLocationTracker.getSourceLocationFromVMTraceIndex(address, this.currentStepIndex, this.debugger.solidityProxy.contracts, (error, sourceLocation) => {
if (!error) {
@ -109,12 +104,14 @@ EthdebuggerUI.prototype.startDebugging = function (blockNumber, txIndex, tx) {
})
})
return true
}
EthdebuggerUI.prototype.createAndAddVmDebugger = function () {
this.vmDebugger = new VmDebugger(this, this.debugger.traceManager, this.debugger.codeManager, this.debugger.solidityProxy, this.debugger.callTree)
yo.update(this.debuggerHeadPanelsView, this.vmDebugger.renderHead())
yo.update(this.debuggerPanelsView, this.vmDebugger.render())
yo.update(this.stepManagerView, this.stepManager.render())
this.debugger.debug(tx)
}
module.exports = EthdebuggerUI

Loading…
Cancel
Save