Skip to content

Commit

Permalink
Merge pull request #1642 from ethereum/refactorApp.js
Browse files Browse the repository at this point in the history
Refactor app.js
  • Loading branch information
yann300 committed Dec 31, 2018
2 parents 797a73f + 9cc1385 commit 9fcfdab
Show file tree
Hide file tree
Showing 29 changed files with 325 additions and 455 deletions.
4 changes: 2 additions & 2 deletions .circleci/config.yml
Expand Up @@ -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
Expand Down
30 changes: 17 additions & 13 deletions ci/makeMockCompiler.js
Expand Up @@ -2,25 +2,29 @@

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')) {
var testDef = require('.' + dir + item)
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
})
}
Expand All @@ -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, '')
Expand All @@ -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) {
Expand Down
6 changes: 3 additions & 3 deletions package.json
Expand Up @@ -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",
Expand All @@ -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",
Expand Down Expand Up @@ -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",
Expand Down
192 changes: 43 additions & 149 deletions src/app.js
@@ -1,31 +1,26 @@
'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')
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')
Expand All @@ -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()

Expand Down Expand Up @@ -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 = {}
Expand Down Expand Up @@ -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', [])
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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'})

Expand Down Expand Up @@ -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()

Expand Down Expand Up @@ -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
Expand Down

0 comments on commit 9fcfdab

Please sign in to comment.