remix-solidity linting fixed

pull/5370/head
aniket-engg 4 years ago
parent b9016e34be
commit 6518d35657
  1. 5
      libs/remix-solidity/.eslintrc
  2. 7
      libs/remix-solidity/src/compiler/compiler-input.ts
  3. 54
      libs/remix-solidity/src/compiler/compiler-worker.ts
  4. 94
      libs/remix-solidity/src/compiler/compiler.ts
  5. 14
      libs/remix-solidity/src/compiler/txHelper.ts
  6. 139
      libs/remix-solidity/src/compiler/types.ts
  7. 2
      package.json

@ -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,

@ -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)

@ -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
})
}

@ -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 <K extends keyof CompilerState>(key: K, value: CompilerState[K]): void {
set <K extends keyof CompilerState> (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<string, any> | null {
getContract (name: string): Record<string, any> | 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
}
}

@ -9,7 +9,7 @@ export default {
* @param contracts 'contracts' object from last compilation result
*/
getContract: (contractName: string, contracts: CompilationResult["contracts"]) : Record<string, any> | null => {
getContract: (contractName: string, contracts: CompilationResult['contracts']) : Record<string, any> | 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
}

@ -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<string, string>
},
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<string, unknown>
id: number
@ -285,8 +284,8 @@ export interface CompilationResult {
symbolAliases?: Array<string>
[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 <M>
| '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 }[]
}
}
}
}

@ -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",

Loading…
Cancel
Save