@cplieger/deadset-ts 2.1.0 → 2.2.1
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 +2 -2
- package/dist/src/references.js +13 -22
- package/dist/src/version.js +1 -1
- package/jsr.json +1 -1
- package/package.json +1 -1
- package/src/references.ts +13 -24
- package/src/version.ts +1 -1
package/README.md
CHANGED
|
@@ -8,7 +8,7 @@ deadset-ts is a command-line analyzer for TypeScript and JavaScript projects. It
|
|
|
8
8
|
|
|
9
9
|
deadset-ts is report-only. It never edits source, and it refuses any `--fix` flag.
|
|
10
10
|
|
|
11
|
-
**Status: pre-release.** This version implements contract 2.
|
|
11
|
+
**Status: pre-release.** This version implements contract 2.1.0 and ships the analyzer's foundation: one compiler session per run over every `tsconfig` project discovered under the target (the explicit scope, every `tsconfig*.json`, each project's `references`), a fail-closed read of every project's diagnostics, configuration decoding against the contract's closed key list with `print-config` and its provenance, `print-projects`, the report-only guard, the symbol inventory of every declaration a project's own files hold down to its class and type members, and the one-pass reference resolution over that inventory. The inventory and the reference pass are library functions the package exports; no verb reports findings yet, so `analyze`, `explain`, `print-roots`, `print-retained` and `describe` exit with a usage message. The one runtime dependency is the `typescript` package at exactly 7.0.2, installed under the `@typescript/native` name until TypeScript 7.1 ships a compiler API the tooling can share.
|
|
12
12
|
|
|
13
13
|
## Install
|
|
14
14
|
|
|
@@ -70,7 +70,7 @@ The symbol inventory:
|
|
|
70
70
|
The reference pass:
|
|
71
71
|
|
|
72
72
|
- `references(project, held, targetRoot, options)`: every reference from one project's own files to a declaration of its inventory, in position order, with the rules that classified files as test files.
|
|
73
|
-
- `DEFAULT_BATCH_CAP`: the batch size
|
|
73
|
+
- `DEFAULT_BATCH_CAP`: the batch size the reference pass takes when its caller passes none; it is an option of the pass, not a configuration key. [Batch-cap calibration](docs/batch-cap-calibration.md) is the measurement that set it.
|
|
74
74
|
- `Reference`, `References`, `ReferenceOptions`, `ReferenceCost`, `TestFileRule`, `Resolution`, `Use`: one reference, one project's set of them, how a run resolves them, what that cost, one test-file rule, which accessor answered a reference, and whether it reads or writes.
|
|
75
75
|
|
|
76
76
|
Positions:
|
package/dist/src/references.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { isArrayLiteralExpression, isBinaryExpression, isDeleteExpression, isElementAccessExpression, isForInStatement, isForOfStatement, isObjectLiteralExpression, isParenthesizedExpression, isPostfixUnaryExpression, isPrefixUnaryExpression, isPropertyAccessExpression, isPropertyAssignment, isShorthandPropertyAssignment, isSpreadAssignment, isSpreadElement, SyntaxKind, } from "@typescript/native/unstable/ast";
|
|
2
|
+
import { SymbolFlags } from "@typescript/native/unstable/sync";
|
|
2
3
|
import { nodeKey } from "./inventory.js";
|
|
3
4
|
import { byPosition, renderPosition } from "./position.js";
|
|
4
5
|
/**
|
|
@@ -31,21 +32,6 @@ const ASSIGNMENTS = new Set([
|
|
|
31
32
|
SyntaxKind.QuestionQuestionEqualsToken,
|
|
32
33
|
SyntaxKind.CaretEqualsToken,
|
|
33
34
|
]);
|
|
34
|
-
/**
|
|
35
|
-
* The declaration forms that name something declared elsewhere. Each is a link rather
|
|
36
|
-
* than a declaration of what it names, so a reference through one names the next link
|
|
37
|
-
* and, at the end of the chain, the declaration itself: a re-export something imports
|
|
38
|
-
* is used, and so is the declaration behind it.
|
|
39
|
-
*/
|
|
40
|
-
const ALIASES = new Set([
|
|
41
|
-
SyntaxKind.ImportClause,
|
|
42
|
-
SyntaxKind.ImportEqualsDeclaration,
|
|
43
|
-
SyntaxKind.ImportSpecifier,
|
|
44
|
-
SyntaxKind.NamespaceImport,
|
|
45
|
-
SyntaxKind.ExportAssignment,
|
|
46
|
-
SyntaxKind.ExportSpecifier,
|
|
47
|
-
SyntaxKind.NamespaceExport,
|
|
48
|
-
]);
|
|
49
35
|
/** Whether one node is an identifier or a private name, the two forms a name takes. */
|
|
50
36
|
function isName(node) {
|
|
51
37
|
return node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.PrivateIdentifier;
|
|
@@ -303,11 +289,17 @@ export function references(project, held, targetRoot, options) {
|
|
|
303
289
|
* is the declaration behind it, so both are named; a link this project does not
|
|
304
290
|
* declare is stepped over rather than recorded.
|
|
305
291
|
*
|
|
306
|
-
* A
|
|
307
|
-
*
|
|
308
|
-
*
|
|
309
|
-
*
|
|
310
|
-
*
|
|
292
|
+
* A symbol is asked to step only where the binder flagged it an alias, which is the
|
|
293
|
+
* same condition the step itself asserts on. The declaration's syntax is not that
|
|
294
|
+
* condition and does not stand in for it: a default export of an expression is
|
|
295
|
+
* written as one of the alias forms and names nothing declared elsewhere, so it is
|
|
296
|
+
* recorded as the declaration it is and the chain ends there.
|
|
297
|
+
*
|
|
298
|
+
* A declaration handle carries the file it is in, so the question the walk asks of a
|
|
299
|
+
* declaration is answered before it is resolved: a declaration outside the project's
|
|
300
|
+
* own files belongs to another program and is never read, which is what keeps the
|
|
301
|
+
* pass from fetching a library file to discover that the inventory does not hold what
|
|
302
|
+
* is in it.
|
|
311
303
|
*/
|
|
312
304
|
const targetsOf = (symbol) => {
|
|
313
305
|
const cached = reached.get(symbol.id);
|
|
@@ -320,9 +312,8 @@ export function references(project, held, targetRoot, options) {
|
|
|
320
312
|
let stepped = false;
|
|
321
313
|
while (at !== undefined && !walked.has(at.id)) {
|
|
322
314
|
walked.add(at.id);
|
|
323
|
-
|
|
315
|
+
const alias = (at.flags & SymbolFlags.Alias) !== 0;
|
|
324
316
|
for (const handle of at.declarations) {
|
|
325
|
-
alias = alias || ALIASES.has(handle.kind);
|
|
326
317
|
if (!ownFiles.has(handle.path)) {
|
|
327
318
|
continue;
|
|
328
319
|
}
|
package/dist/src/version.js
CHANGED
package/jsr.json
CHANGED
package/package.json
CHANGED
package/src/references.ts
CHANGED
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
type Node,
|
|
19
19
|
type SourceFile,
|
|
20
20
|
} from "@typescript/native/unstable/ast";
|
|
21
|
-
import type
|
|
21
|
+
import { SymbolFlags, type Symbol as TSSymbol } from "@typescript/native/unstable/sync";
|
|
22
22
|
import { nodeKey, type Inventory } from "./inventory.ts";
|
|
23
23
|
import { byPosition, renderPosition, type Position } from "./position.ts";
|
|
24
24
|
import type { ProjectView } from "./session.ts";
|
|
@@ -159,22 +159,6 @@ const ASSIGNMENTS: ReadonlySet<SyntaxKind> = new Set([
|
|
|
159
159
|
SyntaxKind.CaretEqualsToken,
|
|
160
160
|
]);
|
|
161
161
|
|
|
162
|
-
/**
|
|
163
|
-
* The declaration forms that name something declared elsewhere. Each is a link rather
|
|
164
|
-
* than a declaration of what it names, so a reference through one names the next link
|
|
165
|
-
* and, at the end of the chain, the declaration itself: a re-export something imports
|
|
166
|
-
* is used, and so is the declaration behind it.
|
|
167
|
-
*/
|
|
168
|
-
const ALIASES: ReadonlySet<SyntaxKind> = new Set([
|
|
169
|
-
SyntaxKind.ImportClause,
|
|
170
|
-
SyntaxKind.ImportEqualsDeclaration,
|
|
171
|
-
SyntaxKind.ImportSpecifier,
|
|
172
|
-
SyntaxKind.NamespaceImport,
|
|
173
|
-
SyntaxKind.ExportAssignment,
|
|
174
|
-
SyntaxKind.ExportSpecifier,
|
|
175
|
-
SyntaxKind.NamespaceExport,
|
|
176
|
-
]);
|
|
177
|
-
|
|
178
162
|
/** Whether one node is an identifier or a private name, the two forms a name takes. */
|
|
179
163
|
function isName(node: Node): boolean {
|
|
180
164
|
return node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.PrivateIdentifier;
|
|
@@ -479,11 +463,17 @@ export function references<Brand>(
|
|
|
479
463
|
* is the declaration behind it, so both are named; a link this project does not
|
|
480
464
|
* declare is stepped over rather than recorded.
|
|
481
465
|
*
|
|
482
|
-
* A
|
|
483
|
-
*
|
|
484
|
-
*
|
|
485
|
-
*
|
|
486
|
-
*
|
|
466
|
+
* A symbol is asked to step only where the binder flagged it an alias, which is the
|
|
467
|
+
* same condition the step itself asserts on. The declaration's syntax is not that
|
|
468
|
+
* condition and does not stand in for it: a default export of an expression is
|
|
469
|
+
* written as one of the alias forms and names nothing declared elsewhere, so it is
|
|
470
|
+
* recorded as the declaration it is and the chain ends there.
|
|
471
|
+
*
|
|
472
|
+
* A declaration handle carries the file it is in, so the question the walk asks of a
|
|
473
|
+
* declaration is answered before it is resolved: a declaration outside the project's
|
|
474
|
+
* own files belongs to another program and is never read, which is what keeps the
|
|
475
|
+
* pass from fetching a library file to discover that the inventory does not hold what
|
|
476
|
+
* is in it.
|
|
487
477
|
*/
|
|
488
478
|
const targetsOf = (symbol: TSSymbol): readonly Target[] => {
|
|
489
479
|
const cached = reached.get(symbol.id);
|
|
@@ -496,9 +486,8 @@ export function references<Brand>(
|
|
|
496
486
|
let stepped = false;
|
|
497
487
|
while (at !== undefined && !walked.has(at.id)) {
|
|
498
488
|
walked.add(at.id);
|
|
499
|
-
|
|
489
|
+
const alias = (at.flags & SymbolFlags.Alias) !== 0;
|
|
500
490
|
for (const handle of at.declarations) {
|
|
501
|
-
alias = alias || ALIASES.has(handle.kind);
|
|
502
491
|
if (!ownFiles.has(handle.path)) {
|
|
503
492
|
continue;
|
|
504
493
|
}
|
package/src/version.ts
CHANGED