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

Commit

Permalink
Merge pull request #2532 from 0xProject/feat/sol-compiler/support-0.6
Browse files Browse the repository at this point in the history
sol-compiler: 0.6 support
  • Loading branch information
dorothy-zbornak committed Apr 1, 2020
2 parents 424cbd4 + b9a68c0 commit 2086bff
Show file tree
Hide file tree
Showing 14 changed files with 615 additions and 270 deletions.
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,
},
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)) {
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 };

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

0 comments on commit 2086bff

Please sign in to comment.