Merge branch 'master' into fixlocal

pull/5370/head
bunsenstraat 3 years ago committed by GitHub
commit 34f75a7e05
  1. 9
      apps/remix-ide/src/app.js
  2. 4
      apps/remix-ide/src/app/files/fileManager.js
  3. 334
      apps/remix-ide/src/app/tabs/compile-tab.js
  4. 235
      apps/remix-ide/src/app/tabs/styles/compile-tab-styles.js
  5. 4
      apps/solidity-compiler/.babelrc
  6. 16
      apps/solidity-compiler/.browserslistrc
  7. 17
      apps/solidity-compiler/src/app/app.tsx
  8. 294
      apps/solidity-compiler/src/app/compiler-api.ts
  9. 75
      apps/solidity-compiler/src/app/compiler.ts
  10. 0
      apps/solidity-compiler/src/assets/.gitkeep
  11. BIN
      apps/solidity-compiler/src/assets/img/ipfs.webp
  12. 4
      apps/solidity-compiler/src/assets/js/.gitignore
  13. 3
      apps/solidity-compiler/src/environments/environment.prod.ts
  14. 6
      apps/solidity-compiler/src/environments/environment.ts
  15. BIN
      apps/solidity-compiler/src/favicon.ico
  16. 15
      apps/solidity-compiler/src/index.html
  17. 1
      apps/solidity-compiler/src/index.ts
  18. 11
      apps/solidity-compiler/src/main.tsx
  19. 7
      apps/solidity-compiler/src/polyfills.ts
  20. 1
      apps/solidity-compiler/src/styles.css
  21. 9
      apps/solidity-compiler/tsconfig.app.json
  22. 16
      apps/solidity-compiler/tsconfig.json
  23. 15
      apps/solidity-compiler/tsconfig.spec.json
  24. 17
      apps/solidity-compiler/webpack.config.js
  25. 21
      libs/remix-lib/src/index.ts
  26. 53
      libs/remix-lib/src/types/ICompilerApi.ts
  27. 5
      libs/remix-lib/src/web3Provider/web3VmProvider.ts
  28. 4
      libs/remix-simulator/src/methods/transactions.ts
  29. 1
      libs/remix-solidity/src/compiler/compiler-utils.ts
  30. 1
      libs/remix-ui/debugger-ui/src/index.ts
  31. 4
      libs/remix-ui/publish-to-storage/src/lib/publish-to-storage.tsx
  32. 13
      libs/remix-ui/renderer/src/lib/renderer.tsx
  33. 12
      libs/remix-ui/solidity-compiler/src/lib/actions/compiler.ts
  34. 59
      libs/remix-ui/solidity-compiler/src/lib/compiler-container.tsx
  35. 2
      libs/remix-ui/solidity-compiler/src/lib/contract-selection.tsx
  36. 52
      libs/remix-ui/solidity-compiler/src/lib/logic/compileTabLogic.ts
  37. 4
      libs/remix-ui/solidity-compiler/src/lib/logic/contract-parser.ts
  38. 52
      libs/remix-ui/solidity-compiler/src/lib/solidity-compiler.tsx
  39. 35
      libs/remix-ui/solidity-compiler/src/lib/types/index.ts
  40. 7
      libs/remix-ui/static-analyser/src/lib/remix-ui-static-analyser.tsx
  41. 3
      nx.json
  42. 2
      package.json
  43. 2
      tsconfig.base.json
  44. 70
      workspace.json

@ -425,13 +425,7 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
}
// CONTENT VIEWS & DEFAULT PLUGINS
const compileTab = new CompileTab(
editor,
registry.get('config').api,
registry.get('fileproviders/browser').api,
registry.get('filemanager').api,
contentImport
)
const compileTab = new CompileTab(registry.get('config').api, registry.get('filemanager').api)
const run = new RunTab(
blockchain,
registry.get('config').api,
@ -456,7 +450,6 @@ Please make a backup of your contracts and start using http://remix.ethereum.org
engine.register([
compileTab,
compileTab.compileTabLogic,
run,
debug,
analysis,

@ -22,7 +22,7 @@ const profile = {
icon: 'assets/img/fileManager.webp',
permission: true,
version: packageJson.version,
methods: ['file', 'exists', 'open', 'writeFile', 'readFile', 'copyFile', 'copyDir', 'rename', 'mkdir', 'readdir', 'remove', 'getCurrentFile', 'getFile', 'getFolder', 'setFile', 'switchFile', 'refresh', 'getProviderOf', 'getProviderByName', 'getPathFromUrl', 'getUrlFromPath'],
methods: ['file', 'exists', 'open', 'writeFile', 'readFile', 'copyFile', 'copyDir', 'rename', 'mkdir', 'readdir', 'remove', 'getCurrentFile', 'getFile', 'getFolder', 'setFile', 'switchFile', 'refresh', 'getProviderOf', 'getProviderByName', 'getPathFromUrl', 'getUrlFromPath', 'saveCurrentFile'],
kind: 'file-system'
}
const errorMsg = {
@ -398,7 +398,7 @@ class FileManager extends Plugin {
}
fileChangedEvent (path) {
this.emit('currentFileChanged', path)
this.emit('fileChanged', path)
}
fileRenamedEvent (oldName, newName, isFolder) {

@ -1,17 +1,18 @@
/* global */
import React from 'react' // eslint-disable-line
import ReactDOM from 'react-dom'
import { SolidityCompiler, CompileTab as CompileTabLogic, parseContracts } from '@remix-ui/solidity-compiler' // eslint-disable-line
import { compile } from '@remix-project/remix-solidity'
import { SolidityCompiler } from '@remix-ui/solidity-compiler' // eslint-disable-line
import { CompileTabLogic } from '@remix-ui/solidity-compiler' // eslint-disable-line
import { CompilerApiMixin } from '@remixproject/solidity-compiler-plugin'
import { ViewPlugin } from '@remixproject/engine-web'
import QueryParams from '../../lib/query-params'
// import { ICompilerApi } from '@remix-project/remix-lib-ts'
import * as packageJson from '../../../../../package.json'
const EventEmitter = require('events')
const $ = require('jquery')
const yo = require('yo-yo')
var QueryParams = require('../../lib/query-params')
const addTooltip = require('../ui/tooltip')
const globalRegistry = require('../../global/registry')
const css = require('./styles/compile-tab-styles')
const profile = {
name: 'solidity',
@ -23,222 +24,72 @@ const profile = {
location: 'sidePanel',
documentation: 'https://remix-ide.readthedocs.io/en/latest/solidity_editor.html',
version: packageJson.version,
methods: ['getCompilationResult', 'compile', 'compileWithParameters', 'setCompilerConfig', 'compileFile']
methods: ['getCompilationResult', 'compile', 'compileWithParameters', 'setCompilerConfig', 'compileFile', 'getCompilerState']
}
// EditorApi:
// - events: ['compilationFinished'],
// - methods: ['getCompilationResult']
class CompileTab extends ViewPlugin {
constructor (editor, config, fileProvider, fileManager, contentImport) {
class CompileTab extends CompilerApiMixin(ViewPlugin) { // implements ICompilerApi
constructor (config, fileManager) {
super(profile)
this.events = new EventEmitter()
this._view = {
el: null,
warnCompilationSlow: null,
errorContainer: null,
contractEl: null
}
this.contentImport = contentImport
this.queryParams = new QueryParams()
this.fileProvider = fileProvider
// dependencies
this.editor = editor
this.config = config
this.fileManager = fileManager
this.contractsDetails = {}
this.data = {
eventHandlers: {},
loading: false
}
this.config = config
this.queryParams = new QueryParams()
this.compileTabLogic = new CompileTabLogic(this, this.contentImport)
this.compiler = this.compileTabLogic.compiler
this.compileTabLogic.init()
this.contractMap = {}
this.isHardHatProject = false
this.compileErrors = {}
this.compiledFileName = ''
this.selectedVersion = ''
this.configurationSettings = null
this.el = document.createElement('div')
this.el.setAttribute('id', 'compileTabView')
this.initCompilerApi()
}
resetResults () {
this.currentFile = ''
this.contractsDetails = {}
this.emit('statusChanged', { key: 'none' })
this.renderComponent()
renderComponent () {
ReactDOM.render(
<SolidityCompiler api={this}/>
, this.el)
}
setCompileErrors (data) {
this.compileErrors = data
onCurrentFileChanged () {
this.renderComponent()
}
/************
* EVENTS
*/
listenToEvents () {
this.data.eventHandlers.onContentChanged = () => {
this.emit('statusChanged', { key: 'edited', title: 'the content has changed, needs recompilation', type: 'info' })
}
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)
this.data.eventHandlers.onStartingCompilation = () => {
this.emit('statusChanged', { key: 'loading', title: 'compiling...', type: 'info' })
}
this.data.eventHandlers.onRemoveAnnotations = () => {
this.call('editor', 'clearAnnotations')
}
const resetView = (isLocalhost) => {
this.compileTabLogic.isHardhatProject().then((result) => {
if (result && isLocalhost) this.isHardHatProject = true
else this.isHardHatProject = false
onResetResults () {
this.renderComponent()
})
this.resetResults()
}
this.on('filePanel', 'setWorkspace', (workspace) => {
resetView(workspace.isLocalhost)
})
this.on('remixd', 'rootFolderChanged', () => {
resetView(true)
})
this.compileTabLogic.event.on('startingCompilation', this.data.eventHandlers.onStartingCompilation)
this.compileTabLogic.event.on('removeAnnotations', this.data.eventHandlers.onRemoveAnnotations)
this.data.eventHandlers.onCurrentFileChanged = (name) => {
this.currentFile = name
onSetWorkspace () {
this.renderComponent()
}
this.fileManager.events.on('currentFileChanged', this.data.eventHandlers.onCurrentFileChanged)
this.data.eventHandlers.onNoFileSelected = () => {
this.currentFile = ''
onNoFileSelected () {
this.renderComponent()
}
this.fileManager.events.on('noFileSelected', this.data.eventHandlers.onNoFileSelected)
this.data.eventHandlers.onCompilationFinished = (success, data, source) => {
this.setCompileErrors(data)
if (success) {
// forwarding the event to the appManager infra
this.emit('compilationFinished', source.target, source, 'soljson', data)
if (data.errors && data.errors.length > 0) {
this.emit('statusChanged', {
key: data.errors.length,
title: `compilation finished successful with warning${data.errors.length > 1 ? 's' : ''}`,
type: 'warning'
})
} else this.emit('statusChanged', { key: 'succeed', title: 'compilation successful', type: 'success' })
// Store the contracts
this.contractsDetails = {}
this.compiler.visitContracts((contract) => {
this.contractsDetails[contract.name] = parseContracts(
contract.name,
contract.object,
this.compiler.getSource(contract.file)
)
})
} else {
const count = (data.errors ? data.errors.filter(error => error.severity === 'error').length : 0) + data.error ? 1 : 0
this.emit('statusChanged', { key: count, title: `compilation failed with ${count} error${count.length > 1 ? 's' : ''}`, type: 'error' })
}
// Update contract Selection
this.contractMap = {}
if (success) this.compiler.visitContracts((contract) => { this.contractMap[contract.name] = contract })
onCompilationFinished () {
this.renderComponent()
}
this.compiler.event.register('compilationFinished', this.data.eventHandlers.onCompilationFinished)
this.data.eventHandlers.onThemeChanged = (theme) => {
const invert = theme.quality === 'dark' ? 1 : 0
const img = document.getElementById('swarmLogo')
if (img) {
img.style.filter = `invert(${invert})`
}
}
globalRegistry.get('themeModule').api.events.on('themeChanged', this.data.eventHandlers.onThemeChanged)
// Run the compiler instead of trying to save the website
$(window).keydown((e) => {
// ctrl+s or command+s
if ((e.metaKey || e.ctrlKey) && e.keyCode === 83) {
e.preventDefault()
this.compileTabLogic.runCompiler(this.hhCompilation)
}
})
}
render () {
if (this.el) return this.el
this.el = yo`
<div class="${css.debuggerTabView}" id="compileTabView">
<div id="compiler" class="${css.compiler}"></div>
</div>`
this.renderComponent()
setHardHatCompilation (value) {
this.hhCompilation = value
return this.el
}
setSelectedVersion (version) {
this.selectedVersion = version
async compileWithParameters (compilationTargets, settings) {
return await super.compileWithParameters(compilationTargets, settings)
}
getCompilationResult () {
return this.compileTabLogic.compiler.state.lastCompilationResult
}
addExternalFile (fileName, content) {
this.fileProvider.addExternal(fileName, content)
}
/**
* 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`<div><b>${this.currentRequest.from}</b> is requiring to compile <b>${fileName}</b></div>`)
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, runs, version, language}
*/
async compileWithParameters (compilationTargets, settings) {
settings.version = settings.version || this.selectedVersion
const res = await compile(compilationTargets, settings)
return res
return super.getCompilationResult()
}
// This function is used for passing the compiler configuration to 'remix-tests'
getCurrentCompilerConfig () {
return {
currentVersion: this.selectedVersion,
evmVersion: this.compileTabLogic.evmVersion,
optimize: this.compileTabLogic.optimize,
runs: this.compileTabLogic.runs
}
getFileManagerMode () {
return this.fileManager.mode
}
/**
@ -247,88 +98,23 @@ class CompileTab extends ViewPlugin {
* @param {object} settings {evmVersion, optimize, runs, version, language}
*/
setCompilerConfig (settings) {
this.configurationSettings = settings
super.setCompilerConfig(settings)
this.renderComponent()
// @todo(#2875) should use loading compiler return value to check whether the compiler is loaded instead of "setInterval"
addTooltip(yo`<div><b>${this.currentRequest.from}</b> is updating the <b>Solidity compiler configuration</b>.<pre class="text-left">${JSON.stringify(settings, null, '\t')}</pre></div>`)
}
// TODO : Add success alert when compilation succeed
contractCompiledSuccess () {
return yo`<div></div>`
}
// TODO : Add error alert when compilation failed
contractCompiledError () {
return yo`<div></div>`
}
/************
* METHODS
*/
selectContract (contractName) {
this.selectedContract = contractName
}
render () {
this.renderComponent()
return this.el
}
renderComponent () {
ReactDOM.render(
<SolidityCompiler plugin={this}/>
, this.el)
}
getParameters () {
return this.queryParams.get()
}
setParameters (params) {
this.queryParams.update(params)
}
getConfiguration (name) {
return this.config.get(name)
}
setConfiguration (name, value) {
this.config.set(name, value)
}
fileProviderOf (fileName) {
return this.fileManager.fileProviderOf(fileName)
}
getFileManagerMode () {
return this.fileManager.mode
}
fileExists (fileName) {
return this.call('fileManager', 'exists', fileName)
}
writeFile (fileName, content) {
return this.call('fileManager', 'writeFile', fileName, content)
}
readFile (fileName) {
return this.call('fileManager', 'readFile', fileName)
}
saveCurrentFile () {
return this.fileManager.saveCurrentFile()
compile (fileName) {
addTooltip(yo`<div><b>${this.currentRequest.from}</b> is requiring to compile <b>${fileName}</b></div>`)
super.compile(fileName)
}
open (fileName) {
return this.call('fileManager', 'open', fileName)
compileFile (event) {
return super.compileFile(event)
}
onActivation () {
this.call('manager', 'activatePlugin', 'solidity-logic')
this.listenToEvents()
super.onActivation()
this.call('filePanel', 'registerContextMenuItem', {
id: 'solidity',
name: 'compileFile',
@ -340,30 +126,26 @@ class CompileTab extends ViewPlugin {
})
}
// Returns if the compilation was successfull
async compileFile (event) {
if (event.path.length > 0) {
try {
return await this.compileTabLogic.compileFile(event.path[0])
} catch (error) {
return false
getCompilerParameters () {
const params = this.queryParams.get()
params.optimize = (params.optimize === 'false' || params.optimize === null || params.optimize === undefined) ? false : params.optimize
params.optimize = params.optimize === 'true' ? true : params.optimize
return params
}
setCompilerParameters (params) {
this.queryParams.update(params)
}
return false
getAppParameter (name) {
const param = this.config.get(name)
if (param === 'true') return true
if (param === 'false') return false
return param
}
onDeactivation () {
this.editor.event.unregister('contentChanged')
this.editor.event.unregister('sessionSwitched')
this.editor.event.unregister('contentChanged', this.data.eventHandlers.onContentChanged)
this.compiler.event.unregister('loadingCompiler', this.data.eventHandlers.onLoadingCompiler)
this.compiler.event.unregister('compilerLoaded', this.data.eventHandlers.onCompilerLoaded)
this.compileTabLogic.event.removeListener('startingCompilation', this.data.eventHandlers.onStartingCompilation)
this.fileManager.events.removeListener('currentFileChanged', this.data.eventHandlers.onCurrentFileChanged)
this.fileManager.events.removeListener('noFileSelected', this.data.eventHandlers.onNoFileSelected)
this.compiler.event.unregister('compilationFinished', this.data.eventHandlers.onCompilationFinished)
globalRegistry.get('themeModule').api.events.removeListener('themeChanged', this.data.eventHandlers.onThemeChanged)
this.call('manager', 'deactivatePlugin', 'solidity-logic')
setAppParameter (name, value) {
this.config.set(name, value)
}
}

@ -1,239 +1,8 @@
const csjs = require('csjs-inject')
const css = csjs`
.title {
font-size: 1.1em;
font-weight: bold;
margin-bottom: 1em;
}
.panicError {
color: red;
font-size: 20px;
}
.crow {
display: flex;
overflow: auto;
clear: both;
padding: .2em;
}
.checkboxText {
font-weight: normal;
}
.crow label {
cursor:pointer;
}
.crowNoFlex {
overflow: auto;
clear: both;
}
.info {
padding: 10px;
word-break: break-word;
}
.contract {
display: block;
margin: 3% 0;
}
.nightlyBuilds {
display: flex;
flex-direction: row;
align-items: center;
}
.autocompileContainer {
display: flex;
align-items: center;
}
.runs {
width: 40%;
}
.hideWarningsContainer {
display: flex;
align-items: center;
}
.autocompile {}
.autocompileTitle {
font-weight: bold;
margin: 1% 0;
}
.autocompileText {
margin: 1% 0;
font-size: 12px;
overflow: hidden;
word-break: normal;
line-height: initial;
}
.warnCompilationSlow {
margin-left: 1%;
}
.compilerConfig {
display: flex;
align-items: center;
}
.compilerConfig label {
margin: 0;
}
.compilerSection {
padding: 12px 24px 16px;
}
.compilerLabel {
margin-bottom: 2px;
font-size: 11px;
line-height: 12px;
text-transform: uppercase;
}
.copyButton {
padding: 6px;
font-weight: bold;
font-size: 11px;
line-height: 15px;
}
.name {
display: flex;
}
.size {
display: flex;
}
.checkboxes {
display: flex;
width: 100%;
justify-content: space-between;
flex-wrap: wrap;
}
.compileButton {
width: 100%;
margin: 15px 0 10px 0;
font-size: 12px;
}
.container {
margin: 0;
margin-bottom: 2%;
}
.optimizeContainer {
display: flex;
}
.noContractAlert {
display: flex;
justify-content: center;
align-items: center;
}
.contractHelperButtons {
margin-top: 6px;
display: flex;
align-items: center;
justify-content: space-between;
float: right;
}
.copyToClipboard {
font-size: 1rem;
}
.copyIcon {
margin-right: 5px;
}
.log {
display: flex;
flex-direction: column;
margin-bottom: 5%;
overflow: visible;
}
.key {
margin-right: 5px;
text-transform: uppercase;
width: 100%;
}
.value {
display: flex;
width: 100%;
margin-top: 1.5%;
}
.questionMark {
margin-left: 2%;
cursor: pointer;
}
.questionMark:hover {
}
.detailsJSON {
padding: 8px 0;
border: none;
}
.icon {
margin-right: 0.3em;
}
.errorBlobs {
padding-left: 5px;
padding-right: 5px;
word-break: break-word;
}
.storageLogo {
width: 20px;
height: 20px;
}
.spinningIcon {
display: inline-block;
position: relative;
animation: spin 2s infinite linear;
-moz-animation: spin 2s infinite linear;
-o-animation: spin 2s infinite linear;
-webkit-animation: spin 2s infinite linear;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
@-webkit-keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
@-moz-keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
@-o-keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
@-ms-keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.bouncingIcon {
display: inline-block;
position: relative;
-moz-animation: bounce 2s infinite linear;
-o-animation: bounce 2s infinite linear;
-webkit-animation: bounce 2s infinite linear;
animation: bounce 2s infinite linear;
}
@-webkit-keyframes bounce {
0% { top: 0; }
50% { top: -0.2em; }
70% { top: -0.3em; }
100% { top: 0; }
}
@-moz-keyframes bounce {
0% { top: 0; }
50% { top: -0.2em; }
70% { top: -0.3em; }
100% { top: 0; }
}
@-o-keyframes bounce {
0% { top: 0; }
50% { top: -0.2em; }
70% { top: -0.3em; }
100% { top: 0; }
}
@-ms-keyframes bounce {
0% { top: 0; }
50% { top: -0.2em; }
70% { top: -0.3em; }
100% { top: 0; }
}
@keyframes bounce {
0% { top: 0; }
50% { top: -0.2em; }
70% { top: -0.3em; }
100% { top: 0; }
.compilerTabView {
padding: 2%;
}
`

@ -0,0 +1,4 @@
{
"presets": ["@nrwl/react/babel"],
"plugins": []
}

@ -0,0 +1,16 @@
# This file is used by:
# 1. autoprefixer to adjust CSS to support the below specified browsers
# 2. babel preset-env to adjust included polyfills
#
# For additional information regarding the format and rule options, please see:
# https://github.com/browserslist/browserslist#queries
#
# If you need to support different browsers in production, you may tweak the list below.
last 1 Chrome version
last 1 Firefox version
last 2 Edge major versions
last 2 Safari major version
last 2 iOS major versions
Firefox ESR
not IE 9-11 # For IE 9-11 support, remove 'not'.

@ -0,0 +1,17 @@
import React, { useState, useEffect } from 'react';
import { SolidityCompiler } from '@remix-ui/solidity-compiler' // eslint-disable-line
import { CompilerClientApi } from './compiler'
const remix = new CompilerClientApi()
export const App = () => {
return (
<div>
<SolidityCompiler api={remix} />
</div>
);
};
export default App;

@ -0,0 +1,294 @@
import { compile } from '@remix-project/remix-solidity'
import { CompileTabLogic, parseContracts } from '@remix-ui/solidity-compiler' // eslint-disable-line
import type { ConfigurationSettings } from '@remix-project/remix-lib-ts'
export const CompilerApiMixin = (Base) => class extends Base {
currentFile: string
contractMap: {
file: string
} | Record<string, any>
compileErrors: any
compileTabLogic: CompileTabLogic
contractsDetails: Record<string, any>
configurationSettings: ConfigurationSettings
onCurrentFileChanged: (fileName: string) => void
onResetResults: () => void
onSetWorkspace: (workspace: any) => void
onNoFileSelected: () => void
onCompilationFinished: (contractsDetails: any, contractMap: any) => void
onSessionSwitched: () => void
onContentChanged: () => void
initCompilerApi () {
this.configurationSettings = null
this._view = {
warnCompilationSlow: null,
errorContainer: null,
contractEl: null
}
this.contractsDetails = {}
this.data = {
eventHandlers: {},
loading: false
}
this.contractMap = {}
this.contractsDetails = {}
this.compileErrors = {}
this.compiledFileName = ''
this.currentFile = ''
}
onActivation () {
this.listenToEvents()
}
onDeactivation () {
this.off('editor', 'contentChanged')
if (this.data.eventHandlers.onLoadingCompiler) {
this.compiler.event.unregister('loadingCompiler', this.data.eventHandlers.onLoadingCompiler)
}
if (this.data.eventHandlers.onCompilerLoaded) {
this.compiler.event.unregister('compilerLoaded', this.data.eventHandlers.onCompilerLoaded)
}
if (this.data.eventHandlers.onCompilationFinished) {
this.compiler.event.unregister('compilationFinished', this.data.eventHandlers.onCompilationFinished)
}
this.off('filePanel', 'setWorkspace')
this.off('remixd', 'rootFolderChanged')
this.off('editor', 'sessionSwitched')
if (this.data.eventHandlers.onStartingCompilation) {
this.compileTabLogic.event.off('startingCompilation', this.data.eventHandlers.onStartingCompilation)
}
if (this.data.eventHandlers.onRemoveAnnotations) {
this.compileTabLogic.event.off('removeAnnotations', this.data.eventHandlers.onRemoveAnnotations)
}
this.off('fileManager', 'currentFileChanged')
this.off('fileManager', 'noFileSelected')
this.off('themeModule', 'themeChanged')
if (this.data.eventHandlers.onKeyDown) {
window.document.removeEventListener('keydown', this.data.eventHandlers.onKeyDown)
}
}
resolveContentAndSave (url) {
return this.call('contentImport', 'resolveAndSave', url)
}
compileWithHardhat (configFile) {
return this.call('hardhat', 'compile', configFile)
}
logToTerminal (content) {
return this.call('terminal', 'log', content)
}
getCompilationResult () {
return this.compileTabLogic.compiler.state.lastCompilationResult
}
getCompilerState () {
return this.compileTabLogic.getCompilerState()
}
/**
* 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) {
return this.compileTabLogic.compileFile(fileName)
}
compileFile (event) {
if (event.path.length > 0) {
this.compileTabLogic.compileFile(event.path[0])
}
}
/**
* 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, runs, version, language}
*/
async compileWithParameters (compilationTargets, settings) {
const compilerState = this.getCompilerState()
settings.version = settings.version || compilerState.currentVersion
const res = await compile(compilationTargets, settings, (url, cb) => this.call('contentImport', 'resolveAndSave', url).then((result) => cb(null, result)).catch((error) => cb(error.message)))
return res
}
// This function is used for passing the compiler configuration to 'remix-tests'
getCurrentCompilerConfig () {
const compilerState = this.getCompilerState()
return {
currentVersion: compilerState.currentVersion,
evmVersion: compilerState.evmVersion,
optimize: compilerState.optimize,
runs: compilerState.runs
}
}
/**
* set the compiler configuration
* This function is used by remix-plugin compiler API.
* @param {object} settings {evmVersion, optimize, runs, version, language}
*/
setCompilerConfig (settings) {
this.configurationSettings = settings
}
fileExists (fileName) {
return this.call('fileManager', 'exists', fileName)
}
writeFile (fileName, content) {
return this.call('fileManager', 'writeFile', fileName, content)
}
readFile (fileName) {
return this.call('fileManager', 'readFile', fileName)
}
open (fileName) {
return this.call('fileManager', 'open', fileName)
}
saveCurrentFile () {
return this.call('fileManager', 'saveCurrentFile')
}
resetResults () {
this.currentFile = ''
this.contractsDetails = {}
this.emit('statusChanged', { key: 'none' })
if (this.onResetResults) this.onResetResults()
}
listenToEvents () {
this.on('editor', 'contentChanged', () => {
this.emit('statusChanged', { key: 'edited', title: 'the content has changed, needs recompilation', type: 'info' })
if (this.onContentChanged) this.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)
this.data.eventHandlers.onStartingCompilation = () => {
this.emit('statusChanged', { key: 'loading', title: 'compiling...', type: 'info' })
}
this.data.eventHandlers.onRemoveAnnotations = () => {
this.call('editor', 'clearAnnotations')
}
this.on('filePanel', 'setWorkspace', (workspace) => {
this.resetResults()
if (this.onSetWorkspace) this.onSetWorkspace(workspace.isLocalhost)
})
this.on('remixd', 'rootFolderChanged', () => {
this.resetResults()
if (this.onSetWorkspace) this.onSetWorkspace(true)
})
this.on('editor', 'sessionSwitched', () => {
if (this.onSessionSwitched) this.onSessionSwitched()
})
this.compileTabLogic.event.on('startingCompilation', this.data.eventHandlers.onStartingCompilation)
this.compileTabLogic.event.on('removeAnnotations', this.data.eventHandlers.onRemoveAnnotations)
this.data.eventHandlers.onCurrentFileChanged = (name) => {
this.currentFile = name
if (this.onCurrentFileChanged) this.onCurrentFileChanged(name)
}
this.on('fileManager', 'currentFileChanged', this.data.eventHandlers.onCurrentFileChanged)
this.data.eventHandlers.onNoFileSelected = () => {
this.currentFile = ''
if (this.onNoFileSelected) this.onNoFileSelected()
}
this.on('fileManager', 'noFileSelected', this.data.eventHandlers.onNoFileSelected)
this.data.eventHandlers.onCompilationFinished = (success, data, source) => {
this.compileErrors = data
if (success) {
// forwarding the event to the appManager infra
this.emit('compilationFinished', source.target, source, 'soljson', data)
if (data.errors && data.errors.length > 0) {
this.emit('statusChanged', {
key: data.errors.length,
title: `compilation finished successful with warning${data.errors.length > 1 ? 's' : ''}`,
type: 'warning'
})
} else this.emit('statusChanged', { key: 'succeed', title: 'compilation successful', type: 'success' })
// Store the contracts
this.contractsDetails = {}
this.compiler.visitContracts((contract) => {
this.contractsDetails[contract.name] = parseContracts(
contract.name,
contract.object,
this.compiler.getSource(contract.file)
)
})
} else {
const count = (data.errors ? data.errors.filter(error => error.severity === 'error').length : 0) + data.error ? 1 : 0
this.emit('statusChanged', { key: count, title: `compilation failed with ${count} error${count > 1 ? 's' : ''}`, type: 'error' })
}
// Update contract Selection
this.contractMap = {}
if (success) this.compiler.visitContracts((contract) => { this.contractMap[contract.name] = contract })
if (this.onCompilationFinished) this.onCompilationFinished(this.contractsDetails, this.contractMap)
}
this.compiler.event.register('compilationFinished', this.data.eventHandlers.onCompilationFinished)
this.data.eventHandlers.onThemeChanged = (theme) => {
const invert = theme.quality === 'dark' ? 1 : 0
const img = document.getElementById('swarmLogo')
if (img) {
img.style.filter = `invert(${invert})`
}
}
this.on('themeModule', 'themeChanged', this.data.eventHandlers.onThemeChanged)
// Run the compiler instead of trying to save the website
this.data.eventHandlers.onKeyDown = (e) => {
// ctrl+s or command+s
if ((e.metaKey || e.ctrlKey) && e.keyCode === 83) {
e.preventDefault()
this.compileTabLogic.runCompiler(this.getAppParameter('hardhat-compilation'))
}
}
window.document.addEventListener('keydown', this.data.eventHandlers.onKeyDown)
}
}

@ -0,0 +1,75 @@
import { PluginClient } from "@remixproject/plugin";
import { createClient } from "@remixproject/plugin-webview";
import { CompilerApiMixin } from './compiler-api'
import { ICompilerApi } from '@remix-project/remix-lib-ts'
import { CompileTabLogic } from '@remix-ui/solidity-compiler'
const profile = {
name: 'solidity',
displayName: 'Solidity compiler',
icon: 'assets/img/solidity.webp',
description: 'Compile solidity contracts',
kind: 'compiler',
permission: true,
location: 'sidePanel',
documentation: 'https://remix-ide.readthedocs.io/en/latest/solidity_editor.html',
version: '0.0.1',
methods: ['getCompilationResult', 'compile', 'compileWithParameters', 'setCompilerConfig', 'compileFile' ,'getCompilerState']
}
const defaultAppParameters = {
hideWarnings: false,
autoCompile: false,
includeNightlies: false
}
const defaultCompilerParameters = {
runs: '200',
optimize: false,
version: 'soljson-v0.8.7+commit.e28d00a7',
evmVersion: null, // compiler default
language: 'Solidity'
}
export class CompilerClientApi extends CompilerApiMixin(PluginClient) implements ICompilerApi {
constructor () {
super()
createClient(this as any)
this.compileTabLogic = new CompileTabLogic(this, this.contentImport)
this.compiler = this.compileTabLogic.compiler
this.compileTabLogic.init()
this.initCompilerApi()
}
getCompilerParameters () {
const params = {
runs: localStorage.getItem('runs') || defaultCompilerParameters['runs'],
optimize: localStorage.getItem('optimize') === 'true' ? true : false,
version: localStorage.getItem('version') || defaultCompilerParameters['version'],
evmVersion: localStorage.getItem('evmVersion') || defaultCompilerParameters['evmVersion'], // default
language: localStorage.getItem('language') || defaultCompilerParameters['language']
}
return params
}
setCompilerParameters (params) {
for (const key of Object.keys(params)) {
localStorage.setItem(key, params[key])
}
}
getAppParameter (name) {
const param = localStorage.getItem(name) || defaultAppParameters[name]
if (param === 'true') return true
if (param === 'false') return false
return param
}
setAppParameter (name, value) {
localStorage.setItem(name, value)
}
getFileManagerMode () {
return 'browser'
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

@ -0,0 +1,4 @@
# Ignore everything in this directory
*
# Except this file
!.gitignore

@ -0,0 +1,3 @@
export const environment = {
production: true
};

@ -0,0 +1,6 @@
// This file can be replaced during build by using the `fileReplacements` array.
// When building for production, this file is replaced with `environment.prod.ts`.
export const environment = {
production: false
};

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

@ -0,0 +1,15 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Solidity Compiler</title>
<base href="./" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" type="image/x-icon" href="favicon.ico" />
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.1/css/all.css" integrity="sha384-50oBUHEmvpQ+1lW4y57PTFmhCaXp0ML5d60M1M7uH2+nqUivzIebhndOJK28anvf" crossorigin="anonymous"/>
</head>
<body>
<div id="root"></div>
</body>
</html>

@ -0,0 +1 @@
export * from './app/compiler-api';

@ -0,0 +1,11 @@
import React from 'react';
import ReactDOM from 'react-dom';
import App from './app/app';
ReactDOM.render(
<React.StrictMode>
<App />
</React.StrictMode>,
document.getElementById('root')
);

@ -0,0 +1,7 @@
/**
* Polyfill stable language features. These imports will be optimized by `@babel/preset-env`.
*
* See: https://github.com/zloirock/core-js#babel
*/
import 'core-js/stable';
import 'regenerator-runtime/runtime';

@ -0,0 +1 @@
/* You can add global styles to this file, and also import other style files */

@ -0,0 +1,9 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"types": ["node"]
},
"exclude": ["**/*.spec.ts", "**/*.spec.tsx"],
"include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"]
}

@ -0,0 +1,16 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"jsx": "react",
"allowJs": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"types": ["node", "jest"],
"resolveJsonModule": true
},
"files": [
"../../node_modules/@nrwl/react/typings/cssmodule.d.ts",
"../../node_modules/@nrwl/react/typings/image.d.ts"
],
"include": ["**/*.js", "**/*.jsx", "**/*.ts", "**/*.tsx"]
}

@ -0,0 +1,15 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"outDir": "../../dist/out-tsc",
"module": "commonjs",
"types": ["jest", "node"]
},
"include": [
"**/*.spec.ts",
"**/*.spec.tsx",
"**/*.spec.js",
"**/*.spec.jsx",
"**/*.d.ts"
]
}

@ -0,0 +1,17 @@
const nxWebpack = require('@nrwl/react/plugins/webpack')
module.exports = config => {
const nxWebpackConfig = nxWebpack(config)
return {
...nxWebpackConfig,
node: {
fs: 'empty',
tls: 'empty',
readline: 'empty',
net: 'empty',
module: 'empty',
child_process: 'empty'
}
}
}

@ -18,25 +18,19 @@ import * as typeConversion from './execution/typeConversion'
import { TxRunnerVM } from './execution/txRunnerVM'
import { TxRunnerWeb3 } from './execution/txRunnerWeb3'
import * as txResultHelper from './helpers/txResultHelper'
export { ICompilerApi, ConfigurationSettings } from './types/ICompilerApi'
export = modules()
function modules () {
return {
EventManager: EventManager,
helpers: {
const helpers = {
ui: uiHelper,
compiler: compilerHelper,
txResultHelper
},
vm: {
}
const vm = {
Web3Providers: Web3Providers,
DummyProvider: DummyProvider,
Web3VMProvider: Web3VmProvider
},
Storage: Storage,
util: util,
execution: {
}
const execution = {
EventsDecoder: EventsDecoder,
txExecution: txExecution,
txHelper: txHelper,
@ -49,5 +43,4 @@ function modules () {
LogsManager,
forkAt
}
}
}
export { EventManager, helpers, vm, Storage, util, execution }

@ -0,0 +1,53 @@
export interface ICompilerApi {
currentFile: string
contractMap: {
file: string
} | Record<string, any>
compileErrors: any
compileTabLogic: any
contractsDetails: Record<string, any>
configurationSettings: ConfigurationSettings
getCompilerParameters: () => ConfigurationSettings
setCompilerParameters: (ConfigurationSettings?) => void
getAppParameter: (value: string) => string | boolean
setAppParameter: (name: string, value: string | boolean) => void
getFileManagerMode: () => string
setCompilerConfig: (settings: any) => void
getCompilationResult: () => any
onCurrentFileChanged: (fileName: string) => void
onResetResults: () => void,
onSetWorkspace: (workspace: any) => void
onNoFileSelected: () => void
onCompilationFinished: (contractsDetails: any, contractMap: any) => void
onSessionSwitched: () => void
onContentChanged: () => void
resolveContentAndSave: (url: string) => Promise<string>
fileExists: (file: string) => Promise<boolean>
writeFile: (file: string, content: string) => Promise<void>
readFile: (file: string) => Promise<string>
open: (file: string) => void
saveCurrentFile: () => void
logToTerminal: (log: terminalLog) => {}
compileWithHardhat: (configPath: string) => Promise<string>
}
export type terminalLog = {
type: 'info' | 'error' | 'warning'
value: string
}
export interface ConfigurationSettings {
version: string,
evmVersion: string,
language: string,
optimize: boolean,
runs: string
}

@ -144,8 +144,9 @@ export class Web3VmProvider {
if (lastOp) {
lastOp.error = lastOp.op !== 'RETURN' && lastOp.op !== 'STOP' && lastOp.op !== 'DESTRUCT'
}
this.vmTraces[this.processingHash].gas = '0x' + data.gasUsed.toString(16)
const gasUsed = '0x' + data.gasUsed.toString(16)
this.vmTraces[this.processingHash].gas = gasUsed
this.txsReceipt[this.processingHash].gasUsed = gasUsed
const logs = []
for (const l in data.execResult.logs) {
const log = data.execResult.logs[l]

@ -102,8 +102,8 @@ export class Transactions {
transactionIndex: '0x00',
blockHash: '0x' + txBlock.hash().toString('hex'),
blockNumber: '0x' + txBlock.header.number.toString('hex'),
gasUsed: Web3.utils.toHex(receipt.gas),
cumulativeGasUsed: Web3.utils.toHex(receipt.gas),
gasUsed: receipt.gasUsed,
cumulativeGasUsed: receipt.gasUsed, // only 1 tx per block
contractAddress: receipt.contractAddress,
logs: receipt.logs,
status: receipt.status,

@ -22,6 +22,7 @@ export function urlFromVersion (version) {
if (!location.endsWith('/')) location += '/'
url = `${location}soljson.js`
} else {
version = version.replace('.Emscripten.clang', '')
if (!version.startsWith('soljson-v')) version = 'soljson-v' + version
if (!version.endsWith('.js')) version = version + '.js'
url = `${pathToURL[version]}/${version}`

@ -1,3 +1,2 @@
export * from './lib/debugger-ui'
export * from './lib/idebugger-api'
export * from './lib/idebugger-api'

@ -29,7 +29,7 @@ export const PublishToStorage = (props: RemixUiPublishToStorageProps) => {
modal(`Published ${contract.name}'s Metadata`, publishMessage(result.uploaded))
// triggered each time there's a new verified publish (means hash correspond)
api.addExternalFile('swarm/' + result.item.hash, result.item.content)
api.writeFile('swarm/' + result.item.hash, result.item.content)
} catch (err) {
let parseError = err
try {
@ -43,7 +43,7 @@ export const PublishToStorage = (props: RemixUiPublishToStorageProps) => {
modal(`Published ${contract.name}'s Metadata`, publishMessage(result.uploaded))
// triggered each time there's a new verified publish (means hash correspond)
api.addExternalFile('ipfs/' + result.item.hash, result.item.content)
api.writeFile('ipfs/' + result.item.hash, result.item.content)
} catch (err) {
modal('IPFS Publish Failed', publishMessageFailed(storage, err))
}

@ -69,7 +69,7 @@ export const Renderer = ({ message, opt = {}, plugin }: RendererProps) => {
}
const addAnnotation = (file, error) => {
if (file === plugin.getConfiguration('currentFile')) {
if (file === plugin.getAppParameter('currentFile')) {
plugin.call('editor', 'addAnnotation', error, file)
}
}
@ -86,17 +86,12 @@ export const Renderer = ({ message, opt = {}, plugin }: RendererProps) => {
setClose(true)
}
const _errorClick = (errFile, errLine, errCol) => {
if (errFile !== plugin.getConfiguration('currentFile')) {
const _errorClick = async (errFile, errLine, errCol) => {
if (errFile !== plugin.getAppParameter('currentFile')) {
// TODO: refactor with this._components.contextView.jumpTo
const provider = plugin.fileProviderOf(errFile)
if (provider) {
provider.exists(errFile).then(() => {
if (await plugin.fileExists(errFile)) {
plugin.open(errFile)
plugin.call('editor', 'gotoLine', errLine, errCol)
}).catch(error => {
if (error) return console.log(error)
})
}
} else {
plugin.call('editor', 'gotoLine', errLine, errCol)

@ -1,5 +1,5 @@
import React from 'react'
import { CompileTabLogic } from '../logic/compileTabLogic'
export const setEditorMode = (mode: string) => {
return {
type: 'SET_EDITOR_MODE',
@ -26,10 +26,10 @@ export const resetCompilerMode = () => (dispatch: React.Dispatch<any>) => {
})
}
export const listenToEvents = (compileTabLogic, api) => (dispatch: React.Dispatch<any>) => {
api.on('editor', 'sessionSwitched', () => {
export const listenToEvents = (compileTabLogic: CompileTabLogic, api) => (dispatch: React.Dispatch<any>) => {
api.onSessionSwitched = () => {
dispatch(setEditorMode('sessionSwitched'))
})
}
compileTabLogic.event.on('startingCompilation', () => {
dispatch(setCompilerMode('startingCompilation'))
@ -39,9 +39,9 @@ export const listenToEvents = (compileTabLogic, api) => (dispatch: React.Dispatc
dispatch(setCompilerMode('compilationDuration', speed))
})
api.on('editor', 'contentChanged', () => {
api.onContentChanged = () => {
dispatch(setEditorMode('contentChanged'))
})
}
compileTabLogic.compiler.event.register('loadingCompiler', () => {
dispatch(setCompilerMode('loadingCompiler'))

@ -1,6 +1,7 @@
import React, { useEffect, useState, useRef, useReducer } from 'react' // eslint-disable-line
import semver from 'semver'
import { CompilerContainerProps, ConfigurationSettings } from './types'
import { CompilerContainerProps } from './types'
import { ConfigurationSettings } from '@remix-project/remix-lib-ts'
import * as helper from '../../../../../apps/remix-ide/src/lib/helper'
import { canUseWorker, baseURLBin, baseURLWasm, urlFromVersion, pathToURL, promisedMiniXhr } from '@remix-project/remix-solidity'
import { compilerReducer, compilerInitialState } from './reducers/compiler'
@ -18,22 +19,21 @@ declare global {
const _paq = window._paq = window._paq || [] //eslint-disable-line
export const CompilerContainer = (props: CompilerContainerProps) => {
const { api, compileTabLogic, tooltip, modal, compiledFileName, updateCurrentVersion, configurationSettings } = props // eslint-disable-line
const { api, compileTabLogic, tooltip, modal, compiledFileName, updateCurrentVersion, configurationSettings, isHardhatProject } = props // eslint-disable-line
const [state, setState] = useState({
hideWarnings: false,
autoCompile: false,
optimise: false,
optimize: false,
compileTimeout: null,
timeout: 300,
allversions: [],
customVersions: [],
selectedVersion: null,
defaultVersion: 'soljson-v0.8.7+commit.e28d00a7.js', // this default version is defined: in makeMockCompiler (for browser test)
selectedLanguage: '',
runs: '',
compiledFileName: '',
includeNightlies: false,
language: '',
language: 'Solidity',
evmVersion: ''
})
const [disableCompileButton, setDisableCompileButton] = useState<boolean>(false)
@ -56,7 +56,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
_updateVersionSelector(selectedVersion)
}
})
const currentFileName = api.getConfiguration('currentFile')
const currentFileName = api.currentFile
currentFile(currentFileName)
listenToEvents(compileTabLogic, api)(dispatch)
@ -65,19 +65,18 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
useEffect(() => {
if (compileTabLogic && compileTabLogic.compiler) {
setState(prevState => {
const params = api.getParameters()
const optimize = params.optimize === 'false' ? false : params.optimize === 'true' ? true : null
const runs = params.runs
const params = api.getCompilerParameters()
const optimize = params.optimize
const runs = params.runs as string
const evmVersion = params.evmVersion
const autoCompile = params.autoCompile === 'false' ? false : params.autoCompile === 'true' ? true : null
return {
...prevState,
hideWarnings: api.getConfiguration('hideWarnings') || false,
autoCompile: typeof autoCompile === 'boolean' ? autoCompile : api.getConfiguration('autoCompile') || false,
includeNightlies: api.getConfiguration('includeNightlies') || false,
optimise: typeof optimize === 'boolean' ? optimize : api.getConfiguration('optimise') || false,
runs: (runs !== null) && (runs !== 'null') && (runs !== undefined) && (runs !== 'undefined') ? runs : 200,
hideWarnings: api.getAppParameter('hideWarnings') as boolean || false,
autoCompile: api.getAppParameter('autoCompile') as boolean || false,
includeNightlies: api.getAppParameter('includeNightlies') as boolean || false,
optimize: optimize,
runs: runs,
evmVersion: (evmVersion !== null) && (evmVersion !== 'null') && (evmVersion !== undefined) && (evmVersion !== 'undefined') ? evmVersion : 'default'
}
})
@ -153,7 +152,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
allVersions = [...allVersions, ...versions]
selectedVersion = state.defaultVersion
if (api.getParameters().version) selectedVersion = api.getParameters().version
if (api.getCompilerParameters().version) selectedVersion = api.getCompilerParameters().version
// Check if version is a URL and corresponding filename starts with 'soljson'
if (selectedVersion.startsWith('https://')) {
const urlArr = selectedVersion.split('/')
@ -228,8 +227,8 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
})
}
const isSolFileSelected = (currentFile = '') => {
if (!currentFile) currentFile = api.getConfiguration('currentFile')
const isSolFileSelected = (currentFile: string = '') => {
if (!currentFile) currentFile = api.currentFile
if (!currentFile) return false
const extention = currentFile.substr(currentFile.length - 3, currentFile.length)
return extention.toLowerCase() === 'sol' || extention.toLowerCase() === 'yul'
@ -298,7 +297,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
}
const compile = () => {
const currentFile = api.getConfiguration('currentFile')
const currentFile = api.currentFile
if (!isSolFileSelected()) return
@ -322,7 +321,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
})
}
updateCurrentVersion(selectedVersion)
api.setParameters({ version: selectedVersion })
api.setCompilerParameters({ version: selectedVersion })
let url
if (customUrl !== '') {
@ -332,7 +331,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
})
updateCurrentVersion(selectedVersion)
url = customUrl
api.setParameters({ version: selectedVersion })
api.setCompilerParameters({ version: selectedVersion })
} else {
if (helper.checkSpecialChars(selectedVersion)) {
return console.log('loading ' + selectedVersion + ' not allowed, special chars not allowed.')
@ -403,7 +402,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
const handleAutoCompile = (e) => {
const checked = e.target.checked
api.setConfiguration('autoCompile', checked)
api.setAppParameter('autoCompile', checked)
checked && compile()
setState(prevState => {
return { ...prevState, autoCompile: checked }
@ -413,7 +412,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
const handleOptimizeChange = (value) => {
const checked = !!value
api.setConfiguration('optimise', checked)
api.setAppParameter('optimize', checked)
compileTabLogic.setOptimize(checked)
if (compileTabLogic.optimize) {
compileTabLogic.setRuns(parseInt(state.runs))
@ -422,7 +421,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
}
state.autoCompile && compile()
setState(prevState => {
return { ...prevState, optimise: checked }
return { ...prevState, optimize: checked }
})
}
@ -439,7 +438,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
const handleHideWarningsChange = (e) => {
const checked = e.target.checked
api.setConfiguration('hideWarnings', checked)
api.setAppParameter('hideWarnings', checked)
state.autoCompile && compile()
setState(prevState => {
return { ...prevState, hideWarnings: checked }
@ -450,7 +449,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
const checked = e.target.checked
if (!checked) handleLoadVersion(state.defaultVersion)
api.setConfiguration('includeNightlies', checked)
api.setAppParameter('includeNightlies', checked)
setState(prevState => {
return { ...prevState, includeNightlies: checked }
})
@ -481,7 +480,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
const checked = event.target.checked
sethhCompilation(checked)
api.setHardHatCompilation(checked)
api.setAppParameter('hardhat-compilation', checked)
}
/*
@ -552,7 +551,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
</div>
<div className="mt-2 remixui_compilerConfig custom-control custom-checkbox">
<div className="justify-content-between align-items-center d-flex">
<input onChange={(e) => { handleOptimizeChange(e.target.checked) }} className="custom-control-input" id="optimize" type="checkbox" checked={state.optimise} />
<input onChange={(e) => { handleOptimizeChange(e.target.checked) }} className="custom-control-input" id="optimize" type="checkbox" checked={state.optimize} />
<label className="form-check-label custom-control-label" htmlFor="optimize">Enable optimization</label>
<input
min="1"
@ -563,7 +562,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
type="number"
title="Estimated number of times each opcode of the deployed code will be executed across the life-time of the contract."
onChange={(e) => onChangeRuns(e.target.value)}
disabled={!state.optimise}
disabled={!state.optimize}
/>
</div>
</div>
@ -573,7 +572,7 @@ export const CompilerContainer = (props: CompilerContainerProps) => {
</div>
</div>
{
api.isHardHatProject &&
isHardhatProject &&
<div className="mt-3 remixui_compilerConfig custom-control custom-checkbox">
<input className="remixui_autocompile custom-control-input" onChange={updatehhCompilation} id="enableHardhat" type="checkbox" title="Enable Hardhat Compilation" checked={hhCompilation} />
<label className="form-check-label custom-control-label" htmlFor="enableHardhat">Enable Hardhat Compilation</label>

@ -115,7 +115,7 @@ export const ContractSelection = (props: ContractSelectionProps) => {
let node
if (propertyName === 'web3Deploy' || propertyName === 'name' || propertyName === 'Assembly') {
node = <pre>{ details[propertyName] }</pre>
} else if (propertyName === 'abi' || propertyName === 'metadata') {
} else if (details[propertyName] && (propertyName === 'abi' || propertyName === 'metadata')) {
if (details[propertyName] !== '') {
try {
node = <div>

@ -1,15 +1,7 @@
import { Plugin } from '@remixproject/engine'
import { ICompilerApi } from '@remix-project/remix-lib-ts'
const packageJson = require('../../../../../../package.json')
const Compiler = require('@remix-project/remix-solidity').Compiler
const EventEmitter = require('events')
const profile = {
name: 'solidity-logic',
displayName: 'Solidity compiler logic',
description: 'Compile solidity contracts - Logic',
methods: ['getCompilerState'],
version: packageJson.version
}
declare global {
interface Window {
@ -18,7 +10,7 @@ declare global {
}
const _paq = window._paq = window._paq || [] //eslint-disable-line
export class CompileTab extends Plugin {
export class CompileTabLogic {
public compiler
public optimize
public runs
@ -26,46 +18,44 @@ export class CompileTab extends Plugin {
public compilerImport
public event
constructor (public api, public contentImport) {
super(profile)
constructor (public api: ICompilerApi, public contentImport) {
this.event = new EventEmitter()
this.compiler = new Compiler((url, cb) => this.call('contentImport', 'resolveAndSave', url).then((result) => cb(null, result)).catch((error) => cb(error.message)))
this.compiler = new Compiler((url, cb) => api.resolveContentAndSave(url).then((result) => cb(null, result)).catch((error) => cb(error.message)))
}
init () {
this.optimize = this.api.getParameters().optimize
this.optimize = this.optimize === 'true'
this.api.setParameters({ optimize: this.optimize })
this.optimize = this.api.getCompilerParameters().optimize
this.api.setCompilerParameters({ optimize: this.optimize })
this.compiler.set('optimize', this.optimize)
this.runs = this.api.getParameters().runs
this.runs = this.api.getCompilerParameters().runs
this.runs = this.runs && this.runs !== 'undefined' ? this.runs : 200
this.api.setParameters({ runs: this.runs })
this.api.setCompilerParameters({ runs: this.runs })
this.compiler.set('runs', this.runs)
this.evmVersion = this.api.getParameters().evmVersion
this.evmVersion = this.api.getCompilerParameters().evmVersion
if (this.evmVersion === 'undefined' || this.evmVersion === 'null' || !this.evmVersion) {
this.evmVersion = null
}
this.api.setParameters({ evmVersion: this.evmVersion })
this.api.setCompilerParameters({ evmVersion: this.evmVersion })
this.compiler.set('evmVersion', this.evmVersion)
}
setOptimize (newOptimizeValue) {
this.optimize = newOptimizeValue
this.api.setParameters({ optimize: this.optimize })
this.api.setCompilerParameters({ optimize: this.optimize })
this.compiler.set('optimize', this.optimize)
}
setRuns (runs) {
this.runs = runs
this.api.setParameters({ runs: this.runs })
this.api.setCompilerParameters({ runs: this.runs })
this.compiler.set('runs', this.runs)
}
setEvmVersion (newEvmVersion) {
this.evmVersion = newEvmVersion
this.api.setParameters({ evmVersion: this.evmVersion })
this.api.setCompilerParameters({ evmVersion: this.evmVersion })
this.compiler.set('evmVersion', this.evmVersion)
}
@ -87,15 +77,14 @@ export class CompileTab extends Plugin {
*/
compileFile (target) {
if (!target) throw new Error('No target provided for compiliation')
const provider = this.api.fileProviderOf(target)
if (!provider) throw new Error(`cannot compile ${target}. Does not belong to any explorer`)
return new Promise((resolve, reject) => {
provider.get(target, (error, content) => {
if (error) return reject(error)
this.api.readFile(target).then((content) => {
const sources = { [target]: { content } }
this.event.emit('startingCompilation')
// setTimeout fix the animation on chrome... (animation triggered by 'staringCompilation')
setTimeout(() => { this.compiler.compile(sources, target); resolve(true) }, 100)
}).catch((error) => {
reject(error)
})
})
}
@ -124,16 +113,17 @@ export class CompileTab extends Plugin {
const configFilePath = 'remix-compiler.config.js'
this.api.writeFile(configFilePath, fileContent)
_paq.push(['trackEvent', 'compiler', 'compileWithHardhat'])
this.call('hardhat', 'compile', configFilePath).then((result) => {
this.call('terminal', 'log', { type: 'info', value: result })
this.api.compileWithHardhat(configFilePath).then((result) => {
this.api.logToTerminal({ type: 'info', value: result })
}).catch((error) => {
this.call('terminal', 'log', { type: 'error', value: error })
this.api.logToTerminal({ type: 'error', value: error })
})
}
}
// TODO readd saving current file
this.api.saveCurrentFile()
this.event.emit('removeAnnotations')
var currentFile = this.api.getConfiguration('currentFile')
var currentFile = this.api.currentFile
return this.compileFile(currentFile)
} catch (err) {
console.error(err)

@ -1,8 +1,8 @@
'use strict'
import * as solcTranslate from 'solc/translate'
import * as remixLib from '@remix-project/remix-lib'
import { execution } from '@remix-project/remix-lib'
const txHelper = remixLib.execution.txHelper
const txHelper = execution.txHelper
export function parseContracts (contractName, contract, source) {
const detail: Record<string, any> = {}

@ -9,10 +9,12 @@ import { Renderer } from '@remix-ui/renderer' // eslint-disable-line
import './css/style.css'
export const SolidityCompiler = (props: SolidityCompilerProps) => {
const { plugin, plugin: { compileTabLogic, contractsDetails, contractMap, compileErrors, configurationSettings } } = props
const { api, api: { currentFile, compileTabLogic, contractsDetails, contractMap, compileErrors, configurationSettings } } = props
const [state, setState] = useState({
isHardhatProject: false,
currentFile,
contractsDetails: {},
eventHandlers: {},
contractMap: {},
loading: false,
compileTabLogic: null,
compiler: null,
@ -30,6 +32,37 @@ export const SolidityCompiler = (props: SolidityCompilerProps) => {
})
const [currentVersion, setCurrentVersion] = useState('')
api.onCurrentFileChanged = (currentFile: string) => {
setState(prevState => {
return { ...prevState, currentFile }
})
}
api.onResetResults = () => {
setState(prevState => {
return { ...prevState, currentFile: '', contractsDetails: {}, contractMap: {} }
})
}
api.onSetWorkspace = async (isLocalhost: boolean) => {
const isHardhat = isLocalhost && await compileTabLogic.isHardhatProject()
setState(prevState => {
return { ...prevState, currentFile, isHardhatProject: isHardhat }
})
}
api.onNoFileSelected = () => {
setState(prevState => {
return { ...prevState, currentFile: '' }
})
}
api.onCompilationFinished = (contractsDetails: any, contractMap: any) => {
setState(prevState => {
return { ...prevState, contractsDetails, contractMap }
})
}
const toast = (message: string) => {
setState(prevState => {
return { ...prevState, toasterMsg: message }
@ -38,7 +71,7 @@ export const SolidityCompiler = (props: SolidityCompilerProps) => {
const updateCurrentVersion = (value) => {
setCurrentVersion(value)
plugin.setSelectedVersion(value)
api.setCompilerParameters({ version: value })
}
const modal = async (title: string, message: string | JSX.Element, okLabel: string, okFn: () => void, cancelLabel?: string, cancelFn?: () => void) => {
@ -75,23 +108,22 @@ export const SolidityCompiler = (props: SolidityCompilerProps) => {
</div>
)
const currentFile = plugin.getConfiguration('currentFile')
return (
<>
<div id="compileTabView">
<CompilerContainer api={plugin} compileTabLogic={compileTabLogic} tooltip={toast} modal={modal} compiledFileName={currentFile} updateCurrentVersion={updateCurrentVersion} configurationSettings={configurationSettings} />
<ContractSelection api={plugin} contractMap={contractMap} contractsDetails={contractsDetails} modal={modal} />
<CompilerContainer api={api} isHardhatProject={state.isHardhatProject} compileTabLogic={compileTabLogic} tooltip={toast} modal={modal} compiledFileName={currentFile} updateCurrentVersion={updateCurrentVersion} configurationSettings={configurationSettings} />
<ContractSelection api={api} contractMap={contractMap} contractsDetails={contractsDetails} modal={modal} />
<div className="remixui_errorBlobs p-4" data-id="compiledErrors">
<span data-id={`compilationFinishedWith_${currentVersion}`}></span>
{ compileErrors.error && <Renderer message={compileErrors.error.formattedMessage || compileErrors.error} plugin={plugin} opt={{ type: compileErrors.error.severity || 'error', errorType: compileErrors.error.type }} /> }
{ compileErrors.error && <Renderer message={compileErrors.error.formattedMessage || compileErrors.error} plugin={api} opt={{ type: compileErrors.error.severity || 'error', errorType: compileErrors.error.type }} /> }
{ compileErrors.error && (compileErrors.error.mode === 'panic') && modal('Error', panicMessage(compileErrors.error.formattedMessage), 'Close', null) }
{ compileErrors.errors && compileErrors.errors.length && compileErrors.errors.map((err, index) => {
if (plugin.getConfiguration('hideWarnings')) {
if (api.getAppParameter('hideWarnings')) {
if (err.severity !== 'warning') {
return <Renderer key={index} message={err.formattedMessage} plugin={plugin} opt={{ type: err.severity, errorType: err.type }} />
return <Renderer key={index} message={err.formattedMessage} plugin={api} opt={{ type: err.severity, errorType: err.type }} />
}
} else {
return <Renderer key={index} message={err.formattedMessage} plugin={plugin} opt={{ type: err.severity, errorType: err.type }} />
return <Renderer key={index} message={err.formattedMessage} plugin={api} opt={{ type: err.severity, errorType: err.type }} />
}
}) }
</div>

@ -1,24 +1,15 @@
import { ICompilerApi, ConfigurationSettings } from '@remix-project/remix-lib-ts'
import { CompileTabLogic } from '../logic/compileTabLogic'
export type onCurrentFileChanged = (fileName: string) => void
export interface SolidityCompilerProps {
plugin: {
contractMap: {
file: string
} | Record<string, any>
compileErrors: any,
compileTabLogic: any,
contractsDetails: Record<string, any>,
contentImport: any,
call: (...args) => void
on: (...args) => void,
setSelectedVersion: (value: string) => void,
configurationSettings: ConfigurationSettings,
getConfiguration: (value: string) => string,
setConfiguration: (name: string, value: string) => void
},
api: ICompilerApi
}
export interface CompilerContainerProps {
api: any,
compileTabLogic: any,
api: ICompilerApi,
compileTabLogic: CompileTabLogic,
isHardhatProject: boolean,
tooltip: (message: string | JSX.Element) => void,
modal: (title: string, message: string | JSX.Element, okLabel: string, okFn: () => void, cancelLabel?: string, cancelFn?: () => void) => void,
compiledFileName: string,
@ -26,18 +17,10 @@ export interface CompilerContainerProps {
configurationSettings: ConfigurationSettings
}
export interface ContractSelectionProps {
api: any,
api: ICompilerApi,
contractMap: {
file: string
} | Record<string, any>,
modal: (title: string, message: string | JSX.Element, okLabel: string, okFn: () => void, cancelLabel?: string, cancelFn?: () => void) => void,
contractsDetails: Record<string, any>
}
export interface ConfigurationSettings {
version: string,
evmVersion: string,
language: string,
optimize: boolean,
runs: string
}

@ -1,6 +1,6 @@
import React, { useEffect, useState, useReducer } from 'react'
import Button from './Button/StaticAnalyserButton' // eslint-disable-line
import remixLib from '@remix-project/remix-lib'
import { util } from '@remix-project/remix-lib'
import _ from 'lodash'
import { TreeView, TreeViewItem } from '@remix-ui/tree-view' // eslint-disable-line
import { RemixUiCheckbox } from '@remix-ui/checkbox' // eslint-disable-line
@ -9,7 +9,6 @@ import { compilation } from './actions/staticAnalysisActions'
import { initialState, analysisReducer } from './reducers/staticAnalysisReducer'
import { OverlayTrigger, Tooltip } from 'react-bootstrap'// eslint-disable-line
const StaticAnalysisRunner = require('@remix-project/remix-analyzer').CodeAnalysis
const utils = remixLib.util
declare global {
interface Window {
@ -38,7 +37,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => {
})
}
const groupedModules = utils.groupBy(
const groupedModules = util.groupBy(
preProcessModules(runner.modules()),
'categoryId'
)
@ -217,7 +216,7 @@ export const RemixUiStaticAnalyser = (props: RemixUiStaticAnalyserProps) => {
})
// Slither Analysis
if (slitherEnabled) {
props.analysisModule.call('solidity-logic', 'getCompilerState').then(async (compilerState) => {
props.analysisModule.call('solidity', 'getCompilerState').then((compilerState) => {
const { currentVersion, optimize, evmVersion } = compilerState
props.analysisModule.call('terminal', 'log', { type: 'info', value: '[Slither Analysis]: Running...' })
_paq.push(['trackEvent', 'solidityStaticAnalyzer', 'analyzeWithSlither'])

@ -120,6 +120,9 @@
},
"remix-ui-renderer": {
"tags": []
},
"solidity-compiler": {
"tags": []
}
}
}

@ -50,7 +50,7 @@
"bumpVersion:libs": "gulp & gulp syncLibVersions;",
"browsertest": "sleep 5 && npm run nightwatch_local",
"csslint": "csslint --ignore=order-alphabetical --errors='errors,duplicate-properties,empty-rules' --exclude-list='apps/remix-ide/src/assets/css/font-awesome.min.css' apps/remix-ide/src/assets/css/",
"downloadsolc_assets": "wget --no-check-certificate https://binaries.soliditylang.org/wasm/soljson-v0.8.7+commit.e28d00a7.js -O ./apps/remix-ide/src/assets/js/soljson.js",
"downloadsolc_assets": "wget --no-check-certificate https://binaries.soliditylang.org/wasm/soljson-v0.8.7+commit.e28d00a7.js -O ./apps/remix-ide/src/assets/js/soljson.js && wget --no-check-certificate https://binaries.soliditylang.org/wasm/soljson-v0.8.7+commit.e28d00a7.js -O ./apps/solidity-compiler/src/assets/js/soljson.js",
"make-mock-compiler": "node apps/remix-ide/ci/makeMockCompiler.js",
"minify": "uglifyjs --in-source-map inline --source-map-inline -c warnings=false",
"build:production": "NODE_ENV=production npx nx build remix-ide --with-deps --skip-nx-cache",

@ -25,12 +25,14 @@
"@remix-project/remix-tests": ["dist/libs/remix-tests/src/index.js"],
"@remix-project/remix-url-resolver": ["dist/libs/remix-url-resolver/index.js"],
"@remixproject/debugger-plugin": ["apps/debugger/src/index.ts"],
"@remixproject/solidity-compiler-plugin": ["apps/solidity-compiler/src/index.ts"],
"@remix-project/remixd": ["dist/libs/remixd/index.js"],
"@remix-ui/tree-view": ["libs/remix-ui/tree-view/src/index.ts"],
"@remix-ui/debugger-ui": ["libs/remix-ui/debugger-ui/src/index.ts"],
"@remix-ui/utils": ["libs/remix-ui/utils/src/index.ts"],
"@remix-ui/clipboard": ["libs/remix-ui/clipboard/src/index.ts"],
"@remix-project/remix-solidity-ts": ["libs/remix-solidity/src/index.ts"],
"@remix-project/remix-lib-ts": ["libs/remix-lib/src/index.ts"],
"@remix-ui/modal-dialog": ["libs/remix-ui/modal-dialog/src/index.ts"],
"@remix-ui/toaster": ["libs/remix-ui/toaster/src/index.ts"],
"@remix-ui/file-explorer": ["libs/remix-ui/file-explorer/src/index.ts"],

@ -875,6 +875,76 @@
}
}
}
},
"solidity-compiler": {
"root": "apps/solidity-compiler",
"sourceRoot": "apps/solidity-compiler/src",
"projectType": "application",
"schematics": {},
"architect": {
"build": {
"builder": "@nrwl/web:build",
"options": {
"outputPath": "dist/apps/solidity-compiler",
"index": "apps/solidity-compiler/src/index.html",
"main": "apps/solidity-compiler/src/main.tsx",
"polyfills": "apps/solidity-compiler/src/polyfills.ts",
"tsConfig": "apps/solidity-compiler/tsconfig.app.json",
"assets": [
"apps/solidity-compiler/src/favicon.ico",
"apps/solidity-compiler/src/assets",
"apps/solidity-compiler/src/index.html"
],
"styles": ["apps/solidity-compiler/src/styles.css"],
"scripts": [],
"webpackConfig": "apps/solidity-compiler/webpack.config.js",
"maxWorkers": 2
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "apps/solidity-compiler/src/environments/environment.ts",
"with": "apps/solidity-compiler/src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"extractLicenses": true,
"vendorChunk": false,
"budgets": [
{
"type": "initial",
"maximumWarning": "2mb",
"maximumError": "5mb"
}
]
}
}
},
"serve": {
"builder": "@nrwl/web:dev-server",
"options": {
"buildTarget": "solidity-compiler:build"
},
"configurations": {
"production": {
"buildTarget": "solidity-compiler:build:production"
}
}
},
"lint": {
"builder": "@nrwl/linter:lint",
"options": {
"linter": "eslint",
"tsConfig": ["apps/solidity-compiler/tsconfig.app.json"],
"exclude": ["**/node_modules/**", "!apps/solidity-compiler/**/*"]
}
}
}
}
},
"cli": {

Loading…
Cancel
Save