From 605f9067468da7fb9925b6210ad583dac3579b39 Mon Sep 17 00:00:00 2001 From: OmarTawfik <15987992+OmarTawfik@users.noreply.github.com> Date: Thu, 14 Nov 2024 20:43:21 -0800 Subject: [PATCH 1/7] upgrade slang to `0.18.3` The newest version includes many performance improvements, and adds WASM support. It also adds a bunch of requested public APIs. This allows importing Slang from any WASM-compatible environment (NodeJS), at the cost of using ESM (or using `await import()` from CJS). That turns the calling utility `makeNamespacedInput()` to be `async`. Please let me know if I need to verify/run anything else. --- packages/core/package.json | 2 +- .../core/src/utils/make-namespaced.test.ts | 2 +- packages/core/src/utils/make-namespaced.ts | 82 +++++++------- packages/core/src/utils/slang/trivia.ts | 23 ---- packages/plugin-hardhat/src/index.ts | 12 ++- tsconfig.base.json | 4 +- yarn.lock | 101 +++--------------- 7 files changed, 61 insertions(+), 165 deletions(-) delete mode 100644 packages/core/src/utils/slang/trivia.ts diff --git a/packages/core/package.json b/packages/core/package.json index 31d27cb30..797375dd8 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -61,7 +61,7 @@ "typescript": "^5.0.0" }, "dependencies": { - "@nomicfoundation/slang": "^0.17.0", + "@nomicfoundation/slang": "^0.18.3", "cbor": "^9.0.0", "chalk": "^4.1.0", "compare-versions": "^6.0.0", diff --git a/packages/core/src/utils/make-namespaced.test.ts b/packages/core/src/utils/make-namespaced.test.ts index 918b4ec67..e236f3d57 100644 --- a/packages/core/src/utils/make-namespaced.test.ts +++ b/packages/core/src/utils/make-namespaced.test.ts @@ -40,7 +40,7 @@ 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 = makeNamespacedInput( + const modifiedInput = await makeNamespacedInput( origBuildInfo.input, origBuildInfo.output, keepAllNatSpec ? undefined : origBuildInfo.solcVersion, diff --git a/packages/core/src/utils/make-namespaced.ts b/packages/core/src/utils/make-namespaced.ts index 850f33f58..9d1a1b7a1 100644 --- a/packages/core/src/utils/make-namespaced.ts +++ b/packages/core/src/utils/make-namespaced.ts @@ -37,7 +37,11 @@ const OUTPUT_SELECTION = { * @param solcVersion The version of the solc compiler that was originally used to compile the input. * @returns The modified solc input with storage layout that includes namespaced type information. */ -export function makeNamespacedInput(input: SolcInput, output: SolcOutput, solcVersion?: string): SolcInput { +export async function makeNamespacedInput( + input: SolcInput, + output: SolcOutput, + solcVersion?: string, +): Promise { const modifiedSources: Record = {}; for (const [sourcePath] of Object.entries(input.sources)) { @@ -163,7 +167,7 @@ export function makeNamespacedInput(input: SolcInput, output: SolcOutput, solcVe } } - const modifiedSource = tryRemoveNonStructNatSpec(getModifiedSource(orig, modifications), solcVersion); + const modifiedSource = await tryRemoveNonStructNatSpec(getModifiedSource(orig, modifications), solcVersion); modifiedSources[sourcePath] = { ...source, content: modifiedSource }; } @@ -177,60 +181,46 @@ export function makeNamespacedInput(input: SolcInput, output: SolcOutput, solcVe * * Otherwise, return the original content. */ -function tryRemoveNonStructNatSpec(origContent: string, solcVersion: string | undefined): string { - const natSpecRemovals: Modification[] = []; +async function tryRemoveNonStructNatSpec(origContent: string, solcVersion: string | undefined): Promise { + if (solcVersion === undefined) { + return origContent; + } - if (solcVersion !== undefined && tryRequire('@nomicfoundation/slang') && slangSupportsVersion(solcVersion)) { - /* eslint-disable @typescript-eslint/no-var-requires */ - const { Language } = require('@nomicfoundation/slang/language'); - const { NonterminalKind, TerminalKind } = require('@nomicfoundation/slang/kinds'); - const { TerminalNode } = require('@nomicfoundation/slang/cst'); - const { isTrivia } = require('./slang/trivia'); - /* eslint-enable @typescript-eslint/no-var-requires */ + const { Parser } = await import('@nomicfoundation/slang/parser'); + if (!Parser.supportedVersions().includes(solcVersion)) { + return origContent; + } - const language = new Language(solcVersion); - const parseOutput = language.parse(NonterminalKind.SourceUnit, origContent); - const cursor = parseOutput.createTreeCursor(); + const { TerminalKind, TerminalKindExtensions } = await import('@nomicfoundation/slang/cst'); + const parser = Parser.create(solcVersion); + const parseOutput = parser.parse(Parser.rootKind(), origContent); + const cursor = parseOutput.createTreeCursor(); + + const natSpecRemovals: Modification[] = []; + + while ( + cursor.goToNextTerminalWithKinds([TerminalKind.MultiLineNatSpecComment, TerminalKind.SingleLineNatSpecComment]) + ) { + // Lookahead to determine if the next non-trivia node is the struct keyword. + // If so, this NatSpec is part of the struct definition and should not be removed. + const lookaheadCursor = cursor.clone(); while ( - cursor.goToNextTerminalWithKinds([TerminalKind.MultiLineNatSpecComment, TerminalKind.SingleLineNatSpecComment]) + lookaheadCursor.goToNextTerminal() && + lookaheadCursor.node.isTerminalNode() && + TerminalKindExtensions.isTrivia(lookaheadCursor.node.kind) ) { - // Lookahead to determine if the next non-trivia node is the struct keyword. - // If so, this NatSpec is part of the struct definition and should not be removed. - const lookaheadCursor = cursor.clone(); - while (lookaheadCursor.goToNextTerminal() && isTrivia(lookaheadCursor.node())) { - // skip over trivia nodes - } - if (lookaheadCursor.node().kind === TerminalKind.StructKeyword) { - continue; - } + // skip over trivia nodes + } - const triviaNode = cursor.node(); - assert(triviaNode instanceof TerminalNode); - natSpecRemovals.push(makeDeleteRange(cursor.textRange.start.utf8, cursor.textRange.end.utf8)); + if (lookaheadCursor.node.kind === TerminalKind.StructKeyword) { + continue; } - return getModifiedSource(Buffer.from(origContent, 'utf8'), natSpecRemovals); - } else { - return origContent; - } -} -function tryRequire(id: string) { - try { - require(id); - return true; - } catch (e: any) { - // do nothing + natSpecRemovals.push(makeDeleteRange(cursor.textRange.start.utf8, cursor.textRange.end.utf8)); } - return false; -} - -function slangSupportsVersion(solcVersion: string): boolean { - /* eslint-disable @typescript-eslint/no-var-requires */ - const { Language } = require('@nomicfoundation/slang/language'); - /* eslint-enable @typescript-eslint/no-var-requires */ - return Language.supportedVersions().includes(solcVersion); + return getModifiedSource(Buffer.from(origContent, 'utf8'), natSpecRemovals); } interface Modification { diff --git a/packages/core/src/utils/slang/trivia.ts b/packages/core/src/utils/slang/trivia.ts deleted file mode 100644 index b8b716b0a..000000000 --- a/packages/core/src/utils/slang/trivia.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { TerminalKind } from '@nomicfoundation/slang/kinds'; -import { Node, TerminalNode } from '@nomicfoundation/slang/cst'; - -/** - * Returns true if the node is a trivia terminal (whitespace or comment or NatSpec) - * - * CAUTION: This must be imported dynamically. - * Only import this file if Slang is supported on the current platform, otherwise an error will be thrown on import. - */ -export function isTrivia(node: Node) { - return node instanceof TerminalNode && isTriviaKind(node.kind); -} - -function isTriviaKind(kind: TerminalKind) { - return ( - kind === TerminalKind.EndOfLine || - kind === TerminalKind.MultiLineComment || - kind === TerminalKind.MultiLineNatSpecComment || - kind === TerminalKind.SingleLineComment || - kind === TerminalKind.SingleLineNatSpecComment || - kind === TerminalKind.Whitespace - ); -} diff --git a/packages/plugin-hardhat/src/index.ts b/packages/plugin-hardhat/src/index.ts index f7458a300..37f9d6177 100644 --- a/packages/plugin-hardhat/src/index.ts +++ b/packages/plugin-hardhat/src/index.ts @@ -69,7 +69,9 @@ interface RunCompilerArgs { } subtask(TASK_COMPILE_SOLIDITY, async (args: { force: boolean }, hre, runSuper) => { - const { readValidations, ValidationsCacheOutdated, ValidationsCacheNotFound } = await import('./utils/validations'); + const { readValidations, ValidationsCacheOutdated, ValidationsCacheNotFound } = await import( + './utils/validations.js' + ); try { await readValidations(hre); @@ -88,18 +90,18 @@ subtask(TASK_COMPILE_SOLIDITY_COMPILE, async (args: RunCompilerArgs, hre, runSup const { isNamespaceSupported, validate, solcInputOutputDecoder, makeNamespacedInput } = await import( '@openzeppelin/upgrades-core' ); - const { writeValidations } = await import('./utils/validations'); + const { writeValidations } = await import('./utils/validations.js'); // TODO: patch input const { output, solcBuild } = await runSuper(); - const { isFullSolcOutput } = await import('./utils/is-full-solc-output'); + const { isFullSolcOutput } = await import('./utils/is-full-solc-output.js'); if (isFullSolcOutput(output)) { const decodeSrc = solcInputOutputDecoder(args.input, output); let namespacedOutput = undefined; if (isNamespaceSupported(args.solcVersion)) { - const namespacedInput = makeNamespacedInput(args.input, output, args.solcVersion); + const namespacedInput = await makeNamespacedInput(args.input, output, args.solcVersion); namespacedOutput = (await runSuper({ ...args, quiet: true, input: namespacedInput })).output; const namespacedCompileErrors = getNamespacedCompileErrors(namespacedOutput); @@ -210,7 +212,7 @@ extendConfig((config: HardhatConfig) => { if (tryRequire('@nomicfoundation/hardhat-verify')) { subtask('verify:etherscan').setAction(async (args, hre, runSuper) => { - const { verify } = await import('./verify-proxy'); + const { verify } = await import('./verify-proxy.js'); return await verify(args, hre, runSuper); }); } diff --git a/tsconfig.base.json b/tsconfig.base.json index 3d424f2c4..546061581 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -2,9 +2,9 @@ "compilerOptions": { "incremental": true, "target": "es2020", - "module": "commonjs", + "module": "nodenext", "strict": true, - "moduleResolution": "node", + "moduleResolution": "nodenext", "esModuleInterop": true, "sourceMap": true, "declaration": true, diff --git a/yarn.lock b/yarn.lock index 1a58a33ab..8a44640ba 100644 --- a/yarn.lock +++ b/yarn.lock @@ -208,6 +208,11 @@ "@babel/helper-validator-identifier" "^7.24.7" to-fast-properties "^2.0.0" +"@bytecodealliance/preview2-shim@0.17.0": + version "0.17.0" + resolved "https://registry.yarnpkg.com/@bytecodealliance/preview2-shim/-/preview2-shim-0.17.0.tgz#9bc1cadbb9f86c446c6f579d3431c08a06a6672e" + integrity sha512-JorcEwe4ud0x5BS/Ar2aQWOQoFzjq/7jcnxYXCvSMh0oRm0dQXzOA+hqLDBnOMks1LLBA7dmiLLsEBl09Yd6iQ== + "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": version "4.4.0" resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" @@ -685,65 +690,12 @@ table "^6.8.0" undici "^5.14.0" -"@nomicfoundation/slang-darwin-arm64@0.17.0": - version "0.17.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/slang-darwin-arm64/-/slang-darwin-arm64-0.17.0.tgz#8cded3c24322624e3b6618760caba8e840bd1c1d" - integrity sha512-O0q94EUtoWy9A5kOTOa9/khtxXDYnLqmuda9pQELurSiwbQEVCPQL8kb34VbOW+ifdre66JM/05Xw9JWhIZ9sA== - -"@nomicfoundation/slang-darwin-x64@0.17.0": - version "0.17.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/slang-darwin-x64/-/slang-darwin-x64-0.17.0.tgz#6ebeb33a2ced89fc6023f6cda4af96403486038a" - integrity sha512-IaDbHzvT08sBK2HyGzonWhq1uu8IxdjmTqAWHr25Oh/PYnamdi8u4qchZXXYKz/DHLoYN3vIpBXoqLQIomhD/g== - -"@nomicfoundation/slang-linux-arm64-gnu@0.17.0": - version "0.17.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/slang-linux-arm64-gnu/-/slang-linux-arm64-gnu-0.17.0.tgz#41c7e57a9b1a3aee6911f0cab22e683c149fb470" - integrity sha512-Lj4anvOsQZxs1SycG8VyT2Rl2oqIhyLSUCgGepTt3CiJ/bM+8r8bLJIgh8vKkki4BWz49YsYIgaJB2IPv8FFTw== - -"@nomicfoundation/slang-linux-arm64-musl@0.17.0": - version "0.17.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/slang-linux-arm64-musl/-/slang-linux-arm64-musl-0.17.0.tgz#9c4b51689274ae75c2c8a4cddd2e1cc0a79c191d" - integrity sha512-/xkTCa9d5SIWUBQE3BmLqDFfJRr4yUBwbl4ynPiGUpRXrD69cs6pWKkwjwz/FdBpXqVo36I+zY95qzoTj/YhOA== - -"@nomicfoundation/slang-linux-x64-gnu@0.17.0": - version "0.17.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/slang-linux-x64-gnu/-/slang-linux-x64-gnu-0.17.0.tgz#c3a3b6a7b775fc617832958d10e6664bf86d39d0" - integrity sha512-oe5IO5vntOqYvTd67deCHPIWuSuWm6aYtT2/0Kqz2/VLtGz4ClEulBSRwfnNzBVtw2nksWipE1w8BzhImI7Syg== - -"@nomicfoundation/slang-linux-x64-musl@0.17.0": - version "0.17.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/slang-linux-x64-musl/-/slang-linux-x64-musl-0.17.0.tgz#725118ff99a7217b9f1d1bd84411d9442084077d" - integrity sha512-PpYCI5K/kgLAMXaPY0V4VST5gCDprEOh7z/47tbI8kJQumI5odjsj/Cs8MpTo7/uRH6flKYbVNgUzcocWVYrAQ== - -"@nomicfoundation/slang-win32-arm64-msvc@0.17.0": - version "0.17.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/slang-win32-arm64-msvc/-/slang-win32-arm64-msvc-0.17.0.tgz#9c8bc4ccf21eaaac0cfcb6d3954ede4e2dea4c02" - integrity sha512-u/Mkf7OjokdBilP7QOJj6QYJU4/mjkbKnTX21wLyCIzeVWS7yafRPYpBycKIBj2pRRZ6ceAY5EqRpb0aiCq+0Q== - -"@nomicfoundation/slang-win32-ia32-msvc@0.17.0": - version "0.17.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/slang-win32-ia32-msvc/-/slang-win32-ia32-msvc-0.17.0.tgz#3fc5d00a3f8c1d85a5e94146af78a5526a4f3d27" - integrity sha512-XJBVQfNnZQUv0tP2JSJ573S+pmgrLWgqSZOGaMllnB/TL1gRci4Z7dYRJUF2s82GlRJE+FHSI2Ro6JISKmlXCg== - -"@nomicfoundation/slang-win32-x64-msvc@0.17.0": - version "0.17.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/slang-win32-x64-msvc/-/slang-win32-x64-msvc-0.17.0.tgz#f6a5e3250fa07cbda49151edeb80f09090e5b71a" - integrity sha512-zPGsAeiTfqfPNYHD8BfrahQmYzA78ZraoHKTGraq/1xwJwzBK4bu/NtvVA4pJjBV+B4L6DCxVhSbpn40q26JQA== - -"@nomicfoundation/slang@^0.17.0": - version "0.17.0" - resolved "https://registry.yarnpkg.com/@nomicfoundation/slang/-/slang-0.17.0.tgz#d9c25cd711ebf3490c9d0c99e9b4ca2481341a6b" - integrity sha512-1GlkGRcGpVnjFw9Z1vvDKOKo2mzparFt7qrl2pDxWp+jrVtlvej98yCMX52pVyrYE7ZeOSZFnx/DtsSgoukStQ== - dependencies: - "@nomicfoundation/slang-darwin-arm64" "0.17.0" - "@nomicfoundation/slang-darwin-x64" "0.17.0" - "@nomicfoundation/slang-linux-arm64-gnu" "0.17.0" - "@nomicfoundation/slang-linux-arm64-musl" "0.17.0" - "@nomicfoundation/slang-linux-x64-gnu" "0.17.0" - "@nomicfoundation/slang-linux-x64-musl" "0.17.0" - "@nomicfoundation/slang-win32-arm64-msvc" "0.17.0" - "@nomicfoundation/slang-win32-ia32-msvc" "0.17.0" - "@nomicfoundation/slang-win32-x64-msvc" "0.17.0" +"@nomicfoundation/slang@^0.18.3": + version "0.18.3" + resolved "https://registry.yarnpkg.com/@nomicfoundation/slang/-/slang-0.18.3.tgz#976b6c3820081cebf050afbea434038aac9313cc" + integrity sha512-YqAWgckqbHM0/CZxi9Nlf4hjk9wUNLC9ngWCWBiqMxPIZmzsVKYuChdlrfeBPQyvQQBoOhbx+7C1005kLVQDZQ== + dependencies: + "@bytecodealliance/preview2-shim" "0.17.0" "@nomicfoundation/solidity-analyzer-darwin-arm64@0.1.2": version "0.1.2" @@ -5146,16 +5098,7 @@ statuses@2.0.1: resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== -"string-width-cjs@npm:string-width@^4.2.0": - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -5226,7 +5169,7 @@ string_decoder@^1.1.1: dependencies: safe-buffer "~5.2.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": +"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -5240,13 +5183,6 @@ strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: dependencies: ansi-regex "^4.1.0" -strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - strip-ansi@^7.0.1, strip-ansi@^7.1.0: version "7.1.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" @@ -5719,7 +5655,7 @@ workerpool@^6.5.1: resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.5.1.tgz#060f73b39d0caf97c6db64da004cd01b4c099544" integrity sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -5746,15 +5682,6 @@ wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" From c2bdbee379f0af4a6a2989977473427ee91f6c1d Mon Sep 17 00:00:00 2001 From: Eric Lau Date: Wed, 20 Nov 2024 12:46:47 -0500 Subject: [PATCH 2/7] Export new function to avoid breaking changes --- packages/core/src/index.ts | 2 +- .../core/src/utils/make-namespaced.test.ts | 9 +++-- packages/core/src/utils/make-namespaced.ts | 35 +++++++++++++------ packages/plugin-hardhat/src/index.ts | 5 +-- 4 files changed, 35 insertions(+), 16 deletions(-) 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); From b719a991daa1bfe38435815f23a50d9deac2f968 Mon Sep 17 00:00:00 2001 From: Eric Lau Date: Wed, 20 Nov 2024 13:39:32 -0500 Subject: [PATCH 3/7] Fix lint --- packages/core/src/utils/make-namespaced.test.ts | 6 +----- packages/core/src/utils/make-namespaced.ts | 6 +----- packages/plugin-hardhat/src/index.ts | 5 ++--- 3 files changed, 4 insertions(+), 13 deletions(-) diff --git a/packages/core/src/utils/make-namespaced.test.ts b/packages/core/src/utils/make-namespaced.test.ts index a5448a9b8..06e409ae2 100644 --- a/packages/core/src/utils/make-namespaced.test.ts +++ b/packages/core/src/utils/make-namespaced.test.ts @@ -40,11 +40,7 @@ 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 = makeNamespacedInput( - origBuildInfo.input, - origBuildInfo.output, - origBuildInfo.solcVersion, - ); + const modifiedInput = makeNamespacedInput(origBuildInfo.input, origBuildInfo.output, origBuildInfo.solcVersion); if (!keepAllNatSpec) { await trySanitizeNatSpec(modifiedInput, origBuildInfo.solcVersion); } diff --git a/packages/core/src/utils/make-namespaced.ts b/packages/core/src/utils/make-namespaced.ts index 25f170a3f..93e7c8e2e 100644 --- a/packages/core/src/utils/make-namespaced.ts +++ b/packages/core/src/utils/make-namespaced.ts @@ -37,11 +37,7 @@ const OUTPUT_SELECTION = { * @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 function makeNamespacedInput( - input: SolcInput, - output: SolcOutput, - _solcVersion?: string, -): SolcInput { +export function makeNamespacedInput(input: SolcInput, output: SolcOutput, _solcVersion?: string): SolcInput { const modifiedSources: Record = {}; for (const [sourcePath] of Object.entries(input.sources)) { diff --git a/packages/plugin-hardhat/src/index.ts b/packages/plugin-hardhat/src/index.ts index d30ef0d51..c7b8ae5ee 100644 --- a/packages/plugin-hardhat/src/index.ts +++ b/packages/plugin-hardhat/src/index.ts @@ -87,9 +87,8 @@ 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, trySanitizeNatSpec } = await import( - '@openzeppelin/upgrades-core' - ); + const { isNamespaceSupported, validate, solcInputOutputDecoder, makeNamespacedInput, trySanitizeNatSpec } = + await import('@openzeppelin/upgrades-core'); const { writeValidations } = await import('./utils/validations.js'); // TODO: patch input From c317401f05ab989d6731bbdc99003391f73c6211 Mon Sep 17 00:00:00 2001 From: Eric Lau Date: Wed, 20 Nov 2024 13:56:32 -0500 Subject: [PATCH 4/7] Bump versions, add changelogs --- packages/core/CHANGELOG.md | 4 ++++ packages/core/package.json | 2 +- packages/plugin-hardhat/CHANGELOG.md | 4 ++++ packages/plugin-hardhat/package.json | 4 ++-- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md index e69df217c..182a4255e 100644 --- a/packages/core/CHANGELOG.md +++ b/packages/core/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## Unreleased + +- Update Slang dependency to 0.18.3. ([#1102](https://github.com/OpenZeppelin/openzeppelin-upgrades/pull/1102)) + ## 1.40.0 (2024-10-10) - Fix Hardhat compile error when overriding interface functions with public constant variables. ([#1091](https://github.com/OpenZeppelin/openzeppelin-upgrades/pull/1091)) diff --git a/packages/core/package.json b/packages/core/package.json index 797375dd8..905b44a63 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "name": "@openzeppelin/upgrades-core", - "version": "1.40.0", + "version": "1.41.0", "description": "", "repository": "https://github.com/OpenZeppelin/openzeppelin-upgrades/tree/master/packages/core", "license": "MIT", diff --git a/packages/plugin-hardhat/CHANGELOG.md b/packages/plugin-hardhat/CHANGELOG.md index 02f25b39b..7b9cd79b2 100644 --- a/packages/plugin-hardhat/CHANGELOG.md +++ b/packages/plugin-hardhat/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## Unreleased + +- Update Slang dependency to 0.18.3. ([#1102](https://github.com/OpenZeppelin/openzeppelin-upgrades/pull/1102)) + ## 3.5.0 (2024-10-10) - Support ignoring Hardhat compile errors when extracting detailed namespaced storage layouts for validations. ([#1090](https://github.com/OpenZeppelin/openzeppelin-upgrades/pull/1090)) diff --git a/packages/plugin-hardhat/package.json b/packages/plugin-hardhat/package.json index 12223d56a..ba1ea5e8f 100644 --- a/packages/plugin-hardhat/package.json +++ b/packages/plugin-hardhat/package.json @@ -1,6 +1,6 @@ { "name": "@openzeppelin/hardhat-upgrades", - "version": "3.5.0", + "version": "3.5.1", "description": "", "repository": "https://github.com/OpenZeppelin/openzeppelin-upgrades/tree/master/packages/plugin-hardhat", "license": "MIT", @@ -38,7 +38,7 @@ "@openzeppelin/defender-sdk-base-client": "^1.14.4", "@openzeppelin/defender-sdk-deploy-client": "^1.14.4", "@openzeppelin/defender-sdk-network-client": "^1.14.4", - "@openzeppelin/upgrades-core": "^1.40.0", + "@openzeppelin/upgrades-core": "^1.41.0", "chalk": "^4.1.0", "debug": "^4.1.1", "ethereumjs-util": "^7.1.5", From d940ff313c105af2ba315665f3dcf628072a0dc0 Mon Sep 17 00:00:00 2001 From: Eric Lau Date: Mon, 25 Nov 2024 16:51:56 -0500 Subject: [PATCH 5/7] Return input from function --- packages/core/src/utils/make-namespaced.test.ts | 4 ++-- packages/core/src/utils/make-namespaced.ts | 6 ++++-- packages/plugin-hardhat/src/index.ts | 4 ++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/core/src/utils/make-namespaced.test.ts b/packages/core/src/utils/make-namespaced.test.ts index 06e409ae2..b267fbbd8 100644 --- a/packages/core/src/utils/make-namespaced.test.ts +++ b/packages/core/src/utils/make-namespaced.test.ts @@ -40,9 +40,9 @@ 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 = makeNamespacedInput(origBuildInfo.input, origBuildInfo.output, origBuildInfo.solcVersion); + let modifiedInput = makeNamespacedInput(origBuildInfo.input, origBuildInfo.output, origBuildInfo.solcVersion); if (!keepAllNatSpec) { - await trySanitizeNatSpec(modifiedInput, origBuildInfo.solcVersion); + modifiedInput = await trySanitizeNatSpec(modifiedInput, origBuildInfo.solcVersion); } // Run hardhat compile on the modified input and make sure it has no errors diff --git a/packages/core/src/utils/make-namespaced.ts b/packages/core/src/utils/make-namespaced.ts index 93e7c8e2e..c30c74ed1 100644 --- a/packages/core/src/utils/make-namespaced.ts +++ b/packages/core/src/utils/make-namespaced.ts @@ -171,19 +171,21 @@ export function makeNamespacedInput(input: SolcInput, output: SolcOutput, _solcV /** * Attempts to remove all NatSpec comments that do not precede a struct definition from the input source contents. - * Directly modifies the input source contents. + * Directly modifies the input source contents, and also returns the modified input. * * 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. + * @returns The modified solc input with NatSpec comments removed where they do not precede a struct definition. */ -export async function trySanitizeNatSpec(solcInput: SolcInput, solcVersion: string) { +export async function trySanitizeNatSpec(solcInput: SolcInput, solcVersion: string): Promise { for (const [sourcePath, source] of Object.entries(solcInput.sources)) { if (source.content !== undefined) { solcInput.sources[sourcePath].content = await tryRemoveNonStructNatSpec(source.content, solcVersion); } } + return solcInput; } /** diff --git a/packages/plugin-hardhat/src/index.ts b/packages/plugin-hardhat/src/index.ts index c7b8ae5ee..21bb4241f 100644 --- a/packages/plugin-hardhat/src/index.ts +++ b/packages/plugin-hardhat/src/index.ts @@ -100,8 +100,8 @@ subtask(TASK_COMPILE_SOLIDITY_COMPILE, async (args: RunCompilerArgs, hre, runSup let namespacedOutput = undefined; if (isNamespaceSupported(args.solcVersion)) { - const namespacedInput = makeNamespacedInput(args.input, output, args.solcVersion); - await trySanitizeNatSpec(namespacedInput, args.solcVersion); + let namespacedInput = makeNamespacedInput(args.input, output, args.solcVersion); + namespacedInput = await trySanitizeNatSpec(namespacedInput, args.solcVersion); namespacedOutput = (await runSuper({ ...args, quiet: true, input: namespacedInput })).output; const namespacedCompileErrors = getNamespacedCompileErrors(namespacedOutput); From aa7f05c02674c4357c60a240bde5e2b2a99a1fec Mon Sep 17 00:00:00 2001 From: Eric Lau Date: Mon, 25 Nov 2024 17:00:49 -0500 Subject: [PATCH 6/7] Bump minor version, update changelogs --- packages/core/CHANGELOG.md | 1 + packages/plugin-hardhat/CHANGELOG.md | 1 + packages/plugin-hardhat/package.json | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md index 182a4255e..15658952e 100644 --- a/packages/core/CHANGELOG.md +++ b/packages/core/CHANGELOG.md @@ -3,6 +3,7 @@ ## Unreleased - Update Slang dependency to 0.18.3. ([#1102](https://github.com/OpenZeppelin/openzeppelin-upgrades/pull/1102)) + - Improves reliability of Hardhat compilation step for namespaced storage layout validations when using Solidity versions 0.8.27 and 0.8.28. ## 1.40.0 (2024-10-10) diff --git a/packages/plugin-hardhat/CHANGELOG.md b/packages/plugin-hardhat/CHANGELOG.md index 7b9cd79b2..a99695588 100644 --- a/packages/plugin-hardhat/CHANGELOG.md +++ b/packages/plugin-hardhat/CHANGELOG.md @@ -3,6 +3,7 @@ ## Unreleased - Update Slang dependency to 0.18.3. ([#1102](https://github.com/OpenZeppelin/openzeppelin-upgrades/pull/1102)) + - Improves reliability of Hardhat compilation step for namespaced storage layout validations when using Solidity versions 0.8.27 and 0.8.28. ## 3.5.0 (2024-10-10) diff --git a/packages/plugin-hardhat/package.json b/packages/plugin-hardhat/package.json index ba1ea5e8f..0489675d6 100644 --- a/packages/plugin-hardhat/package.json +++ b/packages/plugin-hardhat/package.json @@ -1,6 +1,6 @@ { "name": "@openzeppelin/hardhat-upgrades", - "version": "3.5.1", + "version": "3.6.0", "description": "", "repository": "https://github.com/OpenZeppelin/openzeppelin-upgrades/tree/master/packages/plugin-hardhat", "license": "MIT", From f2d21aaaa95589c98c16931c2bedad814dc16b46 Mon Sep 17 00:00:00 2001 From: Eric Lau Date: Mon, 25 Nov 2024 17:02:42 -0500 Subject: [PATCH 7/7] Set versions in changelog --- packages/core/CHANGELOG.md | 2 +- packages/plugin-hardhat/CHANGELOG.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/core/CHANGELOG.md b/packages/core/CHANGELOG.md index 15658952e..aaac478b3 100644 --- a/packages/core/CHANGELOG.md +++ b/packages/core/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## Unreleased +## 1.41.0 (2024-11-25) - Update Slang dependency to 0.18.3. ([#1102](https://github.com/OpenZeppelin/openzeppelin-upgrades/pull/1102)) - Improves reliability of Hardhat compilation step for namespaced storage layout validations when using Solidity versions 0.8.27 and 0.8.28. diff --git a/packages/plugin-hardhat/CHANGELOG.md b/packages/plugin-hardhat/CHANGELOG.md index a99695588..9f0b7efdd 100644 --- a/packages/plugin-hardhat/CHANGELOG.md +++ b/packages/plugin-hardhat/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## Unreleased +## 3.6.0 (2024-11-25) - Update Slang dependency to 0.18.3. ([#1102](https://github.com/OpenZeppelin/openzeppelin-upgrades/pull/1102)) - Improves reliability of Hardhat compilation step for namespaced storage layout validations when using Solidity versions 0.8.27 and 0.8.28.