diff --git a/package.json b/package.json
index afacc50006..aac26fff09 100644
--- a/package.json
+++ b/package.json
@@ -185,6 +185,7 @@
"nightwatch_local_fileExplorer": "nightwatch ./test-browser/tests/fileExplorer.test.js --config nightwatch.js --env chrome ",
"nightwatch_local_debugger": "nightwatch ./test-browser/tests/debugger.test.js --config nightwatch.js --env chrome ",
"nightwatch_local_editor": "nightwatch ./test-browser/tests/editor.test.js --config nightwatch.js --env chrome ",
+ "nightwatch_local_compiler": "nightwatch ./test-browser/tests/compiler_api.test.js --config nightwatch.js --env chrome ",
"nightwatch_local_runAndDeploy": "nightwatch ./test-browser/tests/runAndDeploy.js --config nightwatch.js --env chrome-runAndDeploy ",
"onchange": "onchange build/app.js -- npm-run-all lint",
"prepublish": "mkdirp build; npm-run-all -ls downloadsolc_root build",
diff --git a/src/app/compiler/compiler-helpers.js b/src/app/compiler/compiler-helpers.js
index 820e5c298f..c4ca22c001 100644
--- a/src/app/compiler/compiler-helpers.js
+++ b/src/app/compiler/compiler-helpers.js
@@ -9,8 +9,10 @@ export const compile = async (compilationTargets, settings) => {
const compiler = new Compiler(() => {})
compiler.set('evmVersion', settings.evmVersion)
compiler.set('optimize', settings.optimize)
+ compiler.set('language', settings.language)
compiler.loadVersion(canUseWorker(settings.version), urlFromVersion(settings.version))
compiler.event.register('compilationFinished', (success, compilationData, source) => {
+ console.log(success, compilationData)
if (!success) return reject(compilationData)
resolve(new CompilerAbstract(settings.version, compilationData, source))
})
diff --git a/src/app/compiler/compiler-sourceVerifier-fetchAndCompile.js b/src/app/compiler/compiler-sourceVerifier-fetchAndCompile.js
index 5df4e66390..d608a8d061 100644
--- a/src/app/compiler/compiler-sourceVerifier-fetchAndCompile.js
+++ b/src/app/compiler/compiler-sourceVerifier-fetchAndCompile.js
@@ -105,7 +105,7 @@ export default class FetchAndCompile extends Plugin {
// compile
const settings = {
version: data.metadata.compiler.version,
- languageName: data.metadata.language,
+ language: data.metadata.language,
evmVersion: data.metadata.settings.evmVersion,
optimize: data.metadata.settings.optimizer.enabled
}
diff --git a/src/app/tabs/compile-tab.js b/src/app/tabs/compile-tab.js
index 52de47dd7e..e027e1e5ce 100644
--- a/src/app/tabs/compile-tab.js
+++ b/src/app/tabs/compile-tab.js
@@ -20,6 +20,7 @@ const CompilerContainer = require('./compileTab/compilerContainer.js')
import { ViewPlugin } from '@remixproject/engine'
import * as packageJson from '../../../package.json'
import publishToStorage from '../../publishToStorage'
+import { compile } from '../compiler/compiler-helpers'
const profile = {
name: 'solidity',
@@ -31,7 +32,7 @@ const profile = {
location: 'sidePanel',
documentation: 'https://remix-ide.readthedocs.io/en/latest/solidity_editor.html',
version: packageJson.version,
- methods: ['getCompilationResult', 'compile']
+ methods: ['getCompilationResult', 'compile', 'compileWithParameters', 'setCompilerConfig']
}
@@ -60,7 +61,8 @@ class CompileTab extends ViewPlugin {
this.data = {
contractsDetails: {},
- eventHandlers: {}
+ eventHandlers: {},
+ loading: false
}
}
@@ -88,11 +90,13 @@ class CompileTab extends ViewPlugin {
this.editor.event.register('contentChanged', this.data.eventHandlers.onContentChanged)
this.data.eventHandlers.onLoadingCompiler = () => {
+ this.data.loading = true
this.emit('statusChanged', {key: 'loading', title: 'loading compiler...', type: 'info'})
}
this.compiler.event.register('loadingCompiler', this.data.eventHandlers.onLoadingCompiler)
this.data.eventHandlers.onCompilerLoaded = () => {
+ this.data.loading = false
this.emit('statusChanged', {key: 'none'})
}
this.compiler.event.register('compilerLoaded', this.data.eventHandlers.onCompilerLoaded)
@@ -198,11 +202,28 @@ class CompileTab extends ViewPlugin {
return this.compileTabLogic.compiler.state.lastCompilationResult
}
- // This function is used by remix-plugin
+ /**
+ * compile using @arg fileName.
+ * The module UI will be updated accordingly to the new compilation result.
+ * This function is used by remix-plugin compiler API.
+ * @param {string} fileName to compile
+ */
compile (fileName) {
+ addTooltip(yo`
${this.currentRequest.from} is requiring to compile ${fileName}
`)
return this.compileTabLogic.compileFile(fileName)
}
+ /**
+ * compile using @arg compilationTargets and @arg settings
+ * The module UI will *not* be updated, the compilation result is returned
+ * This function is used by remix-plugin compiler API.
+ * @param {object} map of source files.
+ * @param {object} settings {evmVersion, optimize, compilerUrl, version, language}
+ */
+ async compileWithParameters (compilationTargets, settings) {
+ return await compile(compilationTargets, settings)
+ }
+
// This function is used for passing the compiler remix-tests
getCurrentVersion () {
return this.compilerContainer.data.selectedVersion
@@ -217,6 +238,31 @@ class CompileTab extends ViewPlugin {
}
}
+ /**
+ * set the compiler configuration
+ * This function is used by remix-plugin compiler API.
+ * @param {object} settings {evmVersion, optimize, compilerUrl, version, language}
+ */
+ setCompilerConfig (settings) {
+ return new Promise((resolve, reject) => {
+ addTooltip(yo`${this.currentRequest.from} is updating the
Solidity compiler configuration .
${JSON.stringify(settings, null, '\t')} `)
+ this.compilerContainer.setLanguage(settings.language)
+ this.compilerContainer.setEvmVersion(settings.evmVersion)
+ this.compilerContainer.setOptimize(settings.optimize)
+ this.compilerContainer.setVersion(settings.version)
+ // @todo(#2875) should use loading compiler return value to check whether the compiler is loaded instead of "setInterval"
+ let timeout = 0
+ const id = setInterval(() => {
+ timeout++
+ console.log(this.data.loading)
+ if (!this.data.loading || timeout > 10) {
+ resolve()
+ clearInterval(id)
+ }
+ }, 200)
+ })
+ }
+
/*********
* SUB-COMPONENTS
*/
@@ -261,7 +307,7 @@ class CompileTab extends ViewPlugin {
Publish on Ipfs
-
+
Compilation Details
diff --git a/src/app/tabs/compileTab/compilerContainer.js b/src/app/tabs/compileTab/compilerContainer.js
index b91f933bf3..9c3fbfb50a 100644
--- a/src/app/tabs/compileTab/compilerContainer.js
+++ b/src/app/tabs/compileTab/compilerContainer.js
@@ -318,17 +318,21 @@ class CompilerContainer {
this.compileIfAutoCompileOn()
}
+ /*
+ The following functions are handlers for internal events.
+ */
+
onchangeOptimize () {
this.compileTabLogic.setOptimize(!!this._view.optimize.checked)
this.compileIfAutoCompileOn()
}
- onchangeLanguage (event) {
- this.compileTabLogic.setLanguage(event.target.value)
+ onchangeLanguage () {
+ this.compileTabLogic.setLanguage(this._view.languageSelector.value)
this.compileIfAutoCompileOn()
}
- onchangeEvmVersion (_) {
+ onchangeEvmVersion () {
let s = this._view.evmVersionSelector
let v = s.value
if (v === 'default') {
@@ -338,12 +342,37 @@ class CompilerContainer {
this.compileIfAutoCompileOn()
}
- onchangeLoadVersion (event) {
+ onchangeLoadVersion () {
this.data.selectedVersion = this._view.versionSelector.value
this._updateVersionSelector()
this._updateLanguageSelector()
}
+ /*
+ The following functions map with the above event handlers.
+ They are an external API for modifying the compiler configuration.
+ */
+
+ setOptimize (enabled) {
+ this._view.optimize.checked = enabled
+ this.onchangeOptimize()
+ }
+
+ setLanguage (lang) {
+ this._view.languageSelector.value = lang
+ this.onchangeLanguage()
+ }
+
+ setEvmVersion (version) {
+ this._view.evmVersionSelector.value = version || 'default'
+ this.onchangeEvmVersion()
+ }
+
+ setVersion (version) {
+ this._view.versionSelector.value = `soljson-v${version}.js`
+ this.onchangeLoadVersion()
+ }
+
_shouldBeAdded (version) {
return !version.includes('nightly') ||
(version.includes('nightly') && this._view.includeNightlies.checked)
diff --git a/test-browser/commands/verifyContracts.js b/test-browser/commands/verifyContracts.js
index 14f006504e..3275cfb65a 100644
--- a/test-browser/commands/verifyContracts.js
+++ b/test-browser/commands/verifyContracts.js
@@ -1,7 +1,7 @@
const EventEmitter = require('events')
class VerifyContracts extends EventEmitter {
- command (compiledContractNames, opts = { wait: 1000 }) {
+ command (compiledContractNames, opts = { wait: 1000, version: null }) {
this.api.perform((done) => {
verifyContracts(this.api, compiledContractNames, opts, () => {
done()
@@ -17,6 +17,17 @@ function getCompiledContracts (browser, opts, callback) {
.clickLaunchIcon('solidity')
.pause(opts.wait)
.waitForElementPresent('*[data-id="compiledContracts"] option')
+ .perform((done) => {
+ if (opts.version) {
+ browser
+ .click('*[data-id="compilation-details"]')
+ .waitForElementPresent('*[data-id="treeViewLicompiler"]')
+ .click('*[data-id="treeViewLicompiler"]')
+ .waitForElementPresent('*[data-id="treeViewTogglecompiler/version"]')
+ .assert.containsText('*[data-id="treeViewLicompiler/version"]', `version: ${opts.version}`)
+ .perform(done)
+ } else done()
+ })
.execute(function () {
var contracts = document.querySelectorAll('*[data-id="compiledContracts"] option')
if (!contracts) {
diff --git a/test-browser/tests/compiler_api.test.js b/test-browser/tests/compiler_api.test.js
new file mode 100644
index 0000000000..2c267b8177
--- /dev/null
+++ b/test-browser/tests/compiler_api.test.js
@@ -0,0 +1,101 @@
+'use strict'
+var examples = require('../../src/app/editor/example-contracts')
+var init = require('../helpers/init')
+var sauce = require('./sauce')
+
+var sources = [
+ {'browser/Untitled.sol': {content: examples.ballot.content}}
+]
+
+module.exports = {
+ before: function (browser, done) {
+ init(browser, done)
+ },
+ '@sources': function () {
+ return sources
+ },
+
+ 'Should compile using "compileWithParamaters" API': function (browser) {
+ browser
+ .addFile('test_jsCompile.js', { content: jsCompile })
+ .executeScript('remix.exeCurrent()')
+ .pause(5000)
+ .journalChildIncludes('"languageversion": "0.6.8+commit.0bbfe453"')
+ },
+
+ 'Should update the compiler configuration with "setCompilerConfig" API': function (browser) {
+ browser
+ .addFile('test_updateConfiguration.js', { content: updateConfiguration })
+ .executeScript('remix.exeCurrent()')
+ .pause(5000)
+ .addFile('test_updateConfiguration.sol', { content: simpleContract })
+ .verifyContracts(['StorageTestUpdateConfiguration'], {wait: 5000, version: '0.6.8+commit.0bbfe453'})
+ .end()
+ },
+
+ tearDown: sauce
+}
+
+const simpleContract = `pragma solidity >=0.4.22 <0.7.0;
+
+/**
+* @title Storage
+* @dev Store & retreive value in a variable
+*/
+contract StorageTestUpdateConfiguration {
+
+ uint256 number;
+
+ /**
+ * @dev Store value in variable
+ * @param num value to store
+ */
+ function store(uint256 num) public {
+ number = num;
+ }
+
+ /**
+ * @dev Return value
+ * @return value of 'number'
+ */
+ function retreive() public view returns (uint256){
+ return number;
+ }
+}
+
+ `
+
+const jsCompile = `(async () => {
+
+ try {
+ const contract = {
+ "storage.sol": {content : \`${simpleContract}\` }
+ }
+ console.log('compile')
+ const params = {
+ optimize: false,
+ evmVersion: null,
+ language: 'Solidity',
+ version: '0.6.8+commit.0bbfe453',
+ compilerUrl: 'https://solc-bin.ethereum.org/bin/soljson-v0.6.8+commit.0bbfe453.js'
+ }
+ const result = await remix.call('solidity', 'compileWithParameters', contract, params)
+ console.log('result ', result)
+ } catch (e) {
+ console.log(e.message)
+ }
+})()`
+
+const updateConfiguration = `(async () => {
+ try {
+ const params = {
+ optimize: false,
+ evmVersion: null,
+ language: 'Solidity',
+ version: '0.6.8+commit.0bbfe453'
+ }
+ await remix.call('solidity', 'setCompilerConfig', params)
+ } catch (e) {
+ console.log(e.message)
+ }
+})()`