create solidity web app

pull/1342/head
yann300 3 years ago committed by davidzagi93@gmail.com
parent 3917d989ad
commit 10a68f7aa8
  1. 8
      apps/remix-ide/src/app.js
  2. 210
      apps/remix-ide/src/app/tabs/compile-tab.js
  3. 238
      apps/remix-ide/src/app/tabs/styles/compile-tab-styles.js
  4. 4
      apps/solidity-compiler/.babelrc
  5. 16
      apps/solidity-compiler/.browserslistrc
  6. 17
      apps/solidity-compiler/src/app/app.tsx
  7. 248
      apps/solidity-compiler/src/app/compiler-api.ts
  8. 40
      apps/solidity-compiler/src/app/compiler.ts
  9. 0
      apps/solidity-compiler/src/assets/.gitkeep
  10. 3
      apps/solidity-compiler/src/environments/environment.prod.ts
  11. 6
      apps/solidity-compiler/src/environments/environment.ts
  12. BIN
      apps/solidity-compiler/src/favicon.ico
  13. 14
      apps/solidity-compiler/src/index.html
  14. 1
      apps/solidity-compiler/src/index.ts
  15. 11
      apps/solidity-compiler/src/main.tsx
  16. 7
      apps/solidity-compiler/src/polyfills.ts
  17. 1
      apps/solidity-compiler/src/styles.css
  18. 9
      apps/solidity-compiler/tsconfig.app.json
  19. 16
      apps/solidity-compiler/tsconfig.json
  20. 15
      apps/solidity-compiler/tsconfig.spec.json
  21. 17
      apps/solidity-compiler/webpack.config.js
  22. 1
      libs/remix-ui/debugger-ui/src/index.ts
  23. 1
      libs/remix-ui/solidity-compiler/src/index.ts
  24. 28
      libs/remix-ui/solidity-compiler/src/lib/icompiler-api.ts
  25. 10
      libs/remix-ui/solidity-compiler/src/lib/logic/compileTabLogic.ts
  26. 40
      libs/remix-ui/solidity-compiler/src/lib/solidity-compiler.tsx
  27. 11
      libs/remix-ui/solidity-compiler/src/lib/types/index.ts
  28. 5
      nx.json
  29. 1
      tsconfig.base.json
  30. 70
      workspace.json

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

@ -2,7 +2,7 @@
import React from 'react' // eslint-disable-line import React from 'react' // eslint-disable-line
import ReactDOM from 'react-dom' import ReactDOM from 'react-dom'
import { SolidityCompiler, CompileTab as CompileTabLogic, parseContracts } from '@remix-ui/solidity-compiler' // eslint-disable-line import { SolidityCompiler, CompileTab as CompileTabLogic, parseContracts } from '@remix-ui/solidity-compiler' // eslint-disable-line
import { compile } from '@remix-project/remix-solidity' import { CompilerApiMixin } from '@remixproject/solidity-compiler-plugin'
import { ViewPlugin } from '@remixproject/engine-web' import { ViewPlugin } from '@remixproject/engine-web'
import * as packageJson from '../../../../../package.json' import * as packageJson from '../../../../../package.json'
@ -13,6 +13,8 @@ var QueryParams = require('../../lib/query-params')
const addTooltip = require('../ui/tooltip') const addTooltip = require('../ui/tooltip')
const globalRegistry = require('../../global/registry') const globalRegistry = require('../../global/registry')
const css = require('./styles/compile-tab-styles')
const profile = { const profile = {
name: 'solidity', name: 'solidity',
displayName: 'Solidity compiler', displayName: 'Solidity compiler',
@ -30,51 +32,19 @@ const profile = {
// - events: ['compilationFinished'], // - events: ['compilationFinished'],
// - methods: ['getCompilationResult'] // - methods: ['getCompilationResult']
class CompileTab extends ViewPlugin { class CompileTab extends CompilerApiMixin(ViewPlugin) {
constructor (editor, config, fileProvider, fileManager, contentImport) { constructor () {
super(profile) super(profile)
this.events = new EventEmitter() this.initCompilerApi()
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.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')
} }
resetResults () { renderComponent () {
this.currentFile = '' ReactDOM.render(
this.contractsDetails = {} <SolidityCompiler plugin={this}/>
this.emit('statusChanged', { key: 'none' }) , this.el)
this.renderComponent()
} }
setCompileErrors (data) { onCurrentFileChanged () {
this.compileErrors = data
this.renderComponent() this.renderComponent()
} }
@ -191,6 +161,10 @@ class CompileTab extends ViewPlugin {
}) })
} }
onResetResults () {
this.renderComponent()
}
setHardHatCompilation (value) { setHardHatCompilation (value) {
this.hhCompilation = value this.hhCompilation = value
} }
@ -199,46 +173,27 @@ class CompileTab extends ViewPlugin {
this.selectedVersion = version this.selectedVersion = version
} }
getCompilationResult () { onSetWorkspace () {
return this.compileTabLogic.compiler.state.lastCompilationResult this.renderComponent()
} }
addExternalFile (fileName, content) { onNoFileSelected () {
this.fileProvider.addExternal(fileName, content) this.renderComponent()
} }
/** onCompilationFinished () {
* compile using @arg fileName. this.renderComponent()
* 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)
} }
/** render () {
* compile using @arg compilationTargets and @arg settings if (this.el) return this.el
* The module UI will *not* be updated, the compilation result is returned this.el = yo`
* This function is used by remix-plugin compiler API. <div class="${css.debuggerTabView}" id="compileTabView">
* @param {object} map of source files. <div id="compiler" class="${css.compiler}"></div>
* @param {object} settings {evmVersion, optimize, runs, version, language} </div>`
*/ this.renderComponent()
async compileWithParameters (compilationTargets, settings) {
settings.version = settings.version || this.selectedVersion
const res = await compile(compilationTargets, settings)
return res
}
// This function is used for passing the compiler configuration to 'remix-tests' return this.el
getCurrentCompilerConfig () {
return {
currentVersion: this.selectedVersion,
evmVersion: this.compileTabLogic.evmVersion,
optimize: this.compileTabLogic.optimize,
runs: this.compileTabLogic.runs
}
} }
/** /**
@ -246,89 +201,20 @@ class CompileTab extends ViewPlugin {
* This function is used by remix-plugin compiler API. * This function is used by remix-plugin compiler API.
* @param {object} settings {evmVersion, optimize, runs, version, language} * @param {object} settings {evmVersion, optimize, runs, version, language}
*/ */
setCompilerConfig (settings) { setCompilerConfig (settings) {
this.configurationSettings = settings super.setCompilerConfig(settings)
this.renderComponent() this.renderComponent()
// @todo(#2875) should use loading compiler return value to check whether the compiler is loaded instead of "setInterval" // @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>`) 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 compile (fileName) {
contractCompiledSuccess () { addTooltip(yo`<div><b>${this.currentRequest.from}</b> is requiring to compile <b>${fileName}</b></div>`)
return yo`<div></div>` super.compile(fileName)
}
// 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()
}
open (fileName) {
return this.call('fileManager', 'open', fileName)
} }
onActivation () { onActivation () {
this.call('manager', 'activatePlugin', 'solidity-logic') super.onActivation()
this.listenToEvents()
this.call('filePanel', 'registerContextMenuItem', { this.call('filePanel', 'registerContextMenuItem', {
id: 'solidity', id: 'solidity',
name: 'compileFile', name: 'compileFile',
@ -339,32 +225,6 @@ class CompileTab extends ViewPlugin {
pattern: [] pattern: []
}) })
} }
// 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
}
}
return false
}
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')
}
} }
module.exports = CompileTab module.exports = CompileTab

@ -1,239 +1,11 @@
const csjs = require('csjs-inject') var csjs = require('csjs-inject')
const css = csjs` const css = csjs`
.title { .compilerTabView {
font-size: 1.1em; padding: 2%;
font-weight: bold;
margin-bottom: 1em;
} }
.panicError { .compiler {
color: red; margin-bottom: 1%;
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; }
} }
` `

@ -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 className="debugger">
<SolidityCompiler plugin={remix} />
</div>
);
};
export default App;

@ -0,0 +1,248 @@
import { compile } from '@remix-project/remix-solidity'
import { CompileTab as CompileTabLogic, parseContracts } from '@remix-ui/solidity-compiler' // eslint-disable-line
export const CompilerApiMixin = (Base) => class extends Base {
initCompilerApi () {
this.configurationSettings = null
this._view = {
warnCompilationSlow: null,
errorContainer: null,
contractEl: null
}
this.contractsDetails = {}
this.data = {
eventHandlers: {},
loading: false
}
this.compileTabLogic = new CompileTabLogic(this, this.contentImport)
this.compiler = this.compileTabLogic.compiler
this.compileTabLogic.init()
this.contractMap = {}
this.contractsDetails = {}
this.compileErrors = {}
this.compiledFileName = ''
this.selectedVersion = ''
this.currentFile = ''
}
onActivation () {
this.call('manager', 'activatePlugin', 'solidity-logic')
this.listenToEvents()
}
onDeactivation () {
this.call('manager', 'deactivatePlugin', 'solidity-logic')
}
setHardHatCompilation (value) {
this.hhCompilation = value
}
setSelectedVersion (version) {
this.selectedVersion = version
}
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) {
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) {
settings.version = settings.version || this.selectedVersion
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 () {
return {
currentVersion: this.selectedVersion,
evmVersion: this.compileTabLogic.evmVersion,
optimize: this.compileTabLogic.optimize,
runs: this.compileTabLogic.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
}
getParameters () {
return {}
}
setParameters (params) {}
getConfiguration (name) {
const conf = {
'currentFile': () => this.currentFile,
'hideWarnings': () => false,
'autoCompile': () => false,
'includeNightlies': () => false,
'optimise': () => false
}
return conf[name]()
}
setConfiguration (name, value) {}
getFileManagerMode () {
return 'browser'
}
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)
}
resetResults () {
this.currentFile = ''
this.contractsDetails = {}
this.emit('statusChanged', { key: 'none' })
if (this.onResetResults()) this.onResetResults()
}
listenToEvents () {
this.data.eventHandlers.onContentChanged = () => {
this.emit('statusChanged', { key: 'edited', title: 'the content has changed, needs recompilation', type: 'info' })
}
this.on('editor', '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')
}
this.on('filePanel', 'setWorkspace', (workspace) => {
this.resetResults()
if (this.onSetWorkspace) this.onSetWorkspace(workspace)
})
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.length > 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
window.document.addEventListener('keydown', (e) => {
// ctrl+s or command+s
if ((e.metaKey || e.ctrlKey) && e.keyCode === 83) {
e.preventDefault()
this.compileTabLogic.runCompiler(this.hhCompilation)
}
})
}
}

@ -0,0 +1,40 @@
import { PluginClient } from "@remixproject/plugin";
import { createClient } from "@remixproject/plugin-webview";
import { CompilerApiMixin } from './compiler-api'
export interface ConfigurationSettings {
version: string,
evmVersion: string,
language: string,
optimize: boolean,
runs: string
}
export class CompilerClientApi extends CompilerApiMixin(PluginClient) {
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
currentFile: string
onCurrentFileChanged: (fileName: string) => void
onResetResults: () => void
onSetWorkspace: (workspace: any) => void
onNoFileSelected: () => void
onCompilationFinished: (contractsDetails: any, contractMap: any) => void
constructor () {
super()
createClient(this as any)
this.initCompilerApi()
}
}

@ -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,14 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>SolidityCompiler</title>
<base href="/" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" type="image/x-icon" href="favicon.ico" />
</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.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'
}
}
}

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

@ -1,2 +1,3 @@
export * from './lib/solidity-compiler' export * from './lib/solidity-compiler'
export * from './lib/logic' export * from './lib/logic'
export * from './lib/icompiler-api'

@ -0,0 +1,28 @@
export type onCurrentFileChanged = (fileName: string) => void
export interface ICompilerApi {
contractMap: {
file: string
} | Record<string, any>
compileErrors:any
currentFile: string
configurationSettings: any
setHardHatCompilation(value: boolean): void
setSelectedVersion(version: string): void
getCompilationResult(): any
setCompilerConfig: (settings: any) => void
getParameters: () => any
setParameters: (params) => void
getConfiguration: (name: string) => string
setConfiguration: (name: string, value: string) => void
fileProviderOf: (file: string) => string
getFileManagerMode: () => string
fileExists: (file: string) => Promise<boolean>
writeFile: (file: string, content: string) => Promise<void>
readFile: (file: string) => Promise<string>
open: (file: string) => void
addExternalFile: (file: string, content: string) => void
onCurrentFileChanged: (listener: onCurrentFileChanged) => void
}

@ -87,15 +87,14 @@ export class CompileTab extends Plugin {
*/ */
compileFile (target) { compileFile (target) {
if (!target) throw new Error('No target provided for compiliation') 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) => { return new Promise((resolve, reject) => {
provider.get(target, (error, content) => { this.api.readFile(target).then((content) => {
if (error) return reject(error)
const sources = { [target]: { content } } const sources = { [target]: { content } }
this.event.emit('startingCompilation') this.event.emit('startingCompilation')
// setTimeout fix the animation on chrome... (animation triggered by 'staringCompilation') // setTimeout fix the animation on chrome... (animation triggered by 'staringCompilation')
setTimeout(() => { this.compiler.compile(sources, target); resolve(true) }, 100) setTimeout(() => { this.compiler.compile(sources, target); resolve(true) }, 100)
}).catch((error) => {
reject(error)
}) })
}) })
} }
@ -131,7 +130,8 @@ export class CompileTab extends Plugin {
}) })
} }
} }
this.api.saveCurrentFile() // TODO readd saving current file
// this.api.saveCurrentFile()
this.event.emit('removeAnnotations') this.event.emit('removeAnnotations')
var currentFile = this.api.getConfiguration('currentFile') var currentFile = this.api.getConfiguration('currentFile')
return this.compileFile(currentFile) return this.compileFile(currentFile)

@ -9,10 +9,12 @@ import { Renderer } from '@remix-ui/renderer' // eslint-disable-line
import './css/style.css' import './css/style.css'
export const SolidityCompiler = (props: SolidityCompilerProps) => { export const SolidityCompiler = (props: SolidityCompilerProps) => {
const { plugin, plugin: { compileTabLogic, contractsDetails, contractMap, compileErrors, configurationSettings } } = props const { plugin, plugin: { currentFile, compileTabLogic, contractsDetails, contractMap, compileErrors, configurationSettings } } = props
const [state, setState] = useState({ const [state, setState] = useState({
isHardhatProject: false,
currentFile,
contractsDetails: {}, contractsDetails: {},
eventHandlers: {}, contractMap: {},
loading: false, loading: false,
compileTabLogic: null, compileTabLogic: null,
compiler: null, compiler: null,
@ -30,6 +32,37 @@ export const SolidityCompiler = (props: SolidityCompilerProps) => {
}) })
const [currentVersion, setCurrentVersion] = useState('') const [currentVersion, setCurrentVersion] = useState('')
plugin.onCurrentFileChanged = (currentFile: string) => {
setState(prevState => {
return { ...prevState, currentFile }
})
}
plugin.onResetResults = () => {
setState(prevState => {
return { ...prevState, currentFile: '', contractsDetails: {}, contractMap: {} }
})
}
plugin.onSetWorkspace = async (workspace: any) => {
const isHardhat = workspace.isLocalhost && await compileTabLogic.isHardhatProject()
setState(prevState => {
return { ...prevState, currentFile, isHardhatProject: isHardhat }
})
}
plugin.onNoFileSelected = () => {
setState(prevState => {
return { ...prevState, currentFile: '' }
})
}
plugin.onCompilationFinished = (contractsDetails: any, contractMap: any) => {
setState(prevState => {
return { ...prevState, contractsDetails, contractMap }
})
}
const toast = (message: string) => { const toast = (message: string) => {
setState(prevState => { setState(prevState => {
return { ...prevState, toasterMsg: message } return { ...prevState, toasterMsg: message }
@ -75,11 +108,10 @@ export const SolidityCompiler = (props: SolidityCompilerProps) => {
</div> </div>
) )
const currentFile = plugin.getConfiguration('currentFile')
return ( return (
<> <>
<div id="compileTabView"> <div id="compileTabView">
<CompilerContainer api={plugin} compileTabLogic={compileTabLogic} tooltip={toast} modal={modal} compiledFileName={currentFile} updateCurrentVersion={updateCurrentVersion} configurationSettings={configurationSettings} /> <CompilerContainer api={plugin} isHardhatProject={state.isHardhatProject} compileTabLogic={compileTabLogic} tooltip={toast} modal={modal} compiledFileName={currentFile} updateCurrentVersion={updateCurrentVersion} configurationSettings={configurationSettings} />
<ContractSelection api={plugin} contractMap={contractMap} contractsDetails={contractsDetails} modal={modal} /> <ContractSelection api={plugin} contractMap={contractMap} contractsDetails={contractsDetails} modal={modal} />
<div className="remixui_errorBlobs p-4" data-id="compiledErrors"> <div className="remixui_errorBlobs p-4" data-id="compiledErrors">
<span data-id={`compilationFinishedWith_${currentVersion}`}></span> <span data-id={`compilationFinishedWith_${currentVersion}`}></span>

@ -1,5 +1,8 @@
export type onCurrentFileChanged = (fileName: string) => void
export interface SolidityCompilerProps { export interface SolidityCompilerProps {
plugin: { plugin: {
currentFile: string
contractMap: { contractMap: {
file: string file: string
} | Record<string, any> } | Record<string, any>
@ -12,13 +15,19 @@ export interface SolidityCompilerProps {
setSelectedVersion: (value: string) => void, setSelectedVersion: (value: string) => void,
configurationSettings: ConfigurationSettings, configurationSettings: ConfigurationSettings,
getConfiguration: (value: string) => string, getConfiguration: (value: string) => string,
setConfiguration: (name: string, value: string) => void setConfiguration: (name: string, value: string) => void,
onCurrentFileChanged: (fileName: string) => void,
onResetResults: () => void,
onSetWorkspace: (workspace: any) => void,
onNoFileSelected: () => void,
onCompilationFinished: (contractsDetails: any, contractMap: any) => void
}, },
} }
export interface CompilerContainerProps { export interface CompilerContainerProps {
api: any, api: any,
compileTabLogic: any, compileTabLogic: any,
isHardhatProject: boolean,
tooltip: (message: string | JSX.Element) => void, tooltip: (message: string | JSX.Element) => void,
modal: (title: string, message: string | JSX.Element, okLabel: string, okFn: () => void, cancelLabel?: string, cancelFn?: () => void) => void, modal: (title: string, message: string | JSX.Element, okLabel: string, okFn: () => void, cancelLabel?: string, cancelFn?: () => void) => void,
compiledFileName: string, compiledFileName: string,

@ -98,7 +98,7 @@
"tags": [] "tags": []
}, },
"remix-ui-settings": { "remix-ui-settings": {
"tags": [] "tags": []
}, },
"remix-ui-static-analyser": { "remix-ui-static-analyser": {
"tags": [] "tags": []
@ -123,6 +123,9 @@
}, },
"remix-ui-terminal": { "remix-ui-terminal": {
"tags": [] "tags": []
},
"solidity-compiler": {
"tags": []
} }
} }
} }

@ -25,6 +25,7 @@
"@remix-project/remix-tests": ["dist/libs/remix-tests/src/index.js"], "@remix-project/remix-tests": ["dist/libs/remix-tests/src/index.js"],
"@remix-project/remix-url-resolver": ["dist/libs/remix-url-resolver/index.js"], "@remix-project/remix-url-resolver": ["dist/libs/remix-url-resolver/index.js"],
"@remixproject/debugger-plugin": ["apps/debugger/src/index.ts"], "@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-project/remixd": ["dist/libs/remixd/index.js"],
"@remix-ui/tree-view": ["libs/remix-ui/tree-view/src/index.ts"], "@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/debugger-ui": ["libs/remix-ui/debugger-ui/src/index.ts"],

@ -891,6 +891,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": { "cli": {

Loading…
Cancel
Save