show local variable value in the editor context

pull/3199/head
yann300 2 years ago committed by Aniket
parent d9ee952377
commit 903ba09290
  1. 7
      apps/debugger/src/app/debugger-api.ts
  2. 6
      apps/remix-ide/src/app/tabs/debugger-tab.js
  3. 11
      libs/remix-debug/src/Ethdebugger.ts
  4. 12
      libs/remix-debug/src/solidity-decoder/internalCallTree.ts
  5. 6
      libs/remix-ui/debugger-ui/src/lib/debugger-ui.tsx
  6. 9
      libs/remix-ui/editor/src/lib/providers/hoverProvider.ts

@ -6,6 +6,7 @@ import { lineText } from '@remix-ui/editor'
export const DebuggerApiMixin = (Base) => class extends Base { export const DebuggerApiMixin = (Base) => class extends Base {
initialWeb3 initialWeb3
debuggerBackend
initDebuggerApi () { initDebuggerApi () {
const self = this const self = this
@ -148,7 +149,11 @@ export const DebuggerApiMixin = (Base) => class extends Base {
if (web3) this._web3 = web3 if (web3) this._web3 = web3
else this._web3 = this.initialWeb3 else this._web3 = this.initialWeb3
remixDebug.init.extendWeb3(this._web3) remixDebug.init.extendWeb3(this._web3)
if (this.onDebugRequestedListener) this.onDebugRequestedListener(hash, web3) if (this.onDebugRequestedListener) {
this.onDebugRequestedListener(hash, web3).then((debuggerBackend) => {
this.debuggerBackend = debuggerBackend
})
}
} }
onActivation () { onActivation () {

@ -10,7 +10,7 @@ const css = require('./styles/debugger-tab-styles')
const profile = { const profile = {
name: 'debugger', name: 'debugger',
displayName: 'Debugger', displayName: 'Debugger',
methods: ['debug', 'getTrace'], methods: ['debug', 'getTrace', 'decodeVariable'],
events: [], events: [],
icon: 'assets/img/debuggerLogo.webp', icon: 'assets/img/debuggerLogo.webp',
description: 'Debug transactions', description: 'Debug transactions',
@ -66,4 +66,8 @@ export class DebuggerTab extends DebuggerApiMixin(ViewPlugin) {
} }
} }
async decodeVariable (variableId) {
if (!this.debuggerBackend) return null
return await this.debuggerBackend.debugger.decodeLocalVariableByIdAtCurrentStep(this.debuggerBackend.step_manager.currentStepIndex, variableId)
}
} }

@ -100,6 +100,17 @@ export class Ethdebugger {
return this.callTree.findScope(step) return this.callTree.findScope(step)
} }
async decodeLocalVariableByIdAtCurrentStep (step: number, id: number) {
const variable = this.callTree.getLocalVariableById(id)
if (!variable) return null
const stack = this.traceManager.getStackAt(step)
const memory = this.traceManager.getMemoryAt(step)
const address = this.traceManager.getCurrentCalledAddressAt(step)
const calldata = this.traceManager.getCallDataAt(step)
const storageViewer = new StorageViewer({ stepIndex: step, tx: this.tx, address: address }, this.storageResolver, this.traceManager)
return await variable.type.decodeFromStack(variable.stackDepth, stack, memory, storageViewer, calldata, null, variable)
}
async decodeLocalsAt (step, sourceLocation, callback) { async decodeLocalsAt (step, sourceLocation, callback) {
try { try {
const stack = this.traceManager.getStackAt(step) const stack = this.traceManager.getStackAt(step)

@ -46,6 +46,9 @@ export class InternalCallTree {
pendingConstructorId: number pendingConstructorId: number
pendingConstructor pendingConstructor
constructorsStartExecution constructorsStartExecution
variables: {
[Key: number]: any
}
/** /**
* constructor * constructor
@ -122,6 +125,7 @@ export class InternalCallTree {
this.pendingConstructorId = -1 this.pendingConstructorId = -1
this.constructorsStartExecution = {} this.constructorsStartExecution = {}
this.pendingConstructor = null this.pendingConstructor = null
this.variables = {}
} }
/** /**
@ -203,6 +207,10 @@ export class InternalCallTree {
} }
throw new Error('Could not find gas cost per line') throw new Error('Could not find gas cost per line')
} }
getLocalVariableById (id: number) {
return this.variables[id]
}
} }
async function buildTree (tree, step, scopeId, isCreation, functionDefinition?, contractObj?, sourceLocation?, validSourceLocation?) { async function buildTree (tree, step, scopeId, isCreation, functionDefinition?, contractObj?, sourceLocation?, validSourceLocation?) {
@ -407,12 +415,14 @@ async function includeVariableDeclaration (tree, step, sourceLocation, scopeId,
let location = extractLocationFromAstVariable(variableDeclaration) let location = extractLocationFromAstVariable(variableDeclaration)
location = location === 'default' ? 'storage' : location location = location === 'default' ? 'storage' : location
// we push the new local variable in our tree // we push the new local variable in our tree
tree.scopes[scopeId].locals[variableDeclaration.name] = { const newVar = {
name: variableDeclaration.name, name: variableDeclaration.name,
type: parseType(variableDeclaration.typeDescriptions.typeString, states, contractObj.name, location), type: parseType(variableDeclaration.typeDescriptions.typeString, states, contractObj.name, location),
stackDepth: stack.length, stackDepth: stack.length,
sourceLocation: sourceLocation sourceLocation: sourceLocation
} }
tree.scopes[scopeId].locals[variableDeclaration.name] = newVar
tree.variables[variableDeclaration.id] = newVar
} }
} catch (error) { } catch (error) {
console.log(error) console.log(error)

@ -63,7 +63,7 @@ export const DebuggerUI = (props: DebuggerUIProps) => {
}, []) }, [])
debuggerModule.onDebugRequested((hash, web3?) => { debuggerModule.onDebugRequested((hash, web3?) => {
if (hash) debug(hash, web3) if (hash) return debug(hash, web3)
}) })
debuggerModule.onRemoveHighlights(async () => { debuggerModule.onRemoveHighlights(async () => {
@ -314,6 +314,8 @@ export const DebuggerUI = (props: DebuggerUIProps) => {
} }
}, 300) }, 300)
handleResize() handleResize()
return debuggerInstance
} }
const debug = (txHash, web3?) => { const debug = (txHash, web3?) => {
@ -325,7 +327,7 @@ export const DebuggerUI = (props: DebuggerUIProps) => {
sourceLocationStatus: '' sourceLocationStatus: ''
} }
}) })
startDebugging(null, txHash, null, web3) return startDebugging(null, txHash, null, web3)
} }
const stepManager = { const stepManager = {

@ -145,6 +145,15 @@ export class RemixHoverProvider implements languages.HoverProvider {
getLinks(nodeAtPosition) getLinks(nodeAtPosition)
getDocs(nodeAtPosition) getDocs(nodeAtPosition)
// getScope(nodeAtPosition) // getScope(nodeAtPosition)
try {
const decodedVar = await this.props.plugin.call('debugger', 'decodeVariable', nodeAtPosition.id)
if (decodedVar !== null) {
contents.push({
value: JSON.stringify(decodedVar.value, null, '\t')
})
}
} catch (e) {}
} }
setTimeout(() => { setTimeout(() => {

Loading…
Cancel
Save