Merge pull request #1642 from ethereum/refactorApp.js

Refactor app.js
pull/1/head
yann300 6 years ago committed by GitHub
commit 9fcfdabffc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      .circleci/config.yml
  2. 28
      ci/makeMockCompiler.js
  3. 6
      package.json
  4. 192
      src/app.js
  5. 18
      src/app/compiler/compiler-abstract.js
  6. 35
      src/app/debugger/debuggerUI.js
  7. 13
      src/app/editor/contextView.js
  8. 23
      src/app/editor/contextualListener.js
  9. 7
      src/app/editor/sourceHighlighter.js
  10. 6
      src/app/execution/txLogger.js
  11. 64
      src/app/files/chromeCloudStorageSync.js
  12. 10
      src/app/files/compiler-metadata.js
  13. 5
      src/app/files/fileManager.js
  14. 14
      src/app/panels/editor-panel.js
  15. 7
      src/app/panels/file-panel.js
  16. 60
      src/app/panels/righthand-panel.js
  17. 4
      src/app/plugin/pluginAPI.js
  18. 52
      src/app/plugin/pluginManager.js
  19. 11
      src/app/staticanalysis/staticAnalysisView.js
  20. 8
      src/app/tabs/analysis-tab.js
  21. 139
      src/app/tabs/compile-tab.js
  22. 16
      src/app/tabs/run-tab.js
  23. 4
      src/app/tabs/settings-tab.js
  24. 7
      src/app/tabs/test-tab.js
  25. 12
      src/lib/cmdInterpreterAPI.js
  26. 7
      src/lib/offsetToLineColumnConverter.js
  27. 9
      src/universal-dapp.js
  28. 2
      test-browser/tests/ballot.js
  29. 5
      test-browser/tests/sharedFolderExplorer.js

@ -26,10 +26,10 @@ jobs:
- checkout - checkout
- restore_cache: - restore_cache:
keys: keys:
- dep-bundle-24-{{ checksum "package.json" }} - dep-bundle-27-{{ checksum "package.json" }}
- run: npm install - run: npm install
- save_cache: - save_cache:
key: dep-bundle-24-{{ checksum "package.json" }} key: dep-bundle-27-{{ checksum "package.json" }}
paths: paths:
- ~/repo/node_modules - ~/repo/node_modules
- run: npm run lint && npm run test && npm run make-mock-compiler && npm run build - run: npm run lint && npm run test && npm run make-mock-compiler && npm run build

@ -2,14 +2,18 @@
var fs = require('fs') var fs = require('fs')
var compiler = require('solc') var compiler = require('solc')
var compilerInput = require('remix-solidity').CompilerInput var compilerInput = require('remix-solidity').CompilerInput
var defaultVersion = 'v0.5.1+commit.c8a2cb62'
compiler.loadRemoteVersion(defaultVersion, (error, solcSnapshot) => {
if (error) console.log(error)
var compilationResult = {} var compilationResult = {}
gatherCompilationResults('./test-browser/tests/', compilationResult) gatherCompilationResults('./test-browser/tests/', compilationResult, solcSnapshot)
gatherCompilationResults('./test-browser/tests/units/', compilationResult) gatherCompilationResults('./test-browser/tests/units/', compilationResult, solcSnapshot)
replaceSolCompiler(compilationResult) replaceSolCompiler(compilationResult, solcSnapshot)
})
function gatherCompilationResults (dir, compilationResult, callback) { function gatherCompilationResults (dir, compilationResult, solcSnapshot) {
var filenames = fs.readdirSync(dir, 'utf8') var filenames = fs.readdirSync(dir, 'utf8')
filenames.map(function (item, i) { filenames.map(function (item, i) {
if (item.endsWith('.js')) { if (item.endsWith('.js')) {
@ -17,10 +21,10 @@ function gatherCompilationResults (dir, compilationResult, callback) {
if ('@sources' in testDef) { if ('@sources' in testDef) {
var sources = testDef['@sources']() var sources = testDef['@sources']()
for (var files in sources) { for (var files in sources) {
compile(sources[files], true, function (result) { compile(solcSnapshot, sources[files], true, function (result) {
compilationResult[result.key] = result compilationResult[result.key] = result
}) })
compile(sources[files], false, function (result) { compile(solcSnapshot, sources[files], false, function (result) {
compilationResult[result.key] = result compilationResult[result.key] = result
}) })
} }
@ -30,11 +34,11 @@ function gatherCompilationResults (dir, compilationResult, callback) {
return compilationResult return compilationResult
} }
function compile (source, optimization, addCompilationResult) { function compile (solcSnapshot, source, optimization, addCompilationResult) {
var missingInputs = [] var missingInputs = []
try { try {
var input = compilerInput(source, {optimize: optimization}) var input = compilerInput(source, {optimize: optimization})
var result = compiler.compileStandardWrapper(input, function (path) { var result = solcSnapshot.compileStandardWrapper(input, function (path) {
missingInputs.push(path) missingInputs.push(path)
}) })
input = input.replace(/(\t)|(\n)|(\\n)|( )/g, '') input = input.replace(/(\t)|(\n)|(\\n)|( )/g, '')
@ -51,15 +55,15 @@ function compile (source, optimization, addCompilationResult) {
addCompilationResult(ret) addCompilationResult(ret)
} }
function replaceSolCompiler (results) { function replaceSolCompiler (results, solcSnapshot) {
fs.readFile('./test-browser/mockcompiler/compiler.js', 'utf8', function (error, data) { fs.readFile('./test-browser/mockcompiler/compiler.js', 'utf8', function (error, data) {
if (error) { if (error) {
console.log(error) console.log(error)
process.exit(1) process.exit(1)
return return
} }
console.log(compiler.version()) console.log(solcSnapshot.version())
data = data + '\n\nvar mockCompilerVersion = \'' + compiler.version() + '\'' data = data + '\n\nvar mockCompilerVersion = \'' + solcSnapshot.version() + '\''
data = data + '\n\nvar mockData = ' + JSON.stringify(results) + ';\n' data = data + '\n\nvar mockData = ' + JSON.stringify(results) + ';\n'
fs.writeFile('./soljson.js', data, 'utf8', function (error) { fs.writeFile('./soljson.js', data, 'utf8', function (error) {
if (error) { if (error) {

@ -43,7 +43,7 @@
"remix-lib": "0.4.1", "remix-lib": "0.4.1",
"remix-solidity": "0.3.1", "remix-solidity": "0.3.1",
"remix-tests": "0.1.1", "remix-tests": "0.1.1",
"remixd": "git+https://github.com/ethereum/remixd.git", "remixd": "0.1.8-alpha.6",
"request": "^2.83.0", "request": "^2.83.0",
"rimraf": "^2.6.1", "rimraf": "^2.6.1",
"selenium-standalone": "^6.0.1", "selenium-standalone": "^6.0.1",
@ -61,7 +61,7 @@
}, },
"dependencies": { "dependencies": {
"http-server": "0.9.0", "http-server": "0.9.0",
"remixd": "git+https://github.com/ethereum/remixd.git" "remixd": "0.1.8-alpha.6"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
@ -156,7 +156,7 @@
"build_debugger": "browserify src/app/debugger/remix-debugger/index.js -o src/app/debugger/remix-debugger/build/app.js", "build_debugger": "browserify src/app/debugger/remix-debugger/index.js -o src/app/debugger/remix-debugger/build/app.js",
"browsertest": "sleep 5 && npm run nightwatch_local", "browsertest": "sleep 5 && npm run nightwatch_local",
"csslint": "csslint --ignore=order-alphabetical --errors='errors,duplicate-properties,empty-rules' --exclude-list='assets/css/font-awesome.min.css' assets/css/", "csslint": "csslint --ignore=order-alphabetical --errors='errors,duplicate-properties,empty-rules' --exclude-list='assets/css/font-awesome.min.css' assets/css/",
"downloadsolc_root": "wget --no-check-certificate https://solc-bin.ethereum.org/soljson.js", "downloadsolc_root": "wget --no-check-certificate https://solc-bin.ethereum.org/bin/soljson-v0.5.1+commit.c8a2cb62.js -O soljson.js",
"lint": "standard | notify-error", "lint": "standard | notify-error",
"make-mock-compiler": "node ci/makeMockCompiler.js", "make-mock-compiler": "node ci/makeMockCompiler.js",
"minify": "uglifyjs --in-source-map inline --source-map-inline -c warnings=false", "minify": "uglifyjs --in-source-map inline --source-map-inline -c warnings=false",

@ -1,12 +1,10 @@
'use strict' 'use strict'
var $ = require('jquery')
var csjs = require('csjs-inject') var csjs = require('csjs-inject')
var yo = require('yo-yo') var yo = require('yo-yo')
var async = require('async') var async = require('async')
var request = require('request') var request = require('request')
var remixLib = require('remix-lib') var remixLib = require('remix-lib')
var remixTests = require('remix-tests')
var EventManager = require('./lib/events') var EventManager = require('./lib/events')
var registry = require('./global/registry') var registry = require('./global/registry')
@ -14,18 +12,15 @@ var UniversalDApp = require('./universal-dapp.js')
var UniversalDAppUI = require('./universal-dapp-ui.js') var UniversalDAppUI = require('./universal-dapp-ui.js')
var Remixd = require('./lib/remixd') var Remixd = require('./lib/remixd')
var OffsetToLineColumnConverter = require('./lib/offsetToLineColumnConverter') var OffsetToLineColumnConverter = require('./lib/offsetToLineColumnConverter')
var QueryParams = require('./lib/query-params') var QueryParams = require('./lib/query-params')
var GistHandler = require('./lib/gist-handler') var GistHandler = require('./lib/gist-handler')
var helper = require('./lib/helper') var helper = require('./lib/helper')
var Storage = remixLib.Storage var Storage = remixLib.Storage
var Browserfiles = require('./app/files/browser-files') var Browserfiles = require('./app/files/browser-files')
var BrowserfilesTree = require('./app/files/browser-files-tree') var BrowserfilesTree = require('./app/files/browser-files-tree')
var chromeCloudStorageSync = require('./app/files/chromeCloudStorageSync')
var SharedFolder = require('./app/files/shared-folder') var SharedFolder = require('./app/files/shared-folder')
var Config = require('./config') var Config = require('./config')
var Renderer = require('./app/ui/renderer') var Renderer = require('./app/ui/renderer')
var Compiler = require('remix-solidity').Compiler
var executionContext = require('./execution-context') var executionContext = require('./execution-context')
var FilePanel = require('./app/panels/file-panel') var FilePanel = require('./app/panels/file-panel')
var EditorPanel = require('./app/panels/editor-panel') var EditorPanel = require('./app/panels/editor-panel')
@ -35,13 +30,22 @@ var modalDialogCustom = require('./app/ui/modal-dialog-custom')
var TxLogger = require('./app/execution/txLogger') var TxLogger = require('./app/execution/txLogger')
var Txlistener = remixLib.execution.txListener var Txlistener = remixLib.execution.txListener
var EventsDecoder = remixLib.execution.EventsDecoder var EventsDecoder = remixLib.execution.EventsDecoder
var CompilerImport = require('./app/compiler/compiler-imports')
var FileManager = require('./app/files/fileManager') var FileManager = require('./app/files/fileManager')
var BasicReadOnlyExplorer = require('./app/files/basicReadOnlyExplorer') var BasicReadOnlyExplorer = require('./app/files/basicReadOnlyExplorer')
var NotPersistedExplorer = require('./app/files/NotPersistedExplorer') var NotPersistedExplorer = require('./app/files/NotPersistedExplorer')
var toolTip = require('./app/ui/tooltip') var toolTip = require('./app/ui/tooltip')
var TransactionReceiptResolver = require('./transactionReceiptResolver') var TransactionReceiptResolver = require('./transactionReceiptResolver')
const CompilerAbstract = require('./app/compiler/compiler-abstract')
const PluginManager = require('./app/plugin/pluginManager')
const CompileTab = require('./app/tabs/compile-tab')
const SettingsTab = require('./app/tabs/settings-tab')
const AnalysisTab = require('./app/tabs/analysis-tab')
const DebuggerTab = require('./app/tabs/debugger-tab')
const SupportTab = require('./app/tabs/support-tab')
const TestTab = require('./app/tabs/test-tab')
const RunTab = require('./app/tabs/run-tab')
var styleGuide = require('./app/ui/styles-guide/theme-chooser') var styleGuide = require('./app/ui/styles-guide/theme-chooser')
var styles = styleGuide.chooser() var styles = styleGuide.chooser()
@ -126,8 +130,6 @@ class App {
executionContext.init(self._components.config) executionContext.init(self._components.config)
executionContext.listenOnLastBlock() executionContext.listenOnLastBlock()
self._components.compilerImport = new CompilerImport()
registry.put({api: self._components.compilerImport, name: 'compilerimport'})
self._components.gistHandler = new GistHandler() self._components.gistHandler = new GistHandler()
self._components.filesProviders = {} self._components.filesProviders = {}
@ -228,34 +230,6 @@ class App {
self._adjustLayout('right', self.data._layout.right.offset) self._adjustLayout('right', self.data._layout.right.offset)
return self._view.el return self._view.el
} }
runCompiler () {
const self = this
if (self._components.righthandpanel.debugger().isDebuggerActive()) return
self._components.fileManager.saveCurrentFile()
self._components.editorpanel.getEditor().clearAnnotations()
var currentFile = self._components.config.get('currentFile')
if (currentFile) {
if (/.(.sol)$/.exec(currentFile)) {
// only compile *.sol file.
var target = currentFile
var sources = {}
var provider = self._components.fileManager.fileProviderOf(currentFile)
if (provider) {
provider.get(target, (error, content) => {
if (error) {
console.log(error)
} else {
sources[target] = { content }
self._components.compiler.compile(sources, target)
}
})
} else {
console.log('cannot compile ' + currentFile + '. Does not belong to any explorer')
}
}
}
}
startdebugging (txHash) { startdebugging (txHash) {
const self = this const self = this
self.event.trigger('debuggingRequested', []) self.event.trigger('debuggingRequested', [])
@ -299,55 +273,6 @@ class App {
if (callback) callback(error) if (callback) callback(error)
}) })
} }
importExternal (url, cb) {
const self = this
self._components.compilerImport.import(url,
(loadingMsg) => {
toolTip(loadingMsg)
},
(error, content, cleanUrl, type, url) => {
if (!error) {
if (self._components.filesProviders[type]) {
self._components.filesProviders[type].addReadOnly(cleanUrl, content, url)
}
cb(null, content)
} else {
cb(error)
}
})
}
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) {
if (provider.type === 'localhost' && !provider.isConnected()) {
return filecb(`file provider ${provider.type} not available while trying to resolve ${url}`)
}
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
@ -377,24 +302,13 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
return 'Are you sure you want to leave?' return 'Are you sure you want to leave?'
} }
// Run the compiler instead of trying to save the website
$(window).keydown(function (e) {
// ctrl+s or command+s
if ((e.metaKey || e.ctrlKey) && e.keyCode === 83) {
e.preventDefault()
self.runCompiler()
}
})
registry.put({api: msg => self._components.editorpanel.logHtmlMessage(msg), name: 'logCallback'}) registry.put({api: msg => self._components.editorpanel.logHtmlMessage(msg), name: 'logCallback'})
// ----------------- Compiler ----------------- // helper for converting offset to line/column
self._components.compiler = new Compiler((url, cb) => self.importFileCb(url, cb)) var offsetToLineColumnConverter = new OffsetToLineColumnConverter()
registry.put({api: self._components.compiler, name: 'compiler'})
var offsetToLineColumnConverter = new OffsetToLineColumnConverter(self._components.compiler.event)
registry.put({api: offsetToLineColumnConverter, name: 'offsettolinecolumnconverter'}) registry.put({api: offsetToLineColumnConverter, name: 'offsettolinecolumnconverter'})
// json structure for hosting the last compilattion result
self._components.compilersArtefacts = {} // store all the possible compilation data (key represent a compiler name) self._components.compilersArtefacts = {} // store all the possible compilation data (key represent a compiler name)
registry.put({api: self._components.compilersArtefacts, name: 'compilersartefacts'}) registry.put({api: self._components.compilersArtefacts, name: 'compilersartefacts'})
@ -448,6 +362,23 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
var fileManager = self._components.fileManager var fileManager = self._components.fileManager
registry.put({api: fileManager, name: 'filemanager'}) registry.put({api: fileManager, name: 'filemanager'})
// ---------------- Plugin Manager -------------------------------
let pluginManager = new PluginManager(
self,
self._components.compilersArtefacts,
txlistener,
self._components.fileProviders,
self._components.fileManager,
udapp)
registry.put({api: pluginManager, name: 'pluginmanager'})
pluginManager.event.register('sendCompilationResult', (file, source, languageVersion, data) => {
// TODO check whether the tab is configured
let compiler = new CompilerAbstract(languageVersion, data, source)
self._components.compilersArtefacts['__last'] = compiler
})
self._components.editorpanel.init() self._components.editorpanel.init()
self._components.fileManager.init() self._components.fileManager.init()
@ -485,65 +416,28 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
var renderer = new Renderer() var renderer = new Renderer()
registry.put({api: renderer, name: 'renderer'}) registry.put({api: renderer, name: 'renderer'})
// ---------------- Tabs -------------------------------
let compileTab = new CompileTab(self._components.registry)
let tabs = {
compile: compileTab,
run: new RunTab(self._components.registry),
settings: new SettingsTab(self._components.registry),
analysis: new AnalysisTab(self._components.registry),
debug: new DebuggerTab(self._components.registry),
support: new SupportTab(self._components.registry),
test: new TestTab(self._components.registry, compileTab)
}
// ---------------- Righthand-panel -------------------- // ---------------- Righthand-panel --------------------
self._components.righthandpanel = new RighthandPanel() self._components.righthandpanel = new RighthandPanel({ tabs, pluginManager })
self._view.rightpanel.appendChild(self._components.righthandpanel.render()) self._view.rightpanel.appendChild(self._components.righthandpanel.render())
self._components.righthandpanel.init() self._components.righthandpanel.init()
self._components.righthandpanel.event.register('resize', delta => self._adjustLayout('right', delta)) self._components.righthandpanel.event.register('resize', delta => self._adjustLayout('right', delta))
var txLogger = new TxLogger() // eslint-disable-line var txLogger = new TxLogger() // eslint-disable-line
executionContext.event.register('contextChanged', this, function (context) {
self.runCompiler()
})
// rerun the compiler when the environement changed
executionContext.event.register('web3EndpointChanged', this, function (context) {
self.runCompiler()
})
var queryParams = new QueryParams() var queryParams = new QueryParams()
// check init query parameters from the URL once the compiler is loaded
self._components.compiler.event.register('compilerLoaded', this, function (version) {
self.runCompiler()
if (queryParams.get().context) {
let context = queryParams.get().context
let endPointUrl = queryParams.get().endPointUrl
executionContext.setContext(context, endPointUrl,
() => {
modalDialogCustom.confirm(null, 'Are you sure you want to connect to an ethereum node?', () => {
if (!endPointUrl) {
endPointUrl = 'http://localhost:8545'
}
modalDialogCustom.prompt(null, 'Web3 Provider Endpoint', endPointUrl, (target) => {
executionContext.setProviderFromEndpoint(target, context)
}, () => {})
}, () => {})
},
(alertMsg) => {
modalDialogCustom.alert(alertMsg)
})
}
if (queryParams.get().debugtx) {
self.startdebugging(queryParams.get().debugtx)
}
if (queryParams.get().pluginurl) {
var title = queryParams.get().plugintitle
var url = queryParams.get().pluginurl
modalDialogCustom.confirm(null, `Remix is going to load the extension "${title}" located at ${queryParams.get().pluginurl}. Are you sure to load this external extension?`, () => {
self._components.righthandpanel.loadPlugin({title, url})
})
}
})
// chrome app
window.syncStorage = chromeCloudStorageSync
chromeCloudStorageSync()
var loadingFromGist = self.loadFromGist(queryParams.get()) var loadingFromGist = self.loadFromGist(queryParams.get())
if (!loadingFromGist) { if (!loadingFromGist) {
// insert ballot contract if there are no files to show // insert ballot contract if there are no files to show

@ -3,9 +3,10 @@ var remixLib = require('remix-lib')
var txHelper = remixLib.execution.txHelper var txHelper = remixLib.execution.txHelper
module.exports = class CompilerAbstract { module.exports = class CompilerAbstract {
constructor (languageversion, data) { constructor (languageversion, data, source) {
this.languageversion = languageversion this.languageversion = languageversion
this.data = data this.data = data
this.source = source // source code
} }
getContracts () { getContracts () {
@ -23,4 +24,19 @@ module.exports = class CompilerAbstract {
getData () { getData () {
return this.data return this.data
} }
getAsts () {
return this.data.sources // ast
}
getSourceName (fileIndex) {
if (this.data && this.data.sources) {
return Object.keys(this.data.sources)[fileIndex]
}
return null
}
getSourceCode () {
return this.source
}
} }

@ -90,16 +90,10 @@ class DebuggerUI {
this.contextManager = new ContextManager() this.contextManager = new ContextManager()
this.debugger = new Debugger({
web3: this.contextManager.getWeb3(),
offsetToLineColumnConverter: this.registry.get('offsettolinecolumnconverter').api,
compiler: this.registry.get('compiler').api
})
this.contextManager.initProviders() this.contextManager.initProviders()
this.contextManager.event.register('providerChanged', () => { this.contextManager.event.register('providerChanged', () => {
this.debugger.updateWeb3(this.contextManager.getWeb3()) if (this.debugger) this.debugger.updateWeb3(this.contextManager.getWeb3())
}) })
this.isActive = false this.isActive = false
@ -116,7 +110,6 @@ class DebuggerUI {
container.appendChild(this.render()) container.appendChild(this.render())
this.setEditor() this.setEditor()
this.listenToEvents()
} }
setEditor () { setEditor () {
@ -124,20 +117,22 @@ class DebuggerUI {
this.editor = this.registry.get('editor').api this.editor = this.registry.get('editor').api
self.editor.event.register('breakpointCleared', (fileName, row) => { self.editor.event.register('breakpointCleared', (fileName, row) => {
self.debugger.breakPointManager.remove({fileName: fileName, row: row}) if (self.debugger) self.debugger.breakPointManager.remove({fileName: fileName, row: row})
}) })
self.editor.event.register('breakpointAdded', (fileName, row) => { self.editor.event.register('breakpointAdded', (fileName, row) => {
self.debugger.breakPointManager.add({fileName: fileName, row: row}) if (self.debugger) self.debugger.breakPointManager.add({fileName: fileName, row: row})
}) })
self.editor.event.register('contentChanged', function () { self.editor.event.register('contentChanged', function () {
self.debugger.unload() if (self.debugger) self.debugger.unload()
}) })
} }
listenToEvents () { listenToEvents () {
const self = this const self = this
if (!self.debugger) return
this.debugger.event.register('debuggerStatus', function (isActive) { this.debugger.event.register('debuggerStatus', function (isActive) {
self.sourceHighlighter.currentSourceLocation(null) self.sourceHighlighter.currentSourceLocation(null)
self.isActive = isActive self.isActive = isActive
@ -156,12 +151,12 @@ class DebuggerUI {
this.txBrowser = txBrowser this.txBrowser = txBrowser
txBrowser.event.register('requestDebug', function (blockNumber, txNumber, tx) { txBrowser.event.register('requestDebug', function (blockNumber, txNumber, tx) {
self.debugger.unload() if (self.debugger) self.debugger.unload()
self.startDebugging(blockNumber, txNumber, tx) self.startDebugging(blockNumber, txNumber, tx)
}) })
txBrowser.event.register('unloadRequested', this, function (blockNumber, txIndex, tx) { txBrowser.event.register('unloadRequested', this, function (blockNumber, txIndex, tx) {
self.debugger.unload() if (self.debugger) self.debugger.unload()
}) })
} }
@ -171,6 +166,20 @@ class DebuggerUI {
startDebugging (blockNumber, txNumber, tx) { startDebugging (blockNumber, txNumber, tx) {
const self = this const self = this
if (this.debugger) delete this.debugger
let compilers = this.registry.get('compilersartefacts').api
let lastCompilationResult
if (compilers['__last']) lastCompilationResult = compilers['__last']
// TODO debugging with source highlight is disabled. see line 98
this.debugger = new Debugger({
web3: this.contextManager.getWeb3(),
offsetToLineColumnConverter: this.registry.get('offsettolinecolumnconverter').api,
compiler: { lastCompilationResult }
})
this.listenToEvents()
this.debugger.debugger.updateWeb3(this.executionContext.web3()) this.debugger.debugger.updateWeb3(this.executionContext.web3())
this.debugger.debug(blockNumber, txNumber, tx, () => { this.debugger.debug(blockNumber, txNumber, tx, () => {

@ -21,7 +21,7 @@ class ContextView {
self.contextualListener = opts.contextualListener self.contextualListener = opts.contextualListener
self.editor = opts.editor self.editor = opts.editor
self._deps = { self._deps = {
compiler: self._components.registry.get('compiler').api, compilersArtefacts: self._components.registry.get('compilersartefacts').api,
offsetToLineColumnConverter: self._components.registry.get('offsettolinecolumnconverter').api, offsetToLineColumnConverter: self._components.registry.get('offsettolinecolumnconverter').api,
config: self._components.registry.get('config').api, config: self._components.registry.get('config').api,
fileManager: self._components.registry.get('filemanager').api fileManager: self._components.registry.get('filemanager').api
@ -97,9 +97,14 @@ class ContextView {
self.editor.gotoLine(lineColumn.start.line, lineColumn.end.column + 1) self.editor.gotoLine(lineColumn.start.line, lineColumn.end.column + 1)
} }
} }
if (self._deps.compiler.lastCompilationResult && self._deps.compiler.lastCompilationResult.data) { let lastCompilationResult = self._deps.compilersArtefacts['__last']
var lineColumn = self._deps.offsetToLineColumnConverter.offsetToLineColumn(position, position.file, self._deps.compiler.lastCompilationResult.source.sources, self._deps.compiler.lastCompilationResult.data.sources) if (lastCompilationResult && lastCompilationResult.data) {
var filename = self._deps.compiler.getSourceName(position.file) var lineColumn = self._deps.offsetToLineColumnConverter.offsetToLineColumn(
position,
position.file,
lastCompilationResult.getSourceCode().sources,
lastCompilationResult.getAsts())
var filename = lastCompilationResult.getSourceName(position.file)
// TODO: refactor with rendererAPI.errorClick // TODO: refactor with rendererAPI.errorClick
if (filename !== self._deps.config.get('currentFile')) { if (filename !== self._deps.config.get('currentFile')) {
var provider = self._deps.fileManager.fileProviderOf(filename) var provider = self._deps.fileManager.fileProviderOf(filename)

@ -15,8 +15,9 @@ class ContextualListener {
self._components = {} self._components = {}
self._components.registry = localRegistry || globalRegistry self._components.registry = localRegistry || globalRegistry
self.editor = opts.editor self.editor = opts.editor
self.pluginManager = opts.pluginManager
self._deps = { self._deps = {
compiler: self._components.registry.get('compiler').api, compilersArtefacts: self._components.registry.get('compilersartefacts').api,
config: self._components.registry.get('config').api, config: self._components.registry.get('config').api,
offsetToLineColumnConverter: self._components.registry.get('offsettolinecolumnconverter').api offsetToLineColumnConverter: self._components.registry.get('offsettolinecolumnconverter').api
} }
@ -26,15 +27,13 @@ class ContextualListener {
} }
this._activeHighlights = [] this._activeHighlights = []
self._deps.compiler.event.register('compilationFinished', (success, data, source) => { self.pluginManager.event.register('sendCompilationResult', (file, source, languageVersion, data) => {
this._stopHighlighting() this._stopHighlighting()
this._index = { this._index = {
Declarations: {}, Declarations: {},
FlatReferences: {} FlatReferences: {}
} }
if (success) {
this._buildIndex(data, source) this._buildIndex(data, source)
}
}) })
self.editor.event.register('contentChanged', () => { this._stopHighlighting() }) self.editor.event.register('contentChanged', () => { this._stopHighlighting() })
@ -42,7 +41,9 @@ class ContextualListener {
this.sourceMappingDecoder = new SourceMappingDecoder() this.sourceMappingDecoder = new SourceMappingDecoder()
this.astWalker = new AstWalker() this.astWalker = new AstWalker()
setInterval(() => { setInterval(() => {
this._highlightItems(self.editor.getCursorPosition(), self._deps.compiler.lastCompilationResult, self._deps.config.get('currentFile')) if (self._deps.compilersArtefacts['__last']) {
this._highlightItems(self.editor.getCursorPosition(), self._deps.compilersArtefacts['__last'], self._deps.config.get('currentFile'))
}
}, 1000) }, 1000)
} }
@ -106,15 +107,17 @@ class ContextualListener {
var self = this var self = this
var position = this.sourceMappingDecoder.decode(node.src) var position = this.sourceMappingDecoder.decode(node.src)
var eventId = this._highlightInternal(position, node) var eventId = this._highlightInternal(position, node)
if (eventId) { let lastCompilationResult = self._deps.compilersArtefacts['__last']
this._activeHighlights.push({ eventId, position, fileTarget: self._deps.compiler.getSourceName(position.file), nodeId: node.id }) if (eventId && lastCompilationResult) {
this._activeHighlights.push({ eventId, position, fileTarget: lastCompilationResult.getSourceName(position.file), nodeId: node.id })
} }
} }
_highlightInternal (position, node) { _highlightInternal (position, node) {
var self = this var self = this
if (self._deps.compiler.lastCompilationResult && self._deps.compiler.lastCompilationResult.data) { let lastCompilationResult = self._deps.compilersArtefacts['__last']
var lineColumn = self._deps.offsetToLineColumnConverter.offsetToLineColumn(position, position.file, self._deps.compiler.lastCompilationResult.source.sources, self._deps.compiler.lastCompilationResult.data.sources) if (lastCompilationResult) {
var lineColumn = self._deps.offsetToLineColumnConverter.offsetToLineColumn(position, position.file, lastCompilationResult.getSourceCode().sources, lastCompilationResult.getAsts())
var css = 'highlightreference' var css = 'highlightreference'
if (node.children && node.children.length) { if (node.children && node.children.length) {
// If node has children, highlight the entire line. if not, just highlight the current source position of the node. // If node has children, highlight the entire line. if not, just highlight the current source position of the node.
@ -130,7 +133,7 @@ class ContextualListener {
} }
} }
} }
var fileName = self._deps.compiler.getSourceName(position.file) var fileName = lastCompilationResult.getSourceName(position.file)
if (fileName) { if (fileName) {
return self.editor.addMarker(lineColumn, fileName, css) return self.editor.addMarker(lineColumn, fileName, css)
} }

@ -14,7 +14,7 @@ class SourceHighlighter {
editor: self._components.registry.get('editor').api, editor: self._components.registry.get('editor').api,
config: self._components.registry.get('config').api, config: self._components.registry.get('config').api,
fileManager: self._components.registry.get('filemanager').api, fileManager: self._components.registry.get('filemanager').api,
compiler: self._components.registry.get('compiler').api compilerArtefacts: self._components.registry.get('compilersartefacts').api
} }
this.statementMarker = null this.statementMarker = null
this.fullLineMarker = null this.fullLineMarker = null
@ -24,8 +24,9 @@ class SourceHighlighter {
currentSourceLocation (lineColumnPos, location) { currentSourceLocation (lineColumnPos, location) {
if (this.statementMarker) this._deps.editor.removeMarker(this.statementMarker, this.source) if (this.statementMarker) this._deps.editor.removeMarker(this.statementMarker, this.source)
if (this.fullLineMarker) this._deps.editor.removeMarker(this.fullLineMarker, this.source) if (this.fullLineMarker) this._deps.editor.removeMarker(this.fullLineMarker, this.source)
if (location && location.file !== undefined) { let lastCompilationResult = this._deps.compilerArtefacts['__last']
var path = this._deps.compiler.getSourceName(location.file) if (location && location.file !== undefined && lastCompilationResult) {
var path = lastCompilationResult.getSourceName(location.file)
if (path) { if (path) {
this.currentSourceLocationFromfileName(lineColumnPos, path) this.currentSourceLocationFromfileName(lineColumnPos, path)
} }

@ -142,7 +142,7 @@ class TxLogger {
editorPanel: this._components.registry.get('editorpanel').api, editorPanel: this._components.registry.get('editorpanel').api,
txListener: this._components.registry.get('txlistener').api, txListener: this._components.registry.get('txlistener').api,
eventsDecoder: this._components.registry.get('eventsdecoder').api, eventsDecoder: this._components.registry.get('eventsdecoder').api,
compiler: this._components.registry.get('compiler').api, compilersArtefacts: this._components.registry.get('compilersartefacts').api,
app: this._components.registry.get('app').api app: this._components.registry.get('app').api
} }
@ -216,8 +216,8 @@ function log (self, tx, receipt) {
var resolvedTransaction = self._deps.txListener.resolvedTransaction(tx.hash) var resolvedTransaction = self._deps.txListener.resolvedTransaction(tx.hash)
if (resolvedTransaction) { if (resolvedTransaction) {
var compiledContracts = null var compiledContracts = null
if (self._deps.compiler.lastCompilationResult && self._deps.compiler.lastCompilationResult.data) { if (self._deps.compilersArtefacts['__last']) {
compiledContracts = self._deps.compiler.lastCompilationResult.data.contracts compiledContracts = self._deps.compilersArtefacts['__last'].getContracts()
} }
self._deps.eventsDecoder.parseLogs(tx, resolvedTransaction.contractName, compiledContracts, (error, logs) => { self._deps.eventsDecoder.parseLogs(tx, resolvedTransaction.contractName, compiledContracts, (error, logs) => {
if (!error) { if (!error) {

@ -1,64 +0,0 @@
/* global chrome */
'use strict'
var modalDialogCustom = require('../ui/modal-dialog-custom')
module.exports = function (filesProviders) {
if (typeof chrome === 'undefined' || !chrome || !chrome.storage || !chrome.storage.sync) {
return
}
var obj = {}
var done = false
var count = 0
function check (key) {
chrome.storage.sync.get(key, function (resp) {
console.log('comparing to cloud', key, resp)
function confirmDialog (callback) {
modalDialogCustom.confirm('', 'Overwrite "' + key + '"? Click Ok to overwrite local file with file from cloud. Cancel will push your local file to the cloud.', () => { callback(true) }, () => { callback(false) })
}
if (typeof resp[key] !== 'undefined' && obj[key] !== resp[key]) {
confirmDialog((result) => {
if (result) {
console.log('Overwriting', key)
filesProviders['browser'].set(key, resp[key])
}
})
} else {
console.log('add to obj', obj, key)
filesProviders['browser'].get(key, (error, content) => {
if (error) {
console.log(error)
} else {
obj[key] = content
}
})
}
done++
if (done >= count) {
chrome.storage.sync.set(obj, function () {
console.log('updated cloud files with: ', obj, this, arguments)
})
}
})
}
filesProviders['browser'].resolve('browser', (error, files) => {
if (!error) {
Object.keys(files).forEach((path) => {
filesProviders['browser'].get(path, (error, content) => {
if (error) {
console.log(error)
} else {
obj[path] = content
count++
check(path)
}
})
})
}
})
}

@ -1,23 +1,23 @@
'use strict' 'use strict'
var executionContext = require('../../execution-context') var executionContext = require('../../execution-context')
var CompilerAbstract = require('../compiler/compiler-abstract')
class CompilerMetadata { class CompilerMetadata {
constructor (events, opts) { constructor (opts) {
var self = this var self = this
self._events = events
self._opts = opts self._opts = opts
self.networks = ['VM:-', 'main:1', 'ropsten:3', 'rinkeby:4', 'kovan:42', 'Custom'] self.networks = ['VM:-', 'main:1', 'ropsten:3', 'rinkeby:4', 'kovan:42', 'Custom']
} }
syncContractMetadata () { syncContractMetadata () {
var self = this var self = this
self._events.compiler.register('compilationFinished', (success, data, source) => { self._opts.pluginManager.event.register('sendCompilationResult', (file, source, languageVersion, data) => {
if (!success) return
if (!self._opts.config.get('settings/generate-contract-metadata')) return if (!self._opts.config.get('settings/generate-contract-metadata')) return
let compiler = new CompilerAbstract(languageVersion, data, source)
var provider = self._opts.fileManager.currentFileProvider() var provider = self._opts.fileManager.currentFileProvider()
var path = self._opts.fileManager.currentPath() var path = self._opts.fileManager.currentPath()
if (provider && path) { if (provider && path) {
self._opts.compiler.visitContracts((contract) => { compiler.visitContracts((contract) => {
if (contract.file !== source.target) return if (contract.file !== source.target) return
var fileName = path + '/' + contract.name + '.json' var fileName = path + '/' + contract.name + '.json'

@ -4,6 +4,7 @@ var $ = require('jquery')
var yo = require('yo-yo') var yo = require('yo-yo')
var EventManager = require('../../lib/events') var EventManager = require('../../lib/events')
var globalRegistry = require('../../global/registry') var globalRegistry = require('../../global/registry')
var CompilerImport = require('../compiler/compiler-imports')
/* /*
attach to files event (removed renamed) attach to files event (removed renamed)
@ -15,13 +16,13 @@ class FileManager {
this.tabbedFiles = {} this.tabbedFiles = {}
this.event = new EventManager() this.event = new EventManager()
this._components = {} this._components = {}
this._components.compilerImport = new CompilerImport()
this._components.registry = localRegistry || globalRegistry this._components.registry = localRegistry || globalRegistry
} }
init () { init () {
var self = this var self = this
self._deps = { self._deps = {
compilerImport: self._components.registry.get('compilerimport').api,
editor: self._components.registry.get('editor').api, editor: self._components.registry.get('editor').api,
config: self._components.registry.get('config').api, config: self._components.registry.get('config').api,
browserExplorer: self._components.registry.get('fileproviders/browser').api, browserExplorer: self._components.registry.get('fileproviders/browser').api,
@ -182,7 +183,7 @@ class FileManager {
if (provider !== null && this._deps.filesProviders[provider[0]]) { if (provider !== null && this._deps.filesProviders[provider[0]]) {
return this._deps.filesProviders[provider[0]] return this._deps.filesProviders[provider[0]]
} else { } else {
for (var handler of this._deps.compilerImport.handlers()) { for (var handler of this._components.compilerImport.handlers()) {
if (handler.match.exec(file)) { if (handler.match.exec(file)) {
return this._deps.filesProviders[handler.type] return this._deps.filesProviders[handler.type]
} }

@ -26,7 +26,7 @@ class EditorPanel {
txListener: self._components.registry.get('txlistener').api, txListener: self._components.registry.get('txlistener').api,
fileManager: self._components.registry.get('filemanager').api, fileManager: self._components.registry.get('filemanager').api,
udapp: self._components.registry.get('udapp').api, udapp: self._components.registry.get('udapp').api,
compiler: self._components.registry.get('compiler').api pluginManager: self._components.registry.get('pluginmanager').api
} }
self.data = { self.data = {
_FILE_SCROLL_DELTA: 200, _FILE_SCROLL_DELTA: 200,
@ -40,16 +40,18 @@ class EditorPanel {
self._view = {} self._view = {}
var editor = new Editor({}) var editor = new Editor({})
self._components.registry.put({api: editor, name: 'editor'}) self._components.registry.put({api: editor, name: 'editor'})
var contextualListener = new ContextualListener({editor: editor})
var contextualListener = new ContextualListener({editor, pluginManager: self._deps.pluginManager})
var contextView = new ContextView({contextualListener, editor})
self._components = { self._components = {
editor: editor, editor: editor,
contextualListener: contextualListener, contextualListener: contextualListener,
contextView: new ContextView({contextualListener: contextualListener, editor: editor}), contextView: contextView,
// TODO list of compilers is always empty; should find a path to add plugin compiler here
terminal: new Terminal({ terminal: new Terminal({
udapp: self._deps.udapp, udapp: self._deps.udapp,
compilers: { compilers: {}
'solidity': self._deps.compiler
}
}, },
{ {
getPosition: (event) => { getPosition: (event) => {

@ -49,7 +49,7 @@ function filepanel (localRegistry) {
fileProviders: self._components.registry.get('fileproviders').api, fileProviders: self._components.registry.get('fileproviders').api,
fileManager: self._components.registry.get('filemanager').api, fileManager: self._components.registry.get('filemanager').api,
config: self._components.registry.get('config').api, config: self._components.registry.get('config').api,
compiler: self._components.registry.get('compiler').api pluginManager: self._components.registry.get('pluginmanager').api
} }
var fileExplorer = new FileExplorer(self._components.registry, self._deps.fileProviders['browser']) var fileExplorer = new FileExplorer(self._components.registry, self._deps.fileProviders['browser'])
var fileSystemExplorer = new FileExplorer(self._components.registry, self._deps.fileProviders['localhost']) var fileSystemExplorer = new FileExplorer(self._components.registry, self._deps.fileProviders['localhost'])
@ -62,12 +62,9 @@ function filepanel (localRegistry) {
// ----------------- editor panel ---------------------- // ----------------- editor panel ----------------------
self._compilerMetadata = new CompilerMetadata( self._compilerMetadata = new CompilerMetadata(
{
compiler: self._deps.compiler.event
},
{ {
fileManager: self._deps.fileManager, fileManager: self._deps.fileManager,
compiler: self._deps.compiler, pluginManager: self._deps.pluginManager,
config: self._deps.config config: self._deps.config
} }
) )

@ -5,22 +5,14 @@ const EventManager = require('../../lib/events')
var globalRegistry = require('../../global/registry') var globalRegistry = require('../../global/registry')
const styleguide = require('../ui/styles-guide/theme-chooser') const styleguide = require('../ui/styles-guide/theme-chooser')
const PluginManager = require('../plugin/pluginManager')
const TabbedMenu = require('../tabs/tabbed-menu') const TabbedMenu = require('../tabs/tabbed-menu')
const CompileTab = require('../tabs/compile-tab')
const SettingsTab = require('../tabs/settings-tab')
const AnalysisTab = require('../tabs/analysis-tab')
const DebuggerTab = require('../tabs/debugger-tab')
const SupportTab = require('../tabs/support-tab')
const PluginTab = require('../tabs/plugin-tab') const PluginTab = require('../tabs/plugin-tab')
const TestTab = require('../tabs/test-tab')
const RunTab = require('../tabs/run-tab')
const DraggableContent = require('../ui/draggableContent') const DraggableContent = require('../ui/draggableContent')
const styles = styleguide.chooser() const styles = styleguide.chooser()
module.exports = class RighthandPanel { module.exports = class RighthandPanel {
constructor (localRegistry) { constructor ({pluginManager, tabs}, localRegistry) {
const self = this const self = this
self._components = {} self._components = {}
self._components.registry = localRegistry || globalRegistry self._components.registry = localRegistry || globalRegistry
@ -33,57 +25,25 @@ module.exports = class RighthandPanel {
dragbar: null dragbar: null
} }
self._deps = {
fileProviders: self._components.registry.get('fileproviders').api,
fileManager: self._components.registry.get('filemanager').api,
compiler: self._components.registry.get('compiler').api,
udapp: self._components.registry.get('udapp').api,
app: self._components.registry.get('app').api,
txlistener: self._components.registry.get('txlistener').api
}
var tabbedMenu = new TabbedMenu(self._components.registry) var tabbedMenu = new TabbedMenu(self._components.registry)
var pluginManager = new PluginManager(
self._deps.app,
self._deps.compiler,
self._deps.txlistener,
self._deps.fileProviders,
self._deps.fileManager,
self._deps.udapp
)
self._components.registry.put({api: pluginManager, name: 'pluginmanager'})
var analysisTab = new AnalysisTab(self._components.registry)
analysisTab.event.register('newStaticAnaysisWarningMessage', (msg, settings) => { self._components.compile.addWarning(msg, settings) })
self._components.debuggerTab = new DebuggerTab(self._components.registry)
self._components = { self._components = {
pluginManager: pluginManager,
tabbedMenu: tabbedMenu, tabbedMenu: tabbedMenu,
compile: new CompileTab(self._components.registry), tabs
run: new RunTab(self._components.registry),
settings: new SettingsTab(self._components.registry),
analysis: analysisTab,
debug: self._components.debuggerTab,
support: new SupportTab(self._components.registry),
test: new TestTab(self._components.registry)
} }
self._components.settings.event.register('plugin-loadRequest', json => { self._components.tabs.settings.event.register('plugin-loadRequest', json => {
self.loadPlugin(json) self.loadPlugin(json)
}) })
self.loadPlugin = function (json) { self.loadPlugin = function (json) {
var modal = new DraggableContent(() => { var modal = new DraggableContent(() => {
self._components.pluginManager.unregister(json) pluginManager.unregister(json)
}) })
var tab = new PluginTab(json) var tab = new PluginTab(json)
var content = tab.render() var content = tab.render()
document.querySelector('body').appendChild(modal.render(json.title, json.url, content)) document.querySelector('body').appendChild(modal.render(json.title, json.url, content))
self._components.pluginManager.register(json, modal, content) pluginManager.register(json, modal, content)
} }
self._view.dragbar = yo`<div id="dragbar" class=${css.dragbar}></div>` self._view.dragbar = yo`<div id="dragbar" class=${css.dragbar}></div>`
@ -96,7 +56,7 @@ module.exports = class RighthandPanel {
</div> </div>
</div>` </div>`
const { compile, run, settings, analysis, debug, support, test } = self._components const { compile, run, settings, analysis, debug, support, test } = tabs
self._components.tabbedMenu.addTab('Compile', 'compileView', compile.render()) self._components.tabbedMenu.addTab('Compile', 'compileView', compile.render())
self._components.tabbedMenu.addTab('Run', 'runView', run.render()) self._components.tabbedMenu.addTab('Run', 'runView', run.render())
self._components.tabbedMenu.addTab('Analysis', 'staticanalysisView', analysis.render()) self._components.tabbedMenu.addTab('Analysis', 'staticanalysisView', analysis.render())
@ -106,11 +66,7 @@ module.exports = class RighthandPanel {
self._components.tabbedMenu.addTab('Support', 'supportView', support.render()) self._components.tabbedMenu.addTab('Support', 'supportView', support.render())
self._components.tabbedMenu.selectTabByTitle('Compile') self._components.tabbedMenu.selectTabByTitle('Compile')
} }
// showDebugger () {
// const self = this
// if (!self._components.tabbedMenu) return
// self._components.tabbedMenu.selectTab(self._view.el.querySelector('li.debugView'))
// }
render () { render () {
const self = this const self = this
if (self._view.element) return self._view.element if (self._view.element) return self._view.element
@ -118,7 +74,7 @@ module.exports = class RighthandPanel {
} }
debugger () { debugger () {
return this._components.debug.debugger() return this._components.tabs.debug.debugger()
} }
focusOn (x) { focusOn (x) {

@ -4,7 +4,7 @@ var SourceHighlighter = require('../editor/sourceHighlighter')
/* /*
Defines available API. `key` / `type` Defines available API. `key` / `type`
*/ */
module.exports = (pluginManager, fileProviders, fileManager, compiler, udapp) => { module.exports = (pluginManager, fileProviders, fileManager, compilesrArtefacts, udapp) => {
let highlighters = {} let highlighters = {}
return { return {
app: { app: {
@ -51,7 +51,7 @@ module.exports = (pluginManager, fileProviders, fileManager, compiler, udapp) =>
}, },
compiler: { compiler: {
getCompilationResult: (mod, cb) => { getCompilationResult: (mod, cb) => {
cb(null, compiler.lastCompilationResult) cb(null, compilesrArtefacts['__last'])
}, },
sendCompilationResult: (mod, file, source, languageVersion, data, cb) => { sendCompilationResult: (mod, file, source, languageVersion, data, cb) => {
pluginManager.receivedDataFrom('sendCompilationResult', mod, [file, source, languageVersion, data]) pluginManager.receivedDataFrom('sendCompilationResult', mod, [file, source, languageVersion, data])

@ -79,14 +79,14 @@ const PluginAPI = require('./pluginAPI')
* *
*/ */
module.exports = class PluginManager { module.exports = class PluginManager {
constructor (app, compiler, txlistener, fileProviders, fileManager, udapp) { constructor (app, compilersArtefacts, txlistener, fileProviders, fileManager, udapp) {
const self = this const self = this
self.event = new EventManager() self.event = new EventManager()
var pluginAPI = new PluginAPI( var pluginAPI = new PluginAPI(
this, this,
fileProviders, fileProviders,
fileManager, fileManager,
compiler, compilersArtefacts,
udapp udapp
) )
self._components = { pluginAPI } self._components = { pluginAPI }
@ -101,14 +101,6 @@ module.exports = class PluginManager {
value: [ file ] value: [ file ]
})) }))
}) })
compiler.event.register('compilationFinished', (success, data, source) => {
self.broadcast(JSON.stringify({
action: 'notification',
key: 'compiler',
type: 'compilationFinished',
value: [ success, data, source ]
}))
})
txlistener.event.register('newTransaction', (tx) => { txlistener.event.register('newTransaction', (tx) => {
self.broadcast(JSON.stringify({ self.broadcast(JSON.stringify({
@ -119,38 +111,6 @@ module.exports = class PluginManager {
})) }))
}) })
app.event.register('tabChanged', (tabName) => {
// TODO Fix this cause this event is no longer triggered
if (self.inFocus && self.inFocus !== tabName) {
// trigger unfocus
self.post(self.inFocus, JSON.stringify({
action: 'notification',
key: 'app',
type: 'unfocus',
value: []
}))
}
if (self.plugins[tabName]) {
// trigger focus
self.post(tabName, JSON.stringify({
action: 'notification',
key: 'app',
type: 'focus',
value: []
}))
self.inFocus = tabName
pluginAPI.compiler.getCompilationResult(tabName, (error, data) => {
if (!error) return
self.post(tabName, JSON.stringify({
action: 'notification',
key: 'compiler',
type: 'compilationData',
value: [data]
}))
})
}
})
window.addEventListener('message', (event) => { window.addEventListener('message', (event) => {
if (event.type !== 'message') return if (event.type !== 'message') return
var extension = self.origins[event.origin] var extension = self.origins[event.origin]
@ -202,7 +162,13 @@ module.exports = class PluginManager {
receivedDataFrom (methodName, mod, argumentsArray) { receivedDataFrom (methodName, mod, argumentsArray) {
// TODO check whether 'mod' as right to do that // TODO check whether 'mod' as right to do that
console.log(argumentsArray) console.log(argumentsArray)
this.event.trigger(methodName, argumentsArray) this.event.trigger(methodName, argumentsArray) // forward to internal modules
this.broadcast(JSON.stringify({ // forward to plugins
action: 'notification',
key: mod,
type: methodName,
value: argumentsArray
}))
} }
post (name, value) { post (name, value) {
const self = this const self = this

@ -25,22 +25,20 @@ function staticAnalysisView (localRegistry) {
self._components.registry = localRegistry || globlalRegistry self._components.registry = localRegistry || globlalRegistry
// dependencies // dependencies
self._deps = { self._deps = {
compiler: self._components.registry.get('compiler').api, pluginManager: self._components.registry.get('pluginmanager').api,
renderer: self._components.registry.get('renderer').api, renderer: self._components.registry.get('renderer').api,
offsetToLineColumnConverter: self._components.registry.get('offsettolinecolumnconverter').api offsetToLineColumnConverter: self._components.registry.get('offsettolinecolumnconverter').api
} }
self._deps.compiler.event.register('compilationFinished', function (success, data, source) { self._deps.pluginManager.event.register('sendCompilationResult', (file, source, languageVersion, data) => {
self.lastCompilationResult = null self.lastCompilationResult = null
self.lastCompilationSource = null self.lastCompilationSource = null
$('#staticanalysisresult').empty() $('#staticanalysisresult').empty()
if (success) {
self.lastCompilationResult = data self.lastCompilationResult = data
self.lastCompilationSource = source self.lastCompilationSource = source
if (self.view.querySelector('#autorunstaticanalysis').checked) { if (self.view.querySelector('#autorunstaticanalysis').checked) {
self.run() self.run()
} }
}
}) })
} }
@ -113,7 +111,10 @@ staticAnalysisView.prototype.run = function () {
start: parseInt(split[0]), start: parseInt(split[0]),
length: parseInt(split[1]) length: parseInt(split[1])
} }
location = self._deps.offsetToLineColumnConverter.offsetToLineColumn(location, parseInt(file), self._deps.compiler.lastCompilationResult.source.sources, self._deps.compiler.lastCompilationResult.data.sources) location = self._deps.offsetToLineColumnConverter.offsetToLineColumn(location,
parseInt(file),
self.lastCompilationSource.sources,
self.lastCompilationResult.sources)
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++

@ -13,17 +13,15 @@ module.exports = class AnalysisTab {
self.data = {} self.data = {}
self._components = {} self._components = {}
self._components.registry = localRegistry || globalRegistry self._components.registry = localRegistry || globalRegistry
self._deps = { self._deps = {}
rightHandPanel: self._components.registry.get('righthandpanel').api
}
} }
render () { render () {
const self = this const self = this
var staticanalysis = new StaticAnalysis() var staticanalysis = new StaticAnalysis()
staticanalysis.event.register('staticAnaysisWarning', (count) => { staticanalysis.event.register('staticAnaysisWarning', (count) => {
if (count > 0) { if (count > 0) {
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. Check Solidity Static Analysis Module for more information.`
const settings = { type: 'staticAnalysisWarning', click: () => self._deps.rightHandPanel.focusOn('staticanalysisView'), useSpan: true } const settings = { type: 'staticAnalysisWarning', useSpan: true }
self.event.trigger('newStaticAnaysisWarningMessage', [msg, settings]) self.event.trigger('newStaticAnaysisWarningMessage', [msg, settings])
} }
}) })

@ -1,9 +1,13 @@
/* global Worker */ /* global Worker */
const async = require('async')
const $ = require('jquery')
const yo = require('yo-yo') const yo = require('yo-yo')
const csjs = require('csjs-inject') const csjs = require('csjs-inject')
const copy = require('clipboard-copy') const copy = require('clipboard-copy')
var minixhr = require('minixhr') var minixhr = require('minixhr')
var tooltip = require('../ui/tooltip') var remixTests = require('remix-tests')
var Compiler = require('remix-solidity').Compiler
var CompilerImport = require('../compiler/compiler-imports')
var QueryParams = require('../../lib/query-params') var QueryParams = require('../../lib/query-params')
var globalRegistry = require('../../global/registry') var globalRegistry = require('../../global/registry')
const TreeView = require('../ui/TreeView') const TreeView = require('../ui/TreeView')
@ -40,15 +44,18 @@ module.exports = class CompileTab {
self._components = {} self._components = {}
self._components.registry = localRegistry || globalRegistry self._components.registry = localRegistry || globalRegistry
self._components.queryParams = new QueryParams() self._components.queryParams = new QueryParams()
self._components.compilerImport = new CompilerImport()
self._components.compiler = new Compiler((url, cb) => self.importFileCb(url, cb))
// dependencies // dependencies
self._deps = { self._deps = {
app: self._components.registry.get('app').api,
editor: self._components.registry.get('editor').api, editor: self._components.registry.get('editor').api,
config: self._components.registry.get('config').api, config: self._components.registry.get('config').api,
compiler: self._components.registry.get('compiler').api,
renderer: self._components.registry.get('renderer').api, renderer: self._components.registry.get('renderer').api,
swarmfileProvider: self._components.registry.get('fileproviders/swarm').api, swarmfileProvider: self._components.registry.get('fileproviders/swarm').api,
fileManager: self._components.registry.get('filemanager').api fileManager: self._components.registry.get('filemanager').api,
fileProviders: self._components.registry.get('fileproviders').api,
pluginManager: self._components.registry.get('pluginmanager').api
} }
self.data = { self.data = {
hideWarnings: self._deps.config.get('hideWarnings') || false, hideWarnings: self._deps.config.get('hideWarnings') || false,
@ -59,21 +66,22 @@ module.exports = class CompileTab {
timeout: 300, timeout: 300,
allversions: null, allversions: null,
selectedVersion: null, selectedVersion: null,
defaultVersion: 'soljson-v0.5.1+commit.c8a2cb62.js', // this default version is defined: in makeMockCompiler (for browser test) and in package.json (downloadsolc_root) for the builtin compiler
baseurl: 'https://solc-bin.ethereum.org/bin' baseurl: 'https://solc-bin.ethereum.org/bin'
} }
self.data.optimize = self._components.queryParams.get().optimize self.data.optimize = self._components.queryParams.get().optimize
self.data.optimize = self.data.optimize === 'true' self.data.optimize = self.data.optimize === 'true'
self._components.queryParams.update({ optimize: self.data.optimize }) self._components.queryParams.update({ optimize: self.data.optimize })
self._deps.compiler.setOptimize(self.data.optimize) self._components.compiler.setOptimize(self.data.optimize)
self._deps.editor.event.register('contentChanged', scheduleCompilation) self._deps.editor.event.register('contentChanged', scheduleCompilation)
self._deps.editor.event.register('sessionSwitched', scheduleCompilation) self._deps.editor.event.register('sessionSwitched', scheduleCompilation)
function scheduleCompilation () { function scheduleCompilation () {
if (!self._deps.config.get('autoCompile')) return if (!self._deps.config.get('autoCompile')) return
if (self.data.compileTimeout) window.clearTimeout(self.data.compileTimeout) if (self.data.compileTimeout) window.clearTimeout(self.data.compileTimeout)
self.data.compileTimeout = window.setTimeout(() => self._deps.app.runCompiler(), self.data.timeout) self.data.compileTimeout = window.setTimeout(() => self.runCompiler(), self.data.timeout)
} }
self._deps.compiler.event.register('compilationDuration', function tabHighlighting (speed) { self._components.compiler.event.register('compilationDuration', function tabHighlighting (speed) {
if (!self._view.warnCompilationSlow) return if (!self._view.warnCompilationSlow) return
if (speed > self.data.maxTime) { if (speed > self.data.maxTime) {
const msg = `Last compilation took ${speed}ms. We suggest to turn off autocompilation.` const msg = `Last compilation took ${speed}ms. We suggest to turn off autocompilation.`
@ -87,13 +95,13 @@ module.exports = class CompileTab {
if (!self._view.compileIcon) return if (!self._view.compileIcon) return
self._view.compileIcon.classList.add(`${css.bouncingIcon}`) // @TODO: compileView tab self._view.compileIcon.classList.add(`${css.bouncingIcon}`) // @TODO: compileView tab
}) })
self._deps.compiler.event.register('loadingCompiler', function start () { self._components.compiler.event.register('loadingCompiler', function start () {
if (!self._view.compileIcon) return if (!self._view.compileIcon) return
self._view.compileIcon.classList.add(`${css.spinningIcon}`) self._view.compileIcon.classList.add(`${css.spinningIcon}`)
self._view.warnCompilationSlow.style.visibility = 'hidden' self._view.warnCompilationSlow.style.visibility = 'hidden'
self._view.compileIcon.setAttribute('title', 'compiler is loading, please wait a few moments.') self._view.compileIcon.setAttribute('title', 'compiler is loading, please wait a few moments.')
}) })
self._deps.compiler.event.register('compilationStarted', function start () { self._components.compiler.event.register('compilationStarted', function start () {
if (!self._view.compileIcon) return if (!self._view.compileIcon) return
self._view.errorContainer.innerHTML = '' self._view.errorContainer.innerHTML = ''
self._view.errorContainerHead.innerHTML = '' self._view.errorContainerHead.innerHTML = ''
@ -101,12 +109,12 @@ module.exports = class CompileTab {
self._view.compileIcon.classList.add(`${css.spinningIcon}`) self._view.compileIcon.classList.add(`${css.spinningIcon}`)
self._view.compileIcon.setAttribute('title', 'compiling...') self._view.compileIcon.setAttribute('title', 'compiling...')
}) })
self._deps.compiler.event.register('compilerLoaded', function loaded () { self._components.compiler.event.register('compilerLoaded', function loaded () {
if (!self._view.compileIcon) return if (!self._view.compileIcon) return
self._view.compileIcon.classList.remove(`${css.spinningIcon}`) self._view.compileIcon.classList.remove(`${css.spinningIcon}`)
self._view.compileIcon.setAttribute('title', '') self._view.compileIcon.setAttribute('title', '')
}) })
self._deps.compiler.event.register('compilationFinished', function finish (success, data, source) { self._components.compiler.event.register('compilationFinished', function finish (success, data, source) {
if (self._view.compileIcon) { if (self._view.compileIcon) {
const compileTab = document.querySelector('.compileView') const compileTab = document.querySelector('.compileView')
compileTab.style.color = styles.colors.black compileTab.style.color = styles.colors.black
@ -120,9 +128,11 @@ module.exports = class CompileTab {
// refill the dropdown list // refill the dropdown list
self._view.contractNames.innerHTML = '' self._view.contractNames.innerHTML = ''
if (success) { if (success) {
// TODO consider using compile tab as a proper module instead of just forwarding event
self._deps.pluginManager.receivedDataFrom('sendCompilationResult', 'solidity-compiler', [data.target, source, self.data.selectedVersion, data])
self._view.contractNames.removeAttribute('disabled') self._view.contractNames.removeAttribute('disabled')
self._deps.compiler.visitContracts(contract => { self._components.compiler.visitContracts(contract => {
self.data.contractsDetails[contract.name] = parseContracts(contract.name, contract.object, self._deps.compiler.getSource(contract.file)) self.data.contractsDetails[contract.name] = parseContracts(contract.name, contract.object, self._components.compiler.getSource(contract.file))
var contractName = yo`<option>${contract.name}</option>` var contractName = yo`<option>${contract.name}</option>`
self._view.contractNames.appendChild(contractName) self._view.contractNames.appendChild(contractName)
}) })
@ -160,11 +170,20 @@ module.exports = class CompileTab {
}) })
} }
if (!error && data.contracts) { if (!error && data.contracts) {
self._deps.compiler.visitContracts((contract) => { self._components.compiler.visitContracts((contract) => {
self._deps.renderer.error(contract.name, self._view.errorContainer, {type: 'success'}) self._deps.renderer.error(contract.name, self._view.errorContainer, {type: 'success'})
}) })
} }
}) })
// Run the compiler instead of trying to save the website
$(window).keydown(function (e) {
// ctrl+s or command+s
if ((e.metaKey || e.ctrlKey) && e.keyCode === 83) {
e.preventDefault()
self.runCompiler()
}
})
} }
addWarning (msg, settings) { addWarning (msg, settings) {
const self = this const self = this
@ -182,11 +201,11 @@ module.exports = class CompileTab {
function onchangeOptimize (event) { function onchangeOptimize (event) {
self.data.optimize = !!self._view.optimize.checked self.data.optimize = !!self._view.optimize.checked
self._components.queryParams.update({ optimize: self.data.optimize }) self._components.queryParams.update({ optimize: self.data.optimize })
self._deps.compiler.setOptimize(self.data.optimize) self._components.compiler.setOptimize(self.data.optimize)
self._deps.app.runCompiler() self.runCompiler()
} }
self._deps.compiler.event.register('compilerLoaded', (version) => self.setVersionText(version)) self._components.compiler.event.register('compilerLoaded', (version) => self.setVersionText(version))
self.fetchAllVersion((allversions, selectedVersion) => { self.fetchAllVersion((allversions, selectedVersion) => {
self.data.allversions = allversions self.data.allversions = allversions
self.data.selectedVersion = selectedVersion self.data.selectedVersion = selectedVersion
@ -200,7 +219,6 @@ module.exports = class CompileTab {
<select onchange=${onchangeLoadVersion} class="${css.select}" id="versionSelector" disabled> <select onchange=${onchangeLoadVersion} class="${css.select}" id="versionSelector" disabled>
<option disabled selected>Select new compiler version</option> <option disabled selected>Select new compiler version</option>
</select>` </select>`
if (self.data.allversions && self.data.selectedVersion) self._updateVersionSelector()
self._view.version = yo`<span id="version"></span>` self._view.version = yo`<span id="version"></span>`
self._view.warnCompilationSlow = yo`<i title="Compilation Slow" style="visibility:hidden" class="${css.warnCompilationSlow} fa fa-exclamation-triangle" aria-hidden="true"></i>` self._view.warnCompilationSlow = yo`<i title="Compilation Slow" style="visibility:hidden" class="${css.warnCompilationSlow} fa fa-exclamation-triangle" aria-hidden="true"></i>`
@ -279,7 +297,7 @@ module.exports = class CompileTab {
'web3Deploy': 'Copy/paste this code to any JavaScript/Web3 console to deploy this contract' 'web3Deploy': 'Copy/paste this code to any JavaScript/Web3 console to deploy this contract'
} }
function updateAutoCompile (event) { self._deps.config.set('autoCompile', self._view.autoCompile.checked) } function updateAutoCompile (event) { self._deps.config.set('autoCompile', self._view.autoCompile.checked) }
function compile (event) { self._deps.app.runCompiler() } function compile (event) { self.runCompiler() }
function hideWarnings (event) { function hideWarnings (event) {
self._deps.config.set('hideWarnings', self._view.hideWarningsBox.checked) self._deps.config.set('hideWarnings', self._view.hideWarningsBox.checked)
compile() compile()
@ -424,10 +442,10 @@ module.exports = class CompileTab {
// Workers cannot load js on "file:"-URLs and we get a // Workers cannot load js on "file:"-URLs and we get a
// "Uncaught RangeError: Maximum call stack size exceeded" error on Chromium, // "Uncaught RangeError: Maximum call stack size exceeded" error on Chromium,
// resort to non-worker version in that case. // resort to non-worker version in that case.
self._deps.compiler.loadVersion(true, url) self._components.compiler.loadVersion(true, url)
self.setVersionText('(loading using worker)') self.setVersionText('(loading using worker)')
} else { } else {
self._deps.compiler.loadVersion(false, url) self._components.compiler.loadVersion(false, url)
self.setVersionText('(loading)') self.setVersionText('(loading)')
} }
} }
@ -440,10 +458,10 @@ module.exports = class CompileTab {
try { try {
const data = JSON.parse(json) const data = JSON.parse(json)
allversions = data.builds.slice().reverse() allversions = data.builds.slice().reverse()
selectedVersion = data.releases[data.latestRelease] selectedVersion = self.data.defaultVersion
if (self._components.queryParams.get().version) selectedVersion = self._components.queryParams.get().version if (self._components.queryParams.get().version) selectedVersion = self._components.queryParams.get().version
} catch (e) { } catch (e) {
tooltip('Cannot load compiler version list. It might have been blocked by an advertisement blocker. Please try deactivating any of them from this page and reload.') addTooltip('Cannot load compiler version list. It might have been blocked by an advertisement blocker. Please try deactivating any of them from this page and reload.')
} }
} else { } else {
allversions = [{ path: 'builtin', longVersion: 'latest local version' }] allversions = [{ path: 'builtin', longVersion: 'latest local version' }]
@ -452,6 +470,81 @@ module.exports = class CompileTab {
callback(allversions, selectedVersion) callback(allversions, selectedVersion)
}) })
} }
runCompiler () {
const self = this
self._deps.fileManager.saveCurrentFile()
self._deps.editor.clearAnnotations()
var currentFile = self._deps.config.get('currentFile')
if (currentFile) {
if (/.(.sol)$/.exec(currentFile)) {
// only compile *.sol file.
var target = currentFile
var sources = {}
var provider = self._deps.fileManager.fileProviderOf(currentFile)
if (provider) {
provider.get(target, (error, content) => {
if (error) {
console.log(error)
} else {
sources[target] = { content }
self._components.compiler.compile(sources, target)
}
})
} else {
console.log('cannot compile ' + currentFile + '. Does not belong to any explorer')
}
}
}
}
importExternal (url, cb) {
const self = this
self._components.compilerImport.import(url,
(loadingMsg) => {
addTooltip(loadingMsg)
},
(error, content, cleanUrl, type, url) => {
if (!error) {
if (self._deps.filesProviders[type]) {
self._deps.filesProviders[type].addReadOnly(cleanUrl, content, url)
}
cb(null, content)
} else {
cb(error)
}
})
}
importFileCb (url, filecb) {
const self = this
if (url.indexOf('/remix_tests.sol') !== -1) {
return filecb(null, remixTests.assertLibCode)
}
var provider = self._deps.fileManager.fileProviderOf(url)
if (provider) {
if (provider.type === 'localhost' && !provider.isConnected()) {
return filecb(`file provider ${provider.type} not available while trying to resolve ${url}`)
}
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)
}
}
} }
const css = csjs` const css = csjs`

@ -71,7 +71,6 @@ function runTab (opts, localRegistry) {
} }
// dependencies // dependencies
self._deps = { self._deps = {
compiler: self._components.registry.get('compiler').api,
udapp: self._components.registry.get('udapp').api, udapp: self._components.registry.get('udapp').api,
udappUI: self._components.registry.get('udappUI').api, udappUI: self._components.registry.get('udappUI').api,
config: self._components.registry.get('config').api, config: self._components.registry.get('config').api,
@ -310,21 +309,10 @@ function contractDropdown (events, self) {
} }
self._deps.pluginManager.event.register('sendCompilationResult', (file, source, languageVersion, data) => { self._deps.pluginManager.event.register('sendCompilationResult', (file, source, languageVersion, data) => {
// TODO check whether the tab is configured let compiler = new CompilerAbstract(languageVersion, data, source)
let compiler = new CompilerAbstract(languageVersion, data)
self._deps.compilersArtefacts[languageVersion] = compiler
self._deps.compilersArtefacts['__last'] = compiler
newlyCompiled(true, data, source, compiler, languageVersion) newlyCompiled(true, data, source, compiler, languageVersion)
}) })
self._deps.compiler.event.register('compilationFinished', (success, data, source) => {
var name = 'solidity'
let compiler = new CompilerAbstract(name, data)
self._deps.compilersArtefacts[name] = compiler
self._deps.compilersArtefacts['__last'] = compiler
newlyCompiled(success, data, source, self._deps.compiler, name)
})
var deployAction = (value) => { var deployAction = (value) => {
self._view.createPanel.style.display = value self._view.createPanel.style.display = value
self._view.orLabel.style.display = value self._view.orLabel.style.display = value
@ -350,7 +338,7 @@ function contractDropdown (events, self) {
function getSelectedContract () { function getSelectedContract () {
var contract = selectContractNames.children[selectContractNames.selectedIndex] var contract = selectContractNames.children[selectContractNames.selectedIndex]
var contractName = contract.innerHTML var contractName = contract.innerHTML
var compiler = self._deps.compilersArtefacts[contract.getAttribute('compiler')] var compiler = self._deps.compilersArtefacts['__last']
if (!compiler) return null if (!compiler) return null
if (contractName) { if (contractName) {

@ -18,11 +18,9 @@ module.exports = class SettingsTab {
self._components.registry = localRegistry || globalRegistry self._components.registry = localRegistry || globalRegistry
// dependencies // dependencies
self._deps = { self._deps = {
compiler: self._components.registry.get('compiler').api,
config: self._components.registry.get('config').api, config: self._components.registry.get('config').api,
editorPanel: self._components.registry.get('editorpanel').api, editorPanel: self._components.registry.get('editorpanel').api,
editor: self._components.registry.get('editor').api, editor: self._components.registry.get('editor').api
righthandpanel: self._components.registry.get('righthandpanel').api
} }
self._view = { /* eslint-disable */ self._view = { /* eslint-disable */
el: null, el: null,

@ -8,15 +8,16 @@ var css = require('./styles/test-tab-styles')
var remixTests = require('remix-tests') var remixTests = require('remix-tests')
module.exports = class TestTab { module.exports = class TestTab {
constructor (localRegistry) { constructor (localRegistry, compileTab) {
// TODO here is a direct reference to compile tab, should be removed
const self = this const self = this
self.compileTab = compileTab
self._view = { el: null } self._view = { el: null }
self._components = {} self._components = {}
self._components.registry = localRegistry || globalRegistry self._components.registry = localRegistry || globalRegistry
// dependencies // dependencies
self._deps = { self._deps = {
fileManager: self._components.registry.get('filemanager').api, fileManager: self._components.registry.get('filemanager').api,
app: self._components.registry.get('app').api,
filePanel: self._components.registry.get('filepanel').api filePanel: self._components.registry.get('filepanel').api
} }
self.data = {} self.data = {}
@ -76,7 +77,7 @@ module.exports = class TestTab {
remixTests.runTestSources(runningTest, testCallback, resultsCallback, (error, result) => { remixTests.runTestSources(runningTest, testCallback, resultsCallback, (error, result) => {
updateFinalResult(error, result, testFilePath) updateFinalResult(error, result, testFilePath)
callback(error) callback(error)
}, (url, cb) => { self._deps.app.importFileCb(url, cb) }) }, (url, cb) => { self.compileTab.importFileCb(url, cb) })
} }
}) })
} }

@ -24,7 +24,7 @@ class CmdInterpreterAPI {
app: self._components.registry.get('app').api, app: self._components.registry.get('app').api,
fileManager: self._components.registry.get('filemanager').api, fileManager: self._components.registry.get('filemanager').api,
editor: self._components.registry.get('editor').api, editor: self._components.registry.get('editor').api,
compiler: self._components.registry.get('compiler').api, compilersArtefacts: self._components.registry.get('compilersartefacts').api,
offsetToLineColumnConverter: self._components.registry.get('offsettolinecolumnconverter').api offsetToLineColumnConverter: self._components.registry.get('offsettolinecolumnconverter').api
} }
self.commandHelp = { self.commandHelp = {
@ -47,7 +47,9 @@ class CmdInterpreterAPI {
self._components.sourceHighlighter.currentSourceLocation(null) self._components.sourceHighlighter.currentSourceLocation(null)
return return
} }
var lineColumnPos = self._deps.offsetToLineColumnConverter.offsetToLineColumn(rawLocation, rawLocation.file, self._deps.compiler.lastCompilationResult.source.sources, self._deps.compiler.lastCompilationResult.data.sources) var lineColumnPos = self._deps.offsetToLineColumnConverter.offsetToLineColumn(rawLocation, rawLocation.file,
self._deps.compilersArtefacts['__last'].getSourceCode().sources,
self._deps.compilersArtefacts['__last'].getAsts())
self._components.sourceHighlighter.currentSourceLocation(lineColumnPos, rawLocation) self._components.sourceHighlighter.currentSourceLocation(lineColumnPos, rawLocation)
} }
debug (hash, cb) { debug (hash, cb) {
@ -57,7 +59,7 @@ class CmdInterpreterAPI {
if (error) return cb(error) if (error) return cb(error)
var debugSession = new RemixDebug({ var debugSession = new RemixDebug({
compilationResult: () => { compilationResult: () => {
return self._deps.compiler.lastCompilationResult.data return self._deps.compilersArtefacts['__last'].getData()
} }
}) })
debugSession.addProvider('web3', executionContext.web3()) debugSession.addProvider('web3', executionContext.web3())
@ -108,7 +110,9 @@ class CmdInterpreterAPI {
self.d.goTo = (row) => { self.d.goTo = (row) => {
if (self._deps.editor.current()) { if (self._deps.editor.current()) {
var breakPoint = new remixLib.code.BreakpointManager(self.d, (sourceLocation) => { var breakPoint = new remixLib.code.BreakpointManager(self.d, (sourceLocation) => {
return self._deps.offsetToLineColumnConverter.offsetToLineColumn(sourceLocation, sourceLocation.file, self._deps.compiler.lastCompilationResult.source.sources, self._deps.compiler.lastCompilationResult.data.sources) return self._deps.offsetToLineColumnConverter.offsetToLineColumn(sourceLocation, sourceLocation.file,
self._deps.compilersArtefacts['__last'].getSourceCode().sources,
self._deps.compilersArtefacts['__last'].getAsts())
}) })
breakPoint.event.register('breakpointHit', (sourceLocation, currentStep) => { breakPoint.event.register('breakpointHit', (sourceLocation, currentStep) => {
self.log(null, 'step index ' + currentStep) self.log(null, 'step index ' + currentStep)

@ -1,13 +1,10 @@
'use strict' 'use strict'
var SourceMappingDecoder = require('remix-lib').SourceMappingDecoder var SourceMappingDecoder = require('remix-lib').SourceMappingDecoder
function offsetToColumnConverter (compilerEvent) { function offsetToColumnConverter () {
this.lineBreakPositionsByContent = {} this.lineBreakPositionsByContent = {}
this.sourceMappingDecoder = new SourceMappingDecoder() this.sourceMappingDecoder = new SourceMappingDecoder()
var self = this // we don't listen anymore on compilation result for clearing the cache
compilerEvent.register('compilationFinished', function (success, data, source) {
self.clear()
})
} }
offsetToColumnConverter.prototype.offsetToLineColumn = function (rawLocation, file, sources, asts) { offsetToColumnConverter.prototype.offsetToLineColumn = function (rawLocation, file, sources, asts) {

@ -31,7 +31,7 @@ function UniversalDApp (opts, localRegistry) {
self.removable_instances = opts.removable_instances self.removable_instances = opts.removable_instances
self._deps = { self._deps = {
config: self._components.registry.get('config').api, config: self._components.registry.get('config').api,
compiler: self._components.registry.get('compiler').api, compilersartefacts: self._components.registry.get('compilersartefacts').api,
logCallback: self._components.registry.get('logCallback').api logCallback: self._components.registry.get('logCallback').api
} }
executionContext.event.register('contextChanged', this, function (context) { executionContext.event.register('contextChanged', this, function (context) {
@ -47,10 +47,6 @@ function UniversalDApp (opts, localRegistry) {
} }
} }
self.txRunner = new TxRunner({}, self._txRunnerAPI) self.txRunner = new TxRunner({}, self._txRunnerAPI)
self.data.contractsDetails = {}
self._deps.compiler.event.register('compilationFinished', (success, data, source) => {
self.data.contractsDetails = success && data ? data.contracts : {}
})
self.accounts = {} self.accounts = {}
self.resetEnvironment() self.resetEnvironment()
} }
@ -204,8 +200,7 @@ UniversalDApp.prototype.call = function (isUserAction, args, value, lookupOnly,
logMsg = `call to ${args.contractName}.${(args.funABI.name) ? args.funABI.name : '(fallback)'}` logMsg = `call to ${args.contractName}.${(args.funABI.name) ? args.funABI.name : '(fallback)'}`
} }
} }
// contractsDetails is used to resolve libraries txFormat.buildData(args.contractName, args.contractAbi, self._deps.compilersartefacts['__last'].getData().contracts, false, args.funABI, args.funABI.type !== 'fallback' ? value : '', (error, data) => {
txFormat.buildData(args.contractName, args.contractAbi, self.data.contractsDetails, false, args.funABI, args.funABI.type !== 'fallback' ? value : '', (error, data) => {
if (!error) { if (!error) {
if (isUserAction) { if (isUserAction) {
if (!args.funABI.constant) { if (!args.funABI.constant) {

@ -48,7 +48,7 @@ function runTests (browser, testData) {
.pause(2000) .pause(2000)
.perform(function (client, done) { .perform(function (client, done) {
console.log('goToVMtraceStep') console.log('goToVMtraceStep')
contractHelper.goToVMtraceStep(browser, 55, () => { contractHelper.goToVMtraceStep(browser, 59, () => {
done() done()
}) })
}) })

@ -58,6 +58,11 @@ function runTests (browser, testData) {
browser.end() browser.end()
return return
} }
if (browserName === 'chrome') {
console.log('do not run remixd test for ' + browserName + ': TODO to reenable later')
browser.end()
return
}
browser browser
.waitForElementVisible('.newFile', 10000) .waitForElementVisible('.newFile', 10000)
.click('.websocketconn') .click('.websocketconn')

Loading…
Cancel
Save