carrick 0.3.108 → 0.3.109
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/package.json +9 -10
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/sidecar/dist/src/capture/check-deep.js +2 -1
- package/sidecar/dist/src/capture/check-workspace.d.ts +1 -0
- package/sidecar/dist/src/capture/check-workspace.js +13 -2
- package/sidecar/dist/src/capture/compiler-options.d.ts +39 -0
- package/sidecar/dist/src/capture/compiler-options.js +100 -0
- package/sidecar/dist/src/capture/deno-project.js +3 -2
- package/sidecar/dist/src/capture/index.d.ts +1 -0
- package/sidecar/dist/src/capture/index.js +7 -5
- package/sidecar/dist/src/capture/installed-package.js +3 -2
- package/sidecar/dist/src/capture/self-check.js +3 -2
- package/sidecar/dist/src/definition-resolver.js +3 -2
- package/sidecar/dist/src/index.js +91 -7
- package/sidecar/dist/src/print-type.d.ts +48 -0
- package/sidecar/dist/src/print-type.js +71 -0
- package/sidecar/dist/src/printed-names.js +2 -1
- package/sidecar/dist/src/program-files.d.ts +44 -0
- package/sidecar/dist/src/program-files.js +64 -0
- package/sidecar/dist/src/project-loader.d.ts +5 -0
- package/sidecar/dist/src/project-loader.js +14 -5
- package/sidecar/dist/src/retype.js +7 -1
- package/sidecar/dist/src/type-inferrer.d.ts +11 -0
- package/sidecar/dist/src/type-inferrer.js +30 -3
- package/sidecar/dist/src/types.d.ts +34 -2
- package/sidecar/dist/src/validators.d.ts +120 -72
- package/sidecar/dist/src/validators.js +9 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The compiler's own print of a type, with a module the print names written
|
|
3
|
+
* as the file that declares it (carrick#2019).
|
|
4
|
+
*
|
|
5
|
+
* When a type comes from a module the enclosing file does not import, the
|
|
6
|
+
* compiler writes it as `import("<module>").Name`. TypeScript 5 wrote the
|
|
7
|
+
* declaring file's path there: the node builder had no module-specifier host
|
|
8
|
+
* unless a declaration emit gave it one. TypeScript 6 gives every print a
|
|
9
|
+
* host, so the same type printed at an enclosing node reads
|
|
10
|
+
* `import("../model").Name` or `import("<package>").Name`: a specifier that
|
|
11
|
+
* depends on which file it was printed from, so one type printed from two
|
|
12
|
+
* files gives two texts. Everything downstream reads the declaring file's
|
|
13
|
+
* path: the scanner's path scrub writes it repo-relative or as
|
|
14
|
+
* `<package>@<version>`, and a capture pastes an inferred text into its
|
|
15
|
+
* surface entry, where a specifier relative to another file names nothing.
|
|
16
|
+
*
|
|
17
|
+
* These functions run the compiler's own code with no host: a tracker whose
|
|
18
|
+
* `moduleResolverHost` is `false` (falsy, so the builder writes the declaring
|
|
19
|
+
* file; not nullish, so the builder does not supply its own). Nothing in the
|
|
20
|
+
* text is rewritten afterwards. `typeToStringAsDeclared` is the checker's
|
|
21
|
+
* `typeToString`, step for step, with that one tracker.
|
|
22
|
+
*
|
|
23
|
+
* Only prints with an enclosing node differ: with none, the compiler has no
|
|
24
|
+
* file to write a specifier relative to and writes the declaring file
|
|
25
|
+
* anyway. A print that must name modules the way a declaration file would
|
|
26
|
+
* (the capture's surface emit) passes a host of its own and does not use
|
|
27
|
+
* this.
|
|
28
|
+
*/
|
|
29
|
+
import { ts } from 'ts-morph';
|
|
30
|
+
/** A symbol tracker that leaves the node builder without a module-specifier host. */
|
|
31
|
+
const NO_SPECIFIER_HOST = { moduleResolverHost: false };
|
|
32
|
+
/** The checker's own default for `typeToString`. */
|
|
33
|
+
const DEFAULT_TYPE_FORMAT = ts.TypeFormatFlags.AllowUniqueESSymbolType | ts.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope;
|
|
34
|
+
/** `typeToString`'s caps: a print this long is cut, `...` included. */
|
|
35
|
+
const DEFAULT_MAXIMUM_LENGTH = 160;
|
|
36
|
+
const NO_TRUNCATION_MAXIMUM_LENGTH = 1_000_000;
|
|
37
|
+
/** `typeToString`'s printers: comments removed, except for the unresolved type. */
|
|
38
|
+
const PRINTER = ts.createPrinter({ removeComments: true });
|
|
39
|
+
const PRINTER_WITH_COMMENTS = ts.createPrinter({});
|
|
40
|
+
/**
|
|
41
|
+
* The checker's `typeToTypeNode`, writing each module a node names as the
|
|
42
|
+
* file that declares it. A caller's own tracker keeps its callbacks.
|
|
43
|
+
*/
|
|
44
|
+
export function typeToTypeNodeAsDeclared(checker, type, enclosing, flags, tracker) {
|
|
45
|
+
const withoutHost = tracker
|
|
46
|
+
? Object.assign(Object.create(tracker), { moduleResolverHost: false })
|
|
47
|
+
: NO_SPECIFIER_HOST;
|
|
48
|
+
return checker.typeToTypeNode(type, enclosing, flags, undefined, withoutHost);
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* The checker's `typeToString(type, enclosing, flags)`, writing each module
|
|
52
|
+
* the print names as the file that declares it. `noErrorTruncation` is the
|
|
53
|
+
* program's option of that name, which `typeToString` reads when `flags`
|
|
54
|
+
* leave truncation on.
|
|
55
|
+
*/
|
|
56
|
+
export function typeToStringAsDeclared(checker, type, enclosing, flags = DEFAULT_TYPE_FORMAT, noErrorTruncation = false) {
|
|
57
|
+
const noTruncation = noErrorTruncation || (flags & ts.TypeFormatFlags.NoTruncation) !== 0;
|
|
58
|
+
const node = typeToTypeNodeAsDeclared(checker, type, enclosing, (flags & ts.TypeFormatFlags.NodeBuilderFlagsMask) |
|
|
59
|
+
ts.NodeBuilderFlags.IgnoreErrors |
|
|
60
|
+
(noTruncation ? ts.NodeBuilderFlags.NoTruncation : 0));
|
|
61
|
+
// `typeToString` asserts a node here too (`Debug.fail`). Falling back to it
|
|
62
|
+
// would print the other specifier form, so fail the same way it does.
|
|
63
|
+
if (node === undefined)
|
|
64
|
+
throw new Error('the node builder gave no type node to print');
|
|
65
|
+
const unresolved = type.intrinsicName === 'unresolved';
|
|
66
|
+
const writer = ts.createTextWriter('');
|
|
67
|
+
(unresolved ? PRINTER_WITH_COMMENTS : PRINTER).writeNode(ts.EmitHint.Unspecified, node, enclosing?.getSourceFile(), writer);
|
|
68
|
+
const result = writer.getText();
|
|
69
|
+
const maximum = (noTruncation ? NO_TRUNCATION_MAXIMUM_LENGTH : DEFAULT_MAXIMUM_LENGTH) * 2;
|
|
70
|
+
return result.length >= maximum ? result.substring(0, maximum - 3) + '...' : result;
|
|
71
|
+
}
|
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
* no more than keeping the list.
|
|
24
24
|
*/
|
|
25
25
|
import { ts } from 'ts-morph';
|
|
26
|
+
import { typeToTypeNodeAsDeclared } from './print-type.js';
|
|
26
27
|
/** The prints of the inference running now, when one is recording. */
|
|
27
28
|
let recording;
|
|
28
29
|
/**
|
|
@@ -82,7 +83,7 @@ export class PrintedTypes {
|
|
|
82
83
|
visited.set(type, at.add(enclosing));
|
|
83
84
|
let node;
|
|
84
85
|
try {
|
|
85
|
-
node = checker
|
|
86
|
+
node = typeToTypeNodeAsDeclared(checker, type, enclosing, NODE_FLAGS);
|
|
86
87
|
}
|
|
87
88
|
catch {
|
|
88
89
|
continue;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The files a program was built from, and files added to a program in an
|
|
3
|
+
* order the caller gives (carrick#2027).
|
|
4
|
+
*
|
|
5
|
+
* With `stableTypeOrdering` the compiler orders two types of the same name by
|
|
6
|
+
* where their declarations sit in the program's file list. That list follows
|
|
7
|
+
* the program's root files: the compiler lists each root after the files it
|
|
8
|
+
* imports. ts-morph hands the compiler every file it has loaded as a root, in
|
|
9
|
+
* the order it loaded them, and a process asked about a file outside its
|
|
10
|
+
* tsconfig loads it when it is asked. Two processes asked the same questions
|
|
11
|
+
* in different orders therefore build from roots in different orders, and
|
|
12
|
+
* print a union of two same-named types in different orders.
|
|
13
|
+
*
|
|
14
|
+
* The roots decide the whole program, not only its order. A dependency file
|
|
15
|
+
* the compiler reached by resolving an import is not the same to it as the
|
|
16
|
+
* same file named as a root: a second copy of a package reached by resolution
|
|
17
|
+
* is folded into the first, and named as a root it is read as a file of its
|
|
18
|
+
* own and its imports are followed. So the list here is the roots themselves.
|
|
19
|
+
* A process that has built only what its tsconfig names, given another
|
|
20
|
+
* process's roots in order, ends with the same roots and builds the same
|
|
21
|
+
* program.
|
|
22
|
+
*/
|
|
23
|
+
import type { Project } from 'ts-morph';
|
|
24
|
+
/**
|
|
25
|
+
* The root files `project`'s program was built from, in order, as absolute
|
|
26
|
+
* paths: every file the project had loaded when the program was last built,
|
|
27
|
+
* the compiler's library files and the dependencies earlier builds reached
|
|
28
|
+
* among them.
|
|
29
|
+
*/
|
|
30
|
+
export declare function listProgramFiles(project: Project): string[];
|
|
31
|
+
/**
|
|
32
|
+
* Add to `project` each of `files` it has not loaded, in the given order, and
|
|
33
|
+
* build the program once if any was added. A file it has loaded keeps its
|
|
34
|
+
* place. A file that cannot be read is skipped and reported to `onSkipped`.
|
|
35
|
+
*
|
|
36
|
+
* Nothing is built before the files join. A project built from a tsconfig has
|
|
37
|
+
* built once already, from the files the tsconfig names, as every process's
|
|
38
|
+
* does; one built from source patterns or a Deno graph has loaded only its
|
|
39
|
+
* own files, and the given list names whatever the other process's first
|
|
40
|
+
* build loaded, in the place that build put it.
|
|
41
|
+
*
|
|
42
|
+
* @returns how many files were added
|
|
43
|
+
*/
|
|
44
|
+
export declare function addProgramFiles(project: Project, files: readonly string[], onSkipped: (file: string, reason: string) => void): number;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The files a program was built from, and files added to a program in an
|
|
3
|
+
* order the caller gives (carrick#2027).
|
|
4
|
+
*
|
|
5
|
+
* With `stableTypeOrdering` the compiler orders two types of the same name by
|
|
6
|
+
* where their declarations sit in the program's file list. That list follows
|
|
7
|
+
* the program's root files: the compiler lists each root after the files it
|
|
8
|
+
* imports. ts-morph hands the compiler every file it has loaded as a root, in
|
|
9
|
+
* the order it loaded them, and a process asked about a file outside its
|
|
10
|
+
* tsconfig loads it when it is asked. Two processes asked the same questions
|
|
11
|
+
* in different orders therefore build from roots in different orders, and
|
|
12
|
+
* print a union of two same-named types in different orders.
|
|
13
|
+
*
|
|
14
|
+
* The roots decide the whole program, not only its order. A dependency file
|
|
15
|
+
* the compiler reached by resolving an import is not the same to it as the
|
|
16
|
+
* same file named as a root: a second copy of a package reached by resolution
|
|
17
|
+
* is folded into the first, and named as a root it is read as a file of its
|
|
18
|
+
* own and its imports are followed. So the list here is the roots themselves.
|
|
19
|
+
* A process that has built only what its tsconfig names, given another
|
|
20
|
+
* process's roots in order, ends with the same roots and builds the same
|
|
21
|
+
* program.
|
|
22
|
+
*/
|
|
23
|
+
/**
|
|
24
|
+
* The root files `project`'s program was built from, in order, as absolute
|
|
25
|
+
* paths: every file the project had loaded when the program was last built,
|
|
26
|
+
* the compiler's library files and the dependencies earlier builds reached
|
|
27
|
+
* among them.
|
|
28
|
+
*/
|
|
29
|
+
export function listProgramFiles(project) {
|
|
30
|
+
return [...project.getProgram().compilerObject.getRootFileNames()];
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Add to `project` each of `files` it has not loaded, in the given order, and
|
|
34
|
+
* build the program once if any was added. A file it has loaded keeps its
|
|
35
|
+
* place. A file that cannot be read is skipped and reported to `onSkipped`.
|
|
36
|
+
*
|
|
37
|
+
* Nothing is built before the files join. A project built from a tsconfig has
|
|
38
|
+
* built once already, from the files the tsconfig names, as every process's
|
|
39
|
+
* does; one built from source patterns or a Deno graph has loaded only its
|
|
40
|
+
* own files, and the given list names whatever the other process's first
|
|
41
|
+
* build loaded, in the place that build put it.
|
|
42
|
+
*
|
|
43
|
+
* @returns how many files were added
|
|
44
|
+
*/
|
|
45
|
+
export function addProgramFiles(project, files, onSkipped) {
|
|
46
|
+
let added = 0;
|
|
47
|
+
for (const file of new Set(files)) {
|
|
48
|
+
if (project.getSourceFile(file) !== undefined)
|
|
49
|
+
continue;
|
|
50
|
+
try {
|
|
51
|
+
project.addSourceFileAtPath(file);
|
|
52
|
+
added += 1;
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
onSkipped(file, err instanceof Error ? err.message : String(err));
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
// ts-morph drops its program on each add and builds the next one when it is
|
|
59
|
+
// read, so reading it once here is the one rebuild the adds need, done in
|
|
60
|
+
// this request rather than in the next one.
|
|
61
|
+
if (added > 0)
|
|
62
|
+
project.getProgram().compilerObject;
|
|
63
|
+
return added;
|
|
64
|
+
}
|
|
@@ -120,6 +120,11 @@ export declare class ProjectLoader {
|
|
|
120
120
|
* @throws Error if load() has not succeeded, or if the build fails
|
|
121
121
|
*/
|
|
122
122
|
getProject(): Project;
|
|
123
|
+
/**
|
|
124
|
+
* The default project when a request has built it, and `undefined` before
|
|
125
|
+
* that, without building it (carrick#2027).
|
|
126
|
+
*/
|
|
127
|
+
builtProject(): Project | undefined;
|
|
123
128
|
/**
|
|
124
129
|
* The registry package a resolved file belongs to, when the module graph
|
|
125
130
|
* names one (carrick#1260). `undefined` for a project that did not resolve
|
|
@@ -9,10 +9,10 @@
|
|
|
9
9
|
* - Tsconfig snapshot (closed/merged extends chains) for synthetic monorepo
|
|
10
10
|
* - Pinned dependency snapshots for deterministic builds
|
|
11
11
|
*/
|
|
12
|
-
import { Project } from 'ts-morph';
|
|
12
|
+
import { Project, getCompilerOptionsFromTsConfig } from 'ts-morph';
|
|
13
13
|
import * as path from 'node:path';
|
|
14
14
|
import * as fs from 'node:fs';
|
|
15
|
-
import { DenoProject, findDenoConfig, findServiceTsconfig, serviceConfigPath } from './capture/index.js';
|
|
15
|
+
import { DenoProject, findDenoConfig, findServiceTsconfig, serviceConfigPath, sidecarCompilerOptions, } from './capture/index.js';
|
|
16
16
|
import { moduleFormatResolutionHost } from './module-format.js';
|
|
17
17
|
import { ExternalImports, registerExternalImports } from './origin.js';
|
|
18
18
|
/**
|
|
@@ -177,7 +177,7 @@ export class ProjectLoader {
|
|
|
177
177
|
this.log('Project will load with tsconfig snapshot');
|
|
178
178
|
this.buildProject = () => {
|
|
179
179
|
const project = new Project({
|
|
180
|
-
compilerOptions: this.snapshotToCompilerOptions(snapshot),
|
|
180
|
+
compilerOptions: sidecarCompilerOptions(this.snapshotToCompilerOptions(snapshot)),
|
|
181
181
|
skipAddingFilesFromTsConfig: true,
|
|
182
182
|
});
|
|
183
183
|
this.addDefaultSourceFiles(project);
|
|
@@ -197,7 +197,7 @@ export class ProjectLoader {
|
|
|
197
197
|
// rebuilds that drop them (carrick#1731).
|
|
198
198
|
const imports = new ExternalImports();
|
|
199
199
|
const project = new Project({
|
|
200
|
-
compilerOptions: deno.parsed.options,
|
|
200
|
+
compilerOptions: sidecarCompilerOptions(deno.parsed.options),
|
|
201
201
|
skipAddingFilesFromTsConfig: true,
|
|
202
202
|
resolutionHost: imports.recording((host, getOptions) => ({
|
|
203
203
|
resolveModuleNames: (names, from) => names.map(name => deno.resolve(name, from, getOptions(), host)),
|
|
@@ -221,7 +221,7 @@ export class ProjectLoader {
|
|
|
221
221
|
this.log('No tsconfig.json found, using default compiler options');
|
|
222
222
|
this.buildProject = () => {
|
|
223
223
|
const project = new Project({
|
|
224
|
-
compilerOptions: DEFAULT_COMPILER_OPTIONS,
|
|
224
|
+
compilerOptions: sidecarCompilerOptions(DEFAULT_COMPILER_OPTIONS),
|
|
225
225
|
skipAddingFilesFromTsConfig: true,
|
|
226
226
|
});
|
|
227
227
|
// Add source files from common locations
|
|
@@ -323,6 +323,8 @@ export class ProjectLoader {
|
|
|
323
323
|
const imports = new ExternalImports();
|
|
324
324
|
const project = new Project({
|
|
325
325
|
tsConfigFilePath: configPath,
|
|
326
|
+
// Over the tsconfig's own options: ts-morph lays these on top.
|
|
327
|
+
compilerOptions: sidecarCompilerOptions(getCompilerOptionsFromTsConfig(configPath).options),
|
|
326
328
|
skipAddingFilesFromTsConfig: false,
|
|
327
329
|
// Each import resolves in its file's own module format (carrick#1619),
|
|
328
330
|
// and every external-library answer is kept past the program rebuilds
|
|
@@ -385,6 +387,13 @@ export class ProjectLoader {
|
|
|
385
387
|
}
|
|
386
388
|
return this.project;
|
|
387
389
|
}
|
|
390
|
+
/**
|
|
391
|
+
* The default project when a request has built it, and `undefined` before
|
|
392
|
+
* that, without building it (carrick#2027).
|
|
393
|
+
*/
|
|
394
|
+
builtProject() {
|
|
395
|
+
return this.project ?? undefined;
|
|
396
|
+
}
|
|
388
397
|
/**
|
|
389
398
|
* The registry package a resolved file belongs to, when the module graph
|
|
390
399
|
* names one (carrick#1260). `undefined` for a project that did not resolve
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
import { Node, SyntaxKind, ts } from 'ts-morph';
|
|
28
28
|
import { readsResponseStatus, statusesIn, SUCCEEDED, testsOnPath, } from './failure-path.js';
|
|
29
29
|
import { lineIndex } from './line-index.js';
|
|
30
|
+
import { typeToStringAsDeclared } from './print-type.js';
|
|
30
31
|
import { fileDiagnostics } from './unwidened.js';
|
|
31
32
|
/** Names appended to a file that is not ours carry this prefix. */
|
|
32
33
|
const PREFIX = '__carrick_';
|
|
@@ -233,7 +234,12 @@ export class Retyper {
|
|
|
233
234
|
};
|
|
234
235
|
}
|
|
235
236
|
return (`the consumer call takes no type argument and returns ` +
|
|
236
|
-
`'${call.
|
|
237
|
+
`'${typeToStringAsDeclared(call.getProject().getTypeChecker().compilerObject, call.getType().compilerType, call.compilerNode,
|
|
238
|
+
// ts-morph's own default for Type.getText, which this print used.
|
|
239
|
+
ts.TypeFormatFlags.UseTypeOfFunction |
|
|
240
|
+
ts.TypeFormatFlags.NoTruncation |
|
|
241
|
+
ts.TypeFormatFlags.UseFullyQualifiedType |
|
|
242
|
+
ts.TypeFormatFlags.WriteTypeArgumentsOfSignature)}', so it cannot be retyped`);
|
|
237
243
|
}
|
|
238
244
|
/**
|
|
239
245
|
* Apply one rewrite, type-check, restore. Returns the diagnostics the
|
|
@@ -1186,6 +1186,17 @@ export declare class TypeInferrer {
|
|
|
1186
1186
|
* keep both segments.
|
|
1187
1187
|
*/
|
|
1188
1188
|
private declaringPackageOf;
|
|
1189
|
+
/**
|
|
1190
|
+
* The declaration a symbol is attributed to (carrick#2031). One declaration
|
|
1191
|
+
* is itself. Where several files merge one symbol (a global interface the
|
|
1192
|
+
* compiler's library declares and a typings package augments), their order
|
|
1193
|
+
* is the order the checker merged them in, and on TypeScript 6 that changes
|
|
1194
|
+
* once the program is rebuilt, so the first one is not an answer. The
|
|
1195
|
+
* compiler's default library wins where it declares the symbol; otherwise,
|
|
1196
|
+
* and among the library's own files, the declaring file whose path sorts
|
|
1197
|
+
* first, then the earliest declaration in it.
|
|
1198
|
+
*/
|
|
1199
|
+
private attributedDeclaration;
|
|
1189
1200
|
/**
|
|
1190
1201
|
* The awaited return type of the member invoked on the receiver. Reported as
|
|
1191
1202
|
* a fact next to the receiver; a caller that classified on it alone would be
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
*/
|
|
20
20
|
import * as path from 'node:path';
|
|
21
21
|
import { Node, SyntaxKind, ts, } from 'ts-morph';
|
|
22
|
+
import { typeToStringAsDeclared } from './print-type.js';
|
|
22
23
|
import { validateInferRequestItem } from './validators.js';
|
|
23
24
|
import { notePrintedType, PrintedTypes } from './printed-names.js';
|
|
24
25
|
import { externalImportsOf, isExternalOrigin } from './origin.js';
|
|
@@ -242,8 +243,12 @@ const RAW_TEXT_FORMAT = 'text';
|
|
|
242
243
|
const TYPE_TEXT_FLAGS = ts.TypeFormatFlags.NoTruncation | ts.TypeFormatFlags.InTypeAlias;
|
|
243
244
|
function typeText(type, enclosingNode) {
|
|
244
245
|
// Timed as the print (carrick#1985): the type is already computed when it
|
|
245
|
-
// gets here, so this is what its length costs.
|
|
246
|
-
|
|
246
|
+
// gets here, so this is what its length costs. A module the print names is
|
|
247
|
+
// written as its declaring file, whichever file it is printed from
|
|
248
|
+
// (carrick#2019).
|
|
249
|
+
const text = timedPhase('print', () => enclosingNode
|
|
250
|
+
? typeToStringAsDeclared(enclosingNode.getProject().getTypeChecker().compilerObject, type.compilerType, enclosingNode.compilerNode, TYPE_TEXT_FLAGS)
|
|
251
|
+
: type.getText(undefined, TYPE_TEXT_FLAGS));
|
|
247
252
|
notePrintedType(type, enclosingNode, text);
|
|
248
253
|
return text;
|
|
249
254
|
}
|
|
@@ -4625,7 +4630,7 @@ export class TypeInferrer {
|
|
|
4625
4630
|
*/
|
|
4626
4631
|
declaringPackageOf(type) {
|
|
4627
4632
|
const symbol = type.getSymbol() ?? type.getAliasSymbol();
|
|
4628
|
-
const declaration = symbol?.getDeclarations()
|
|
4633
|
+
const declaration = this.attributedDeclaration(symbol?.getDeclarations() ?? []);
|
|
4629
4634
|
if (!declaration) {
|
|
4630
4635
|
return undefined;
|
|
4631
4636
|
}
|
|
@@ -4648,6 +4653,28 @@ export class TypeInferrer {
|
|
|
4648
4653
|
}
|
|
4649
4654
|
return rest[0];
|
|
4650
4655
|
}
|
|
4656
|
+
/**
|
|
4657
|
+
* The declaration a symbol is attributed to (carrick#2031). One declaration
|
|
4658
|
+
* is itself. Where several files merge one symbol (a global interface the
|
|
4659
|
+
* compiler's library declares and a typings package augments), their order
|
|
4660
|
+
* is the order the checker merged them in, and on TypeScript 6 that changes
|
|
4661
|
+
* once the program is rebuilt, so the first one is not an answer. The
|
|
4662
|
+
* compiler's default library wins where it declares the symbol; otherwise,
|
|
4663
|
+
* and among the library's own files, the declaring file whose path sorts
|
|
4664
|
+
* first, then the earliest declaration in it.
|
|
4665
|
+
*/
|
|
4666
|
+
attributedDeclaration(declarations) {
|
|
4667
|
+
if (declarations.length <= 1)
|
|
4668
|
+
return declarations[0];
|
|
4669
|
+
const program = this.project.getProgram().compilerObject;
|
|
4670
|
+
const fromLibrary = declarations.filter((declaration) => program.isSourceFileDefaultLibrary(declaration.getSourceFile().compilerNode));
|
|
4671
|
+
const candidates = fromLibrary.length > 0 ? fromLibrary : declarations;
|
|
4672
|
+
return [...candidates].sort((a, b) => {
|
|
4673
|
+
const pathA = a.getSourceFile().getFilePath();
|
|
4674
|
+
const pathB = b.getSourceFile().getFilePath();
|
|
4675
|
+
return pathA < pathB ? -1 : pathA > pathB ? 1 : a.getStart() - b.getStart();
|
|
4676
|
+
})[0];
|
|
4677
|
+
}
|
|
4651
4678
|
/**
|
|
4652
4679
|
* The awaited return type of the member invoked on the receiver. Reported as
|
|
4653
4680
|
* a fact next to the receiver; a caller that classified on it alone would be
|
|
@@ -206,6 +206,22 @@ export interface HealthRequest extends BaseRequest {
|
|
|
206
206
|
export interface ShutdownRequest extends BaseRequest {
|
|
207
207
|
action: 'shutdown';
|
|
208
208
|
}
|
|
209
|
+
/**
|
|
210
|
+
* List the root files the init'd project's program was built from, in order
|
|
211
|
+
* (carrick#2027).
|
|
212
|
+
*/
|
|
213
|
+
export interface ListProgramFilesRequest extends BaseRequest {
|
|
214
|
+
action: 'list_program_files';
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* Add files to the programs that type them, in the given order
|
|
218
|
+
* (carrick#2027).
|
|
219
|
+
*/
|
|
220
|
+
export interface AddProgramFilesRequest extends BaseRequest {
|
|
221
|
+
action: 'add_program_files';
|
|
222
|
+
/** Absolute paths, or relative to the init'd root. */
|
|
223
|
+
files: string[];
|
|
224
|
+
}
|
|
209
225
|
/**
|
|
210
226
|
* Request to resolve type definitions from a v2 capture stub package.
|
|
211
227
|
* Returns both the original declaration and the compiler-expanded form for
|
|
@@ -461,7 +477,7 @@ export interface ListLibrarySurfaceRequest extends BaseRequest {
|
|
|
461
477
|
/**
|
|
462
478
|
* Union type for all possible sidecar requests
|
|
463
479
|
*/
|
|
464
|
-
export type SidecarRequest = RetypeCheckRequest | VerifyClientSemanticsRequest | VerifyLibraryClaimsRequest | ListLibrarySurfaceRequest | InitRequest | BundleRequest | CaptureV2Request | CheckV2Request | InferRequest | ResolveDefinitionsRequest | HealthRequest | ShutdownRequest;
|
|
480
|
+
export type SidecarRequest = RetypeCheckRequest | VerifyClientSemanticsRequest | VerifyLibraryClaimsRequest | ListLibrarySurfaceRequest | InitRequest | BundleRequest | CaptureV2Request | CheckV2Request | InferRequest | ResolveDefinitionsRequest | HealthRequest | ShutdownRequest | ListProgramFilesRequest | AddProgramFilesRequest;
|
|
465
481
|
/**
|
|
466
482
|
* Request for a specific symbol to be bundled
|
|
467
483
|
*/
|
|
@@ -645,6 +661,22 @@ export interface HealthResponse extends BaseResponse {
|
|
|
645
661
|
export interface ShutdownResponse extends BaseResponse {
|
|
646
662
|
status: 'success';
|
|
647
663
|
}
|
|
664
|
+
/**
|
|
665
|
+
* Response for list_program_files action
|
|
666
|
+
*/
|
|
667
|
+
export interface ListProgramFilesResponse extends BaseResponse {
|
|
668
|
+
/** The program's root files, as absolute paths, in order. */
|
|
669
|
+
files?: string[];
|
|
670
|
+
errors?: string[];
|
|
671
|
+
}
|
|
672
|
+
/**
|
|
673
|
+
* Response for add_program_files action
|
|
674
|
+
*/
|
|
675
|
+
export interface AddProgramFilesResponse extends BaseResponse {
|
|
676
|
+
/** How many of the given files were added. */
|
|
677
|
+
added?: number;
|
|
678
|
+
errors?: string[];
|
|
679
|
+
}
|
|
648
680
|
/**
|
|
649
681
|
* Error response
|
|
650
682
|
*/
|
|
@@ -785,7 +817,7 @@ export interface ListLibrarySurfaceResponse extends BaseResponse {
|
|
|
785
817
|
/**
|
|
786
818
|
* Union type for all possible sidecar responses
|
|
787
819
|
*/
|
|
788
|
-
export type SidecarResponse = RetypeCheckResponse | VerifyClientSemanticsResponse | VerifyLibraryClaimsResponse | ListLibrarySurfaceResponse | InitResponse | BundleResponse | CaptureV2Response | CheckV2Response | InferResponse | ResolveDefinitionsResponse | HealthResponse | ShutdownResponse | ErrorResponse;
|
|
820
|
+
export type SidecarResponse = RetypeCheckResponse | VerifyClientSemanticsResponse | VerifyLibraryClaimsResponse | ListLibrarySurfaceResponse | InitResponse | BundleResponse | CaptureV2Response | CheckV2Response | InferResponse | ResolveDefinitionsResponse | HealthResponse | ShutdownResponse | ListProgramFilesResponse | AddProgramFilesResponse | ErrorResponse;
|
|
789
821
|
/**
|
|
790
822
|
* An entry in the type manifest
|
|
791
823
|
*/
|