chore(deps): count triple-slash type references as candidates
From Copilot's twelfth pass of #1962. A `/// <reference types="x" />` pulls in a package's declarations exactly like an import does, but TypeScript reports it in `preProcessFile`'s `typeReferenceDirectives`, not `importedFiles` — and only the latter was read. A shared source using one could therefore load the root's copy of a package alongside a client's without it ever entering the candidate set, so its skew would pass. Same silent-miss direction as the earlier syntax gaps, through a channel the parser switch didn't cover because I only read one of its two outputs. `typeReferencePackageNames` maps a directive to both candidates, since the name is the *type* name and not the package: `node` resolves to `@types/node`, while a package shipping its own declarations resolves to itself. Returning both over-approximates, the safe direction — whichever isn't installed drops out downstream. Scoped names mangle `@scope/pkg` → `@types/scope__pkg`, TypeScript's convention. `path` references name a file, not a package, and are ignored. The real candidate set is unchanged at 17: no shared source uses a triple-slash reference today. As with the other syntax fixes, this closes the channel against the one that arrives later. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HDdo1rNRVQnVRRdsqSrvG3
This commit is contained in:
parent
af63a07817
commit
87c1e05420
1 changed files with 64 additions and 2 deletions
|
|
@ -16,6 +16,7 @@ import {
|
|||
partitionSkew,
|
||||
sourcesWithNoFiles,
|
||||
topLevelLockVersions,
|
||||
typeReferencePackageNames,
|
||||
} from "./verify-dep-lockstep.mjs";
|
||||
|
||||
test("isSharedSourceFile: all four TS extensions, not just .ts/.tsx", () => {
|
||||
|
|
@ -196,6 +197,41 @@ test("importedPackageNames: static, side-effect, and dynamic forms; builtins and
|
|||
]);
|
||||
});
|
||||
|
||||
test("importedPackageNames: triple-slash type references count (Copilot, #1962)", () => {
|
||||
// A `/// <reference types="x" />` pulls in declarations exactly like an
|
||||
// import, but TypeScript reports it in `typeReferenceDirectives`, not
|
||||
// `importedFiles` — so reading only the latter let a referenced package skew
|
||||
// unseen. `path` references name a file, not a package, and are ignored.
|
||||
const source = [
|
||||
'/// <reference types="node" />',
|
||||
'/// <reference types="express" />',
|
||||
'/// <reference path="./local.d.ts" />',
|
||||
'import { z } from "zod";',
|
||||
].join("\n");
|
||||
assert.deepEqual([...importedPackageNames(source)].sort(), [
|
||||
"@types/express",
|
||||
"@types/node",
|
||||
"express",
|
||||
"node",
|
||||
"zod",
|
||||
]);
|
||||
});
|
||||
|
||||
test("typeReferencePackageNames: both the bare and the @types form (Copilot, #1962)", () => {
|
||||
// The directive names a *type*, not a package: `node` resolves to
|
||||
// `@types/node`, while a package shipping its own declarations resolves to
|
||||
// itself. Returning both over-approximates, the safe direction — whichever
|
||||
// isn't installed drops out downstream.
|
||||
assert.deepEqual(typeReferencePackageNames("node"), ["node", "@types/node"]);
|
||||
// Scoped names mangle with a double underscore, TypeScript's convention.
|
||||
assert.deepEqual(typeReferencePackageNames("@scope/pkg"), [
|
||||
"@scope/pkg",
|
||||
"@types/scope__pkg",
|
||||
]);
|
||||
assert.deepEqual(typeReferencePackageNames("./relative"), []);
|
||||
assert.deepEqual(typeReferencePackageNames(""), []);
|
||||
});
|
||||
|
||||
test("importedPackageNames: prose in comments never becomes a package (Copilot, #1962)", () => {
|
||||
// The regex scan this replaced could not tell code from a comment, so
|
||||
// `// adapted from "react"` added `react` to the candidate set — and if that
|
||||
|
|
|
|||
Loading…
Reference in a new issue