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. 30
      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. 25
      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. 19
      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
- restore_cache:
keys:
- dep-bundle-24-{{ checksum "package.json" }}
- dep-bundle-27-{{ checksum "package.json" }}
- run: npm install
- save_cache:
key: dep-bundle-24-{{ checksum "package.json" }}
key: dep-bundle-27-{{ checksum "package.json" }}
paths:
- ~/repo/node_modules
- run: npm run lint && npm run test && npm run make-mock-compiler && npm run build

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

@ -43,7 +43,7 @@
"remix-lib": "0.4.1",
"remix-solidity": "0.3.1",
"remix-tests": "0.1.1",
"remixd": "git+https://github.com/ethereum/remixd.git",
"remixd": "0.1.8-alpha.6",
"request": "^2.83.0",
"rimraf": "^2.6.1",
"selenium-standalone": "^6.0.1",
@ -61,7 +61,7 @@
},
"dependencies": {
"http-server": "0.9.0",
"remixd": "git+https://github.com/ethereum/remixd.git"
"remixd": "0.1.8-alpha.6"
},
"repository": {
"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",
"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/",
"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",
"make-mock-compiler": "node ci/makeMockCompiler.js",
"minify": "uglifyjs --in-source-map inline --source-map-inline -c warnings=false",

@ -1,12 +1,10 @@
'use strict'
var $ = require('jquery')
var csjs = require('csjs-inject')
var yo = require('yo-yo')
var async = require('async')
var request = require('request')
var remixLib = require('remix-lib')
var remixTests = require('remix-tests')
var EventManager = require('./lib/events')
var registry = require('./global/registry')
@ -14,18 +12,15 @@ var UniversalDApp = require('./universal-dapp.js')
var UniversalDAppUI = require('./universal-dapp-ui.js')
var Remixd = require('./lib/remixd')
var OffsetToLineColumnConverter = require('./lib/offsetToLineColumnConverter')
var QueryParams = require('./lib/query-params')
var GistHandler = require('./lib/gist-handler')
var helper = require('./lib/helper')
var Storage = remixLib.Storage
var Browserfiles = require('./app/files/browser-files')
var BrowserfilesTree = require('./app/files/browser-files-tree')
var chromeCloudStorageSync = require('./app/files/chromeCloudStorageSync')
var SharedFolder = require('./app/files/shared-folder')
var Config = require('./config')
var Renderer = require('./app/ui/renderer')
var Compiler = require('remix-solidity').Compiler
var executionContext = require('./execution-context')
var FilePanel = require('./app/panels/file-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 Txlistener = remixLib.execution.txListener
var EventsDecoder = remixLib.execution.EventsDecoder
var CompilerImport = require('./app/compiler/compiler-imports')
var FileManager = require('./app/files/fileManager')
var BasicReadOnlyExplorer = require('./app/files/basicReadOnlyExplorer')
var NotPersistedExplorer = require('./app/files/NotPersistedExplorer')
var toolTip = require('./app/ui/tooltip')
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 styles = styleGuide.chooser()
@ -126,8 +130,6 @@ class App {
executionContext.init(self._components.config)
executionContext.listenOnLastBlock()
self._components.compilerImport = new CompilerImport()
registry.put({api: self._components.compilerImport, name: 'compilerimport'})
self._components.gistHandler = new GistHandler()
self._components.filesProviders = {}
@ -228,34 +230,6 @@ class App {
self._adjustLayout('right', self.data._layout.right.offset)
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) {
const self = this
self.event.trigger('debuggingRequested', [])
@ -299,55 +273,6 @@ class App {
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
@ -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?'
}
// 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'})
// ----------------- Compiler -----------------
self._components.compiler = new Compiler((url, cb) => self.importFileCb(url, cb))
registry.put({api: self._components.compiler, name: 'compiler'})
var offsetToLineColumnConverter = new OffsetToLineColumnConverter(self._components.compiler.event)
// helper for converting offset to line/column
var offsetToLineColumnConverter = new 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)
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
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.fileManager.init()
@ -485,65 +416,28 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
var renderer = new 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 --------------------
self._components.righthandpanel = new RighthandPanel()
self._components.righthandpanel = new RighthandPanel({ tabs, pluginManager })
self._view.rightpanel.appendChild(self._components.righthandpanel.render())
self._components.righthandpanel.init()
self._components.righthandpanel.event.register('resize', delta => self._adjustLayout('right', delta))
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()
// 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())
if (!loadingFromGist) {
// insert ballot contract if there are no files to show

@ -3,9 +3,10 @@ var remixLib = require('remix-lib')
var txHelper = remixLib.execution.txHelper
module.exports = class CompilerAbstract {
constructor (languageversion, data) {
constructor (languageversion, data, source) {
this.languageversion = languageversion
this.data = data
this.source = source // source code
}
getContracts () {
@ -23,4 +24,19 @@ module.exports = class CompilerAbstract {
getData () {
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.debugger = new Debugger({
web3: this.contextManager.getWeb3(),
offsetToLineColumnConverter: this.registry.get('offsettolinecolumnconverter').api,
compiler: this.registry.get('compiler').api
})
this.contextManager.initProviders()
this.contextManager.event.register('providerChanged', () => {
this.debugger.updateWeb3(this.contextManager.getWeb3())
if (this.debugger) this.debugger.updateWeb3(this.contextManager.getWeb3())
})
this.isActive = false
@ -116,7 +110,6 @@ class DebuggerUI {
container.appendChild(this.render())
this.setEditor()
this.listenToEvents()
}
setEditor () {
@ -124,20 +117,22 @@ class DebuggerUI {
this.editor = this.registry.get('editor').api
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.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.debugger.unload()
if (self.debugger) self.debugger.unload()
})
}
listenToEvents () {
const self = this
if (!self.debugger) return
this.debugger.event.register('debuggerStatus', function (isActive) {
self.sourceHighlighter.currentSourceLocation(null)
self.isActive = isActive
@ -156,12 +151,12 @@ class DebuggerUI {
this.txBrowser = txBrowser
txBrowser.event.register('requestDebug', function (blockNumber, txNumber, tx) {
self.debugger.unload()
if (self.debugger) self.debugger.unload()
self.startDebugging(blockNumber, txNumber, 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) {
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.debug(blockNumber, txNumber, tx, () => {

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

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

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

@ -142,7 +142,7 @@ class TxLogger {
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,
compilersArtefacts: this._components.registry.get('compilersartefacts').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)
if (resolvedTransaction) {
var compiledContracts = null
if (self._deps.compiler.lastCompilationResult && self._deps.compiler.lastCompilationResult.data) {
compiledContracts = self._deps.compiler.lastCompilationResult.data.contracts
if (self._deps.compilersArtefacts['__last']) {
compiledContracts = self._deps.compilersArtefacts['__last'].getContracts()
}
self._deps.eventsDecoder.parseLogs(tx, resolvedTransaction.contractName, compiledContracts, (error, logs) => {
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'
var executionContext = require('../../execution-context')
var CompilerAbstract = require('../compiler/compiler-abstract')
class CompilerMetadata {
constructor (events, opts) {
constructor (opts) {
var self = this
self._events = events
self._opts = opts
self.networks = ['VM:-', 'main:1', 'ropsten:3', 'rinkeby:4', 'kovan:42', 'Custom']
}
syncContractMetadata () {
var self = this
self._events.compiler.register('compilationFinished', (success, data, source) => {
if (!success) return
self._opts.pluginManager.event.register('sendCompilationResult', (file, source, languageVersion, data) => {
if (!self._opts.config.get('settings/generate-contract-metadata')) return
let compiler = new CompilerAbstract(languageVersion, data, source)
var provider = self._opts.fileManager.currentFileProvider()
var path = self._opts.fileManager.currentPath()
if (provider && path) {
self._opts.compiler.visitContracts((contract) => {
compiler.visitContracts((contract) => {
if (contract.file !== source.target) return
var fileName = path + '/' + contract.name + '.json'

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

@ -26,7 +26,7 @@ class EditorPanel {
txListener: self._components.registry.get('txlistener').api,
fileManager: self._components.registry.get('filemanager').api,
udapp: self._components.registry.get('udapp').api,
compiler: self._components.registry.get('compiler').api
pluginManager: self._components.registry.get('pluginmanager').api
}
self.data = {
_FILE_SCROLL_DELTA: 200,
@ -40,16 +40,18 @@ class EditorPanel {
self._view = {}
var editor = new 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 = {
editor: editor,
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({
udapp: self._deps.udapp,
compilers: {
'solidity': self._deps.compiler
}
compilers: {}
},
{
getPosition: (event) => {

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

@ -5,22 +5,14 @@ const EventManager = require('../../lib/events')
var globalRegistry = require('../../global/registry')
const styleguide = require('../ui/styles-guide/theme-chooser')
const PluginManager = require('../plugin/pluginManager')
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 TestTab = require('../tabs/test-tab')
const RunTab = require('../tabs/run-tab')
const DraggableContent = require('../ui/draggableContent')
const styles = styleguide.chooser()
module.exports = class RighthandPanel {
constructor (localRegistry) {
constructor ({pluginManager, tabs}, localRegistry) {
const self = this
self._components = {}
self._components.registry = localRegistry || globalRegistry
@ -33,57 +25,25 @@ module.exports = class RighthandPanel {
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 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 = {
pluginManager: pluginManager,
tabbedMenu: tabbedMenu,
compile: new CompileTab(self._components.registry),
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)
tabs
}
self._components.settings.event.register('plugin-loadRequest', json => {
self._components.tabs.settings.event.register('plugin-loadRequest', json => {
self.loadPlugin(json)
})
self.loadPlugin = function (json) {
var modal = new DraggableContent(() => {
self._components.pluginManager.unregister(json)
pluginManager.unregister(json)
})
var tab = new PluginTab(json)
var content = tab.render()
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>`
@ -96,7 +56,7 @@ module.exports = class RighthandPanel {
</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('Run', 'runView', run.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.selectTabByTitle('Compile')
}
// showDebugger () {
// const self = this
// if (!self._components.tabbedMenu) return
// self._components.tabbedMenu.selectTab(self._view.el.querySelector('li.debugView'))
// }
render () {
const self = this
if (self._view.element) return self._view.element
@ -118,7 +74,7 @@ module.exports = class RighthandPanel {
}
debugger () {
return this._components.debug.debugger()
return this._components.tabs.debug.debugger()
}
focusOn (x) {

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

@ -79,14 +79,14 @@ const PluginAPI = require('./pluginAPI')
*
*/
module.exports = class PluginManager {
constructor (app, compiler, txlistener, fileProviders, fileManager, udapp) {
constructor (app, compilersArtefacts, txlistener, fileProviders, fileManager, udapp) {
const self = this
self.event = new EventManager()
var pluginAPI = new PluginAPI(
this,
fileProviders,
fileManager,
compiler,
compilersArtefacts,
udapp
)
self._components = { pluginAPI }
@ -101,14 +101,6 @@ module.exports = class PluginManager {
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) => {
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) => {
if (event.type !== 'message') return
var extension = self.origins[event.origin]
@ -202,7 +162,13 @@ module.exports = class PluginManager {
receivedDataFrom (methodName, mod, argumentsArray) {
// TODO check whether 'mod' as right to do that
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) {
const self = this

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

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

@ -1,9 +1,13 @@
/* global Worker */
const async = require('async')
const $ = require('jquery')
const yo = require('yo-yo')
const csjs = require('csjs-inject')
const copy = require('clipboard-copy')
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 globalRegistry = require('../../global/registry')
const TreeView = require('../ui/TreeView')
@ -40,15 +44,18 @@ module.exports = class CompileTab {
self._components = {}
self._components.registry = localRegistry || globalRegistry
self._components.queryParams = new QueryParams()
self._components.compilerImport = new CompilerImport()
self._components.compiler = new Compiler((url, cb) => self.importFileCb(url, cb))
// dependencies
self._deps = {
app: self._components.registry.get('app').api,
editor: self._components.registry.get('editor').api,
config: self._components.registry.get('config').api,
compiler: self._components.registry.get('compiler').api,
renderer: self._components.registry.get('renderer').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 = {
hideWarnings: self._deps.config.get('hideWarnings') || false,
@ -59,21 +66,22 @@ module.exports = class CompileTab {
timeout: 300,
allversions: 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'
}
self.data.optimize = self._components.queryParams.get().optimize
self.data.optimize = self.data.optimize === 'true'
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('sessionSwitched', scheduleCompilation)
function scheduleCompilation () {
if (!self._deps.config.get('autoCompile')) return
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 (speed > self.data.maxTime) {
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
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
self._view.compileIcon.classList.add(`${css.spinningIcon}`)
self._view.warnCompilationSlow.style.visibility = 'hidden'
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
self._view.errorContainer.innerHTML = ''
self._view.errorContainerHead.innerHTML = ''
@ -101,12 +109,12 @@ module.exports = class CompileTab {
self._view.compileIcon.classList.add(`${css.spinningIcon}`)
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
self._view.compileIcon.classList.remove(`${css.spinningIcon}`)
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) {
const compileTab = document.querySelector('.compileView')
compileTab.style.color = styles.colors.black
@ -120,9 +128,11 @@ module.exports = class CompileTab {
// refill the dropdown list
self._view.contractNames.innerHTML = ''
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._deps.compiler.visitContracts(contract => {
self.data.contractsDetails[contract.name] = parseContracts(contract.name, contract.object, self._deps.compiler.getSource(contract.file))
self._components.compiler.visitContracts(contract => {
self.data.contractsDetails[contract.name] = parseContracts(contract.name, contract.object, self._components.compiler.getSource(contract.file))
var contractName = yo`<option>${contract.name}</option>`
self._view.contractNames.appendChild(contractName)
})
@ -160,11 +170,20 @@ module.exports = class CompileTab {
})
}
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'})
})
}
})
// 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) {
const self = this
@ -182,11 +201,11 @@ module.exports = class CompileTab {
function onchangeOptimize (event) {
self.data.optimize = !!self._view.optimize.checked
self._components.queryParams.update({ optimize: self.data.optimize })
self._deps.compiler.setOptimize(self.data.optimize)
self._deps.app.runCompiler()
self._components.compiler.setOptimize(self.data.optimize)
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.data.allversions = allversions
self.data.selectedVersion = selectedVersion
@ -200,7 +219,6 @@ module.exports = class CompileTab {
<select onchange=${onchangeLoadVersion} class="${css.select}" id="versionSelector" disabled>
<option disabled selected>Select new compiler version</option>
</select>`
if (self.data.allversions && self.data.selectedVersion) self._updateVersionSelector()
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>`
@ -279,7 +297,7 @@ module.exports = class CompileTab {
'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 compile (event) { self._deps.app.runCompiler() }
function compile (event) { self.runCompiler() }
function hideWarnings (event) {
self._deps.config.set('hideWarnings', self._view.hideWarningsBox.checked)
compile()
@ -424,10 +442,10 @@ module.exports = class CompileTab {
// Workers cannot load js on "file:"-URLs and we get a
// "Uncaught RangeError: Maximum call stack size exceeded" error on Chromium,
// 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)')
} else {
self._deps.compiler.loadVersion(false, url)
self._components.compiler.loadVersion(false, url)
self.setVersionText('(loading)')
}
}
@ -440,10 +458,10 @@ module.exports = class CompileTab {
try {
const data = JSON.parse(json)
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
} 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 {
allversions = [{ path: 'builtin', longVersion: 'latest local version' }]
@ -452,6 +470,81 @@ module.exports = class CompileTab {
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`

@ -71,7 +71,6 @@ function runTab (opts, localRegistry) {
}
// dependencies
self._deps = {
compiler: self._components.registry.get('compiler').api,
udapp: self._components.registry.get('udapp').api,
udappUI: self._components.registry.get('udappUI').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) => {
// TODO check whether the tab is configured
let compiler = new CompilerAbstract(languageVersion, data)
self._deps.compilersArtefacts[languageVersion] = compiler
self._deps.compilersArtefacts['__last'] = compiler
let compiler = new CompilerAbstract(languageVersion, data, source)
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) => {
self._view.createPanel.style.display = value
self._view.orLabel.style.display = value
@ -350,7 +338,7 @@ function contractDropdown (events, self) {
function getSelectedContract () {
var contract = selectContractNames.children[selectContractNames.selectedIndex]
var contractName = contract.innerHTML
var compiler = self._deps.compilersArtefacts[contract.getAttribute('compiler')]
var compiler = self._deps.compilersArtefacts['__last']
if (!compiler) return null
if (contractName) {

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

@ -8,15 +8,16 @@ var css = require('./styles/test-tab-styles')
var remixTests = require('remix-tests')
module.exports = class TestTab {
constructor (localRegistry) {
constructor (localRegistry, compileTab) {
// TODO here is a direct reference to compile tab, should be removed
const self = this
self.compileTab = compileTab
self._view = { el: null }
self._components = {}
self._components.registry = localRegistry || globalRegistry
// dependencies
self._deps = {
fileManager: self._components.registry.get('filemanager').api,
app: self._components.registry.get('app').api,
filePanel: self._components.registry.get('filepanel').api
}
self.data = {}
@ -76,7 +77,7 @@ module.exports = class TestTab {
remixTests.runTestSources(runningTest, testCallback, resultsCallback, (error, result) => {
updateFinalResult(error, result, testFilePath)
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,
fileManager: self._components.registry.get('filemanager').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
}
self.commandHelp = {
@ -47,7 +47,9 @@ class CmdInterpreterAPI {
self._components.sourceHighlighter.currentSourceLocation(null)
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)
}
debug (hash, cb) {
@ -57,7 +59,7 @@ class CmdInterpreterAPI {
if (error) return cb(error)
var debugSession = new RemixDebug({
compilationResult: () => {
return self._deps.compiler.lastCompilationResult.data
return self._deps.compilersArtefacts['__last'].getData()
}
})
debugSession.addProvider('web3', executionContext.web3())
@ -108,7 +110,9 @@ class CmdInterpreterAPI {
self.d.goTo = (row) => {
if (self._deps.editor.current()) {
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) => {
self.log(null, 'step index ' + currentStep)

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

@ -31,7 +31,7 @@ function UniversalDApp (opts, localRegistry) {
self.removable_instances = opts.removable_instances
self._deps = {
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
}
executionContext.event.register('contextChanged', this, function (context) {
@ -47,10 +47,6 @@ function UniversalDApp (opts, localRegistry) {
}
}
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.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)'}`
}
}
// contractsDetails is used to resolve libraries
txFormat.buildData(args.contractName, args.contractAbi, self.data.contractsDetails, false, args.funABI, args.funABI.type !== 'fallback' ? value : '', (error, data) => {
txFormat.buildData(args.contractName, args.contractAbi, self._deps.compilersartefacts['__last'].getData().contracts, false, args.funABI, args.funABI.type !== 'fallback' ? value : '', (error, data) => {
if (!error) {
if (isUserAction) {
if (!args.funABI.constant) {

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

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

Loading…
Cancel
Save