Skip to content
This repository has been archived by the owner on Jul 9, 2021. It is now read-only.

sol-compiler: 0.6 support #2532

Merged
merged 6 commits into from
Apr 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions packages/sol-compiler/CHANGELOG.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,13 @@
[
{
"version": "4.1.0",
"changes": [
{
"note": "Refactor + add solidity 0.6 support",
"pr": 2532
}
]
},
{
"timestamp": 1582623685,
"version": "4.0.8",
Expand Down
17 changes: 10 additions & 7 deletions packages/sol-compiler/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,16 @@ const SEPARATOR = ',';
: argv.contracts === DEFAULT_CONTRACTS_LIST
? DEFAULT_CONTRACTS_LIST
: argv.contracts.split(SEPARATOR);
const opts = {
contractsDir: argv.contractsDir,
artifactsDir: argv.artifactsDir,
contracts,
isOfflineMode: process.env.SOLC_OFFLINE ? true : undefined,
};
const compiler = new Compiler(opts);
const opts = _.omitBy(
{
contractsDir: argv.contractsDir,
artifactsDir: argv.artifactsDir,
contracts,
isOfflineMode: process.env.SOLC_OFFLINE ? true : undefined,
dorothy-zbornak marked this conversation as resolved.
Show resolved Hide resolved
},
v => v === undefined,
);
const compiler = new Compiler(await Compiler.getCompilerOptionsAsync(opts));
if (argv.watch) {
await compiler.watchAsync();
} else {
Expand Down
381 changes: 199 additions & 182 deletions packages/sol-compiler/src/compiler.ts

Large diffs are not rendered by default.

35 changes: 35 additions & 0 deletions packages/sol-compiler/src/solc_wrapper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { StandardOutput } from 'ethereum-types';
import { StandardInput } from 'solc';

export interface ContractContentsByPath {
[path: string]: string;
}

export interface ImportPrefixRemappings {
[prefix: string]: string;
}

export interface CompilationResult {
input: StandardInput;
output: StandardOutput;
}

export abstract class SolcWrapper {
/**
* Get the solc version.
*/
public abstract get version(): string;

/**
* Check if the configured compiler settings is different from another.
*/
public abstract areCompilerSettingsDifferent(settings: any): boolean;

/**
* Compile contracts, returning standard input and output.
*/
public abstract compileAsync(
contractsByPath: ContractContentsByPath,
dependencies: ImportPrefixRemappings,
): Promise<CompilationResult>;
}
3 changes: 3 additions & 0 deletions packages/sol-compiler/src/solc_wrapper_v04.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { SolcWrapperV05 } from './solc_wrapper_v05';

export const SolcWrapperV04 = SolcWrapperV05;
102 changes: 102 additions & 0 deletions packages/sol-compiler/src/solc_wrapper_v05.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import { CompilerOptions, StandardOutput } from 'ethereum-types';
import * as _ from 'lodash';
import solc = require('solc');

import {
addHexPrefixToContractBytecode,
compileDockerAsync,
compileSolcJSAsync,
getSolcJSAsync,
getSolidityVersionFromSolcVersion,
printCompilationErrorsAndWarnings,
} from './utils/compiler';

import { CompilationResult, ContractContentsByPath, ImportPrefixRemappings, SolcWrapper } from './solc_wrapper';

// Solc compiler settings cannot be configured from the commandline.
// If you need this configured, please create a `compiler.json` config file
// with your desired configurations.
export const DEFAULT_COMPILER_SETTINGS: solc.CompilerSettings = {
optimizer: {
enabled: false,
},
outputSelection: {
'*': {
'*': ['abi', 'evm.bytecode.object'],
},
},
};

// tslint:disable no-non-null-assertion

export class SolcWrapperV05 extends SolcWrapper {
protected readonly _compilerSettings: solc.CompilerSettings;

public static normalizeOutput(output: StandardOutput): StandardOutput {
const _output = _.cloneDeep(output);
// tslint:disable-next-line forin
for (const contractPath in _output.contracts) {
// tslint:disable-next-line forin
for (const contract of Object.values(_output.contracts[contractPath])) {
addHexPrefixToContractBytecode(contract);
}
}
return _output;
}

constructor(protected readonly _solcVersion: string, protected readonly _opts: CompilerOptions) {
super();
this._compilerSettings = {
...DEFAULT_COMPILER_SETTINGS,
..._opts.compilerSettings,
};
}

public get version(): string {
return this._solcVersion;
}

public get solidityVersion(): string {
return getSolidityVersionFromSolcVersion(this._solcVersion);
}

public areCompilerSettingsDifferent(settings: any): boolean {
return !_.isEqual(_.omit(settings, 'remappings'), _.omit(this._compilerSettings, 'remappings'));
}

public async compileAsync(
contractsByPath: ContractContentsByPath,
importRemappings: ImportPrefixRemappings,
): Promise<CompilationResult> {
const input: solc.StandardInput = {
language: 'Solidity',
sources: {},
settings: {
remappings: [],
...this._compilerSettings,
},
};
for (const [contractPath, contractContent] of Object.entries(contractsByPath)) {
input.sources[contractPath] = { content: contractContent };
}
for (const [prefix, _path] of Object.entries(importRemappings)) {
jalextowle marked this conversation as resolved.
Show resolved Hide resolved
input.settings.remappings!.push(`${prefix}=${_path}`);
}
const output = await this._compileInputAsync(input);
if (output.errors !== undefined) {
printCompilationErrorsAndWarnings(output.errors);
}
return {
input,
output: SolcWrapperV05.normalizeOutput(output),
};
}

protected async _compileInputAsync(input: solc.StandardInput): Promise<StandardOutput> {
if (this._opts.useDockerisedSolc) {
return compileDockerAsync(this.solidityVersion, input);
}
const solcInstance = await getSolcJSAsync(this.solidityVersion, !!this._opts.isOfflineMode);
return compileSolcJSAsync(solcInstance, input);
}
}
25 changes: 25 additions & 0 deletions packages/sol-compiler/src/solc_wrapper_v06.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { CompilerOptions, StandardOutput } from 'ethereum-types';
import solc = require('solc');

import { compileSolcJSAsync, getSolcJSAsync } from './utils/compiler';

import { SolcWrapperV05 } from './solc_wrapper_v05';

// 0.6.x has a `compile()` function in lieu of `compileStandardWrapper`.
type SolcV06 = solc.SolcInstance & { compile(input: string): string };
jalextowle marked this conversation as resolved.
Show resolved Hide resolved

export class SolcWrapperV06 extends SolcWrapperV05 {
constructor(solcVersion: string, opts: CompilerOptions) {
super(solcVersion, opts);
}

protected async _compileInputAsync(input: solc.StandardInput): Promise<StandardOutput> {
if (this._opts.useDockerisedSolc) {
return super._compileInputAsync(input);
}
// Shim the old `compileStandardWrapper` function.
const solcInstance = (await getSolcJSAsync(this.solidityVersion, !!this._opts.isOfflineMode)) as SolcV06;
solcInstance.compileStandardWrapper = solcInstance.compile;
return compileSolcJSAsync(solcInstance, input);
}
}
Loading