diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index d173104d6..cfeafaa55 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -60,7 +60,7 @@ export { export { ValidateUpgradeSafetyOptions, validateUpgradeSafety, ProjectReport, ReferenceContractNotFound } from './cli'; export { getUpgradeInterfaceVersion } from './upgrade-interface-version'; -export { makeNamespacedInput } from './utils/make-namespaced'; +export { makeNamespacedInput, trySanitizeNatSpec } from './utils/make-namespaced'; export { isNamespaceSupported } from './storage/namespace'; export { inferProxyAdmin } from './infer-proxy-admin'; export { assertUnreachable } from './utils/assert'; diff --git a/packages/core/src/utils/make-namespaced.test.ts b/packages/core/src/utils/make-namespaced.test.ts index e236f3d57..a5448a9b8 100644 --- a/packages/core/src/utils/make-namespaced.test.ts +++ b/packages/core/src/utils/make-namespaced.test.ts @@ -6,7 +6,7 @@ import { TASK_COMPILE_SOLIDITY_RUN_SOLCJS, } from 'hardhat/builtin-tasks/task-names'; -import { makeNamespacedInput } from './make-namespaced'; +import { makeNamespacedInput, trySanitizeNatSpec } from './make-namespaced'; import { SolcBuild } from 'hardhat/types/builtin-tasks'; import { SolcInput, SolcOutput } from '../solc-api'; import { BuildInfo } from 'hardhat/types'; @@ -40,11 +40,14 @@ async function testMakeNamespaced( // Inefficient, but we want to test that we don't actually modify the original input object const origInput = JSON.parse(JSON.stringify(origBuildInfo.input)); - const modifiedInput = await makeNamespacedInput( + const modifiedInput = makeNamespacedInput( origBuildInfo.input, origBuildInfo.output, - keepAllNatSpec ? undefined : origBuildInfo.solcVersion, + origBuildInfo.solcVersion, ); + if (!keepAllNatSpec) { + await trySanitizeNatSpec(modifiedInput, origBuildInfo.solcVersion); + } // Run hardhat compile on the modified input and make sure it has no errors const modifiedOutput = await hardhatCompile(modifiedInput, solcVersion); diff --git a/packages/core/src/utils/make-namespaced.ts b/packages/core/src/utils/make-namespaced.ts index 9d1a1b7a1..25f170a3f 100644 --- a/packages/core/src/utils/make-namespaced.ts +++ b/packages/core/src/utils/make-namespaced.ts @@ -34,14 +34,14 @@ const OUTPUT_SELECTION = { * * @param input The original solc input. * @param output The original solc output. - * @param solcVersion The version of the solc compiler that was originally used to compile the input. + * @param _solcVersion The version of the solc compiler that was originally used to compile the input. This argument is no longer used and is kept for backwards compatibility. * @returns The modified solc input with storage layout that includes namespaced type information. */ -export async function makeNamespacedInput( +export function makeNamespacedInput( input: SolcInput, output: SolcOutput, - solcVersion?: string, -): Promise { + _solcVersion?: string, +): SolcInput { const modifiedSources: Record = {}; for (const [sourcePath] of Object.entries(input.sources)) { @@ -167,21 +167,36 @@ export async function makeNamespacedInput( } } - const modifiedSource = await tryRemoveNonStructNatSpec(getModifiedSource(orig, modifications), solcVersion); - - modifiedSources[sourcePath] = { ...source, content: modifiedSource }; + modifiedSources[sourcePath] = { ...source, content: getModifiedSource(orig, modifications) }; } return { ...input, sources: modifiedSources, settings: { ...input.settings, outputSelection: OUTPUT_SELECTION } }; } /** - * If we have the compiler version available and Slang is supported for the current platform and compiler version, - * use Slang to parse and remove all NatSpec comments that do not precede a struct definition and return the modified content. + * Attempts to remove all NatSpec comments that do not precede a struct definition from the input source contents. + * Directly modifies the input source contents. + * + * If the solc version is not supported by the parser, the original content is kept. + * + * @param solcInput Solc input. + * @param solcVersion The version of the solc compiler that was originally used to compile the input. + */ +export async function trySanitizeNatSpec(solcInput: SolcInput, solcVersion: string) { + for (const [sourcePath, source] of Object.entries(solcInput.sources)) { + if (source.content !== undefined) { + solcInput.sources[sourcePath].content = await tryRemoveNonStructNatSpec(source.content, solcVersion); + } + } +} + +/** + * If Slang is supported for the current compiler version, use Slang to parse and remove all NatSpec comments + * that do not precede a struct definition and return the modified content. * * Otherwise, return the original content. */ -async function tryRemoveNonStructNatSpec(origContent: string, solcVersion: string | undefined): Promise { +async function tryRemoveNonStructNatSpec(origContent: string, solcVersion: string): Promise { if (solcVersion === undefined) { return origContent; } diff --git a/packages/plugin-hardhat/src/index.ts b/packages/plugin-hardhat/src/index.ts index 37f9d6177..d30ef0d51 100644 --- a/packages/plugin-hardhat/src/index.ts +++ b/packages/plugin-hardhat/src/index.ts @@ -87,7 +87,7 @@ subtask(TASK_COMPILE_SOLIDITY, async (args: { force: boolean }, hre, runSuper) = }); subtask(TASK_COMPILE_SOLIDITY_COMPILE, async (args: RunCompilerArgs, hre, runSuper) => { - const { isNamespaceSupported, validate, solcInputOutputDecoder, makeNamespacedInput } = await import( + const { isNamespaceSupported, validate, solcInputOutputDecoder, makeNamespacedInput, trySanitizeNatSpec } = await import( '@openzeppelin/upgrades-core' ); const { writeValidations } = await import('./utils/validations.js'); @@ -101,7 +101,8 @@ subtask(TASK_COMPILE_SOLIDITY_COMPILE, async (args: RunCompilerArgs, hre, runSup let namespacedOutput = undefined; if (isNamespaceSupported(args.solcVersion)) { - const namespacedInput = await makeNamespacedInput(args.input, output, args.solcVersion); + const namespacedInput = makeNamespacedInput(args.input, output, args.solcVersion); + await trySanitizeNatSpec(namespacedInput, args.solcVersion); namespacedOutput = (await runSuper({ ...args, quiet: true, input: namespacedInput })).output; const namespacedCompileErrors = getNamespacedCompileErrors(namespacedOutput);