diff --git a/scripts/verify-dep-lockstep.mjs b/scripts/verify-dep-lockstep.mjs index 0a328e44..5d29497b 100644 --- a/scripts/verify-dep-lockstep.mjs +++ b/scripts/verify-dep-lockstep.mjs @@ -132,10 +132,12 @@ export function packageNameOf(specifier) { // name would silently widen the set. // // Whitespace between tokens is really *trivia*: TypeScript allows a comment -// anywhere whitespace is legal, so `import(/* webpackIgnore: true */ "pkg")` -// and `from /* why */ "pkg"` are valid and must still be seen (Copilot, -// #1962). `TRIVIA` stands in for `\s*` at every such position. -const TRIVIA = String.raw`(?:\s|/\*[\s\S]*?\*/)*`; +// anywhere whitespace is legal, so `import(/* webpackIgnore: true */ "pkg")`, +// `from /* why */ "pkg"`, and the line-comment forms (`import(// lazy\n"pkg")`) +// are all valid and must still be seen (Copilot, #1962). `TRIVIA` stands in for +// `\s*` at every such position and covers both comment syntaxes. A line comment +// runs to end-of-line only — the newline itself is matched by the `\s` branch. +const TRIVIA = String.raw`(?:\s|/\*[\s\S]*?\*/|//[^\n]*)*`; const SPECIFIER_FORMS = [ // import … from "x" / export … from "x" new RegExp(String.raw`\bfrom${TRIVIA}["']([^"']+)["']`, "g"), diff --git a/scripts/verify-dep-lockstep.test.mjs b/scripts/verify-dep-lockstep.test.mjs index 6d0840d7..eee81432 100644 --- a/scripts/verify-dep-lockstep.test.mjs +++ b/scripts/verify-dep-lockstep.test.mjs @@ -118,6 +118,25 @@ test("importedPackageNames: comment trivia between tokens (Copilot, #1962)", () ]); }); +test("importedPackageNames: line-comment trivia, not just block (Copilot, #1962)", () => { + // `//` runs to end-of-line and is legal in every position a block comment is, + // so these are valid imports too. The newline is matched by TRIVIA's `\\s` + // branch rather than by the line-comment branch. + const source = [ + "import { a } from // reason", + ' "express";', + "const b = await import(// lazy", + ' "undici");', + "const c = require(// lazy", + ' "yaml");', + ].join("\n"); + assert.deepEqual([...importedPackageNames(source)].sort(), [ + "express", + "undici", + "yaml", + ]); +}); + test("importedPackageNames: the three specifier forms that introduce types", () => { const source = ` import { z } from "zod/v4";