Merge pull request #1394 from ethereum/refactor6

Clean app.js (6)
pull/1/head
yann300 6 years ago committed by GitHub
commit d4e05ca28c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 115
      src/app.js
  2. 50
      src/app/execution/txLogger.js
  3. 25
      src/app/panels/righthand-panel.js
  4. 21
      src/app/staticanalysis/staticAnalysisView.js
  5. 6
      src/app/tabs/compile-tab.js
  6. 2
      src/app/tabs/test-tab.js
  7. 41
      src/app/ui/renderer.js

@ -313,6 +313,35 @@ class App {
} }
}) })
} }
importFileCb (url, filecb) {
const self = this
if (url.indexOf('/remix_tests.sol') !== -1) {
return filecb(null, remixTests.assertLibCode)
}
var provider = self._components.fileManager.fileProviderOf(url)
if (provider) {
provider.exists(url, (error, exist) => {
if (error) return filecb(error)
if (exist) {
return provider.get(url, filecb)
} else {
self.importExternal(url, filecb)
}
})
} else if (self._components.compilerImport.isRelativeImport(url)) {
// try to resolve localhost modules (aka truffle imports)
var splitted = /([^/]+)\/(.*)$/g.exec(url)
async.tryEach([
(cb) => { self.importFileCb('localhost/installed_contracts/' + url, cb) },
(cb) => { if (!splitted) { cb('url not parseable' + url) } else { self.importFileCb('localhost/installed_contracts/' + splitted[1] + '/contracts/' + splitted[2], cb) } },
(cb) => { self.importFileCb('localhost/node_modules/' + url, cb) },
(cb) => { if (!splitted) { cb('url not parseable' + url) } else { self.importFileCb('localhost/node_modules/' + splitted[1] + '/contracts/' + splitted[2], cb) } }],
(error, result) => { filecb(error, result) }
)
} else {
self.importExternal(url, filecb)
}
}
} }
module.exports = App module.exports = App
@ -352,37 +381,8 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
} }
}) })
function importFileCb (url, filecb) {
if (url.indexOf('/remix_tests.sol') !== -1) {
return filecb(null, remixTests.assertLibCode)
}
var provider = fileManager.fileProviderOf(url)
if (provider) {
provider.exists(url, (error, exist) => {
if (error) return filecb(error)
if (exist) {
return provider.get(url, filecb)
} else {
self.importExternal(url, filecb)
}
})
} else if (self._components.compilerImport.isRelativeImport(url)) {
// try to resolve localhost modules (aka truffle imports)
var splitted = /([^/]+)\/(.*)$/g.exec(url)
async.tryEach([
(cb) => { importFileCb('localhost/installed_contracts/' + url, cb) },
(cb) => { if (!splitted) { cb('url not parseable' + url) } else { importFileCb('localhost/installed_contracts/' + splitted[1] + '/contracts/' + splitted[2], cb) } },
(cb) => { importFileCb('localhost/node_modules/' + url, cb) },
(cb) => { if (!splitted) { cb('url not parseable' + url) } else { importFileCb('localhost/node_modules/' + splitted[1] + '/contracts/' + splitted[2], cb) } }],
(error, result) => { filecb(error, result) }
)
} else {
self.importExternal(url, filecb)
}
}
// ----------------- Compiler ----------------- // ----------------- Compiler -----------------
self._components.compiler = new Compiler(importFileCb) self._components.compiler = new Compiler((url, cb) => self.importFileCb(url, cb))
var compiler = self._components.compiler var compiler = self._components.compiler
registry.put({api: compiler, name: 'compiler'}) registry.put({api: compiler, name: 'compiler'})
@ -461,7 +461,7 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
} }
} }
}) })
registry.put({api: eventsDecoder, name: 'eventsDecoder'}) registry.put({api: eventsDecoder, name: 'eventsdecoder'})
txlistener.startListening() txlistener.startListening()
@ -569,42 +569,11 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
} }
// ----------------- Renderer ----------------- // ----------------- Renderer -----------------
var rendererAPI = { var renderer = new Renderer()
error: (file, error) => {
if (file === config.get('currentFile')) {
editor.addAnnotation(error)
}
},
errorClick: (errFile, errLine, errCol) => {
if (errFile !== config.get('currentFile')) {
// TODO: refactor with this._components.contextView.jumpTo
var provider = fileManager.fileProviderOf(errFile)
if (provider) {
provider.exists(errFile, (error, exist) => {
if (error) return console.log(error)
fileManager.switchFile(errFile)
editor.gotoLine(errLine, errCol)
})
}
} else {
editor.gotoLine(errLine, errCol)
}
}
}
var renderer = new Renderer(rendererAPI)
registry.put({api: renderer, name: 'renderer'}) registry.put({api: renderer, name: 'renderer'})
// ----------------- StaticAnalysis ----------------- // ----------------- StaticAnalysis -----------------
var staticanalysis = new StaticAnalysis()
var staticAnalysisAPI = {
renderWarning: (label, warningContainer, type) => {
return renderer.error(label, warningContainer, type)
},
offsetToLineColumn: (location, file) => {
return offsetToLineColumnConverter.offsetToLineColumn(location, file, compiler.lastCompilationResult)
}
}
var staticanalysis = new StaticAnalysis(staticAnalysisAPI, compiler.event)
registry.put({api: staticanalysis, name: 'staticanalysis'}) registry.put({api: staticanalysis, name: 'staticanalysis'})
// ---------------- Righthand-panel -------------------- // ---------------- Righthand-panel --------------------
@ -671,23 +640,7 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
self._view.transactionDebugger.addProvider('web3', executionContext.internalWeb3()) self._view.transactionDebugger.addProvider('web3', executionContext.internalWeb3())
self._view.transactionDebugger.switchProvider(executionContext.getProvider()) self._view.transactionDebugger.switchProvider(executionContext.getProvider())
var txLogger = new TxLogger({ var txLogger = new TxLogger()
api: {
editorpanel: self._components.editorpanel,
resolvedTransaction: function (hash) {
return txlistener.resolvedTransaction(hash)
},
parseLogs: function (tx, contractName, contracts, cb) {
eventsDecoder.parseLogs(tx, contractName, contracts, cb)
},
compiledContracts: function () {
return compiledContracts()
}
},
events: {
txListener: txlistener.event
}
})
txLogger.event.register('debugRequested', (hash) => { txLogger.event.register('debugRequested', (hash) => {
self.startdebugging(hash) self.startdebugging(hash)

@ -13,6 +13,7 @@ var helper = require('../../lib/helper')
var executionContext = require('../../execution-context') var executionContext = require('../../execution-context')
var modalDialog = require('../ui/modal-dialog-custom') var modalDialog = require('../ui/modal-dialog-custom')
var typeConversion = remixLib.execution.typeConversion var typeConversion = remixLib.execution.typeConversion
var globlalRegistry = require('../../global/registry')
var css = csjs` var css = csjs`
.log { .log {
@ -123,9 +124,8 @@ var css = csjs`
* *
*/ */
class TxLogger { class TxLogger {
constructor (opts = {}) { constructor (localRegistry) {
this.event = new EventManager() this.event = new EventManager()
this.opts = opts
this.seen = {} this.seen = {}
function filterTx (value, query) { function filterTx (value, query) {
if (value.length) { if (value.length) {
@ -134,7 +134,17 @@ class TxLogger {
return false return false
} }
this.logKnownTX = opts.api.editorpanel.registerCommand('knownTransaction', (args, cmds, append) => { this._components = {}
this._components.registry = localRegistry || globlalRegistry
// dependencies
this._deps = {
editorPanel: this._components.registry.get('editorpanel').api,
txListener: this._components.registry.get('txlistener').api,
eventsDecoder: this._components.registry.get('eventsdecoder').api,
compiler: this._components.registry.get('compiler').api
}
this.logKnownTX = this._deps.editorPanel.registerCommand('knownTransaction', (args, cmds, append) => {
var data = args[0] var data = args[0]
var el var el
if (data.tx.isCall) { if (data.tx.isCall) {
@ -146,46 +156,46 @@ class TxLogger {
append(el) append(el)
}, { activate: true, filterFn: filterTx }) }, { activate: true, filterFn: filterTx })
this.logUnknownTX = opts.api.editorpanel.registerCommand('unknownTransaction', (args, cmds, append) => { this.logUnknownTX = this._deps.editorPanel.registerCommand('unknownTransaction', (args, cmds, append) => {
var data = args[0] var data = args[0]
var el = renderUnknownTransaction(this, data) var el = renderUnknownTransaction(this, data)
append(el) append(el)
}, { activate: false, filterFn: filterTx }) }, { activate: false, filterFn: filterTx })
this.logEmptyBlock = opts.api.editorpanel.registerCommand('emptyBlock', (args, cmds, append) => { this.logEmptyBlock = this._deps.editorPanel.registerCommand('emptyBlock', (args, cmds, append) => {
var data = args[0] var data = args[0]
var el = renderEmptyBlock(this, data) var el = renderEmptyBlock(this, data)
append(el) append(el)
}, { activate: true }) }, { activate: true })
opts.api.editorpanel.event.register('terminalFilterChanged', (type, label) => { this._deps.editorPanel.event.register('terminalFilterChanged', (type, label) => {
if (type === 'deselect') { if (type === 'deselect') {
if (label === 'only remix transactions') { if (label === 'only remix transactions') {
opts.api.editorpanel.updateTerminalFilter({ type: 'select', value: 'unknownTransaction' }) this._deps.editorPanel.updateTerminalFilter({ type: 'select', value: 'unknownTransaction' })
} else if (label === 'all transactions') { } else if (label === 'all transactions') {
opts.api.editorpanel.updateTerminalFilter({ type: 'deselect', value: 'unknownTransaction' }) this._deps.editorPanel.updateTerminalFilter({ type: 'deselect', value: 'unknownTransaction' })
} }
} else if (type === 'select') { } else if (type === 'select') {
if (label === 'only remix transactions') { if (label === 'only remix transactions') {
opts.api.editorpanel.updateTerminalFilter({ type: 'deselect', value: 'unknownTransaction' }) this._deps.editorPanel.updateTerminalFilter({ type: 'deselect', value: 'unknownTransaction' })
} else if (label === 'all transactions') { } else if (label === 'all transactions') {
opts.api.editorpanel.updateTerminalFilter({ type: 'select', value: 'unknownTransaction' }) this._deps.editorPanel.updateTerminalFilter({ type: 'select', value: 'unknownTransaction' })
} }
} }
}) })
opts.events.txListener.register('newBlock', (block) => { this._deps.txListener.event.register('newBlock', (block) => {
if (!block.transactions.length) { if (!block.transactions.length) {
this.logEmptyBlock({ block: block }) this.logEmptyBlock({ block: block })
} }
}) })
opts.events.txListener.register('newTransaction', (tx, receipt) => { this._deps.txListener.event.register('newTransaction', (tx, receipt) => {
log(this, tx, receipt, opts.api) log(this, tx, receipt)
}) })
opts.events.txListener.register('newCall', (tx) => { this._deps.txListener.event.register('newCall', (tx) => {
log(this, tx, null, opts.api) log(this, tx, null)
}) })
} }
} }
@ -199,10 +209,14 @@ function debug (e, data, self) {
} }
} }
function log (self, tx, receipt, api) { function log (self, tx, receipt) {
var resolvedTransaction = api.resolvedTransaction(tx.hash) var resolvedTransaction = self._deps.txListener.resolvedTransaction(tx.hash)
if (resolvedTransaction) { if (resolvedTransaction) {
api.parseLogs(tx, resolvedTransaction.contractName, api.compiledContracts(), (error, logs) => { var compiledContracts = null
if (self._deps.compiler.lastCompilationResult && self._deps.compiler.lastCompilationResult.data) {
compiledContracts = self._deps.compiler.lastCompilationResult.data.contracts
}
self._deps.eventsDecoder.parseLogs(tx, resolvedTransaction.contractName, compiledContracts, (error, logs) => {
if (!error) { if (!error) {
self.logKnownTX({ tx: tx, receipt: receipt, resolvedData: resolvedTransaction, logs: logs }) self.logKnownTX({ tx: tx, receipt: receipt, resolvedData: resolvedTransaction, logs: logs })
} }

@ -32,16 +32,18 @@ module.exports = class RighthandPanel {
dragbar: null dragbar: null
} }
self._components.registry.put({api: this, name: 'righthandpanel'})
self._components = { self._components = {
pluginManager: new PluginManager(), pluginManager: new PluginManager(self._components.registry),
tabbedMenu: new TabbedMenu(), tabbedMenu: new TabbedMenu(self._components.registry),
compile: new CompileTab(), compile: new CompileTab(self._components.registry),
run: new RunTab(), run: new RunTab(self._components.registry),
settings: new SettingsTab(), settings: new SettingsTab(self._components.registry),
analysis: new AnalysisTab(), analysis: new AnalysisTab(self._components.registry),
debug: new DebuggerTab(), debug: new DebuggerTab(self._components.registry),
support: new SupportTab(), support: new SupportTab(self._components.registry),
test: new TestTab() test: new TestTab(self._components.registry)
} }
self.event.register('plugin-loadRequest', json => { self.event.register('plugin-loadRequest', json => {
@ -81,6 +83,11 @@ module.exports = class RighthandPanel {
if (self._view.element) return self._view.element if (self._view.element) return self._view.element
return self._view.element return self._view.element
} }
focusOn (x) {
if (this._components.tabbedMenu) this._components.tabbedMenu.selectTabByClassName(x)
}
init () { init () {
// @TODO: init is for resizable drag bar only and should be refactored in the future // @TODO: init is for resizable drag bar only and should be refactored in the future
const self = this const self = this

@ -9,18 +9,27 @@ var styleGuide = require('../ui/styles-guide/theme-chooser')
var styles = styleGuide.chooser() var styles = styleGuide.chooser()
var css = require('./styles/staticAnalysisView-styles') var css = require('./styles/staticAnalysisView-styles')
var globlalRegistry = require('../../global/registry')
var EventManager = remixLib.EventManager var EventManager = remixLib.EventManager
function staticAnalysisView (appAPI, compilerEvent) { function staticAnalysisView (localRegistry) {
var self = this
this.event = new EventManager() this.event = new EventManager()
this.view = null this.view = null
this.appAPI = appAPI
this.runner = new StaticAnalysisRunner() this.runner = new StaticAnalysisRunner()
this.modulesView = renderModules(this.runner.modules()) this.modulesView = renderModules(this.runner.modules())
this.lastCompilationResult = null this.lastCompilationResult = null
var self = this self._components = {}
compilerEvent.register('compilationFinished', function (success, data, source) { self._components.registry = localRegistry || globlalRegistry
// dependencies
self._deps = {
compiler: self._components.registry.get('compiler').api,
renderer: self._components.registry.get('renderer').api,
offsetToLineColumnConverter: self._components.registry.get('offsetToLineColumnConverter').api
}
self._deps.compiler.event.register('compilationFinished', function (success, data, source) {
self.lastCompilationResult = null self.lastCompilationResult = null
$('#staticanalysisresult').empty() $('#staticanalysisresult').empty()
if (success) { if (success) {
@ -85,12 +94,12 @@ staticAnalysisView.prototype.run = function () {
start: parseInt(split[0]), start: parseInt(split[0]),
length: parseInt(split[1]) length: parseInt(split[1])
} }
location = self.appAPI.offsetToLineColumn(location, file) location = self._deps.offsetToLineColumnConverter.offsetToLineColumn(location, file)
location = Object.keys(self.lastCompilationResult.contracts)[file] + ':' + (location.start.line + 1) + ':' + (location.start.column + 1) + ':' location = Object.keys(self.lastCompilationResult.contracts)[file] + ':' + (location.start.line + 1) + ':' + (location.start.column + 1) + ':'
} }
warningCount++ warningCount++
var msg = yo`<span>${location} ${item.warning} ${item.more ? yo`<span><br><a href="${item.more}" target="blank">more</a></span>` : yo`<span></span>`}</span>` var msg = yo`<span>${location} ${item.warning} ${item.more ? yo`<span><br><a href="${item.more}" target="blank">more</a></span>` : yo`<span></span>`}</span>`
self.appAPI.renderWarning(msg, warningContainer, {type: 'staticAnalysisWarning', useSpan: true}) self._deps.renderer.error(msg, warningContainer, {type: 'staticAnalysisWarning', useSpan: true})
}) })
}) })
if (warningContainer.html() === '') { if (warningContainer.html() === '') {

@ -40,7 +40,9 @@ module.exports = class CompileTab {
compiler: self._components.registry.get('compiler').api, compiler: self._components.registry.get('compiler').api,
staticAnalysis: self._components.registry.get('staticanalysis').api, staticAnalysis: self._components.registry.get('staticanalysis').api,
renderer: self._components.registry.get('renderer').api, renderer: self._components.registry.get('renderer').api,
transactionContextAPI: self._components.registry.get('transactionContextAPI').api fileManager: self._components.registry.get('filemanager').api,
transactionContextAPI: self._components.registry.get('transactionContextAPI').api,
rightHandPanel: self._components.registry.get('righthandpanel').api
} }
self.data = { self.data = {
hideWarnings: self._deps.config.get('hideWarnings') || false, hideWarnings: self._deps.config.get('hideWarnings') || false,
@ -148,7 +150,7 @@ module.exports = class CompileTab {
self._deps.staticAnalysis.event.register('staticAnaysisWarning', (count) => { self._deps.staticAnalysis.event.register('staticAnaysisWarning', (count) => {
if (count) { if (count) {
const msg = `Static Analysis raised ${count} warning(s) that requires your attention. Click here to show the warning(s).` const msg = `Static Analysis raised ${count} warning(s) that requires your attention. Click here to show the warning(s).`
const settings = { type: 'staticAnalysisWarning', click: () => self._api.switchTab('staticanalysisView'), useSpan: true } const settings = { type: 'staticAnalysisWarning', click: () => self._deps.rightHandPanel.focusOn('staticanalysisView'), useSpan: true }
self._deps.renderer.error(msg, self._view.errorContainer, settings) self._deps.renderer.error(msg, self._view.errorContainer, settings)
} }
}) })

@ -77,7 +77,7 @@ module.exports = class TestTab {
remixTests.runTestSources(runningTest, testCallback, resultsCallback, (error, result) => { remixTests.runTestSources(runningTest, testCallback, resultsCallback, (error, result) => {
updateFinalResult(error, result) updateFinalResult(error, result)
callback(error) callback(error)
}, this._deps.fileManager.importFileCb) }, (url, cb) => { this._deps.app.importFileCb(url, cb) })
} }
}) })
} }

@ -3,19 +3,52 @@
var $ = require('jquery') var $ = require('jquery')
var yo = require('yo-yo') var yo = require('yo-yo')
var css = require('./styles/renderer-styles') var css = require('./styles/renderer-styles')
var globlalRegistry = require('../../global/registry')
/** /**
* After refactor, the renderer is only used to render error/warning * After refactor, the renderer is only used to render error/warning
* TODO: This don't need to be an object anymore. Simplify and just export the renderError function. * TODO: This don't need to be an object anymore. Simplify and just export the renderError function.
* *
*/ */
function Renderer (appAPI) { function Renderer (localRegistry) {
this.appAPI = appAPI const self = this
self._components = {}
self._components.registry = localRegistry || globlalRegistry
// dependencies
self._deps = {
editor: self._components.registry.get('editor').api,
fileManager: self._components.registry.get('filemanager').api,
config: self._components.registry.get('config').api
}
if (document && document.head) { if (document && document.head) {
document.head.appendChild(css) document.head.appendChild(css)
} }
} }
Renderer.prototype._error = function (file, error) {
const self = this
if (file === self._deps.config.get('currentFile')) {
self._deps.editor.addAnnotation(error)
}
}
Renderer.prototype._errorClick = function (errFile, errLine, errCol) {
const self = this
if (errFile !== self._deps.config.get('currentFile')) {
// TODO: refactor with this._components.contextView.jumpTo
var provider = self._deps.fileManager.fileProviderOf(errFile)
if (provider) {
provider.exists(errFile, (error, exist) => {
if (error) return console.log(error)
self._deps.fileManager.switchFile(errFile)
self._deps.editor.gotoLine(errLine, errCol)
})
}
} else {
self._deps.editor.gotoLine(errLine, errCol)
}
}
/** /**
* format msg like error or warning, * format msg like error or warning,
* *
@ -45,7 +78,7 @@ Renderer.prototype.error = function (message, container, opt) {
} }
if (!opt.noAnnotations && errLocation) { if (!opt.noAnnotations && errLocation) {
this.appAPI.error(errLocation.errFile, { this._error(errLocation.errFile, {
row: errLocation.errLine, row: errLocation.errLine,
column: errLocation.errCol, column: errLocation.errCol,
text: text, text: text,
@ -60,7 +93,7 @@ Renderer.prototype.error = function (message, container, opt) {
$error.click((ev) => { $error.click((ev) => {
if (opt.errFile && opt.errLine) { if (opt.errFile && opt.errLine) {
this.appAPI.errorClick(opt.errFile, opt.errLine, opt.errCol) this._errorClick(opt.errFile, opt.errLine, opt.errCol)
} else if (opt.click) { } else if (opt.click) {
opt.click(message) opt.click(message)
} }

Loading…
Cancel
Save