@cplieger/deadset-ts 7.0.0-dev.2 → 7.0.0-dev.4
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/README.md +1 -1
- package/dist/src/alias-chain.js +2 -2
- package/dist/src/analysis.js +89 -44
- package/dist/src/augmentations.js +14 -12
- package/dist/src/calls.js +2 -2
- package/dist/src/class-members.js +1 -1
- package/dist/src/components.js +62 -20
- package/dist/src/configuration-files.js +6 -6
- package/dist/src/configured-declarations.js +2 -2
- package/dist/src/conformance-record.js +1 -1
- package/dist/src/contextual-uses.js +71 -14
- package/dist/src/convention-rows.js +6 -2
- package/dist/src/conventions.js +4 -2
- package/dist/src/dependencies.js +81 -27
- package/dist/src/deprecation.js +1 -1
- package/dist/src/destructuring.js +2 -2
- package/dist/src/discover.js +1 -1
- package/dist/src/element-access.js +341 -0
- package/dist/src/entry-points.js +2 -2
- package/dist/src/enum-group.js +2 -2
- package/dist/src/erased-stores.js +317 -0
- package/dist/src/findings/completion.js +46 -15
- package/dist/src/findings/dependencies-and-module-machinery.js +1 -1
- package/dist/src/findings/emitters.js +1 -1
- package/dist/src/findings/self-check.js +17 -4
- package/dist/src/findings-pass.js +6 -5
- package/dist/src/framework-lifecycle.js +1 -1
- package/dist/src/html-entries.js +1 -1
- package/dist/src/implementations.js +2 -2
- package/dist/src/in-operands.js +30 -0
- package/dist/src/indexed-access.js +264 -125
- package/dist/src/injection-container.js +1 -1
- package/dist/src/interface-satisfaction.js +2 -2
- package/dist/src/intra-function-parts.js +26 -12
- package/dist/src/inventory.js +26 -1
- package/dist/src/keyof-comparisons.js +170 -0
- package/dist/src/kinds.js +17 -7
- package/dist/src/manifest.js +6 -16
- package/dist/src/matrix.js +20 -2
- package/dist/src/member-names.js +1 -1
- package/dist/src/module-declarations.js +1 -1
- package/dist/src/namespace-objects.js +1 -1
- package/dist/src/outside-tests.js +1 -1
- package/dist/src/overrides.js +2 -2
- package/dist/src/query.js +4 -1
- package/dist/src/references.js +13 -2
- package/dist/src/reflective-lookup.js +2 -2
- package/dist/src/report.js +1 -1
- package/dist/src/reporters/sarif.js +4 -0
- package/dist/src/roots.js +1 -1
- package/dist/src/serialization-contract.js +45 -16
- package/dist/src/session.js +15 -8
- package/dist/src/signatures.js +1 -1
- package/dist/src/stores.js +1 -1
- package/dist/src/suppress-file.js +58 -6
- package/dist/src/suppress-inline.js +14 -5
- package/dist/src/suppress.js +54 -24
- package/dist/src/symbol-keys.js +1 -1
- package/dist/src/type-errors.js +1 -1
- package/dist/src/type-query-alias.js +1 -1
- package/dist/src/unimplemented-callees.js +312 -0
- package/dist/src/value-flow.js +1 -1
- package/dist/src/value-reach.js +8 -8
- package/dist/src/verbs/analyze.js +11 -9
- package/dist/src/workspace-programs.js +2 -2
- package/jsr.json +1 -1
- package/package.json +3 -3
- package/src/alias-chain.ts +2 -2
- package/src/analysis.ts +135 -52
- package/src/augmentations.ts +14 -11
- package/src/calls.ts +2 -2
- package/src/class-members.ts +2 -2
- package/src/component-layer.ts +1 -1
- package/src/components.ts +103 -21
- package/src/configuration-files.ts +6 -5
- package/src/configured-declarations.ts +2 -6
- package/src/conformance-record.ts +1 -1
- package/src/contextual-uses.ts +82 -18
- package/src/convention-rows.ts +6 -2
- package/src/conventions.ts +11 -2
- package/src/decorator.ts +1 -1
- package/src/dependencies.ts +108 -31
- package/src/deprecation.ts +1 -1
- package/src/destructuring.ts +2 -2
- package/src/discover.ts +2 -2
- package/src/element-access.ts +446 -0
- package/src/entry-points.ts +2 -2
- package/src/enum-group.ts +2 -2
- package/src/erased-stores.ts +413 -0
- package/src/file-facts.ts +3 -1
- package/src/findings/completion.ts +54 -20
- package/src/findings/dependencies-and-module-machinery.ts +1 -1
- package/src/findings/emitters.ts +1 -1
- package/src/findings/self-check.ts +18 -4
- package/src/findings-pass.ts +12 -5
- package/src/framework-lifecycle.ts +2 -2
- package/src/html-entries.ts +1 -1
- package/src/implementations.ts +2 -2
- package/src/in-operands.ts +45 -0
- package/src/indexed-access.ts +304 -146
- package/src/injection-container.ts +1 -1
- package/src/interface-satisfaction.ts +2 -2
- package/src/intra-function-parts.ts +42 -17
- package/src/inventory.ts +34 -2
- package/src/keyof-comparisons.ts +211 -0
- package/src/kinds.ts +20 -7
- package/src/manifest.ts +6 -21
- package/src/matrix.ts +34 -2
- package/src/member-names.ts +1 -1
- package/src/module-declarations.ts +1 -1
- package/src/namespace-objects.ts +1 -1
- package/src/outside-tests.ts +1 -1
- package/src/overrides.ts +2 -2
- package/src/position.ts +1 -1
- package/src/query.ts +12 -2
- package/src/references.ts +25 -3
- package/src/reflective-lookup.ts +2 -2
- package/src/report.ts +3 -1
- package/src/reporters/sarif.ts +4 -0
- package/src/roots.ts +2 -2
- package/src/serialization-contract.ts +55 -16
- package/src/session.ts +39 -32
- package/src/signatures.ts +1 -1
- package/src/source-files.ts +1 -1
- package/src/stores.ts +1 -1
- package/src/suppress-file.ts +68 -5
- package/src/suppress-inline.ts +15 -5
- package/src/suppress.ts +63 -28
- package/src/symbol-keys.ts +2 -2
- package/src/type-errors.ts +2 -2
- package/src/type-query-alias.ts +1 -1
- package/src/unimplemented-callees.ts +411 -0
- package/src/value-flow.ts +1 -1
- package/src/value-reach.ts +12 -8
- package/src/verbs/analyze.ts +15 -9
- package/src/workflow-steps.ts +1 -1
- package/src/workspace-programs.ts +4 -4
package/src/matrix.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* and intersected, with the dead components computed once over every configuration.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { componentsOf, type Component } from "./components.ts";
|
|
7
|
+
import { componentsOf, type Component, type Positional } from "./components.ts";
|
|
8
8
|
import { graphOf, OUTSIDE, type Graph } from "./graph.ts";
|
|
9
9
|
import type { InventorySymbol } from "./inventory.ts";
|
|
10
10
|
import { byPosition } from "./position.ts";
|
|
@@ -36,6 +36,8 @@ export interface Configured {
|
|
|
36
36
|
* finding.
|
|
37
37
|
*/
|
|
38
38
|
readonly referenceOnly?: readonly string[] | undefined;
|
|
39
|
+
/** Each declaration's dependents, by id, as the configuration's inventory states them. */
|
|
40
|
+
readonly dependents?: ReadonlyMap<string, readonly string[]> | undefined;
|
|
39
41
|
}
|
|
40
42
|
|
|
41
43
|
/** The run's configurations, indexed for the sweep. */
|
|
@@ -56,6 +58,8 @@ export interface Matrix {
|
|
|
56
58
|
* whose project holds it, in the run's order.
|
|
57
59
|
*/
|
|
58
60
|
readonly heldIn: readonly (readonly string[])[];
|
|
61
|
+
/** Each declaration's dependents, by id, as the first configuration holding it states them. */
|
|
62
|
+
readonly dependents: ReadonlyMap<string, readonly string[]>;
|
|
59
63
|
}
|
|
60
64
|
|
|
61
65
|
/** One declaration dead in every configuration that holds it. */
|
|
@@ -128,7 +132,13 @@ export function matrixOf(per: readonly Configured[]): Matrix {
|
|
|
128
132
|
const references: Reference[] = [];
|
|
129
133
|
const firstSeen = new Map<string, number>();
|
|
130
134
|
const judged = new Set<string>();
|
|
135
|
+
const dependents = new Map<string, readonly string[]>();
|
|
131
136
|
per.forEach((one, index) => {
|
|
137
|
+
for (const [id, after] of one.dependents ?? []) {
|
|
138
|
+
if (!dependents.has(id)) {
|
|
139
|
+
dependents.set(id, after);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
132
142
|
const referenceOnly = new Set(one.referenceOnly);
|
|
133
143
|
for (const symbol of one.symbols) {
|
|
134
144
|
const held = holders.get(symbol.id);
|
|
@@ -168,6 +178,7 @@ export function matrixOf(per: readonly Configured[]): Matrix {
|
|
|
168
178
|
[...new Set(per.flatMap((one) => one.supportFiles ?? []))],
|
|
169
179
|
),
|
|
170
180
|
heldIn: symbols.map((symbol) => holders.get(symbol.id) ?? []),
|
|
181
|
+
dependents,
|
|
171
182
|
};
|
|
172
183
|
}
|
|
173
184
|
|
|
@@ -257,14 +268,16 @@ export function sweepMatrix(matrix: Matrix, input: SweepInput): SweepResult {
|
|
|
257
268
|
});
|
|
258
269
|
});
|
|
259
270
|
|
|
271
|
+
const liveUnder = liveAnywhere(union.symbols, per);
|
|
260
272
|
return {
|
|
261
|
-
liveUnder
|
|
273
|
+
liveUnder,
|
|
262
274
|
candidates,
|
|
263
275
|
components: componentsOf(
|
|
264
276
|
union,
|
|
265
277
|
dead.map((one, at) => one && heldBy[at] === undefined),
|
|
266
278
|
testOfDeadCode,
|
|
267
279
|
unreferencedTest,
|
|
280
|
+
positionsOf(union, matrix.dependents, liveUnder),
|
|
268
281
|
),
|
|
269
282
|
};
|
|
270
283
|
}
|
|
@@ -286,6 +299,25 @@ export function liveFilesAt(
|
|
|
286
299
|
);
|
|
287
300
|
}
|
|
288
301
|
|
|
302
|
+
/**
|
|
303
|
+
* Each declaration's dependents by its place in the union, and per place whether the
|
|
304
|
+
* declaration is live under reachability in some configuration.
|
|
305
|
+
*/
|
|
306
|
+
function positionsOf(
|
|
307
|
+
union: Graph,
|
|
308
|
+
dependents: ReadonlyMap<string, readonly string[]>,
|
|
309
|
+
liveUnder: ReadonlyMap<string, readonly Relation[]>,
|
|
310
|
+
): Positional {
|
|
311
|
+
return {
|
|
312
|
+
dependents: union.symbols.map((symbol) =>
|
|
313
|
+
(dependents.get(symbol.id) ?? []).map((id) => union.at(id)).filter((at) => at !== OUTSIDE),
|
|
314
|
+
),
|
|
315
|
+
live: union.symbols.map(
|
|
316
|
+
(symbol) => liveUnder.get(symbol.id)?.includes("reachability") === true,
|
|
317
|
+
),
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
|
|
289
321
|
/** The relations in the order a declaration's entry lists them. */
|
|
290
322
|
const RELATIONS: readonly Relation[] = ["reference-counting", "reachability"];
|
|
291
323
|
|
package/src/member-names.ts
CHANGED
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
isStringLiteral,
|
|
13
13
|
type Node,
|
|
14
14
|
type SourceFile,
|
|
15
|
-
} from "@typescript/native/
|
|
15
|
+
} from "@typescript/native/ast";
|
|
16
16
|
import { nodeKey, type Inventory, type InventorySymbol, type SymbolKind } from "./inventory.ts";
|
|
17
17
|
|
|
18
18
|
/** The kinds of declaration a member name can name. */
|
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
SyntaxKind,
|
|
23
23
|
type Node,
|
|
24
24
|
type SourceFile,
|
|
25
|
-
} from "@typescript/native/
|
|
25
|
+
} from "@typescript/native/ast";
|
|
26
26
|
import { nodeKey, type Inventory, type InventorySymbol } from "./inventory.ts";
|
|
27
27
|
import { renderPosition } from "./position.ts";
|
|
28
28
|
import { UNANSWERED } from "./query.ts";
|
package/src/namespace-objects.ts
CHANGED
package/src/outside-tests.ts
CHANGED
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
SyntaxKind,
|
|
19
19
|
type Node,
|
|
20
20
|
type SourceFile,
|
|
21
|
-
} from "@typescript/native/
|
|
21
|
+
} from "@typescript/native/ast";
|
|
22
22
|
import { RESOLVED_EXTENSIONS, type ParseFile } from "./configuration-files.ts";
|
|
23
23
|
import { emittedFrom } from "./emit-map.ts";
|
|
24
24
|
import type { Host } from "./host.ts";
|
package/src/overrides.ts
CHANGED
|
@@ -16,11 +16,11 @@ import {
|
|
|
16
16
|
SyntaxKind,
|
|
17
17
|
type HeritageClauseElement,
|
|
18
18
|
type Node,
|
|
19
|
-
} from "@typescript/native/
|
|
19
|
+
} from "@typescript/native/ast";
|
|
20
20
|
import type { AliasChains } from "./alias-chain.ts";
|
|
21
21
|
import { memberComponent } from "./class-members.ts";
|
|
22
22
|
import { nodeKey, type Inventory, type InventorySymbol } from "./inventory.ts";
|
|
23
|
-
import { SymbolFlags, type Symbol as TSSymbol, type Type } from "@typescript/native/
|
|
23
|
+
import { SymbolFlags, type Symbol as TSSymbol, type Type } from "@typescript/native/sync";
|
|
24
24
|
import { UNANSWERED } from "./query.ts";
|
|
25
25
|
import { nameComponent } from "./ref.ts";
|
|
26
26
|
import type { Reference } from "./references.ts";
|
package/src/position.ts
CHANGED
package/src/query.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* form where it has one and otherwise as one batch, one round trip per capped run.
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import { isIdentifier, type Expression, type Node } from "@typescript/native/
|
|
10
|
+
import { isIdentifier, type Expression, type Node } from "@typescript/native/ast";
|
|
11
11
|
import type {
|
|
12
12
|
APIRequestGenerator,
|
|
13
13
|
Checker,
|
|
@@ -18,7 +18,7 @@ import type {
|
|
|
18
18
|
SymbolFlags,
|
|
19
19
|
Symbol as TSSymbol,
|
|
20
20
|
Type,
|
|
21
|
-
} from "@typescript/native/
|
|
21
|
+
} from "@typescript/native/sync";
|
|
22
22
|
|
|
23
23
|
/**
|
|
24
24
|
* The greatest number of locations one batched request asks about. A batch is
|
|
@@ -205,6 +205,8 @@ export interface Queries {
|
|
|
205
205
|
targetOf(type: Type): Answer<Type>;
|
|
206
206
|
/** The constraint of a type parameter, where it declares one; none for another type. */
|
|
207
207
|
constraintOf(type: Type): Answer<Type | undefined>;
|
|
208
|
+
/** The object and the index of an indexed-access type; none for another type. */
|
|
209
|
+
indexedAccessOf(type: Type): Answer<{ readonly object: Type; readonly index: Type } | undefined>;
|
|
208
210
|
/** The symbol a type is declared by. */
|
|
209
211
|
symbolOfType(type: Type): Answer<TSSymbol | undefined>;
|
|
210
212
|
signaturesOf(type: Type, kind: SignatureKind): Answer<readonly Signature[]>;
|
|
@@ -516,6 +518,14 @@ export function queriesOf(
|
|
|
516
518
|
() => type.getConstraint(),
|
|
517
519
|
)
|
|
518
520
|
: undefined,
|
|
521
|
+
indexedAccessOf: (type) =>
|
|
522
|
+
type.isIndexedAccessType()
|
|
523
|
+
? one(
|
|
524
|
+
"getObjectType",
|
|
525
|
+
() => typeLocation(type),
|
|
526
|
+
() => ({ object: type.getObjectType(), index: type.getIndexType() }),
|
|
527
|
+
)
|
|
528
|
+
: undefined,
|
|
519
529
|
symbolOfType: (type) =>
|
|
520
530
|
one(
|
|
521
531
|
"getSymbol",
|
package/src/references.ts
CHANGED
|
@@ -33,8 +33,8 @@ import {
|
|
|
33
33
|
SyntaxKind,
|
|
34
34
|
type Node,
|
|
35
35
|
type SourceFile,
|
|
36
|
-
} from "@typescript/native/
|
|
37
|
-
import type { Symbol as TSSymbol } from "@typescript/native/
|
|
36
|
+
} from "@typescript/native/ast";
|
|
37
|
+
import type { Symbol as TSSymbol } from "@typescript/native/sync";
|
|
38
38
|
import { aliasChains, type ChainTarget } from "./alias-chain.ts";
|
|
39
39
|
import { contextualUses, type FlowAt, type LiteralAt } from "./contextual-uses.ts";
|
|
40
40
|
import { destructuring, propertyReadsOf, type PropertyRead } from "./destructuring.ts";
|
|
@@ -43,7 +43,10 @@ import { namespaceUses } from "./namespace-objects.ts";
|
|
|
43
43
|
import { globExpression } from "./glob.ts";
|
|
44
44
|
import { declarationsByName, nodeKey, type Inventory, type InventorySymbol } from "./inventory.ts";
|
|
45
45
|
import { augmentationReferences } from "./augmentations.ts";
|
|
46
|
+
import { elementAccessReferences } from "./element-access.ts";
|
|
46
47
|
import { indexedAccessReferences } from "./indexed-access.ts";
|
|
48
|
+
import { keyofComparisonReferences } from "./keyof-comparisons.ts";
|
|
49
|
+
import { unimplementedCalleeReads } from "./unimplemented-callees.ts";
|
|
47
50
|
import { moduleDeclarationReferences } from "./module-declarations.ts";
|
|
48
51
|
import { overrideReferences } from "./overrides.ts";
|
|
49
52
|
import { dirnamePath, queriedModulePath, relativePath, resolvePath } from "./paths.ts";
|
|
@@ -185,6 +188,13 @@ export interface ReferenceCost {
|
|
|
185
188
|
readonly contextualBatches: number;
|
|
186
189
|
/** Per-type lookups for the contextual uses: each distinct type's constituents, properties and symbol. */
|
|
187
190
|
readonly contextualLookups: number;
|
|
191
|
+
/**
|
|
192
|
+
* The requests the passes that read members through the checker's types make: element
|
|
193
|
+
* accesses, key comparisons, instantiated signatures and values handed to unimplemented
|
|
194
|
+
* callees. They are
|
|
195
|
+
* counted where the caller measures the client, through `requestCount`, and are 0 otherwise.
|
|
196
|
+
*/
|
|
197
|
+
readonly typedLookups: number;
|
|
188
198
|
}
|
|
189
199
|
|
|
190
200
|
/** One project's references, in position order, and what reading them cost. */
|
|
@@ -221,6 +231,8 @@ export interface ReferenceOptions {
|
|
|
221
231
|
* reference to a declaration of `held`, the target's, is recorded.
|
|
222
232
|
*/
|
|
223
233
|
readonly consumer?: ConsumerSide;
|
|
234
|
+
/** The client's running request count, where the caller measures the client. */
|
|
235
|
+
readonly requestCount?: () => number;
|
|
224
236
|
}
|
|
225
237
|
|
|
226
238
|
/**
|
|
@@ -1556,12 +1568,21 @@ export function references<Brand>(
|
|
|
1556
1568
|
}
|
|
1557
1569
|
}
|
|
1558
1570
|
|
|
1571
|
+
let typedLookups = 0;
|
|
1559
1572
|
if (consumer === undefined) {
|
|
1560
1573
|
found.push(...overrideReferences(project, held, chains, new Set(tests)));
|
|
1574
|
+
const before = options.requestCount?.() ?? 0;
|
|
1561
1575
|
found.push(...indexedAccessReferences(project, held, chains, root, new Set(tests)));
|
|
1576
|
+
found.push(...elementAccessReferences(project, held, chains, root, new Set(tests)));
|
|
1577
|
+
found.push(...keyofComparisonReferences(project, held, chains, root, new Set(tests)));
|
|
1578
|
+
found.push(...unimplementedCalleeReads(project, held, chains, root, new Set(tests)));
|
|
1579
|
+
typedLookups = (options.requestCount?.() ?? 0) - before;
|
|
1562
1580
|
found.push(...moduleDeclarationReferences(project, held, root, new Set(tests)));
|
|
1563
1581
|
}
|
|
1564
|
-
|
|
1582
|
+
const scripts = new Set(
|
|
1583
|
+
walked.filter((one) => one.file.externalModuleIndicator === undefined).map((one) => one.fileId),
|
|
1584
|
+
);
|
|
1585
|
+
found.push(...augmentationReferences(held, found, scripts));
|
|
1565
1586
|
found.sort(
|
|
1566
1587
|
(a, b) =>
|
|
1567
1588
|
byPosition(a.position, b.position) ||
|
|
@@ -1586,6 +1607,7 @@ export function references<Brand>(
|
|
|
1586
1607
|
patternLookups: destructured.cost.patternLookups,
|
|
1587
1608
|
contextualBatches: contextual.batches,
|
|
1588
1609
|
contextualLookups: contextual.lookups,
|
|
1610
|
+
typedLookups,
|
|
1589
1611
|
},
|
|
1590
1612
|
};
|
|
1591
1613
|
}
|
package/src/reflective-lookup.ts
CHANGED
|
@@ -22,8 +22,8 @@ import {
|
|
|
22
22
|
isStringLiteral,
|
|
23
23
|
type Node,
|
|
24
24
|
type SourceFile,
|
|
25
|
-
} from "@typescript/native/
|
|
26
|
-
import { TypeFlags, type Type } from "@typescript/native/
|
|
25
|
+
} from "@typescript/native/ast";
|
|
26
|
+
import { TypeFlags, type Type } from "@typescript/native/sync";
|
|
27
27
|
import type { DetectorInput, Evidence } from "./exempt.ts";
|
|
28
28
|
import { memberNames } from "./member-names.ts";
|
|
29
29
|
import { renderPosition } from "./position.ts";
|
package/src/report.ts
CHANGED
|
@@ -19,7 +19,7 @@ import type { StaleSuppression } from "./findings/self-check.ts";
|
|
|
19
19
|
import type { TestFileRule } from "./references.ts";
|
|
20
20
|
|
|
21
21
|
/** The version of the report schema this analyzer writes a report to. */
|
|
22
|
-
const SCHEMA_VERSION = "8.
|
|
22
|
+
const SCHEMA_VERSION = "8.1.0";
|
|
23
23
|
|
|
24
24
|
/** Every report schema version this analyzer reads: the one the Contract it implements admits. */
|
|
25
25
|
export const SCHEMA_VERSIONS_ACCEPTED: readonly string[] = [SCHEMA_VERSION];
|
|
@@ -45,6 +45,8 @@ interface WireDetails {
|
|
|
45
45
|
readonly position: WirePosition;
|
|
46
46
|
}[];
|
|
47
47
|
readonly write_positions?: readonly WirePosition[];
|
|
48
|
+
/** Set under the name-literal rule, which no finding of this analyzer meets; SARIF still maps it. */
|
|
49
|
+
readonly name_literal?: WirePosition;
|
|
48
50
|
readonly dependency_class?: string;
|
|
49
51
|
readonly mechanism?: string;
|
|
50
52
|
readonly entry?: {
|
package/src/reporters/sarif.ts
CHANGED
|
@@ -160,6 +160,10 @@ function relatedOf(found: WireFinding): readonly Related[] {
|
|
|
160
160
|
for (const at of found.details.write_positions ?? []) {
|
|
161
161
|
related.push({ label: "write", at, endLine: at.end_line });
|
|
162
162
|
}
|
|
163
|
+
if (found.details.name_literal !== undefined) {
|
|
164
|
+
const at = found.details.name_literal;
|
|
165
|
+
related.push({ label: "name", at, endLine: at.end_line });
|
|
166
|
+
}
|
|
163
167
|
for (const one of found.component.members ?? []) {
|
|
164
168
|
if (
|
|
165
169
|
declarationKey(one.ref, one.position.path) !==
|
package/src/roots.ts
CHANGED
|
@@ -20,7 +20,7 @@ import {
|
|
|
20
20
|
isVariableStatement,
|
|
21
21
|
type Node,
|
|
22
22
|
type SourceFile,
|
|
23
|
-
} from "@typescript/native/
|
|
23
|
+
} from "@typescript/native/ast";
|
|
24
24
|
import { aliasChains } from "./alias-chain.ts";
|
|
25
25
|
import type { ParseFile } from "./configuration-files.ts";
|
|
26
26
|
import { conventionEntries, type Conventions } from "./conventions.ts";
|
|
@@ -33,7 +33,7 @@ import { relativePath, resolvePath } from "./paths.ts";
|
|
|
33
33
|
import { byPosition } from "./position.ts";
|
|
34
34
|
import { UNANSWERED } from "./query.ts";
|
|
35
35
|
import type { ProjectView } from "./session.ts";
|
|
36
|
-
import type { Symbol as TSSymbol, Type } from "@typescript/native/
|
|
36
|
+
import type { Symbol as TSSymbol, Type } from "@typescript/native/sync";
|
|
37
37
|
import { sourceFilesOf } from "./source-files.ts";
|
|
38
38
|
import { typeQueryAliases } from "./type-query-alias.ts";
|
|
39
39
|
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The serialization-contract class: the data members and `toJSON` of every
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* destination does, to a fixpoint. A function invoked through `Function.prototype.call`,
|
|
9
|
-
* `apply` or `bind` is the callee, given the arguments those methods pass it.
|
|
2
|
+
* The serialization-contract class: the data members and `toJSON` of every type a value's
|
|
3
|
+
* static type reaches, where the value reaches `JSON.stringify` or a call `ts.serializers`
|
|
4
|
+
* names, and `toString` too where it reaches an `unknown` or `any` parameter of a function
|
|
5
|
+
* outside the analysis or an erased property of a type the program does not declare. A
|
|
6
|
+
* function of the project handing such a parameter to a destination is one, to a fixpoint,
|
|
7
|
+
* and a function invoked through `call`, `apply` or `bind` is the callee.
|
|
10
8
|
*/
|
|
11
9
|
|
|
12
10
|
import {
|
|
@@ -36,14 +34,14 @@ import {
|
|
|
36
34
|
type Expression,
|
|
37
35
|
type Node,
|
|
38
36
|
type ParameterDeclaration,
|
|
39
|
-
} from "@typescript/native/
|
|
37
|
+
} from "@typescript/native/ast";
|
|
40
38
|
import {
|
|
41
39
|
SignatureKind,
|
|
42
40
|
SymbolFlags,
|
|
43
41
|
TypeFlags,
|
|
44
42
|
type Symbol as TSSymbol,
|
|
45
43
|
type Type,
|
|
46
|
-
} from "@typescript/native/
|
|
44
|
+
} from "@typescript/native/sync";
|
|
47
45
|
import { aliasChains, type AliasChains } from "./alias-chain.ts";
|
|
48
46
|
import { calleeName, resolvedTargets, valuesPassed } from "./calls.ts";
|
|
49
47
|
import { classMembers, memberComponent, typesAt } from "./class-members.ts";
|
|
@@ -59,6 +57,7 @@ import { nodeKey, type Inventory } from "./inventory.ts";
|
|
|
59
57
|
import { renderPosition } from "./position.ts";
|
|
60
58
|
import { must } from "./query.ts";
|
|
61
59
|
import type { ProjectView } from "./session.ts";
|
|
60
|
+
import { erasedStores, type ErasedStores } from "./erased-stores.ts";
|
|
62
61
|
import { valueReach, type Reached } from "./value-reach.ts";
|
|
63
62
|
|
|
64
63
|
/** The serializer every run reads, whatever the configuration names. */
|
|
@@ -527,13 +526,20 @@ function destinations<Brand>(
|
|
|
527
526
|
return { invocation, at, mayReceive };
|
|
528
527
|
}
|
|
529
528
|
|
|
530
|
-
/** One
|
|
529
|
+
/** One value that carries classes and object types of the target into a destination. */
|
|
531
530
|
interface Flow {
|
|
532
531
|
readonly site: Node;
|
|
533
532
|
readonly classes: ReadonlySet<string>;
|
|
534
533
|
/** The members of the interfaces and object types the value carries. */
|
|
535
534
|
readonly members: readonly TSSymbol[];
|
|
536
535
|
readonly to: Destination;
|
|
536
|
+
/** What a retention names the destination by. */
|
|
537
|
+
readonly detail: string;
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
/** What two reaches carry together. */
|
|
541
|
+
function joined(a: Reached, b: Reached): Reached {
|
|
542
|
+
return { classes: new Set([...a.classes, ...b.classes]), members: [...a.members, ...b.members] };
|
|
537
543
|
}
|
|
538
544
|
|
|
539
545
|
/** Each argument of a call that can receive one whose value carries a class of the target. */
|
|
@@ -542,8 +548,9 @@ function flowsOf<Brand>(
|
|
|
542
548
|
held: Inventory,
|
|
543
549
|
sites: readonly Site[],
|
|
544
550
|
to: Destinations,
|
|
551
|
+
stores: ErasedStores,
|
|
545
552
|
): readonly Flow[] {
|
|
546
|
-
const reach = valueReach(project, held);
|
|
553
|
+
const reach = valueReach(project, held, stores.inside);
|
|
547
554
|
const arguments_ = sites.flatMap((site) =>
|
|
548
555
|
to.mayReceive(site.call)
|
|
549
556
|
? to.invocation(site.call).arguments.flatMap((argument, index) => {
|
|
@@ -560,7 +567,7 @@ function flowsOf<Brand>(
|
|
|
560
567
|
const typeOf = new Map<Expression, Type | undefined>(
|
|
561
568
|
asked.map((one, index) => [one.value, types[index]]),
|
|
562
569
|
);
|
|
563
|
-
|
|
570
|
+
const passed = arguments_.flatMap((one) => {
|
|
564
571
|
const type = typeOf.get(one.value);
|
|
565
572
|
let reached: Reached = { classes: new Set<string>(), members: [] };
|
|
566
573
|
if (one.value.kind === SyntaxKind.ThisKeyword) {
|
|
@@ -571,12 +578,38 @@ function flowsOf<Brand>(
|
|
|
571
578
|
} else if (type !== undefined) {
|
|
572
579
|
reached = reach.reachedFrom(type);
|
|
573
580
|
}
|
|
581
|
+
for (const stored of stores.ofVariable(one.value) ?? []) {
|
|
582
|
+
reached = joined(reached, reach.reachedFrom(stored));
|
|
583
|
+
}
|
|
574
584
|
const carries = reached.classes.size > 0 || reached.members.length > 0;
|
|
575
585
|
const destination = carries ? to.at(one.site.call, one.argument) : undefined;
|
|
576
586
|
return destination === undefined
|
|
577
587
|
? []
|
|
578
|
-
: [
|
|
588
|
+
: [
|
|
589
|
+
{
|
|
590
|
+
site: one.value,
|
|
591
|
+
classes: reached.classes,
|
|
592
|
+
members: reached.members,
|
|
593
|
+
to: destination,
|
|
594
|
+
detail: `passed to ${destination.callee}`,
|
|
595
|
+
},
|
|
596
|
+
];
|
|
597
|
+
});
|
|
598
|
+
const left = stores.outside.flatMap((store) => {
|
|
599
|
+
const reached = reach.reachedFrom(store.type);
|
|
600
|
+
return reached.classes.size === 0 && reached.members.length === 0
|
|
601
|
+
? []
|
|
602
|
+
: [
|
|
603
|
+
{
|
|
604
|
+
site: store.value,
|
|
605
|
+
classes: reached.classes,
|
|
606
|
+
members: reached.members,
|
|
607
|
+
to: { reach: "conversions" as const, callee: store.property },
|
|
608
|
+
detail: `stored in the property ${store.property} of a type the program does not declare`,
|
|
609
|
+
},
|
|
610
|
+
];
|
|
579
611
|
});
|
|
612
|
+
return [...passed, ...left];
|
|
580
613
|
}
|
|
581
614
|
|
|
582
615
|
/**
|
|
@@ -589,7 +622,13 @@ export function serializationContract<Brand>(input: DetectorInput<Brand>): reado
|
|
|
589
622
|
const { project, held, targetRoot } = input;
|
|
590
623
|
const walked = walkProject(project, held);
|
|
591
624
|
const chains = aliasChains(project, held);
|
|
592
|
-
const flows = flowsOf(
|
|
625
|
+
const flows = flowsOf(
|
|
626
|
+
project,
|
|
627
|
+
held,
|
|
628
|
+
walked.sites,
|
|
629
|
+
destinations(input, chains, walked),
|
|
630
|
+
erasedStores(project),
|
|
631
|
+
);
|
|
593
632
|
if (flows.length === 0) {
|
|
594
633
|
return [];
|
|
595
634
|
}
|
|
@@ -609,7 +648,7 @@ export function serializationContract<Brand>(input: DetectorInput<Brand>): reado
|
|
|
609
648
|
const found: Evidence[] = [];
|
|
610
649
|
for (const flow of flows) {
|
|
611
650
|
const site = renderPosition(flow.site.getSourceFile(), targetRoot, flow.site.getStart());
|
|
612
|
-
const detail =
|
|
651
|
+
const { detail } = flow;
|
|
613
652
|
for (const member of [...flow.classes].flatMap((id) => members.get(id) ?? [])) {
|
|
614
653
|
const symbol = byId.get(member.id);
|
|
615
654
|
const name = symbol === undefined ? "" : (memberComponent(symbol, byId) ?? "");
|
package/src/session.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { API, SymbolFlags } from "@typescript/native/
|
|
1
|
+
import { API, SymbolFlags } from "@typescript/native/sync";
|
|
2
2
|
import type {
|
|
3
3
|
APIRequestGenerator,
|
|
4
4
|
CreateSnapshotProgramParams,
|
|
@@ -12,8 +12,8 @@ import type {
|
|
|
12
12
|
Snapshot,
|
|
13
13
|
Symbol as TSSymbol,
|
|
14
14
|
TimingInfo,
|
|
15
|
-
} from "@typescript/native/
|
|
16
|
-
import type { Node, SourceFile } from "@typescript/native/
|
|
15
|
+
} from "@typescript/native/sync";
|
|
16
|
+
import type { Node, SourceFile } from "@typescript/native/ast";
|
|
17
17
|
import { componentLayer, mapperManifest } from "./component-layer.ts";
|
|
18
18
|
import { DiscoveryError } from "./discover.ts";
|
|
19
19
|
import type { Host, TemporaryDirectory } from "./host.ts";
|
|
@@ -28,13 +28,10 @@ import {
|
|
|
28
28
|
} from "./query.ts";
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
|
-
* The compiler the analysis reads through
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* It is an interface because the run's own accounting for that lifetime is not on
|
|
36
|
-
* the client's surface: a snapshot reports whether it is disposed and not how many
|
|
37
|
-
* a client opened, so the count is observed at this seam.
|
|
31
|
+
* The compiler the analysis reads through: a client over a protocol to a separate
|
|
32
|
+
* process, so every accessor call is a round trip and a run holds one client and one
|
|
33
|
+
* snapshot. It is an interface because a snapshot reports whether it is disposed and not
|
|
34
|
+
* how many a client opened, so the run's count of them is observed at this seam.
|
|
38
35
|
*/
|
|
39
36
|
export interface Engine {
|
|
40
37
|
/**
|
|
@@ -156,6 +153,8 @@ export function openEngine(options: EngineOptions): Engine {
|
|
|
156
153
|
}),
|
|
157
154
|
}),
|
|
158
155
|
readsComponents: mapper !== undefined,
|
|
156
|
+
// Entries, not a resolveModuleName callback: this fallback resolves with the importing
|
|
157
|
+
// file's project-reference options, which the compiler never passes to a callback.
|
|
159
158
|
createModuleResolver: (options, entries) =>
|
|
160
159
|
api.createModuleResolver(options, {
|
|
161
160
|
moduleResolutions: { fallback: "resolve", entries: [...entries] },
|
|
@@ -187,14 +186,10 @@ export function openEngine(options: EngineOptions): Engine {
|
|
|
187
186
|
}
|
|
188
187
|
|
|
189
188
|
/**
|
|
190
|
-
* A node of one project's program, carried with that project's identity.
|
|
191
|
-
*
|
|
192
|
-
*
|
|
193
|
-
*
|
|
194
|
-
* compiler will not exchange and a handle cannot reach another project's checker.
|
|
195
|
-
* Handles are only meaningful inside the program that produced them, and the
|
|
196
|
-
* cross-project step of the analysis compares rendered positions rather than
|
|
197
|
-
* handles.
|
|
189
|
+
* A node of one project's program, carried with that project's identity. `Brand` is a
|
|
190
|
+
* type parameter and never a value: each visitor introduces its own, so two projects'
|
|
191
|
+
* handle types do not exchange and a handle cannot reach another project's checker. The
|
|
192
|
+
* cross-project step compares rendered positions, never handles.
|
|
198
193
|
*/
|
|
199
194
|
export interface Handle<Brand> {
|
|
200
195
|
readonly node: Node;
|
|
@@ -253,14 +248,11 @@ export interface ProjectView<Brand> {
|
|
|
253
248
|
*/
|
|
254
249
|
aliasStepOf(symbol: TSSymbol): Answer<TSSymbol | undefined>;
|
|
255
250
|
/**
|
|
256
|
-
* The node one symbol's declaration handle names, read in this project's program,
|
|
257
|
-
*
|
|
258
|
-
*
|
|
259
|
-
*
|
|
260
|
-
*
|
|
261
|
-
* would answer out of whichever project reached the symbol first. The project is
|
|
262
|
-
* named here instead, and the answer becomes a handle of this project like any
|
|
263
|
-
* other. The read is local once the file has been fetched.
|
|
251
|
+
* The node one symbol's declaration handle names, read in this project's program, or
|
|
252
|
+
* `undefined` where this program does not hold that file. A symbol is shared by every
|
|
253
|
+
* project of the snapshot and remembers the one it was first seen in, so the project is
|
|
254
|
+
* named here, or the answer would come from whichever project reached the symbol first.
|
|
255
|
+
* The read is local once the file has been fetched.
|
|
264
256
|
*/
|
|
265
257
|
declarationAt(handle: NodeHandle): Handle<Brand> | undefined;
|
|
266
258
|
}
|
|
@@ -272,6 +264,13 @@ export interface ProjectView<Brand> {
|
|
|
272
264
|
*/
|
|
273
265
|
export type ProjectVisitor<Result> = <Brand>(project: ProjectView<Brand>) => Result;
|
|
274
266
|
|
|
267
|
+
/** One project a session opened: its configuration and the files of its own program. */
|
|
268
|
+
export interface OpenedFiles {
|
|
269
|
+
readonly configFile: string;
|
|
270
|
+
/** The program's source files no default library and no external library holds. */
|
|
271
|
+
readonly fileNames: () => readonly string[];
|
|
272
|
+
}
|
|
273
|
+
|
|
275
274
|
/**
|
|
276
275
|
* The source files of one program that `own` admits, in the program's order, none of
|
|
277
276
|
* them one of the compiler's default libraries.
|
|
@@ -487,10 +486,10 @@ function projectsOf(
|
|
|
487
486
|
/**
|
|
488
487
|
* Runs `visit` over every project the compiler configurations name, inside one never updated
|
|
489
488
|
* snapshot of one client, and answers in their order. A configuration `programs` describes is
|
|
490
|
-
* built as that program, or opened from the configuration it writes
|
|
491
|
-
*
|
|
492
|
-
*
|
|
493
|
-
*
|
|
489
|
+
* built as that program, or opened from the configuration it writes. One the snapshot holds
|
|
490
|
+
* nothing for ends the run under `"refuse"` and is named in the result under `"record"`.
|
|
491
|
+
* `first` runs over every opened project before the first visit and `last` after the last,
|
|
492
|
+
* both while the client answers; the snapshot and the client are then released.
|
|
494
493
|
*/
|
|
495
494
|
export function runSession<Result>(
|
|
496
495
|
engine: Engine,
|
|
@@ -499,6 +498,7 @@ export function runSession<Result>(
|
|
|
499
498
|
unopened: Unopened = "refuse",
|
|
500
499
|
programs: ReadonlyMap<string, WorkspaceProgram> = new Map(),
|
|
501
500
|
last: () => void = () => undefined,
|
|
501
|
+
first: (opened: readonly OpenedFiles[]) => void = () => undefined,
|
|
502
502
|
): SessionResult<Result> {
|
|
503
503
|
try {
|
|
504
504
|
const built: string[] = [];
|
|
@@ -523,7 +523,7 @@ export function runSession<Result>(
|
|
|
523
523
|
try {
|
|
524
524
|
const opened = projectsOf(snapshot, built, written);
|
|
525
525
|
const log = new UnansweredLog();
|
|
526
|
-
const
|
|
526
|
+
const views: ProjectView<unknown>[] = [];
|
|
527
527
|
const missing: string[] = [];
|
|
528
528
|
for (const configFile of configFiles) {
|
|
529
529
|
const project = opened.get(configFile);
|
|
@@ -534,8 +534,15 @@ export function runSession<Result>(
|
|
|
534
534
|
missing.push(configFile);
|
|
535
535
|
continue;
|
|
536
536
|
}
|
|
537
|
-
|
|
537
|
+
views.push(viewOf(project, configFile, engine, log));
|
|
538
538
|
}
|
|
539
|
+
first(
|
|
540
|
+
views.map((view) => ({
|
|
541
|
+
configFile: view.configFile,
|
|
542
|
+
fileNames: () => view.ownSourceFiles().map((file) => file.fileName),
|
|
543
|
+
})),
|
|
544
|
+
);
|
|
545
|
+
const projects = views.map((view) => visit(view));
|
|
539
546
|
last();
|
|
540
547
|
return {
|
|
541
548
|
projects,
|
package/src/signatures.ts
CHANGED
package/src/source-files.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* compiler emits from it.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import type { SourceFile } from "@typescript/native/
|
|
7
|
+
import type { SourceFile } from "@typescript/native/ast";
|
|
8
8
|
import { commonDirectory, emittedFrom } from "./emit-map.ts";
|
|
9
9
|
import { dirnamePath, relativePath, resolvePath } from "./paths.ts";
|
|
10
10
|
import type { ProjectView } from "./session.ts";
|
package/src/stores.ts
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
isGetAccessorDeclaration,
|
|
9
9
|
isSetAccessorDeclaration,
|
|
10
10
|
type Node,
|
|
11
|
-
} from "@typescript/native/
|
|
11
|
+
} from "@typescript/native/ast";
|
|
12
12
|
import { nodeKey, type Inventory } from "./inventory.ts";
|
|
13
13
|
import type { Reference } from "./references.ts";
|
|
14
14
|
import type { ProjectView } from "./session.ts";
|