debugger: remove old unused code

removeoldcode
yann300 4 years ago
parent cfd41cb939
commit beccd28a56
  1. 1
      apps/remix-ide/src/app/tabs/debugger-tab.js
  2. 279
      apps/remix-ide/src/app/tabs/debugger/debuggerUI.js
  3. 130
      apps/remix-ide/src/app/tabs/debugger/debuggerUI/ButtonNavigator.js
  4. 57
      apps/remix-ide/src/app/tabs/debugger/debuggerUI/Slider.js
  5. 59
      apps/remix-ide/src/app/tabs/debugger/debuggerUI/StepManager.js
  6. 137
      apps/remix-ide/src/app/tabs/debugger/debuggerUI/TxBrowser.js
  7. 179
      apps/remix-ide/src/app/tabs/debugger/debuggerUI/VmDebugger.js
  8. 76
      apps/remix-ide/src/app/tabs/debugger/debuggerUI/styles/basicStyles.js
  9. 31
      apps/remix-ide/src/app/tabs/debugger/debuggerUI/styles/dropdownPanel.js
  10. 6
      apps/remix-ide/src/app/tabs/debugger/debuggerUI/styles/sliderStyles.js
  11. 30
      apps/remix-ide/src/app/tabs/debugger/debuggerUI/styles/treeView.js
  12. 17
      apps/remix-ide/src/app/tabs/debugger/debuggerUI/vmDebugger/CalldataPanel.js
  13. 18
      apps/remix-ide/src/app/tabs/debugger/debuggerUI/vmDebugger/CallstackPanel.js
  14. 75
      apps/remix-ide/src/app/tabs/debugger/debuggerUI/vmDebugger/CodeListView.js
  15. 189
      apps/remix-ide/src/app/tabs/debugger/debuggerUI/vmDebugger/DropdownPanel.js
  16. 21
      apps/remix-ide/src/app/tabs/debugger/debuggerUI/vmDebugger/FullStoragesChanges.js
  17. 17
      apps/remix-ide/src/app/tabs/debugger/debuggerUI/vmDebugger/FunctionPanel.js
  18. 21
      apps/remix-ide/src/app/tabs/debugger/debuggerUI/vmDebugger/MemoryPanel.js
  19. 59
      apps/remix-ide/src/app/tabs/debugger/debuggerUI/vmDebugger/SolidityLocals.js
  20. 36
      apps/remix-ide/src/app/tabs/debugger/debuggerUI/vmDebugger/SolidityState.js
  21. 17
      apps/remix-ide/src/app/tabs/debugger/debuggerUI/vmDebugger/StackPanel.js
  22. 23
      apps/remix-ide/src/app/tabs/debugger/debuggerUI/vmDebugger/StepDetail.js
  23. 17
      apps/remix-ide/src/app/tabs/debugger/debuggerUI/vmDebugger/StoragePanel.js
  24. 77
      apps/remix-ide/src/app/tabs/debugger/debuggerUI/vmDebugger/utils/SolidityTypeFormatter.js

@ -2,7 +2,6 @@ const yo = require('yo-yo')
const css = require('./styles/debugger-tab-styles')
import toaster from '../ui/tooltip'
import { DebuggerUI } from '@remix-ui/debugger-ui'
// const DebuggerUI = require('./debugger/debuggerUI')
import { ViewPlugin } from '@remixproject/engine'
import * as packageJson from '../../../../../package.json'
import React from 'react'

@ -1,279 +0,0 @@
var TxBrowser = require('./debuggerUI/TxBrowser')
var StepManagerUI = require('./debuggerUI/StepManager')
var VmDebugger = require('./debuggerUI/VmDebugger')
var toaster = require('../../ui/tooltip')
var Debugger = require('@remix-project/remix-debug').TransactionDebugger
var SourceHighlighter = require('../../editor/sourceHighlighter')
var EventManager = require('../../../lib/events')
var globalRegistry = require('../../../global/registry')
var remixDebug = require('@remix-project/remix-debug')
var init = remixDebug.init
var yo = require('yo-yo')
var csjs = require('csjs-inject')
var css = csjs`
.statusMessage {
margin-left: 15px;
}
.debuggerConfig {
display: flex;
align-items: center;
}
.debuggerConfig label {
margin: 0;
}
.debuggerSection {
padding: 12px 24px 16px;
}
.debuggerLabel {
margin-bottom: 2px;
font-size: 11px;
line-height: 12px;
text-transform: uppercase;
}
`
class DebuggerUI {
constructor (debuggerModule, component, fetchContractAndCompile) {
this.debuggerModule = debuggerModule
this.fetchContractAndCompile = fetchContractAndCompile
this.event = new EventManager()
this.isActive = false
this.opt = {
debugWithGeneratedSources: false
}
this.sourceHighlighter = new SourceHighlighter()
this.startTxBrowser()
this.stepManager = null
this.statusMessage = ''
this.currentReceipt
this.view
component.appendChild(this.render())
this.setEditor()
}
setEditor () {
this.editor = globalRegistry.get('editor').api
this.editor.event.register('breakpointCleared', (fileName, row) => {
if (this.debugger) this.debugger.breakPointManager.remove({fileName: fileName, row: row})
})
this.editor.event.register('breakpointAdded', (fileName, row) => {
if (this.debugger) this.debugger.breakPointManager.add({fileName: fileName, row: row})
})
this.editor.event.register('contentChanged', () => {
if (this.debugger) this.debugger.unload()
})
}
listenToEvents () {
if (!this.debugger) return
this.debugger.event.register('debuggerStatus', async (isActive) => {
await this.debuggerModule.call('editor', 'discardHighlight')
this.isActive = isActive
})
this.debugger.event.register('newSourceLocation', async (lineColumnPos, rawLocation, generatedSources) => {
if (!lineColumnPos) return
const contracts = await this.fetchContractAndCompile(
this.currentReceipt.contractAddress || this.currentReceipt.to,
this.currentReceipt)
if (contracts) {
let path = contracts.getSourceName(rawLocation.file)
if (!path) {
// check in generated sources
for (const source of generatedSources) {
if (source.id === rawLocation.file) {
path = `browser/.debugger/generated-sources/${source.name}`
let content
try {
content = await this.debuggerModule.call('fileManager', 'getFile', path, source.contents)
} catch (e) {
console.log('unable to fetch generated sources, the file probably doesn\'t exist yet', e)
}
if (content !== source.contents) {
await this.debuggerModule.call('fileManager', 'setFile', path, source.contents)
}
break
}
}
}
if (path) {
await this.debuggerModule.call('editor', 'discardHighlight')
await this.debuggerModule.call('editor', 'highlight', lineColumnPos, path)
}
}
})
this.debugger.event.register('debuggerUnloaded', () => this.unLoad())
}
startTxBrowser () {
let txBrowser = new TxBrowser()
this.txBrowser = txBrowser
txBrowser.event.register('requestDebug', (blockNumber, txNumber, tx) => {
if (this.debugger) this.debugger.unload()
this.startDebugging(blockNumber, txNumber, tx)
})
txBrowser.event.register('unloadRequested', this, (blockNumber, txIndex, tx) => {
if (this.debugger) this.debugger.unload()
})
}
isDebuggerActive () {
return this.isActive
}
getDebugWeb3 () {
return new Promise((resolve, reject) => {
this.debuggerModule.blockchain.detectNetwork((error, network) => {
let web3
if (error || !network) {
web3 = init.web3DebugNode(this.debuggerModule.blockchain.web3())
} else {
const webDebugNode = init.web3DebugNode(network.name)
web3 = !webDebugNode ? this.debuggerModule.blockchain.web3() : webDebugNode
}
init.extendWeb3(web3)
resolve(web3)
})
})
}
async startDebugging (blockNumber, txNumber, tx) {
if (this.debugger) this.unLoad()
let web3 = await this.getDebugWeb3()
this.currentReceipt = await web3.eth.getTransactionReceipt(txNumber)
this.debugger = new Debugger({
web3,
offsetToLineColumnConverter: globalRegistry.get('offsettolinecolumnconverter').api,
compilationResult: async (address) => {
try {
return await this.fetchContractAndCompile(address, this.currentReceipt)
} catch (e) {
console.error(e)
}
return null
},
debugWithGeneratedSources: this.opt.debugWithGeneratedSources
})
this.listenToEvents()
this.debugger.debug(blockNumber, txNumber, tx, () => {
this.stepManager = new StepManagerUI(this.debugger.step_manager)
this.vmDebugger = new VmDebugger(this.debugger.vmDebuggerLogic)
this.txBrowser.setState({ blockNumber, txNumber, debugging: true })
this.renderDebugger()
}).catch((error) => {
toaster(error)
this.unLoad()
})
}
getTrace (hash) {
return new Promise(async (resolve, reject) => {
const web3 = await this.getDebugWeb3()
this.currentReceipt = await web3.eth.getTransactionReceipt(hash)
const debug = new Debugger({
web3,
offsetToLineColumnConverter: globalRegistry.get('offsettolinecolumnconverter').api,
compilationResult: async (address) => {
try {
return await this.fetchContractAndCompile(address, this.currentReceipt)
} catch (e) {
console.error(e)
}
return null
},
debugWithGeneratedSources: false
})
debug.debugger.traceManager.traceRetriever.getTrace(hash, (error, trace) => {
if (error) return reject(error)
resolve(trace)
})
})
}
debug (txHash) {
this.startDebugging(null, txHash, null)
}
render () {
this.debuggerPanelsView = yo`<div class="px-2"></div>`
this.debuggerHeadPanelsView = yo`<div class="px-2"></div>`
this.stepManagerView = yo`<div class="px-2"></div>`
var view = yo`
<div>
<div class="px-2">
<div class="mt-3">
<p class="mt-2 ${css.debuggerLabel}">Debugger Configuration</p>
<div class="mt-2 ${css.debuggerConfig} custom-control custom-checkbox">
<input class="custom-control-input" id="debugGeneratedSourcesInput" onchange=${(event) => { this.opt.debugWithGeneratedSources = event.target.checked }} type="checkbox" title="Debug with generated sources">
<label data-id="debugGeneratedSourcesLabel" class="form-check-label custom-control-label" for="debugGeneratedSourcesInput">Use generated sources (from Solidity v0.7.2)</label>
</div>
</div>
${this.txBrowser.render()}
${this.stepManagerView}
${this.debuggerHeadPanelsView}
<div class="${css.statusMessage}">${this.statusMessage}</div>
${this.debuggerPanelsView}
</div>
`
if (!this.view) {
this.view = view
}
return view
}
async unLoad () {
yo.update(this.debuggerHeadPanelsView, yo`<div></div>`)
yo.update(this.debuggerPanelsView, yo`<div></div>`)
yo.update(this.stepManagerView, yo`<div></div>`)
if (this.vmDebugger) this.vmDebugger.remove()
if (this.stepManager) this.stepManager.remove()
if (this.txBrowser) this.txBrowser.setState({debugging: false})
this.vmDebugger = null
this.stepManager = null
if (this.debugger) delete this.debugger
this.event.trigger('traceUnloaded')
}
async deleteHighlights () {
await this.debuggerModule.call('editor', 'discardHighlight')
}
renderDebugger () {
yo.update(this.debuggerHeadPanelsView, this.vmDebugger.renderHead())
yo.update(this.debuggerPanelsView, this.vmDebugger.render())
yo.update(this.stepManagerView, this.stepManager.render())
}
}
module.exports = DebuggerUI

@ -1,130 +0,0 @@
'use strict'
var EventManager = require('../../../../lib/events')
var yo = require('yo-yo')
var csjs = require('csjs-inject')
var css = csjs`
.buttons {
display: flex;
flex-wrap: wrap;
}
.stepButtons {
width: 100%;
display: flex;
justify-content: center;
}
.stepButton {
}
.jumpButtons {
width: 100%;
display: flex;
justify-content: center;
}
.jumpButton {
}
.navigator {
}
.navigator:hover {
}
`
function ButtonNavigator () {
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.view
}
ButtonNavigator.prototype.render = function () {
var self = this
var view = yo`<div class="${css.buttons}">
<div class="${css.stepButtons} btn-group py-1">
<button id='overback' class='btn btn-primary btn-sm ${css.navigator} ${css.stepButton} fas fa-reply' title='Step over back' onclick=${function () { self.event.trigger('stepOverBack') }} disabled=${this.overBackDisabled} ></button>
<button id='intoback' data-id="buttonNavigatorIntoBack" class='btn btn-primary btn-sm ${css.navigator} ${css.stepButton} fas fa-level-up-alt' title='Step back' onclick=${function () { self.event.trigger('stepIntoBack') }} disabled=${this.intoBackDisabled} ></button>
<button id='intoforward' data-id="buttonNavigatorIntoForward" class='btn btn-primary btn-sm ${css.navigator} ${css.stepButton} fas fa-level-down-alt' title='Step into' onclick=${function () { self.event.trigger('stepIntoForward') }} disabled=${this.intoForwardDisabled} ></button>
<button id='overforward' class='btn btn-primary btn-sm ${css.navigator} ${css.stepButton} fas fa-share' title='Step over forward'onclick=${function () { self.event.trigger('stepOverForward') }} disabled=${this.overForwardDisabled} ></button>
</div>
<div class="${css.jumpButtons} btn-group py-1">
<button class='btn btn-primary btn-sm ${css.navigator} ${css.jumpButton} fas fa-step-backward' id='jumppreviousbreakpoint' data-id="buttonNavigatorJumpPreviousBreakpoint" title='Jump to the previous breakpoint' onclick=${function () { self.event.trigger('jumpPreviousBreakpoint') }} disabled=${this.jumpPreviousBreakpointDisabled} ></button>
<button class='btn btn-primary btn-sm ${css.navigator} ${css.jumpButton} fas fa-eject' id='jumpout' title='Jump out' onclick=${function () { self.event.trigger('jumpOut') }} disabled=${this.jumpOutDisabled} ></button>
<button class='btn btn-primary btn-sm ${css.navigator} ${css.jumpButton} fas fa-step-forward' id='jumpnextbreakpoint' data-id="buttonNavigatorJumpNextBreakpoint" title='Jump to the next breakpoint' onclick=${function () { self.event.trigger('jumpNextBreakpoint') }} disabled=${this.jumpNextBreakpointDisabled} ></button>
</div>
<div id='reverted' style="display:none">
<button class='btn btn-danger btn-sm' id='jumptoexception' title='Jump to exception' class='${css.navigator} ${css.button} fas fa-exclamation-triangle' onclick=${function () { self.event.trigger('jumpToException') }} 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
this.resetWarning('')
}
ButtonNavigator.prototype.stepChanged = function (stepState, jumpOutDisabled) {
if (stepState === 'invalid') {
// TODO: probably not necessary, already implicit done in the next steps
this.reset()
this.updateAll()
return
}
this.intoBackDisabled = (stepState === 'initial')
this.overBackDisabled = (stepState === 'initial')
this.jumpPreviousBreakpointDisabled = (stepState === 'initial')
this.jumpNextBreakpointDisabled = (stepState === 'end')
this.intoForwardDisabled = (stepState === 'end')
this.overForwardDisabled = (stepState === 'end')
this.jumpNextBreakpointDisabled = jumpOutDisabled
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')
}
}
ButtonNavigator.prototype.resetWarning = function (revertedReason) {
if (!this.view) return
this.view.querySelector('#reverted #outofgas').style.display = (revertedReason === 'outofgas') ? 'inline' : 'none'
this.view.querySelector('#reverted #parenthasthrown').style.display = (revertedReason === 'parenthasthrown') ? 'inline' : 'none'
this.view.querySelector('#reverted').style.display = (revertedReason === '') ? 'none' : 'block'
}
module.exports = ButtonNavigator

@ -1,57 +0,0 @@
'use strict'
var EventManager = require('../../../../lib/events')
var yo = require('yo-yo')
class Slider {
constructor () {
this.event = new EventManager()
this.max
this.disabled = true
this.view
this.previousValue = null
}
setSliderLength (length) {
if (!this.view) return
this.view.querySelector('#slider').setAttribute('max', length - 1)
this.max = length - 1
this.disabled = (length === 0)
if (this.disabled) {
this.view.querySelector('#slider').setAttribute('disabled', true)
} else {
this.view.querySelector('#slider').removeAttribute('disabled')
}
this.setValue(0)
}
onChange (event) {
if (!this.view) return
var value = parseInt(this.view.querySelector('#slider').value)
if (value === this.previousValue) return
this.previousValue = value
this.event.trigger('sliderMoved', [value])
}
setValue (value) {
if (!this.view) return
this.view.querySelector('#slider').value = value
}
render () {
var self = this
var view = yo`<div>
<input id='slider' data-id="slider" class='w-100 my-0' 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
}
}
module.exports = Slider

@ -1,59 +0,0 @@
var EventManager = require('../../../../lib/events')
var yo = require('yo-yo')
var ButtonNavigator = require('./ButtonNavigator')
var Slider = require('./Slider')
function StepManager (stepManager) {
this.event = new EventManager()
this.stepManager = stepManager
this.startSlider()
this.startButtonNavigator()
this.stepManager.event.register('stepChanged', this.updateStep.bind(this))
}
StepManager.prototype.startSlider = function () {
this.slider = new Slider()
this.slider.event.register('sliderMoved', this.stepManager.jumpTo.bind(this.stepManager))
this.stepManager.event.register('traceLengthChanged', this.slider.setSliderLength.bind(this.slider))
}
StepManager.prototype.startButtonNavigator = function () {
this.buttonNavigator = new ButtonNavigator()
this.stepManager.event.register('revertWarning', this.buttonNavigator.resetWarning.bind(this.buttonNavigator))
this.buttonNavigator.event.register('stepIntoBack', this.stepManager.stepIntoBack.bind(this.stepManager))
this.buttonNavigator.event.register('stepIntoForward', this.stepManager.stepIntoForward.bind(this.stepManager))
this.buttonNavigator.event.register('stepOverBack', this.stepManager.stepOverBack.bind(this.stepManager))
this.buttonNavigator.event.register('stepOverForward', this.stepManager.stepOverForward.bind(this.stepManager))
this.buttonNavigator.event.register('jumpOut', this.stepManager.jumpOut.bind(this.stepManager))
this.buttonNavigator.event.register('jumpToException', this.stepManager.jumpToException.bind(this.stepManager))
this.buttonNavigator.event.register('jumpNextBreakpoint', this.stepManager.jumpNextBreakpoint.bind(this.stepManager))
this.buttonNavigator.event.register('jumpPreviousBreakpoint', this.stepManager.jumpPreviousBreakpoint.bind(this.stepManager))
}
StepManager.prototype.updateStep = function (step, stepState, jumpOutDisabled) {
if (!this.slider) return
this.slider.setValue(step)
this.buttonNavigator.stepChanged(stepState, jumpOutDisabled)
this.event.trigger('stepChanged', [step])
}
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.render = function () {
return yo`
<div class="py-1">
${this.slider.render()}
${this.buttonNavigator.render()}
</div>`
}
module.exports = StepManager

@ -1,137 +0,0 @@
var EventManager = require('../../../../lib/events')
var yo = require('yo-yo')
var csjs = require('csjs-inject')
var css = csjs`
.container {
display: flex;
flex-direction: column;
}
.txContainer {
display: flex;
flex-direction: column;
}
.txinput {
width: inherit;
font-size: small;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.txbutton {
width: inherit;
}
.txbutton:hover {
}
.vmargin {
margin-top: 10px;
margin-bottom: 10px;
}
`
function TxBrowser () {
this.event = new EventManager()
this.state = {
txNumber: undefined,
debugging: false
}
this.view
}
TxBrowser.prototype.submit = function () {
if (this.state.debugging) {
this.unload()
} else {
this.event.trigger('requestDebug', [undefined, this.state.txNumber])
}
yo.update(this.view, this.render())
}
TxBrowser.prototype.updateTxN = function (ev) {
this.state.txNumber = ev.target.value
if (this.view) {
yo.update(this.view, this.render())
}
}
TxBrowser.prototype.load = function (txHash, tx) {
this.state.txNumber = txHash
}
TxBrowser.prototype.unload = function () {
this.event.trigger('unloadRequested')
}
TxBrowser.prototype.setState = function (state) {
this.state = {...this.state, ...state}
if (this.view) {
yo.update(this.view, this.render())
}
}
TxBrowser.prototype.render = function () {
var self = this
this.state.txNumberInput = yo`
<input
value="${this.state.txNumber || ''}"
class="form-control m-0 ${css.txinput}"
id='txinput'
onkeyup=${function () { self.updateTxN(arguments[0]) }}
type='text'
oninput=${this.txInputChanged.bind(this)}
placeholder=${'Transaction hash, should start with 0x'}
data-id="debuggerTransactionInput"
/>
`
let txButton = yo`
<button
class='btn btn-primary btn-sm ${css.txbutton}'
id='load'
title='${this.state.debugging ? 'Stop' : 'Start'} debugging'
onclick=${function () { self.submit() }}
data-id="debuggerTransactionStartButton"
>
${this.state.debugging ? 'Stop' : 'Start'} debugging
</button>
`
var view = yo`
<div class="${css.container}">
<div class="${css.txContainer}">
<div class=" py-1 d-flex justify-content-center w-100 input-group">
${this.state.txNumberInput}
</div>
<div class="d-flex justify-content-center w-100 btn-group py-1">
${txButton}
</div>
</div>
<span id='error'></span>
</div>
`
if (this.state.debugging) {
view.querySelectorAll('input').forEach(element => { element.setAttribute('disabled', '') })
}
if (!this.state.txNumber) {
view.querySelector("button[id='load']").setAttribute('disabled', '')
} else if (!this.state.debugging) {
this.state.txNumberInput.removeAttribute('disabled')
}
if (!this.view) {
this.view = view
}
return view
}
TxBrowser.prototype.txInputChanged = function (event) {
// todo check validation of txnumber in the input element, use
// required
// oninvalid="setCustomValidity('Please provide a valid transaction number, must start with 0x and have length of 22')"
// pattern="^0[x,X]+[0-9a-fA-F]{22}"
// this.state.txNumberInput.setCustomValidity('')
this.state.txNumber = event.target.value
yo.update(this.view, this.render())
}
module.exports = TxBrowser

@ -1,179 +0,0 @@
'use strict'
var yo = require('yo-yo')
var CodeListView = require('./vmDebugger/CodeListView')
var CalldataPanel = require('./vmDebugger/CalldataPanel')
var MemoryPanel = require('./vmDebugger/MemoryPanel')
var CallstackPanel = require('./vmDebugger/CallstackPanel')
var FunctionPanel = require('./vmDebugger/FunctionPanel')
var StackPanel = require('./vmDebugger/StackPanel')
var StoragePanel = require('./vmDebugger/StoragePanel')
var StepDetail = require('./vmDebugger/StepDetail')
var SolidityState = require('./vmDebugger/SolidityState')
var SolidityLocals = require('./vmDebugger/SolidityLocals')
var FullStoragesChangesPanel = require('./vmDebugger/FullStoragesChanges')
var DropdownPanel = require('./vmDebugger/DropdownPanel')
function VmDebugger (vmDebuggerLogic) {
var self = this
this.view
this.vmDebuggerLogic = vmDebuggerLogic
this.asmCode = new CodeListView()
this.vmDebuggerLogic.event.register('codeManagerChanged', this.asmCode.changed.bind(this.asmCode))
this.vmDebuggerLogic.event.register('traceUnloaded', this.asmCode.reset.bind(this.asmCode))
this.calldataPanel = new CalldataPanel()
this.vmDebuggerLogic.event.register('traceManagerCallDataUpdate', this.calldataPanel.update.bind(this.calldataPanel))
this.memoryPanel = new MemoryPanel()
this.vmDebuggerLogic.event.register('traceManagerMemoryUpdate', this.memoryPanel.update.bind(this.memoryPanel))
this.callstackPanel = new CallstackPanel()
this.vmDebuggerLogic.event.register('traceManagerCallStackUpdate', this.callstackPanel.update.bind(this.callstackPanel))
this.stackPanel = new StackPanel()
this.vmDebuggerLogic.event.register('traceManagerStackUpdate', this.stackPanel.update.bind(this.stackPanel))
this.functionPanel = new FunctionPanel()
this.vmDebuggerLogic.event.register('functionsStackUpdate', (stack) => {
if (stack === null || stack.length === 0) return
let functions = []
for (let func of stack) {
functions.push(func.functionDefinition.name + '(' + func.inputs.join(', ') + ')')
}
this.functionPanel.update(functions)
})
this.storagePanel = new StoragePanel()
this.vmDebuggerLogic.event.register('traceManagerStorageUpdate', this.storagePanel.update.bind(this.storagePanel))
this.stepDetail = new StepDetail()
this.vmDebuggerLogic.event.register('traceUnloaded', this.stepDetail.reset.bind(this.stepDetail))
this.vmDebuggerLogic.event.register('newTraceLoaded', this.stepDetail.reset.bind(this.stepDetail))
this.vmDebuggerLogic.event.register('traceCurrentStepUpdate', function (error, step) {
self.stepDetail.updateField('execution step', (error ? '-' : step))
})
this.vmDebuggerLogic.event.register('traceMemExpandUpdate', function (error, addmem) {
self.stepDetail.updateField('add memory', (error ? '-' : addmem))
})
this.vmDebuggerLogic.event.register('traceStepCostUpdate', function (error, gas) {
self.stepDetail.updateField('gas', (error ? '-' : gas))
})
this.vmDebuggerLogic.event.register('traceCurrentCalledAddressAtUpdate', function (error, address) {
self.stepDetail.updateField('loaded address', (error ? '-' : address))
})
this.vmDebuggerLogic.event.register('traceRemainingGasUpdate', function (error, remainingGas) {
self.stepDetail.updateField('remaining gas', (error ? '-' : remainingGas))
})
this.vmDebuggerLogic.event.register('indexUpdate', function (index) {
self.stepDetail.updateField('vm trace step', index)
})
this.solidityState = new SolidityState()
this.vmDebuggerLogic.event.register('solidityState', this.solidityState.update.bind(this.solidityState))
this.vmDebuggerLogic.event.register('solidityStateMessage', this.solidityState.setMessage.bind(this.solidityState))
this.vmDebuggerLogic.event.register('solidityStateUpdating', this.solidityState.setUpdating.bind(this.solidityState))
this.solidityLocals = new SolidityLocals()
this.solidityLocals.event.register('solidityLocalsLoadMore', (cursor) => {
this.vmDebuggerLogic.event.trigger('solidityLocalsLoadMore', [cursor])
})
this.vmDebuggerLogic.event.register('solidityLocals', this.solidityLocals.update.bind(this.solidityLocals))
this.vmDebuggerLogic.event.register('solidityLocalsMessage', this.solidityLocals.setMessage.bind(this.solidityLocals))
this.vmDebuggerLogic.event.register('solidityLocalsUpdating', this.solidityLocals.setUpdating.bind(this.solidityLocals))
this.vmDebuggerLogic.event.register('solidityLocalsLoadMoreCompleted', this.solidityLocals.loadMore.bind(this.solidityLocals))
this.returnValuesPanel = new DropdownPanel('Return Value', {json: true})
this.returnValuesPanel.data = {}
this.vmDebuggerLogic.event.register('traceReturnValueUpdate', this.returnValuesPanel.update.bind(this.returnValuesPanel))
this.fullStoragesChangesPanel = new FullStoragesChangesPanel()
this.addresses = []
this.vmDebuggerLogic.event.register('traceAddressesUpdate', function (_addresses) {
self.fullStoragesChangesPanel.update({})
})
this.vmDebuggerLogic.event.register('traceStorageUpdate', this.fullStoragesChangesPanel.update.bind(this.fullStoragesChangesPanel))
this.vmDebuggerLogic.event.register('newTrace', () => {
if (!self.view) return
self.asmCode.basicPanel.show()
self.stackPanel.basicPanel.show()
self.functionPanel.basicPanel.show()
self.storagePanel.basicPanel.show()
self.memoryPanel.basicPanel.show()
self.stepDetail.basicPanel.show()
self.calldataPanel.basicPanel.show()
self.callstackPanel.basicPanel.show()
})
this.vmDebuggerLogic.event.register('newCallTree', () => {
if (!self.view) return
self.functionPanel.basicPanel.show()
self.solidityLocals.basicPanel.show()
self.solidityState.basicPanel.show()
self.solidityPanel.hidden = false
})
this.vmDebuggerLogic.start()
}
VmDebugger.prototype.renderHead = function () {
this.solidityPanel = yo`
<div class="w-100" hidden>
${this.functionPanel.render()}
${this.solidityLocals.render()}
${this.solidityState.render()}
</div>
`
const headView = yo`
<div id="vmheadView" class="mt-1 px-0">
<div class="d-flex flex-column">
${this.solidityPanel}
<div class="w-100">${this.asmCode.render()}</div>
<div class="w-100">${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 () {
const view = yo`
<div id="vmdebugger" class="px-2">
<div>
${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

@ -1,76 +0,0 @@
'use strict'
module.exports = {
truncate: {
'white-space': 'nowrap',
'overflow': 'hidden',
'text-overflow': 'ellipsis',
'margin-right': '5px'
},
font: {
'font-family': 'arial,sans-serif'
},
statusMessage: {
'margin-left': '15px'
},
address: {
'font-style': 'italic'
},
instructionsList: {
'width': '52%',
'overflow-y': 'scroll',
'max-height': '250px',
'margin': '0',
'margin-left': '10px',
'padding': '2px'
},
transactionInfo: {
'margin-top': '5px'
},
panel: {
container: {
'border': '1px solid',
'width': '70%'
},
tableContainer: {
'height': '50%',
'overflow-y': 'auto'
},
table: {
'padding': '5px'
},
title: {
'padding': '5px',
'font-style': 'italic'
}
},
hidden: {
'display': 'none'
},
display: {
'display': 'block'
},
inline: {
'display': 'inline-block'
},
vmargin: {
'margin-top': '10px',
'margin-bottom': '10px'
},
button: {
'border-color': 'transparent',
'border-radius': '3px',
'border': '.3px solid hsla(0, 0%, 40%, 1)',
'cursor': 'pointer',
'min-height': '25px',
'max-height': '25px',
'padding': '3px',
'min-width': '100px',
'font-size': '12px',
'overflow': 'hidden',
'word-break': 'normal',
'background-color': 'hsla(0, 0%, 40%, .2)',
'color': 'hsla(0, 0%, 40%, 1)',
'margin': '3px',
'text-decoration': 'none'
}
}

@ -1,31 +0,0 @@
'use strict'
module.exports = {
title: {
'border': '1px solid #dadada',
'background-color': 'white',
'width': '100%',
'color': '#363f47',
'margin-top': '5px',
'cursor': 'pointer'
},
titleInner: {
'display': 'inline-block'
},
content: {
'color': '#111111',
'width': '100%',
'min-height': '20px'
},
inner: {
'padding': '2px',
'word-break': 'break-all'
},
copyBtn: {
'float': 'right',
'margin-top': '3px'
},
caret: {
'margin-left': '10px',
'margin-right': '10px'
}
}

@ -1,6 +0,0 @@
'use strict'
module.exports = {
rule: {
'width': '100%'
}
}

@ -1,30 +0,0 @@
'use strict'
module.exports = {
cssUl: {
'list-style-type': 'none',
'-webkit-margin-before': '0px',
'-webkit-margin-after': '0px',
'-webkit-margin-start': '0px',
'-webkit-margin-end': '0px',
'-webkit-padding-start': '0px'
},
cssLi: {
'list-style-type': 'none',
'-webkit-margin-before': '0px',
'-webkit-margin-after': '0px',
'-webkit-margin-start': '0px',
'-webkit-margin-end': '0px',
'-webkit-padding-start': '0px',
'margin-left': '10px'
},
label: {
'vertical-align': 'top',
'font-family': 'arial,sans-serif'
},
caret: {
'margin-top': '3px',
'width': '10px'
},
data: {
}
}

@ -1,17 +0,0 @@
'use strict'
var DropdownPanel = require('./DropdownPanel')
var yo = require('yo-yo')
function CalldataPanel () {
this.basicPanel = new DropdownPanel('Call Data', {json: true})
}
CalldataPanel.prototype.update = function (calldata) {
this.basicPanel.update(calldata)
}
CalldataPanel.prototype.render = function () {
return yo`<div id='calldatapanel' >${this.basicPanel.render()}</div>`
}
module.exports = CalldataPanel

@ -1,18 +0,0 @@
'use strict'
var DropdownPanel = require('./DropdownPanel')
var yo = require('yo-yo')
function CallstackPanel () {
this.basicPanel = new DropdownPanel('Call Stack', {json: true})
}
CallstackPanel.prototype.update = function (calldata) {
this.basicPanel.update(calldata)
}
CallstackPanel.prototype.render = function () {
return yo`<div id='callstackpanel' >${this.basicPanel.render()}</div>`
}
module.exports = CallstackPanel

@ -1,75 +0,0 @@
'use strict'
var style = require('../styles/basicStyles')
var yo = require('yo-yo')
var DropdownPanel = require('./DropdownPanel')
var EventManager = require('../../../../../lib/events')
var csjs = require('csjs-inject')
var css = csjs`
.instructions {
overflow-y: scroll;
max-height: 130px;
}
`
function CodeListView () {
this.event = new EventManager()
this.code
this.address
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', [])
})
}
CodeListView.prototype.render = function () {
this.view = yo`<div id='asmcodes' >${this.basicPanel.render({height: style.instructionsList.height})}</div>`
return this.view
}
CodeListView.prototype.indexChanged = function (index) {
if (index < 0) return
if (this.itemSelected) {
this.itemSelected.removeAttribute('selected')
this.itemSelected.removeAttribute('style')
if (this.itemSelected.firstChild) {
this.itemSelected.firstChild.removeAttribute('style')
}
}
let codeView = this.view.querySelector('#asmitems')
this.itemSelected = codeView.children[index]
this.itemSelected.style.setProperty('border-color', 'var(--primary)')
this.itemSelected.style.setProperty('border-style', 'solid')
this.itemSelected.setAttribute('selected', 'selected')
codeView.scrollTop = this.itemSelected.offsetTop - parseInt(codeView.offsetTop)
}
CodeListView.prototype.reset = function () {
this.changed([], '', -1)
}
CodeListView.prototype.changed = function (code, address, index) {
if (this.address === address) {
return this.indexChanged(index)
}
this.code = code
this.address = address
this.basicPanel.setContent(this.renderAssemblyItems())
this.indexChanged(index)
}
CodeListView.prototype.renderAssemblyItems = function () {
if (this.code) {
var codeView = this.code.map(function (item, i) {
return yo`<div class="px-1" key=${i} value=${i}><span>${item}</span></div>`
})
return yo`<div class="pl-2 my-1 small ${css.instructions}" id='asmitems' ref='itemsList'>
${codeView}
</div>`
}
}
module.exports = CodeListView

@ -1,189 +0,0 @@
'use strict'
const yo = require('yo-yo')
const copyToClipboard = require('../../../../ui/copy-to-clipboard')
const EventManager = require('../../../../../lib/events')
const TreeView = require('../../../../ui/TreeView') // TODO setup a direct reference to the UI components
const csjs = require('csjs-inject')
const css = csjs`
.title {
display: flex;
align-items: center;
}
.name {
font-weight: bold;
}
.nameDetail {
font-weight: bold;
margin-left: 3px;
}
.icon {
margin-right: 5%;
}
.eyeButton {
margin: 3px;
}
.dropdownpanel {
width: 100%;
word-break: break-word;
}
.dropdownrawcontent {
padding: 2px;
word-break: break-word;
}
.message {
padding: 2px;
word-break: break-word;
}
.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) return
this.view.querySelector('.dropdownpanel .dropdownrawcontent').style.display = 'none'
this.view.querySelector('.dropdownpanel .dropdowncontent').style.display = 'none'
this.view.querySelector('.dropdownpanel > i').style.display = 'none'
this.message(message)
}
DropdownPanel.prototype.setLoading = function () {
if (!this.view) return
this.view.querySelector('.dropdownpanel .dropdownrawcontent').style.display = 'none'
this.view.querySelector('.dropdownpanel .dropdowncontent').style.display = 'none'
this.view.querySelector('.dropdownpanel > i').style.display = 'inline-block'
this.message('')
}
DropdownPanel.prototype.setUpdating = function () {
if (!this.view) return
}
DropdownPanel.prototype.update = function (_data, _header) {
if (!this.view) return
this.view.querySelector('.dropdownpanel > i').style.display = 'none'
this.view.querySelector('.dropdownpanel .dropdowncontent').style.display = 'block'
this.view.querySelector('.dropdownpanel .dropdownrawcontent').innerText = JSON.stringify(_data, null, '\t')
if (!this.displayContentOnly) {
this.view.querySelector('.title i.fa-copy').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) return
yo.update(this.view, this.render(null, node))
}
DropdownPanel.prototype.copyClipboard = function () {
const content = this.view.querySelector('.dropdownpanel .dropdownrawcontent')
return content.innerText ? content.innerText : content.textContent
}
DropdownPanel.prototype.render = function (overridestyle, node) {
var content = yo`<div>Empty</div>`
if (this.json) {
content = this.treeView.render({})
}
overridestyle === undefined ? {} : overridestyle
var self = this
var contentNode = yo`
<div class='dropdownpanel ${css.dropdownpanel}' style='display:none'>
<i class="${css.refresh} fas fa-sync" aria-hidden="true"></i>
<div class='dropdowncontent'>${node || content}</div>
<div class='dropdownrawcontent' style='display:none'></div>
<div class='message' style='display:none'></div>
</div>`
var title = !self.displayContentOnly ? yo`<div class="${css.title} py-0 px-1 title">
<div class="${css.icon} fas 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>
${copyToClipboard(() => this.copyClipboard())}
</div>` : yo`<div></div>`
var view = yo`
<div class="border rounded px-1 mt-1 bg-light">
<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.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} fas fa-caret-right`
this.event.trigger('hide', [])
} else {
el.style.display = ''
caret.className = `${css.icon} fas fa-caret-down`
this.event.trigger('show', [])
}
}
DropdownPanel.prototype.hide = function () {
if (!(this.view && !this.displayContentOnly)) return
var caret = this.view.querySelector('.title').firstElementChild
var el = this.view.querySelector('.dropdownpanel')
el.style.display = 'none'
caret.className = `${css.icon} fas fa-caret-right`
this.event.trigger('hide', [])
}
DropdownPanel.prototype.show = function () {
if (!(this.view && !this.displayContentOnly)) return
var caret = this.view.querySelector('.title').firstElementChild
var el = this.view.querySelector('.dropdownpanel')
el.style.display = ''
caret.className = `${css.icon} fas fa-caret-down`
this.event.trigger('show', [])
}
DropdownPanel.prototype.message = function (message) {
if (!this.view) return
var mes = this.view.querySelector('.dropdownpanel .message')
mes.innerText = message
mes.style.display = (message === '') ? 'none' : 'block'
}
module.exports = DropdownPanel

@ -1,21 +0,0 @@
var DropdownPanel = require('./DropdownPanel')
var yo = require('yo-yo')
function FullStoragesChanges () {
this.view
this.basicPanel = new DropdownPanel('Full Storages Changes', {json: true})
}
FullStoragesChanges.prototype.update = function (storageData) {
this.basicPanel.update(storageData)
}
FullStoragesChanges.prototype.render = function () {
var view = yo`<div id='fullstorageschangespanel' >${this.basicPanel.render()}</div>`
if (!this.view) {
this.view = view
}
return view
}
module.exports = FullStoragesChanges

@ -1,17 +0,0 @@
'use strict'
var DropdownPanel = require('./DropdownPanel')
var yo = require('yo-yo')
function FunctionPanel () {
this.basicPanel = new DropdownPanel('Function Stack', {json: true, displayContentOnly: false})
}
FunctionPanel.prototype.update = function (calldata) {
this.basicPanel.update(calldata)
}
FunctionPanel.prototype.render = function () {
return yo`<div id="FunctionPanel">${this.basicPanel.render()}</div>`
}
module.exports = FunctionPanel

@ -1,21 +0,0 @@
'use strict'
var DropdownPanel = require('./DropdownPanel')
var yo = require('yo-yo')
function MemoryPanel () {
this.basicPanel = new DropdownPanel('Memory', {
json: true,
css: {
'font-family': 'monospace'
}})
}
MemoryPanel.prototype.update = function (calldata) {
this.basicPanel.update(calldata)
}
MemoryPanel.prototype.render = function () {
return yo`<div id="memorypanel">${this.basicPanel.render()}</div>`
}
module.exports = MemoryPanel

@ -1,59 +0,0 @@
'use strict'
var EventManager = require('../../../../../lib/events')
var DropdownPanel = require('./DropdownPanel')
var solidityTypeFormatter = require('./utils/SolidityTypeFormatter')
var yo = require('yo-yo')
class SolidityLocals {
constructor () {
this.event = new EventManager()
this.basicPanel = new DropdownPanel('Solidity Locals', {
json: true,
formatSelf: solidityTypeFormatter.formatSelf,
extractData: solidityTypeFormatter.extractData,
loadMore: (cursor) => {
this.event.trigger('solidityLocalsLoadMore', [cursor])
}
})
this.view
this._data = null
}
update (data) {
this._data = data
this.basicPanel.update(this._data)
}
loadMore (data) {
this._data = this.mergeLocals(data, this._data)
this.basicPanel.update(this._data)
}
setMessage (message) {
this.basicPanel.setMessage(message)
}
setUpdating () {
this.basicPanel.setUpdating()
}
mergeLocals (locals1, locals2) {
Object.keys(locals2).map(item => {
if (locals2[item].cursor && (parseInt(locals2[item].cursor) < parseInt(locals1[item].cursor))) {
locals2[item] = {
...locals1[item],
value: [...locals2[item].value, ...locals1[item].value]
}
}
})
return locals2
}
render () {
this.view = yo`<div id='soliditylocals' data-id="solidityLocals">${this.basicPanel.render()}</div>`
return this.view
}
}
module.exports = SolidityLocals

@ -1,36 +0,0 @@
var DropdownPanel = require('./DropdownPanel')
var solidityTypeFormatter = require('./utils/SolidityTypeFormatter')
var yo = require('yo-yo')
function SolidityState () {
this.basicPanel = new DropdownPanel('Solidity State', {
json: true,
// TODO: used by TreeView ui
formatSelf: solidityTypeFormatter.formatSelf,
extractData: solidityTypeFormatter.extractData
})
this.view
}
SolidityState.prototype.update = function (data) {
this.basicPanel.update(data)
}
SolidityState.prototype.setMessage = function (message) {
this.basicPanel.setMessage(message)
}
SolidityState.prototype.setUpdating = function () {
this.basicPanel.setUpdating()
}
SolidityState.prototype.render = function () {
if (this.view) return
this.view = yo`
<div id='soliditystate' >
${this.basicPanel.render()}
</div>`
return this.view
}
module.exports = SolidityState

@ -1,17 +0,0 @@
'use strict'
var DropdownPanel = require('./DropdownPanel')
var yo = require('yo-yo')
function StackPanel () {
this.basicPanel = new DropdownPanel('Stack', {json: true, displayContentOnly: false})
}
StackPanel.prototype.update = function (calldata) {
this.basicPanel.update(calldata)
}
StackPanel.prototype.render = function () {
return yo`<div id="stackpanel">${this.basicPanel.render()}</div>`
}
module.exports = StackPanel

@ -1,23 +0,0 @@
var yo = require('yo-yo')
var DropdownPanel = require('./DropdownPanel')
function StepDetail () {
this.basicPanel = new DropdownPanel('Step details', {json: true, displayContentOnly: false})
this.detail = { 'vm trace step': '-', 'execution step': '-', 'add memory': '', 'gas': '', 'remaining gas': '-', 'loaded address': '-' }
}
StepDetail.prototype.reset = function () {
this.detail = { 'vm trace step': '-', 'execution step': '-', 'add memory': '', 'gas': '', 'remaining gas': '-', 'loaded address': '-' }
this.basicPanel.update(this.detail)
}
StepDetail.prototype.updateField = function (key, value) {
this.detail[key] = value
this.basicPanel.update(this.detail)
}
StepDetail.prototype.render = function () {
return yo`<div id='stepdetail' data-id="stepdetail">${this.basicPanel.render()}</div>`
}
module.exports = StepDetail

@ -1,17 +0,0 @@
'use strict'
var DropdownPanel = require('./DropdownPanel')
var yo = require('yo-yo')
function StoragePanel (_parent, _traceManager) {
this.basicPanel = new DropdownPanel('Storage', {json: true})
}
StoragePanel.prototype.update = function (storage, header) {
this.basicPanel.update(storage, header)
}
StoragePanel.prototype.render = function () {
return yo`<div id='storagepanel' >${this.basicPanel.render()}</div>`
}
module.exports = StoragePanel

@ -1,77 +0,0 @@
var yo = require('yo-yo')
var BN = require('ethereumjs-util').BN
module.exports = {
formatSelf: formatSelf,
extractData: extractData
}
function formatSelf (key, data) {
const style = fontColor(data)
const keyStyle = data.isProperty ? 'color: var(--info)' : ''
if (data.type === 'string') {
data.self = JSON.stringify(data.self)
}
return yo `<label class="mb-0" style='${keyStyle};white-space:pre-wrap;'> ${' ' + key}:<label class="mb-0" 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
ret.cursor = item.cursor
ret.hasNext = item.hasNext
} 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) {
let color = 'var(--primary)'
if (data.isArray || data.isStruct || data.isMapping) {
color = 'var(--info)'
} else if (
data.type.indexOf('uint') === 0 ||
data.type.indexOf('int') === 0 ||
data.type.indexOf('bool') === 0 ||
data.type.indexOf('enum') === 0
) {
color = 'var(--green)'
} else if (data.type === 'string') {
color = 'var(--teal)'
} else if (data.self == 0x0) { // eslint-disable-line
color = 'var(--gray)'
}
return 'color:' + color
}
Loading…
Cancel
Save