diff --git a/libs/remix-solidity/.eslintrc b/libs/remix-solidity/.eslintrc index e060220185..35c51f7ae7 100644 --- a/libs/remix-solidity/.eslintrc +++ b/libs/remix-solidity/.eslintrc @@ -1,9 +1,8 @@ { "extends": "../../.eslintrc", "rules": { - "@typescript-eslint/no-explicit-any": "off", - "@typescript-eslint/no-var-requires": "off", - "@typescript-eslint/no-unused-vars": "off" + "dot-notation": "off", + "no-unused-vars": "off" }, "env": { "browser": true, diff --git a/libs/remix-solidity/src/compiler/compiler-input.ts b/libs/remix-solidity/src/compiler/compiler-input.ts index 30dfb3eda0..2baabecc79 100644 --- a/libs/remix-solidity/src/compiler/compiler-input.ts +++ b/libs/remix-solidity/src/compiler/compiler-input.ts @@ -14,8 +14,8 @@ export default (sources: Source, opts: CompilerInputOptions): string => { libraries: opts.libraries, outputSelection: { '*': { - '': [ 'ast' ], - '*': [ 'abi', 'metadata', 'devdoc', 'userdoc', 'evm.legacyAssembly', 'evm.bytecode', 'evm.deployedBytecode', 'evm.methodIdentifiers', 'evm.gasEstimates', 'evm.assembly' ] + '': ['ast'], + '*': ['abi', 'metadata', 'devdoc', 'userdoc', 'evm.legacyAssembly', 'evm.bytecode', 'evm.deployedBytecode', 'evm.methodIdentifiers', 'evm.gasEstimates', 'evm.assembly'] } } } @@ -27,8 +27,7 @@ export default (sources: Source, opts: CompilerInputOptions): string => { o.language = opts.language } if (opts.language === 'Yul' && o.settings.optimizer.enabled) { - if (!o.settings.optimizer.details) - o.settings.optimizer.details = {} + if (!o.settings.optimizer.details) { o.settings.optimizer.details = {} } o.settings.optimizer.details.yul = true } return JSON.stringify(o) diff --git a/libs/remix-solidity/src/compiler/compiler-worker.ts b/libs/remix-solidity/src/compiler/compiler-worker.ts index d8c95b3cbe..7685a766f3 100644 --- a/libs/remix-solidity/src/compiler/compiler-worker.ts +++ b/libs/remix-solidity/src/compiler/compiler-worker.ts @@ -12,39 +12,39 @@ export default function (self) { // eslint-disable-line @typescript-eslint/expli const data: MessageToWorker = e.data switch (data.cmd) { case 'loadVersion': - { - delete self.Module - // NOTE: workaround some browsers? - self.Module = undefined - compileJSON = null - //importScripts() method of synchronously imports one or more scripts into the worker's scope - self.importScripts(data.data) - const compiler: solc = solc(self.Module) - compileJSON = (input) => { - try { - const missingInputsCallback = (path) => { - missingInputs.push(path) - return { 'error': 'Deferred import' } - } - return compiler.compile(input, { import: missingInputsCallback }) - } catch (exception) { - return JSON.stringify({ error: 'Uncaught JavaScript exception:\n' + exception }) + { + delete self.Module + // NOTE: workaround some browsers? + self.Module = undefined + compileJSON = null + // importScripts() method of synchronously imports one or more scripts into the worker's scope + self.importScripts(data.data) + const compiler: solc = solc(self.Module) + compileJSON = (input) => { + try { + const missingInputsCallback = (path) => { + missingInputs.push(path) + return { error: 'Deferred import' } } + return compiler.compile(input, { import: missingInputsCallback }) + } catch (exception) { + return JSON.stringify({ error: 'Uncaught JavaScript exception:\n' + exception }) } - self.postMessage({ - cmd: 'versionLoaded', - data: compiler.version() - }) - break } - + self.postMessage({ + cmd: 'versionLoaded', + data: compiler.version() + }) + break + } + case 'compile': missingInputs.length = 0 - if(data.input && compileJSON) { + if (data.input && compileJSON) { self.postMessage({ - cmd: 'compiled', - job: data.job, - data: compileJSON(data.input), + cmd: 'compiled', + job: data.job, + data: compileJSON(data.input), missingInputs: missingInputs }) } diff --git a/libs/remix-solidity/src/compiler/compiler.ts b/libs/remix-solidity/src/compiler/compiler.ts index 0c8f9faca0..8c0d546ca0 100644 --- a/libs/remix-solidity/src/compiler/compiler.ts +++ b/libs/remix-solidity/src/compiler/compiler.ts @@ -4,11 +4,13 @@ import { update } from 'solc/abi' import * as webworkify from 'webworkify-webpack' import compilerInput from './compiler-input' import EventManager from '../lib/eventManager' -import { default as txHelper } from './txHelper'; -import { Source, SourceWithTarget, MessageFromWorker, CompilerState, CompilationResult, - visitContractsCallbackParam, visitContractsCallbackInterface, CompilationError, - gatherImportsCallbackInterface, - isFunctionDescription } from './types' +import txHelper from './txHelper' +import { + Source, SourceWithTarget, MessageFromWorker, CompilerState, CompilationResult, + visitContractsCallbackParam, visitContractsCallbackInterface, CompilationError, + gatherImportsCallbackInterface, + isFunctionDescription +} from './types' /* trigger compilationFinished, compilerLoaded, compilationStarted, compilationDuration @@ -41,7 +43,7 @@ export class Compiler { } this.state.compilationStartTime = null }) - + this.event.register('compilationStarted', () => { this.state.compilationStartTime = new Date().getTime() }) @@ -53,7 +55,7 @@ export class Compiler { * @param value value of key in CompilerState */ - set (key: K, value: CompilerState[K]): void { + set (key: K, value: CompilerState[K]): void { this.state[key] = value if (key === 'runs') this.state['runs'] = parseInt(value) } @@ -68,9 +70,8 @@ export class Compiler { this.gatherImports(files, missingInputs, (error, input) => { if (error) { this.state.lastCompilationResult = null - this.event.trigger('compilationFinished', [false, {'error': { formattedMessage: error, severity: 'error' }}, files]) - } else if(this.state.compileJSON && input) - this.state.compileJSON(input) + this.event.trigger('compilationFinished', [false, { error: { formattedMessage: error, severity: 'error' } }, files]) + } else if (this.state.compileJSON && input) { this.state.compileJSON(input) } }) } @@ -102,7 +103,7 @@ export class Compiler { onInternalCompilerLoaded (): void { if (this.state.worker === null) { - const compiler: any = typeof (window) !== 'undefined' && window['Module'] ? require('solc/wrapper')(window['Module']) : require('solc') + const compiler: any = typeof (window) !== 'undefined' && window['Module'] ? require('solc/wrapper')(window['Module']) : require('solc') this.state.compileJSON = (source: SourceWithTarget) => { const missingInputs: string[] = [] const missingInputsCallback = (path: string) => { @@ -111,9 +112,9 @@ export class Compiler { } let result: CompilationResult = {} try { - if(source && source.sources) { - const {optimize, runs, evmVersion, language} = this.state - const input = compilerInput(source.sources, {optimize, runs, evmVersion, language}) + if (source && source.sources) { + const { optimize, runs, evmVersion, language } = this.state + const input = compilerInput(source.sources, { optimize, runs, evmVersion, language }) result = JSON.parse(compiler.compile(input, { import: missingInputsCallback })) } } catch (exception) { @@ -138,7 +139,7 @@ export class Compiler { const checkIfFatalError = (error: CompilationError) => { // Ignore warnings and the 'Deferred import' error as those are generated by us as a workaround const isValidError = (error.message && error.message.includes('Deferred import')) ? false : error.severity !== 'warning' - if(isValidError) noFatalErrors = false + if (isValidError) noFatalErrors = false } if (data.error) checkIfFatalError(data.error) if (data.errors) data.errors.forEach((err) => checkIfFatalError(err)) @@ -151,9 +152,8 @@ export class Compiler { this.internalCompile(source.sources, missingInputs) } else { data = this.updateInterface(data) - if(source) - { - source.target = this.state.target; + if (source) { + source.target = this.state.target this.state.lastCompilationResult = { data: data, source: source @@ -167,7 +167,7 @@ export class Compiler { * @dev Load compiler using given version (used by remix-tests CLI) * @param version compiler version */ - + loadRemoteVersion (version: string): void { console.log(`Loading remote solc version ${version} ...`) const compiler: any = require('solc') @@ -183,9 +183,9 @@ export class Compiler { } let result: CompilationResult = {} try { - if(source && source.sources) { - const {optimize, runs, evmVersion, language} = this.state - const input = compilerInput(source.sources, {optimize, runs, evmVersion, language}) + if (source && source.sources) { + const { optimize, runs, evmVersion, language } = this.state + const input = compilerInput(source.sources, { optimize, runs, evmVersion, language }) result = JSON.parse(remoteCompiler.compile(input, { import: missingInputsCallback })) } } catch (exception) { @@ -203,7 +203,7 @@ export class Compiler { * @param usingWorker if true, load compiler using worker * @param url URL to load compiler from */ - + loadVersion (usingWorker: boolean, url: string): void { console.log('Loading ' + url + ' ' + (usingWorker ? 'with worker' : 'without worker')) this.event.trigger('loadingCompiler', [url, usingWorker]) @@ -222,7 +222,7 @@ export class Compiler { * @dev Load compiler using 'script' element (without worker) * @param url URL to load compiler from */ - + loadInternal (url: string): void { delete window['Module'] // NOTE: workaround some browsers? @@ -257,16 +257,16 @@ export class Compiler { const data: MessageFromWorker = msg.data switch (data.cmd) { case 'versionLoaded': - if(data.data) this.onCompilerLoaded(data.data) + if (data.data) this.onCompilerLoaded(data.data) break - case 'compiled': + case 'compiled': { let result: CompilationResult - if(data.data && data.job !== undefined && data.job >= 0) { + if (data.data && data.job !== undefined && data.job >= 0) { try { result = JSON.parse(data.data) } catch (exception) { - result = { error : { formattedMessage: 'Invalid JSON output from the compiler: ' + exception }} + result = { error: { formattedMessage: 'Invalid JSON output from the compiler: ' + exception } } } let sources: SourceWithTarget = {} if (data.job in jobs !== undefined) { @@ -281,23 +281,23 @@ export class Compiler { }) this.state.worker.addEventListener('error', (msg: Record <'data', MessageFromWorker>) => { - this.onCompilationFinished({ error: { formattedMessage: 'Worker error: ' + msg.data }}) + this.onCompilationFinished({ error: { formattedMessage: 'Worker error: ' + msg.data } }) }) this.state.compileJSON = (source: SourceWithTarget) => { - if(source && source.sources) { - const {optimize, runs, evmVersion, language} = this.state - jobs.push({sources: source}) + if (source && source.sources) { + const { optimize, runs, evmVersion, language } = this.state + jobs.push({ sources: source }) this.state.worker.postMessage({ - cmd: 'compile', - job: jobs.length - 1, - input: compilerInput(source.sources, {optimize, runs, evmVersion, language}) + cmd: 'compile', + job: jobs.length - 1, + input: compilerInput(source.sources, { optimize, runs, evmVersion, language }) }) } } this.state.worker.postMessage({ - cmd: 'loadVersion', + cmd: 'loadVersion', data: url }) } @@ -340,8 +340,7 @@ export class Compiler { } return } - if(cb) - cb(null, { 'sources': files }) + if (cb) { cb(null, { sources: files }) } } /** @@ -353,7 +352,7 @@ export class Compiler { const tmp: RegExpExecArray | null = /^(\d+.\d+.\d+)/.exec(version) return tmp ? tmp[1] : version } - + /** * @dev Update ABI according to current compiler version * @param data Compilation result @@ -366,12 +365,12 @@ export class Compiler { // yul compiler does not return any abi, // we default to accept the fallback function (which expect raw data as argument). contract.object.abi.push({ - 'payable': true, - 'stateMutability': 'payable', - 'type': 'fallback' + payable: true, + stateMutability: 'payable', + type: 'fallback' }) } - if(data && data.contracts && this.state.currentVersion) { + if (data && data.contracts && this.state.currentVersion) { const version = this.truncateVersion(this.state.currentVersion) data.contracts[contract.file][contract.name].abi = update(version, contract.object.abi) // if "constant" , payable must not be true and stateMutability must be view. @@ -379,10 +378,10 @@ export class Compiler { for (const item of data.contracts[contract.file][contract.name].abi) { if (isFunctionDescription(item) && item.constant) { item.payable = false - item.stateMutability = 'view'; - } + item.stateMutability = 'view' + } } - } + } }) return data } @@ -392,7 +391,7 @@ export class Compiler { * @param name contract name */ - getContract (name: string): Record | null { + getContract (name: string): Record | null { if (this.state.lastCompilationResult && this.state.lastCompilationResult.data && this.state.lastCompilationResult.data.contracts) { return txHelper.getContract(name, this.state.lastCompilationResult.data.contracts) } @@ -457,4 +456,3 @@ export class Compiler { return null } } - diff --git a/libs/remix-solidity/src/compiler/txHelper.ts b/libs/remix-solidity/src/compiler/txHelper.ts index c361da126e..c50bf4c7e6 100644 --- a/libs/remix-solidity/src/compiler/txHelper.ts +++ b/libs/remix-solidity/src/compiler/txHelper.ts @@ -9,7 +9,7 @@ export default { * @param contracts 'contracts' object from last compilation result */ - getContract: (contractName: string, contracts: CompilationResult["contracts"]) : Record | null => { + getContract: (contractName: string, contracts: CompilationResult['contracts']) : Record | null => { for (const file in contracts) { if (contracts[file][contractName]) { return { object: contracts[file][contractName], file: file } @@ -23,14 +23,14 @@ export default { * @param contracts - 'contracts' object from last compilation result * @param cb - callback */ - - visitContracts: (contracts: CompilationResult["contracts"], cb: visitContractsCallbackInterface) : void => { + + visitContracts: (contracts: CompilationResult['contracts'], cb: visitContractsCallbackInterface) : void => { for (const file in contracts) { for (const name in contracts[file]) { - const param: visitContractsCallbackParam = { - name: name, - object: contracts[file][name], - file: file + const param: visitContractsCallbackParam = { + name: name, + object: contracts[file][name], + file: file } if (cb(param)) return } diff --git a/libs/remix-solidity/src/compiler/types.ts b/libs/remix-solidity/src/compiler/types.ts index b3f06e6e4c..4bf4a765d0 100644 --- a/libs/remix-solidity/src/compiler/types.ts +++ b/libs/remix-solidity/src/compiler/types.ts @@ -129,7 +129,6 @@ export interface CompilerInput { } } - export interface Source { [fileName: string]: { @@ -144,7 +143,7 @@ export interface Source { export interface CompilerInputOptions { optimize: boolean | number, runs: number, - libraries?: { + libraries?: { [fileName: string]: Record }, evmVersion?: EVMVersion, @@ -191,7 +190,7 @@ export interface MessageFromWorker { } export interface visitContractsCallbackParam { - name: string, + name: string, object: CompiledContract, file: string } @@ -205,7 +204,7 @@ export interface gatherImportsCallbackInterface { } export interface CompilationResult { - error?: CompilationError, + error?: CompilationError, /** not present if no errors/warnings were encountered */ errors?: CompilationError[] /** This contains the file-level outputs. In can be limited/filtered by the outputSelection settings */ @@ -220,12 +219,12 @@ export interface CompilationResult { } } } - - /////////// - // ERROR // - /////////// - - export interface CompilationError { + +/// //////// +// ERROR // +/// //////// + +export interface CompilationError { /** Location within the source file */ sourceLocation?: { file: string @@ -242,7 +241,7 @@ export interface CompilationResult { /** the message formatted with source location */ formattedMessage?: string } - + type CompilationErrorType = | 'JSONError' | 'IOError' @@ -257,21 +256,21 @@ export interface CompilationResult { | 'CompilerError' | 'FatalError' | 'Warning' - - //////////// - // SOURCE // - //////////// - export interface CompilationSource { + +/// ///////// +// SOURCE // +/// ///////// +export interface CompilationSource { /** Identifier of the source (used in source maps) */ id: number /** The AST object */ ast: AstNode } - - ///////// - // AST // - ///////// - export interface AstNode { + +/// ////// +// AST // +/// ////// +export interface AstNode { absolutePath?: string exportedSymbols?: Record id: number @@ -285,8 +284,8 @@ export interface CompilationResult { symbolAliases?: Array [x: string]: any } - - export interface AstNodeAtt { + +export interface AstNodeAtt { operator?: string string?: null type?: string @@ -299,11 +298,11 @@ export interface CompilationResult { absolutePath?: string [x: string]: any } - - ////////////// - // CONTRACT // - ////////////// - export interface CompiledContract { + +/// /////////// +// CONTRACT // +/// /////////// +export interface CompiledContract { /** The Ethereum Contract ABI. If empty, it is represented as an empty array. */ abi: ABIDescription[] // See the Metadata Output documentation (serialised JSON string) @@ -348,19 +347,19 @@ export interface CompilationResult { wasm: string } } - - ///////// - // ABI // - ///////// - export type ABIDescription = FunctionDescription | EventDescription - - export const isFunctionDescription = (item: ABIDescription): item is FunctionDescription => - (item as FunctionDescription).stateMutability !== undefined; - - export const isEventDescription = (item: ABIDescription): item is EventDescription => - (item as EventDescription).type === 'event'; - - export interface FunctionDescription { + +/// ////// +// ABI // +/// ////// +export type ABIDescription = FunctionDescription | EventDescription + +export const isFunctionDescription = (item: ABIDescription): item is FunctionDescription => + (item as FunctionDescription).stateMutability !== undefined + +export const isEventDescription = (item: ABIDescription): item is EventDescription => + (item as EventDescription).type === 'event' + +export interface FunctionDescription { /** Type of the method. default is 'function' */ type?: 'function' | 'constructor' | 'fallback' | 'receive' /** The name of the function. Constructor and fallback function never have name */ @@ -376,8 +375,8 @@ export interface CompilationResult { /** true if function is either pure or view, false otherwise. Default is false */ constant?: boolean } - - export interface EventDescription { + +export interface EventDescription { type: 'event' name: string inputs: ABIParameter & @@ -388,8 +387,8 @@ export interface CompilationResult { /** true if the event was declared as anonymous. */ anonymous: boolean } - - export interface ABIParameter { + +export interface ABIParameter { /** The name of the parameter */ name: string /** The canonical type of the parameter */ @@ -397,8 +396,8 @@ export interface CompilationResult { /** Used for tuple types */ components?: ABIParameter[] } - - export type ABITypeParameter = + +export type ABITypeParameter = | 'uint' | 'uint[]' // TODO : add | 'int' @@ -418,39 +417,39 @@ export interface CompilationResult { | 'tuple' | 'tuple[]' | string // Fallback - - /////////////////////////// - // NATURAL SPECIFICATION // - /////////////////////////// - - // Userdoc - export interface UserDocumentation { + +/// //////////////////////// +// NATURAL SPECIFICATION // +/// //////////////////////// + +// Userdoc +export interface UserDocumentation { methods: UserMethodList notice: string } - - export type UserMethodList = { + +export type UserMethodList = { [functionIdentifier: string]: UserMethodDoc } & { 'constructor'?: string } - export interface UserMethodDoc { +export interface UserMethodDoc { notice: string } - - // Devdoc - export interface DeveloperDocumentation { + +// Devdoc +export interface DeveloperDocumentation { author: string title: string details: string methods: DevMethodList } - - export interface DevMethodList { + +export interface DevMethodList { [functionIdentifier: string]: DevMethodDoc } - - export interface DevMethodDoc { + +export interface DevMethodDoc { author: string details: string return: string @@ -458,11 +457,11 @@ export interface CompilationResult { [param: string]: string } } - - ////////////// - // BYTECODE // - ////////////// - export interface BytecodeObject { + +/// /////////// +// BYTECODE // +/// /////////// +export interface BytecodeObject { /** The bytecode as a hex string. */ object: string /** Opcodes list */ @@ -476,4 +475,4 @@ export interface CompilationResult { [library: string]: { start: number; length: number }[] } } - } \ No newline at end of file + } diff --git a/package.json b/package.json index ca022a8bce..d685b4426a 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "workspace-schematic": "nx workspace-schematic", "dep-graph": "nx dep-graph", "help": "nx help", - "lint:libs": "nx run-many --target=lint --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remixd,remix-ui-tree-view,remix-ui-modal-dialog,remix-ui-toaster,remix-ui-file-explorer,remix-ui-debugger-ui", + "lint:libs": "nx run-many --target=lint --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remixd,remix-ui-tree-view,remix-ui-modal-dialog,remix-ui-toaster,remix-ui-file-explorer,remix-ui-debugger-ui", "build:libs": "nx run-many --target=build --parallel=false --with-deps=true --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd", "test:libs": "nx run-many --target=test --projects=remix-analyzer,remix-astwalker,remix-debug,remix-lib,remix-simulator,remix-solidity,remix-tests,remix-url-resolver,remixd", "publish:libs": "npm run build:libs & lerna publish --skip-git & npm run bumpVersion:libs",