-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore: replace solc dependency with a thin solidity_compile wrapper
- Loading branch information
Showing
4 changed files
with
159 additions
and
39 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
138 changes: 138 additions & 0 deletions
138
v-next/hardhat/src/internal/builtin-plugins/solidity/build-system/compiler/solcjs-wrapper.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
// This wrapper was created by extracting the parts of the solc-js package | ||
// (https://github.com/ethereum/solc-js) that we need to perform compilation. | ||
|
||
import * as semver from "semver"; | ||
|
||
interface Solc { | ||
cwrap<T>(ident: string, returnType: string | null, argTypes: string[]): T; | ||
|
||
// eslint-disable-next-line @typescript-eslint/naming-convention -- this is a C function | ||
_solidity_reset?: Reset | null; | ||
// eslint-disable-next-line @typescript-eslint/naming-convention -- this is a C function | ||
_solidity_version?: Version | null; | ||
// eslint-disable-next-line @typescript-eslint/naming-convention -- this is a C function | ||
_version?: Version | null; | ||
// eslint-disable-next-line @typescript-eslint/naming-convention -- this is a C function | ||
_compileStandard?: Compile | null; | ||
// eslint-disable-next-line @typescript-eslint/naming-convention -- this is a C function | ||
_solidity_compile?: Compile | null; | ||
} | ||
|
||
type Reset = () => string; | ||
type Version = () => string; | ||
type Compile = ( | ||
input: string, | ||
callbackPtr: number | null, | ||
callbackContextPtr?: null, | ||
) => string; | ||
|
||
export interface SolcWrapper { | ||
compile: CompileWrapper; | ||
} | ||
|
||
export type CompileWrapper = (input: string) => string; | ||
|
||
export default function wrapper(solc: Solc): SolcWrapper { | ||
const version = bindVersion(solc); | ||
const isVersion6OrNewer = semver.gte(versionToSemver(version()), "0.6.0"); | ||
const reset = bindReset(solc); | ||
const compile = bindCompile(solc, isVersion6OrNewer); | ||
|
||
if (compile === undefined) { | ||
// eslint-disable-next-line no-restricted-syntax -- should we use a HardhatError here? | ||
throw new Error( | ||
'Could not find the "compile" function in the solc library', | ||
); | ||
} | ||
|
||
return { | ||
compile: compileWrapper(isVersion6OrNewer, compile, reset), | ||
}; | ||
} | ||
|
||
function compileWrapper( | ||
isVersion6OrNewer: boolean, | ||
compile: Compile, | ||
reset?: Reset, | ||
): CompileWrapper { | ||
return (input: string): string => { | ||
const output = isVersion6OrNewer | ||
? compile(input, null, null) | ||
: compile(input, null); | ||
|
||
if (reset !== undefined) { | ||
// Explicitly free memory. | ||
// | ||
// NOTE: cwrap() of "compile" will copy the returned pointer into a | ||
// Javascript string and it is not possible to call free() on it. | ||
// reset() however will clear up all allocations. | ||
reset(); | ||
} | ||
|
||
return output; | ||
}; | ||
} | ||
|
||
function bindVersion(solc: Solc): Version { | ||
if (solc._solidity_version === null || solc._solidity_version === undefined) { | ||
return solc.cwrap("version", "string", []); | ||
} | ||
|
||
return solc.cwrap("solidity_version", "string", []); | ||
} | ||
|
||
function bindReset(solc: Solc): Reset | undefined { | ||
if (solc._solidity_reset === null || solc._solidity_reset === undefined) { | ||
return undefined; | ||
} | ||
|
||
return solc.cwrap("solidity_reset", null, []); | ||
} | ||
|
||
function bindCompile( | ||
solc: Solc, | ||
isVersion6OrNewer: boolean, | ||
): CompileWrapper | undefined { | ||
if (isVersion6OrNewer) { | ||
if ( | ||
solc._solidity_compile !== null && | ||
solc._solidity_compile !== undefined | ||
) { | ||
return solc.cwrap("solidity_compile", "string", [ | ||
"string", | ||
"number", | ||
"number", | ||
]); | ||
} | ||
} else { | ||
if ( | ||
solc._solidity_compile !== null && | ||
solc._solidity_compile !== undefined | ||
) { | ||
return solc.cwrap("solidity_compile", "string", ["string", "number"]); | ||
} | ||
if (solc._compileStandard !== null && solc._compileStandard !== undefined) { | ||
return solc.cwrap("compileStandard", "string", ["string", "number"]); | ||
} | ||
} | ||
|
||
return undefined; | ||
} | ||
|
||
function versionToSemver(version: string): string { | ||
// FIXME: parse more detail, but this is a good start | ||
const parsed = version.match( | ||
/^([0-9]+\.[0-9]+\.[0-9]+)-([0-9a-f]{8})[/*].*$/, | ||
); | ||
if (parsed !== null) { | ||
return parsed[1] + "+commit." + parsed[2]; | ||
} | ||
if (version.indexOf("0.1.3-0") !== -1) { | ||
return "0.1.3"; | ||
} | ||
if (version.indexOf("0.3.5-0") !== -1) { | ||
return "0.3.5"; | ||
} | ||
// assume it is already semver compatible | ||
return version; | ||
} |