parent
6f7d0a3b08
commit
6ab0929f56
@ -0,0 +1,22 @@ |
||||
'use strict' |
||||
var remixCore = require('remix-core') |
||||
var EthDebugger = require('./src/Ethdebugger') |
||||
|
||||
/* |
||||
Use of breakPointManager : |
||||
|
||||
var breakPointManager = new BreakpointManager(this.debugger, (sourceLocation) => { |
||||
return line/column from offset (sourceLocation) |
||||
}) |
||||
this.debugger.setBreakpointManager(breakPointManager) |
||||
*/ |
||||
module.exports = { |
||||
EthDebugger: EthDebugger, |
||||
/** |
||||
* constructor |
||||
* |
||||
* @param {Object} _debugger - type of EthDebugger |
||||
* @return {Function} _locationToRowConverter - function implemented by editor which return a column/line position for a char source location |
||||
*/ |
||||
BreakpointManager: remixCore.code.BreakpointManager |
||||
} |
@ -0,0 +1,96 @@ |
||||
{ |
||||
"name": "remix-debug", |
||||
"version": "0.0.1", |
||||
"description": "Ethereum IDE and tools for the web", |
||||
"contributors": [ |
||||
{ |
||||
"name": "Yann Levreau", |
||||
"email": "yann@ethdev.com" |
||||
}, |
||||
{ |
||||
"name": "Liana Husikyan", |
||||
"email": "liana@ethdev.com" |
||||
} |
||||
], |
||||
"main": "./index.js", |
||||
"devDependencies": { |
||||
"babel-eslint": "^7.1.1", |
||||
"babel-plugin-transform-object-assign": "^6.22.0", |
||||
"babel-plugin-yo-yoify": "^0.3.3", |
||||
"babel-polyfill": "^6.22.0", |
||||
"babel-preset-env": "^1.6.1", |
||||
"babel-preset-es2015": "^6.24.0", |
||||
"babel-preset-stage-0": "^6.24.1", |
||||
"babelify": "^7.3.0", |
||||
"notify-error": "^1.2.0", |
||||
"npm-run-all": "^4.1.2", |
||||
"remix-core": "latest", |
||||
"remix-lib": "latest", |
||||
"remix-solidity": "latest", |
||||
"standard": "^7.0.1", |
||||
"standard-reporter": "^1.0.5" |
||||
}, |
||||
"scripts": { |
||||
"build": "mkdirp build; browserify index.js > build/app.js", |
||||
"lint": "standard | notify-error" |
||||
}, |
||||
"repository": { |
||||
"type": "git", |
||||
"url": "git+https://github.com/ethereum/remix.git" |
||||
}, |
||||
"author": "cpp-ethereum team", |
||||
"license": "MIT", |
||||
"bugs": { |
||||
"url": "https://github.com/ethereum/remix/issues" |
||||
}, |
||||
"homepage": "https://github.com/ethereum/remix#readme", |
||||
"standard": { |
||||
"ignore": [ |
||||
"node_modules/*", |
||||
"build/*", |
||||
"test/resources/*" |
||||
] |
||||
}, |
||||
"babel": { |
||||
"plugins": [ |
||||
"transform-es2015-template-literals", |
||||
"transform-es2015-literals", |
||||
"transform-es2015-function-name", |
||||
"transform-es2015-arrow-functions", |
||||
"transform-es2015-block-scoped-functions", |
||||
"transform-es2015-classes", |
||||
"transform-es2015-object-super", |
||||
"transform-es2015-shorthand-properties", |
||||
"transform-es2015-duplicate-keys", |
||||
"transform-es2015-computed-properties", |
||||
"transform-es2015-for-of", |
||||
"transform-es2015-sticky-regex", |
||||
"transform-es2015-unicode-regex", |
||||
"check-es2015-constants", |
||||
"transform-es2015-spread", |
||||
"transform-es2015-parameters", |
||||
"transform-es2015-destructuring", |
||||
"transform-es2015-block-scoping", |
||||
"transform-object-assign" |
||||
] |
||||
}, |
||||
"browserify": { |
||||
"transform": [ |
||||
[ |
||||
"babelify", |
||||
{ |
||||
"sourceMapsAbsolute": false, |
||||
"sourceMaps": true, |
||||
"plugins": [ |
||||
[ |
||||
"transform-object-assign" |
||||
] |
||||
], |
||||
"presets": [ |
||||
"es2015" |
||||
] |
||||
} |
||||
] |
||||
] |
||||
} |
||||
} |
@ -0,0 +1,146 @@ |
||||
'use strict' |
||||
var remixCore = require('remix-core') |
||||
var TraceManager = remixCore.trace.TraceManager |
||||
var remixLib = require('remix-lib') |
||||
var global = remixLib.global |
||||
var init = remixLib.init |
||||
var executionContext = remixLib.execution.executionContext |
||||
var EventManager = remixLib.EventManager |
||||
var Web3Providers = remixLib.vm.Web3Providers |
||||
var DummyProvider = remixLib.vm.DummyProvider |
||||
var CodeManager = remixCore.code.CodeManager |
||||
var remixSolidity = require('remix-solidity') |
||||
var SolidityProxy = remixSolidity.SolidityProxy |
||||
var InternalCallTree = remixSolidity.InternalCallTree |
||||
|
||||
/** |
||||
* Ethdebugger is a wrapper around a few classes that helps debugging a transaction |
||||
* |
||||
* - Web3Providers - define which environment (web3) the transaction will be retrieved from |
||||
* - TraceManager - Load / Analyze the trace and retrieve details of specific test |
||||
* - CodeManager - Retrieve loaded byte code and help to resolve AST item from vmtrace index |
||||
* - SolidityProxy - Basically used to extract state variable from AST |
||||
* - Breakpoint Manager - Used to add / remove / jumpto breakpoint |
||||
* - InternalCallTree - Used to retrieved local variables |
||||
* |
||||
* @param {Map} opts - { function compilationResult } //
|
||||
*/ |
||||
function Ethdebugger (opts) { |
||||
this.opts = opts || {} |
||||
if (!this.opts.compilationResult) this.opts.compilationResult = () => { return null } |
||||
|
||||
var self = this |
||||
this.event = new EventManager() |
||||
|
||||
this.tx |
||||
|
||||
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) |
||||
|
||||
this.callTree = new InternalCallTree(this.event, this.traceManager, this.solidityProxy, this.codeManager, { includeLocalVariables: true }) |
||||
|
||||
this.event.register('indexChanged', this, function (index) { |
||||
self.codeManager.resolveStep(index, self.tx) |
||||
}) |
||||
} |
||||
|
||||
Ethdebugger.prototype.sourceLocationFromVMTraceIndex = function (address, stepIndex, callback) { |
||||
this.callTree.sourceLocationTracker.getSourceLocationFromVMTraceIndex(address, stepIndex, this.solidityProxy.contracts, (error, rawLocation) => { |
||||
callback(error, rawLocation) |
||||
}) |
||||
} |
||||
|
||||
Ethdebugger.prototype.sourceLocationFromInstructionIndex = function (address, instIndex, callback) { |
||||
this.debugger.callTree.sourceLocationTracker.getSourceLocationFromInstructionIndex(address, instIndex, this.solidityProxy.contracts, function (error, rawLocation) { |
||||
callback(error, rawLocation) |
||||
}) |
||||
} |
||||
|
||||
Ethdebugger.prototype.setBreakpointManager = function (breakpointManager) { |
||||
this.breakpointManager = breakpointManager |
||||
} |
||||
|
||||
Ethdebugger.prototype.resolveStep = function (index) { |
||||
this.codeManager.resolveStep(index, this.tx) |
||||
} |
||||
|
||||
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.switchProvider = function (type) { |
||||
var self = this |
||||
this.web3Providers.get(type, function (error, obj) { |
||||
if (error) { |
||||
console.log('provider ' + type + ' not defined') |
||||
} else { |
||||
global.web3 = obj |
||||
executionContext.detectNetwork((error, network) => { |
||||
if (error || !network) { |
||||
global.web3Debug = obj |
||||
} else { |
||||
var webDebugNode = init.web3DebugNode(network.name) |
||||
global.web3Debug = !webDebugNode ? obj : webDebugNode |
||||
} |
||||
}) |
||||
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.unLoad = function () { |
||||
this.traceManager.init() |
||||
this.codeManager.clear() |
||||
this.stepManager.reset() |
||||
this.event.trigger('traceUnloaded') |
||||
} |
||||
|
||||
Ethdebugger.prototype.debug = function (blockNumber, txIndex, tx) { |
||||
if (this.traceManager.isLoading) { |
||||
return |
||||
} |
||||
this.setCompilationResult(this.opts.compilationResult()) |
||||
console.log('loading trace...') |
||||
this.tx = tx |
||||
var self = this |
||||
this.traceManager.resolveTrace(tx, function (error, result) { |
||||
console.log('trace loaded ' + result) |
||||
if (result) { |
||||
self.event.trigger('newTraceLoaded', [self.traceManager.trace]) |
||||
if (self.breakpointManager && self.breakpointManager.hasBreakpoint()) { |
||||
self.breakpointManager.jumpNextBreakpoint(false) |
||||
} |
||||
} else { |
||||
self.statusMessage = error ? error.message : 'Trace not loaded' |
||||
} |
||||
}) |
||||
} |
||||
|
||||
module.exports = Ethdebugger |
Loading…
Reference in new issue