UNPKG

hardhat

Version:

Hardhat is an extensible developer tool that helps smart contract developers increase productivity by reliably bringing together the tools they want.

145 lines (123 loc) 3.93 kB
// 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 { HardhatError } from "@nomicfoundation/hardhat-errors"; 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; _version?: Version | null; _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; version: Version; } export type CompileWrapper = (input: string) => string; export default function wrapper(solc: Solc): SolcWrapper { const version = bindVersion(solc); const semverVersion = versionToSemver(version()); const isVersion6OrNewer = semver.gte(semverVersion, "0.6.0"); const reset = bindReset(solc); const compile = bindCompile(solc, isVersion6OrNewer); if (compile === undefined) { throw new HardhatError( HardhatError.ERRORS.CORE.SOLIDITY.INVALID_SOLCJS_COMPILER, { version: version(), }, ); } return { compile: compileWrapper(isVersion6OrNewer, compile, reset), version, }; } 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; }