carrick 0.3.106 → 0.3.107
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/hook/refresh.js +8 -1
- package/dist/hook/refresh.js.map +1 -1
- package/package.json +6 -6
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/sidecar/dist/src/capture/anchors.d.ts +15 -2
- package/sidecar/dist/src/capture/anchors.js +28 -11
- package/sidecar/dist/src/capture/check-poison.js +4 -14
- package/sidecar/dist/src/capture/index.js +54 -36
- package/sidecar/dist/src/capture/installed-package.d.ts +2 -0
- package/sidecar/dist/src/capture/installed-package.js +2 -1
- package/sidecar/dist/src/capture/outside-root.d.ts +19 -0
- package/sidecar/dist/src/capture/outside-root.js +39 -2
- package/sidecar/dist/src/capture/self-check.js +3 -13
- package/sidecar/dist/src/capture/specifiers.d.ts +14 -0
- package/sidecar/dist/src/capture/specifiers.js +25 -0
- package/sidecar/dist/src/function-line-index.d.ts +30 -0
- package/sidecar/dist/src/function-line-index.js +162 -0
- package/sidecar/dist/src/index.d.ts +5 -0
- package/sidecar/dist/src/index.js +29 -5
- package/sidecar/dist/src/line-index.d.ts +9 -0
- package/sidecar/dist/src/line-index.js +26 -0
- package/sidecar/dist/src/progress.d.ts +22 -0
- package/sidecar/dist/src/progress.js +31 -0
- package/sidecar/dist/src/retype.js +1 -19
- package/sidecar/dist/src/type-inferrer.d.ts +92 -11
- package/sidecar/dist/src/type-inferrer.js +356 -149
- package/sidecar/dist/src/types.d.ts +13 -6
package/dist/hook/refresh.js
CHANGED
|
@@ -132,7 +132,14 @@ export function refreshInBackground(root, status, options = {}) {
|
|
|
132
132
|
return null;
|
|
133
133
|
if (!claimRefresh(marker, now, cooldown))
|
|
134
134
|
return null;
|
|
135
|
-
|
|
135
|
+
// Nobody started this refresh and nobody is reading it, so it does not keep
|
|
136
|
+
// the machine awake: that hold is for a scan a person is waiting on, and it
|
|
137
|
+
// comes with a line saying so that this one has nowhere to print
|
|
138
|
+
// (carrick#1889).
|
|
139
|
+
(options.start ?? startDetached)(binary(env), ["refresh", "--workspace", root], {
|
|
140
|
+
...env,
|
|
141
|
+
CARRICK_NO_KEEP_AWAKE: "1",
|
|
142
|
+
});
|
|
136
143
|
return "Carrick: a repo here is connected with no hosted index yet, so a refresh is running in the background. Its rows arrive in the next session.";
|
|
137
144
|
}
|
|
138
145
|
//# sourceMappingURL=refresh.js.map
|
package/dist/hook/refresh.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"refresh.js","sourceRoot":"","sources":["../../src/hook/refresh.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"refresh.js","sourceRoot":"","sources":["../../src/hook/refresh.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "carrick",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.107",
|
|
4
4
|
"description": "Maps your entire TypeScript codebase across services and repositories, giving AI agents full context on existing types, routes, and function behaviours over MCP before they write duplicate or breaking code.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"typescript",
|
|
@@ -58,11 +58,11 @@
|
|
|
58
58
|
"zod": "^3.23.0"
|
|
59
59
|
},
|
|
60
60
|
"optionalDependencies": {
|
|
61
|
-
"@carrick-tools/cli-darwin-arm64": "0.3.
|
|
62
|
-
"@carrick-tools/cli-darwin-x64": "0.3.
|
|
63
|
-
"@carrick-tools/cli-linux-arm64": "0.3.
|
|
64
|
-
"@carrick-tools/cli-linux-x64": "0.3.
|
|
65
|
-
"@carrick-tools/cli-win32-x64": "0.3.
|
|
61
|
+
"@carrick-tools/cli-darwin-arm64": "0.3.107",
|
|
62
|
+
"@carrick-tools/cli-darwin-x64": "0.3.107",
|
|
63
|
+
"@carrick-tools/cli-linux-arm64": "0.3.107",
|
|
64
|
+
"@carrick-tools/cli-linux-x64": "0.3.107",
|
|
65
|
+
"@carrick-tools/cli-win32-x64": "0.3.107"
|
|
66
66
|
},
|
|
67
67
|
"devDependencies": {
|
|
68
68
|
"@types/node": "^24.13.3",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "carrick",
|
|
3
3
|
"description": "Claude Code plugin for Carrick, which indexes TypeScript codebases across service and repository boundaries. After each edit it adds the file's routes, calls, and cross-service type mismatches to the session, and it registers Carrick's language server. It pairs with the Carrick MCP server, which lets agents search functions by intent rather than name.",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.107",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Carrick",
|
|
7
7
|
"email": "hello@carrick.tools"
|
|
@@ -56,8 +56,21 @@ export interface ResolvedAnchor {
|
|
|
56
56
|
*/
|
|
57
57
|
namesUnemittedModule?: true;
|
|
58
58
|
}
|
|
59
|
-
/**
|
|
60
|
-
|
|
59
|
+
/**
|
|
60
|
+
* Repo-root-relative source file -> the specifier the surface entry imports
|
|
61
|
+
* it by: its path from `entryDir`, in the form the entry resolves.
|
|
62
|
+
*
|
|
63
|
+
* With the extension removed (`./a`), where `resolveFromEntry` says the entry
|
|
64
|
+
* resolves that to the module. It does not always (carrick#1911): under
|
|
65
|
+
* `module` `node16`..`nodenext` an entry in a `"type": "module"` package is
|
|
66
|
+
* an ES module, which must name the file the module compiles to, and a `.mts`
|
|
67
|
+
* or `.cts` module has no extensionless form under any setting. There, and
|
|
68
|
+
* with no resolver to ask, the specifier is that output name: `./a.js` for
|
|
69
|
+
* `.ts` and `.tsx`, `./a.mjs` for `.mts`, `./a.cjs` for `.cts`, which every
|
|
70
|
+
* module setting maps back to the source and, in the stub, to its
|
|
71
|
+
* declaration.
|
|
72
|
+
*/
|
|
73
|
+
export declare function entryRelativeSpecifier(entryDir: string, repoRoot: string, sourceFile: string, resolveFromEntry?: (specifier: string) => string | undefined): string;
|
|
61
74
|
/**
|
|
62
75
|
* Resolve one anchor against the analysis program. `placeholder` is the
|
|
63
76
|
* anchor's own placeholder alias declaration in the entry file -- the
|
|
@@ -11,15 +11,32 @@ import { typeIsOrContainsMachinery } from './machinery.js';
|
|
|
11
11
|
import { installedPackageSpecifier } from './installed-package.js';
|
|
12
12
|
import { realPath } from './service-config.js';
|
|
13
13
|
import { unresolvedAtAnchor, unresolvedSpecifiersReachableFrom, } from './unresolved.js';
|
|
14
|
-
/**
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Repo-root-relative source file -> the specifier the surface entry imports
|
|
16
|
+
* it by: its path from `entryDir`, in the form the entry resolves.
|
|
17
|
+
*
|
|
18
|
+
* With the extension removed (`./a`), where `resolveFromEntry` says the entry
|
|
19
|
+
* resolves that to the module. It does not always (carrick#1911): under
|
|
20
|
+
* `module` `node16`..`nodenext` an entry in a `"type": "module"` package is
|
|
21
|
+
* an ES module, which must name the file the module compiles to, and a `.mts`
|
|
22
|
+
* or `.cts` module has no extensionless form under any setting. There, and
|
|
23
|
+
* with no resolver to ask, the specifier is that output name: `./a.js` for
|
|
24
|
+
* `.ts` and `.tsx`, `./a.mjs` for `.mts`, `./a.cjs` for `.cts`, which every
|
|
25
|
+
* module setting maps back to the source and, in the stub, to its
|
|
26
|
+
* declaration.
|
|
27
|
+
*/
|
|
28
|
+
export function entryRelativeSpecifier(entryDir, repoRoot, sourceFile, resolveFromEntry) {
|
|
29
|
+
const target = path.join(repoRoot, sourceFile);
|
|
30
|
+
const from = (file) => {
|
|
31
|
+
const rel = path.relative(entryDir, file).split(path.sep).join('/');
|
|
32
|
+
return rel.startsWith('.') ? rel : `./${rel}`;
|
|
33
|
+
};
|
|
34
|
+
const bare = from(target.replace(/\.(ts|tsx|mts|cts)$/, ''));
|
|
35
|
+
const resolved = resolveFromEntry?.(bare);
|
|
36
|
+
if (resolved !== undefined && realPath(resolved) === realPath(target))
|
|
37
|
+
return bare;
|
|
38
|
+
const kind = /(?:\.d)?\.([cm]?)[jt]sx?$/.exec(target);
|
|
39
|
+
return kind ? from(`${target.slice(0, kind.index)}.${kind[1]}js`) : bare;
|
|
23
40
|
}
|
|
24
41
|
function moduleExport(checker, sourceFile, name) {
|
|
25
42
|
const moduleSymbol = checker.getSymbolAtLocation(sourceFile);
|
|
@@ -100,7 +117,7 @@ export function resolveAnchor(program, request, args) {
|
|
|
100
117
|
if (!sourceFile) {
|
|
101
118
|
return demote(`source file not in program: ${request.source_file}`);
|
|
102
119
|
}
|
|
103
|
-
const spec = entryRelativeSpecifier(args.entryDir, args.repoRoot, request.source_file);
|
|
120
|
+
const spec = entryRelativeSpecifier(args.entryDir, args.repoRoot, request.source_file, args.resolveFromEntry);
|
|
104
121
|
if (request.kind === 'symbol') {
|
|
105
122
|
const exported = moduleExport(checker, sourceFile, request.symbol_name);
|
|
106
123
|
if (!exported) {
|
|
@@ -436,7 +453,7 @@ function qualifyNamesFromSource(text, program, sourceFileRel, printed, args) {
|
|
|
436
453
|
return undefined;
|
|
437
454
|
if (rel.split(path.sep).includes('node_modules'))
|
|
438
455
|
return undefined;
|
|
439
|
-
return entryRelativeSpecifier(args.entryDir, args.repoRoot, rel.split(path.sep).join('/'));
|
|
456
|
+
return entryRelativeSpecifier(args.entryDir, args.repoRoot, rel.split(path.sep).join('/'), args.resolveFromEntry);
|
|
440
457
|
};
|
|
441
458
|
const imports = new Map();
|
|
442
459
|
const importFor = (name) => {
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
import ts from 'typescript';
|
|
28
28
|
import * as fs from 'node:fs';
|
|
29
29
|
import * as path from 'node:path';
|
|
30
|
-
import { collectSpecifiers, isRelative } from './specifiers.js';
|
|
30
|
+
import { collectSpecifiers, declarationCandidates, isDeclarationFileName, isRelative, } from './specifiers.js';
|
|
31
31
|
/** One index per assembled stub, keyed by service name. */
|
|
32
32
|
export function buildPoisonIndexes(ws) {
|
|
33
33
|
const indexes = new Map();
|
|
@@ -45,14 +45,14 @@ function buildOne(ws, serviceName, packageDir) {
|
|
|
45
45
|
return undefined;
|
|
46
46
|
const keyPrefix = `packages/${packageDir}/types`;
|
|
47
47
|
const surfaceFile = `${keyPrefix}/surface.d.ts`;
|
|
48
|
-
// Collect the whole
|
|
48
|
+
// Collect the whole declaration tree, keyed as `packages/<dir>/types/<rel>`.
|
|
49
49
|
const treeAbs = [];
|
|
50
50
|
const walk = (dir) => {
|
|
51
51
|
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
52
52
|
const p = path.join(dir, entry.name);
|
|
53
53
|
if (entry.isDirectory())
|
|
54
54
|
walk(p);
|
|
55
|
-
else if (entry.name
|
|
55
|
+
else if (isDeclarationFileName(entry.name))
|
|
56
56
|
treeAbs.push(p);
|
|
57
57
|
}
|
|
58
58
|
};
|
|
@@ -63,17 +63,7 @@ function buildOne(ws, serviceName, packageDir) {
|
|
|
63
63
|
if (!isRelative(spec))
|
|
64
64
|
return undefined;
|
|
65
65
|
const base = path.resolve(path.dirname(fromAbs), spec);
|
|
66
|
-
|
|
67
|
-
`${base}.d.ts`,
|
|
68
|
-
path.join(base, 'index.d.ts'),
|
|
69
|
-
base.endsWith('.js') ? `${base.slice(0, -3)}.d.ts` : undefined,
|
|
70
|
-
base, // already `.d.ts`
|
|
71
|
-
].filter((c) => c !== undefined);
|
|
72
|
-
for (const c of candidates) {
|
|
73
|
-
if (treeAbsSet.has(path.resolve(c)))
|
|
74
|
-
return c;
|
|
75
|
-
}
|
|
76
|
-
return undefined;
|
|
66
|
+
return declarationCandidates(base).find((candidate) => treeAbsSet.has(candidate));
|
|
77
67
|
};
|
|
78
68
|
// Per-file relative-import adjacency, over the fileKey namespace.
|
|
79
69
|
const adjacency = new Map();
|
|
@@ -34,13 +34,13 @@ import { entryRelativeSpecifier, resolveAnchor } from './anchors.js';
|
|
|
34
34
|
import { findAugmentationFiles } from './augmentations.js';
|
|
35
35
|
import { installedVersions, lockfileVersions } from './lockfile.js';
|
|
36
36
|
import { rewriteEmittedSpecifiers } from './paths-rewrite.js';
|
|
37
|
-
import { typesPackageOf, withInstalledPackages } from './installed-package.js';
|
|
37
|
+
import { installedPackageSpecifier, typesPackageOf, withInstalledPackages } from './installed-package.js';
|
|
38
38
|
import { selfCheckStub } from './self-check.js';
|
|
39
39
|
import { collectSpecifiers, isRelative, packageNameOf } from './specifiers.js';
|
|
40
40
|
import { DenoProject, findDenoConfig } from './deno-project.js';
|
|
41
41
|
import { emitsAlike, ProjectGraph } from './project-references.js';
|
|
42
42
|
import { findServiceTsconfig } from './service-config.js';
|
|
43
|
-
import { placeEmittedTree } from './outside-root.js';
|
|
43
|
+
import { placeEmittedTree, surfaceModuleInTree } from './outside-root.js';
|
|
44
44
|
import { WriteGuard } from './guarded-fs.js';
|
|
45
45
|
export { DenoProject, findDenoConfig } from './deno-project.js';
|
|
46
46
|
export { serviceConfigPath } from './project-references.js';
|
|
@@ -351,7 +351,14 @@ export function captureStub(opts) {
|
|
|
351
351
|
if (emitPartial) {
|
|
352
352
|
errors.push(`declaration emit was partial: kept ${emitted.size} emitted file(s); ` +
|
|
353
353
|
'aliases referencing unemitted modules are demoted to structural_fallback');
|
|
354
|
-
resolved = demoteDanglingAliases({
|
|
354
|
+
resolved = demoteDanglingAliases({
|
|
355
|
+
resolved,
|
|
356
|
+
emitted,
|
|
357
|
+
declarationSources,
|
|
358
|
+
staging,
|
|
359
|
+
entryDir,
|
|
360
|
+
surfaceDeclaration,
|
|
361
|
+
});
|
|
355
362
|
}
|
|
356
363
|
// ---- Relocate the emitted tree into the stub package ----
|
|
357
364
|
const typesDir = path.join(stubDir, 'types');
|
|
@@ -520,43 +527,47 @@ export function captureStub(opts) {
|
|
|
520
527
|
};
|
|
521
528
|
}
|
|
522
529
|
/**
|
|
523
|
-
* Partial-emit demotion:
|
|
524
|
-
*
|
|
525
|
-
* whose alias text references a relative module absent from that set, and
|
|
530
|
+
* Partial-emit demotion: demote every anchor whose alias text names, by a
|
|
531
|
+
* relative or an absolute path, a module the stub will not resolve, and
|
|
526
532
|
* rewrite the demoted aliases' lines in the emitted surface to `unknown`.
|
|
533
|
+
*
|
|
534
|
+
* A path resolves when the tree holds its module (`surfaceModuleInTree`: an
|
|
535
|
+
* emitted declaration inside rootDir or outside it, or a verbatim declaration
|
|
536
|
+
* source), read from where the entry was written, not from where the surface
|
|
537
|
+
* sits in the tree. An absolute path into an installed package resolves too
|
|
538
|
+
* (carrick#1773): no emit writes that module, and the specifier rewrite turns
|
|
539
|
+
* the path into the package's bare specifier and a pin, as it does when the
|
|
540
|
+
* emit is whole. A relative path into a package is not rewritten, so it stays
|
|
541
|
+
* demoted (carrick#1857).
|
|
542
|
+
*
|
|
527
543
|
* Anchors already demoted stay as they are; anchors whose text is
|
|
528
544
|
* self-contained (node-builder structural prints, literal object text) are
|
|
529
545
|
* untouched even when their source file failed to emit — their surface line
|
|
530
546
|
* references nothing that can dangle.
|
|
531
547
|
*/
|
|
532
548
|
function demoteDanglingAliases(args) {
|
|
533
|
-
|
|
534
|
-
const
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
if (
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
const moduleInTree = (spec) => {
|
|
550
|
-
const id = path.posix.normalize(path.posix.join(surfaceDir, spec));
|
|
551
|
-
if (id.startsWith('..'))
|
|
552
|
-
return false;
|
|
553
|
-
return treeModules.has(id) || treeModules.has(`${id}/index`);
|
|
549
|
+
const surfaceKey = [...args.emitted.keys()].find((fileName) => path.basename(fileName) === args.surfaceDeclaration);
|
|
550
|
+
const inTree = surfaceModuleInTree({
|
|
551
|
+
emitted: args.emitted.keys(),
|
|
552
|
+
declarationSources: args.declarationSources.keys(),
|
|
553
|
+
staging: args.staging,
|
|
554
|
+
entryDir: args.entryDir,
|
|
555
|
+
surfaceDeclaration: args.surfaceDeclaration,
|
|
556
|
+
});
|
|
557
|
+
const resolves = new Map();
|
|
558
|
+
const moduleResolves = (spec) => {
|
|
559
|
+
let answer = resolves.get(spec);
|
|
560
|
+
if (answer === undefined) {
|
|
561
|
+
answer = inTree(spec) || (spec.startsWith('/') && installedPackageSpecifier(spec) !== undefined);
|
|
562
|
+
resolves.set(spec, answer);
|
|
563
|
+
}
|
|
564
|
+
return answer;
|
|
554
565
|
};
|
|
555
566
|
const demoted = new Set();
|
|
556
567
|
const next = args.resolved.map((anchor) => {
|
|
557
568
|
if (anchor.failureReason !== undefined)
|
|
558
569
|
return anchor;
|
|
559
|
-
const dangling = [...collectSpecifiers(anchor.aliasText)].find((spec) => isRelative(spec) && !
|
|
570
|
+
const dangling = [...collectSpecifiers(anchor.aliasText)].find((spec) => isRelative(spec) && !moduleResolves(spec));
|
|
560
571
|
if (dangling === undefined)
|
|
561
572
|
return anchor;
|
|
562
573
|
demoted.add(anchor.request.alias);
|
|
@@ -661,6 +672,20 @@ function resolveAnchors(opts, parsed, ctx, deno) {
|
|
|
661
672
|
placeholders.set(stmt.name.text, stmt);
|
|
662
673
|
}
|
|
663
674
|
}
|
|
675
|
+
// A module specifier as the entry resolves it, under the program's own
|
|
676
|
+
// resolution (the Deno graph's, for a Deno service). Asked once per
|
|
677
|
+
// specifier: every anchor of a module asks for the same one.
|
|
678
|
+
const entryMode = entrySource?.impliedNodeFormat;
|
|
679
|
+
const fromEntry = new Map();
|
|
680
|
+
const resolveFromEntry = (specifier) => {
|
|
681
|
+
if (!fromEntry.has(specifier)) {
|
|
682
|
+
fromEntry.set(specifier, (deno
|
|
683
|
+
? deno.resolve(specifier, ctx.entryPath, options)
|
|
684
|
+
: ts.resolveModuleName(specifier, ctx.entryPath, options, ts.sys, undefined, undefined, entryMode)
|
|
685
|
+
.resolvedModule)?.resolvedFileName);
|
|
686
|
+
}
|
|
687
|
+
return fromEntry.get(specifier);
|
|
688
|
+
};
|
|
664
689
|
// A literal anchor whose text is a bare identifier resolves through a
|
|
665
690
|
// sibling symbol anchor's module when one names the same symbol.
|
|
666
691
|
const siblingSymbolSpecs = new Map();
|
|
@@ -668,16 +693,9 @@ function resolveAnchors(opts, parsed, ctx, deno) {
|
|
|
668
693
|
if (anchor.kind !== 'symbol')
|
|
669
694
|
continue;
|
|
670
695
|
if (!siblingSymbolSpecs.has(anchor.symbol_name)) {
|
|
671
|
-
siblingSymbolSpecs.set(anchor.symbol_name, entryRelativeSpecifier(ctx.entryDir, ctx.repoRoot, anchor.source_file));
|
|
696
|
+
siblingSymbolSpecs.set(anchor.symbol_name, entryRelativeSpecifier(ctx.entryDir, ctx.repoRoot, anchor.source_file, resolveFromEntry));
|
|
672
697
|
}
|
|
673
698
|
}
|
|
674
|
-
// A module specifier as the entry resolves it, under the program's own
|
|
675
|
-
// resolution (the Deno graph's, for a Deno service).
|
|
676
|
-
const entryMode = entrySource?.impliedNodeFormat;
|
|
677
|
-
const resolveFromEntry = (specifier) => (deno
|
|
678
|
-
? deno.resolve(specifier, ctx.entryPath, options)
|
|
679
|
-
: ts.resolveModuleName(specifier, ctx.entryPath, options, ts.sys, undefined, undefined, entryMode)
|
|
680
|
-
.resolvedModule)?.resolvedFileName;
|
|
681
699
|
return opts.anchors.map((request) => resolveAnchor(program, request, {
|
|
682
700
|
repoRoot: ctx.repoRoot,
|
|
683
701
|
entryDir: ctx.entryDir,
|
|
@@ -41,6 +41,8 @@ export interface InstalledPackageSpecifier {
|
|
|
41
41
|
* deciding whether a runtime name is covered by a pinned types package.
|
|
42
42
|
*/
|
|
43
43
|
export declare function typesPackageOf(name: string): string;
|
|
44
|
+
/** A path or specifier without its script, source or declaration extension. */
|
|
45
|
+
export declare function withoutExtension(subpath: string): string;
|
|
44
46
|
/**
|
|
45
47
|
* A compiler host that also resolves the packages an absolute specifier was
|
|
46
48
|
* rewritten into, each from its own install directory. The capture's
|
|
@@ -101,7 +101,8 @@ function existingFile(spec) {
|
|
|
101
101
|
}
|
|
102
102
|
return undefined;
|
|
103
103
|
}
|
|
104
|
-
|
|
104
|
+
/** A path or specifier without its script, source or declaration extension. */
|
|
105
|
+
export function withoutExtension(subpath) {
|
|
105
106
|
return subpath.replace(/(?:\.d)?\.(?:ts|mts|cts|js|mjs|cjs|tsx|jsx)$/, '');
|
|
106
107
|
}
|
|
107
108
|
/** Every string target an exports value names, whatever its conditions. */
|
|
@@ -39,3 +39,22 @@ export declare function placeEmittedTree(args: {
|
|
|
39
39
|
entryDir: string;
|
|
40
40
|
surfaceDeclaration: string;
|
|
41
41
|
}): PlacedTree;
|
|
42
|
+
/**
|
|
43
|
+
* A test for whether the tree holds the module a specifier in the surface
|
|
44
|
+
* entry names (carrick#1773).
|
|
45
|
+
*
|
|
46
|
+
* The specifier is read the way the placement above reads one: resolved from
|
|
47
|
+
* the surface's SOURCE-side directory, so an absolute path stays what it is
|
|
48
|
+
* and `../` leaves rootDir, then looked up among the source-side paths of the
|
|
49
|
+
* declarations the tree holds. Those are every emitted declaration, inside
|
|
50
|
+
* rootDir or placed under `OUTSIDE_DIR`, and the declaration sources shipped
|
|
51
|
+
* verbatim (`declarationSources`, relative to rootDir).
|
|
52
|
+
*/
|
|
53
|
+
export declare function surfaceModuleInTree(args: {
|
|
54
|
+
/** tsc's file name for each emitted declaration. */
|
|
55
|
+
emitted: Iterable<string>;
|
|
56
|
+
declarationSources: Iterable<string>;
|
|
57
|
+
staging: string;
|
|
58
|
+
entryDir: string;
|
|
59
|
+
surfaceDeclaration: string;
|
|
60
|
+
}): (spec: string) => boolean;
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
* A capture whose program stays inside rootDir is placed exactly as before.
|
|
16
16
|
*/
|
|
17
17
|
import * as path from 'node:path';
|
|
18
|
+
import { withoutExtension } from './installed-package.js';
|
|
18
19
|
import { rewriteSpecifiers } from './specifiers.js';
|
|
19
20
|
/** Tree directory holding declarations of sources outside rootDir. */
|
|
20
21
|
export const OUTSIDE_DIR = '__outside__';
|
|
@@ -31,13 +32,12 @@ export function placeEmittedTree(args) {
|
|
|
31
32
|
const sourceSideOf = new Map();
|
|
32
33
|
const outsideFiles = [];
|
|
33
34
|
for (const fileName of args.emitted.keys()) {
|
|
35
|
+
sourceSideOf.set(fileName, sourceSidePath(fileName, args.staging, args.entryDir));
|
|
34
36
|
const rel = posix(path.relative(args.staging, fileName));
|
|
35
37
|
if (escapes(rel)) {
|
|
36
38
|
outsideFiles.push(fileName);
|
|
37
|
-
sourceSideOf.set(fileName, path.resolve(fileName));
|
|
38
39
|
continue;
|
|
39
40
|
}
|
|
40
|
-
sourceSideOf.set(fileName, path.join(args.entryDir, rel));
|
|
41
41
|
relOf.set(fileName, path.basename(rel) === args.surfaceDeclaration ? 'surface.d.ts' : rel);
|
|
42
42
|
}
|
|
43
43
|
const outside = new Map();
|
|
@@ -82,6 +82,43 @@ export function placeEmittedTree(args) {
|
|
|
82
82
|
}
|
|
83
83
|
return { relOf, textOf, outside, rewrites };
|
|
84
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* Where tsc would have written an emitted declaration in the source tree. A
|
|
87
|
+
* file under the staging dir mirrors rootDir; one outside it arrived at its
|
|
88
|
+
* source's own path.
|
|
89
|
+
*/
|
|
90
|
+
function sourceSidePath(fileName, staging, entryDir) {
|
|
91
|
+
const rel = posix(path.relative(staging, fileName));
|
|
92
|
+
return escapes(rel) ? path.resolve(fileName) : path.join(entryDir, rel);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* A test for whether the tree holds the module a specifier in the surface
|
|
96
|
+
* entry names (carrick#1773).
|
|
97
|
+
*
|
|
98
|
+
* The specifier is read the way the placement above reads one: resolved from
|
|
99
|
+
* the surface's SOURCE-side directory, so an absolute path stays what it is
|
|
100
|
+
* and `../` leaves rootDir, then looked up among the source-side paths of the
|
|
101
|
+
* declarations the tree holds. Those are every emitted declaration, inside
|
|
102
|
+
* rootDir or placed under `OUTSIDE_DIR`, and the declaration sources shipped
|
|
103
|
+
* verbatim (`declarationSources`, relative to rootDir).
|
|
104
|
+
*/
|
|
105
|
+
export function surfaceModuleInTree(args) {
|
|
106
|
+
const held = new Set();
|
|
107
|
+
let surfaceDir = args.entryDir;
|
|
108
|
+
for (const fileName of args.emitted) {
|
|
109
|
+
const sourceSide = sourceSidePath(fileName, args.staging, args.entryDir);
|
|
110
|
+
if (path.basename(sourceSide) === args.surfaceDeclaration)
|
|
111
|
+
surfaceDir = path.dirname(sourceSide);
|
|
112
|
+
held.add(sourceSide.replace(DECLARATION_EXT, ''));
|
|
113
|
+
}
|
|
114
|
+
for (const rel of args.declarationSources) {
|
|
115
|
+
held.add(path.join(args.entryDir, rel).replace(DECLARATION_EXT, ''));
|
|
116
|
+
}
|
|
117
|
+
return (spec) => {
|
|
118
|
+
const target = path.resolve(surfaceDir, withoutExtension(spec));
|
|
119
|
+
return held.has(target) || held.has(path.join(target, 'index'));
|
|
120
|
+
};
|
|
121
|
+
}
|
|
85
122
|
function posix(p) {
|
|
86
123
|
return p.split(path.sep).join('/');
|
|
87
124
|
}
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
import ts from 'typescript';
|
|
33
33
|
import * as fs from 'node:fs';
|
|
34
34
|
import * as path from 'node:path';
|
|
35
|
-
import { collectSpecifiers, isRelative, packageNameOf } from './specifiers.js';
|
|
35
|
+
import { collectSpecifiers, declarationCandidates, isDeclarationFileName, isRelative, packageNameOf, } from './specifiers.js';
|
|
36
36
|
import { repairDanglingImports } from './repair-dangling.js';
|
|
37
37
|
import { findDisqualifyingTopTypes, findUnresolvedPlaceholders, isErrorPlaceholder, provenanceOf, unemittedModuleProvenance, unresolvedInTreeProvenance, } from './deep-walk.js';
|
|
38
38
|
export function selfCheckStub(args) {
|
|
@@ -43,7 +43,7 @@ export function selfCheckStub(args) {
|
|
|
43
43
|
const p = path.join(dir, entry.name);
|
|
44
44
|
if (entry.isDirectory())
|
|
45
45
|
walk(p);
|
|
46
|
-
else if (entry.name
|
|
46
|
+
else if (isDeclarationFileName(entry.name))
|
|
47
47
|
treeFiles.push(p);
|
|
48
48
|
}
|
|
49
49
|
};
|
|
@@ -464,15 +464,5 @@ function resolveTreeSpecifier(fromAbs, spec, tree) {
|
|
|
464
464
|
if (!isRelative(spec))
|
|
465
465
|
return undefined;
|
|
466
466
|
const base = path.resolve(path.dirname(fromAbs), spec);
|
|
467
|
-
|
|
468
|
-
`${base}.d.ts`,
|
|
469
|
-
path.join(base, 'index.d.ts'),
|
|
470
|
-
base.endsWith('.js') ? `${base.slice(0, -3)}.d.ts` : undefined,
|
|
471
|
-
base, // already .d.ts
|
|
472
|
-
].filter((c) => c !== undefined);
|
|
473
|
-
for (const candidate of candidates) {
|
|
474
|
-
if (tree.has(candidate))
|
|
475
|
-
return candidate;
|
|
476
|
-
}
|
|
477
|
-
return undefined;
|
|
467
|
+
return declarationCandidates(base).find((candidate) => tree.has(candidate));
|
|
478
468
|
}
|
|
@@ -4,6 +4,20 @@
|
|
|
4
4
|
* pattern matching for the post-emit rewrite pass.
|
|
5
5
|
*/
|
|
6
6
|
export declare function isRelative(spec: string): boolean;
|
|
7
|
+
/** A declaration file of any module format: `.d.ts`, `.d.mts`, `.d.cts`. */
|
|
8
|
+
export declare function isDeclarationFileName(name: string): boolean;
|
|
9
|
+
/**
|
|
10
|
+
* The declaration files a relative specifier can name in a stub's tree, in
|
|
11
|
+
* the order tried, given the path it resolves to from the file that holds it.
|
|
12
|
+
*
|
|
13
|
+
* A specifier names its module with no extension (`./a`: `a.d.ts`, or the
|
|
14
|
+
* directory's `index.d.ts`), by the file the module compiles to (`./a.js`:
|
|
15
|
+
* `a.d.ts`, `./a.mjs`: `a.d.mts`, `./a.cjs`: `a.d.cts`), or by the
|
|
16
|
+
* declaration file itself. The surface names an anchor's module the second
|
|
17
|
+
* way where the first does not resolve (carrick#1911), and so does any source
|
|
18
|
+
* written for `node16`..`nodenext`.
|
|
19
|
+
*/
|
|
20
|
+
export declare function declarationCandidates(resolved: string): string[];
|
|
7
21
|
/** zod -> zod, @scope/pkg/sub -> @scope/pkg, pkg/sub -> pkg */
|
|
8
22
|
export declare function packageNameOf(spec: string): string;
|
|
9
23
|
/** Extract every module specifier mentioned in a .d.ts text: `from "x"`,
|
|
@@ -3,9 +3,34 @@
|
|
|
3
3
|
* declaration text, external/internal classification, and tsconfig-`paths`
|
|
4
4
|
* pattern matching for the post-emit rewrite pass.
|
|
5
5
|
*/
|
|
6
|
+
import * as path from 'node:path';
|
|
6
7
|
export function isRelative(spec) {
|
|
7
8
|
return spec.startsWith('./') || spec.startsWith('../') || spec.startsWith('/');
|
|
8
9
|
}
|
|
10
|
+
/** A declaration file of any module format: `.d.ts`, `.d.mts`, `.d.cts`. */
|
|
11
|
+
export function isDeclarationFileName(name) {
|
|
12
|
+
return /\.d\.[cm]?ts$/.test(name);
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* The declaration files a relative specifier can name in a stub's tree, in
|
|
16
|
+
* the order tried, given the path it resolves to from the file that holds it.
|
|
17
|
+
*
|
|
18
|
+
* A specifier names its module with no extension (`./a`: `a.d.ts`, or the
|
|
19
|
+
* directory's `index.d.ts`), by the file the module compiles to (`./a.js`:
|
|
20
|
+
* `a.d.ts`, `./a.mjs`: `a.d.mts`, `./a.cjs`: `a.d.cts`), or by the
|
|
21
|
+
* declaration file itself. The surface names an anchor's module the second
|
|
22
|
+
* way where the first does not resolve (carrick#1911), and so does any source
|
|
23
|
+
* written for `node16`..`nodenext`.
|
|
24
|
+
*/
|
|
25
|
+
export function declarationCandidates(resolved) {
|
|
26
|
+
const output = /\.([cm]?)jsx?$/.exec(resolved);
|
|
27
|
+
return [
|
|
28
|
+
`${resolved}.d.ts`,
|
|
29
|
+
path.join(resolved, 'index.d.ts'),
|
|
30
|
+
...(output ? [`${resolved.slice(0, output.index)}.d.${output[1]}ts`] : []),
|
|
31
|
+
resolved,
|
|
32
|
+
];
|
|
33
|
+
}
|
|
9
34
|
/** zod -> zod, @scope/pkg/sub -> @scope/pkg, pkg/sub -> pkg */
|
|
10
35
|
export function packageNameOf(spec) {
|
|
11
36
|
const parts = spec.split('/');
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The function a line names, from an index built once per source file
|
|
3
|
+
* (carrick#1915).
|
|
4
|
+
*
|
|
5
|
+
* A signature request carries only the line its function starts on, and a
|
|
6
|
+
* signature pass sends one request per unannotated slot: thousands of
|
|
7
|
+
* lookups, several per function and many per file. Answering each by walking
|
|
8
|
+
* the file's every node cost the file's size per slot, and was 81% of the
|
|
9
|
+
* pass on a 2,345-file program. Here the file is walked once, over the
|
|
10
|
+
* compiler's own nodes, and each lookup reads the few entries near its line.
|
|
11
|
+
*
|
|
12
|
+
* The index belongs to the compiler's source file node, not to the file's
|
|
13
|
+
* name: replacing a file's text gives it a new node, so a file rewritten for
|
|
14
|
+
* one reading (the unwidened reading, the retype check) and then restored is
|
|
15
|
+
* indexed again each time, and never answered from positions it no longer has.
|
|
16
|
+
*/
|
|
17
|
+
import { type ArrowFunction, type FunctionDeclaration, type FunctionExpression, type MethodDeclaration, type SourceFile } from 'ts-morph';
|
|
18
|
+
/** The declarations a line can name. */
|
|
19
|
+
export type LineFunction = FunctionDeclaration | ArrowFunction | FunctionExpression | MethodDeclaration;
|
|
20
|
+
/**
|
|
21
|
+
* The function whose declaration starts at, or within `LINE_TOLERANCE` lines
|
|
22
|
+
* of, the given line: the closest, then the smallest, then the first in the
|
|
23
|
+
* file. A function starting after the line is passed over when a statement
|
|
24
|
+
* that opens on the line or after it, on a line before the function's, does
|
|
25
|
+
* not contain the function. Undefined when no function is left.
|
|
26
|
+
*
|
|
27
|
+
* These are `TypeInferrer.findFunctionByLine`'s rules, which says why each is
|
|
28
|
+
* there; this is where they are computed.
|
|
29
|
+
*/
|
|
30
|
+
export declare function functionAtLine(sourceFile: SourceFile, line: number): LineFunction | undefined;
|