@cplieger/deadset-ts 2.0.0 → 2.2.0
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 +3 -3
- package/dist/src/inventory.js +23 -6
- package/dist/src/version.js +1 -1
- package/jsr.json +1 -1
- package/package.json +1 -1
- package/src/inventory.ts +27 -5
- 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 1.
|
|
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
|
|
|
@@ -20,7 +20,7 @@ npx jsr add -D @cplieger/deadset-ts
|
|
|
20
20
|
npx @cplieger/deadset-ts version
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
-
The npm package carries the command and the library as JavaScript that the compiler emits at publish, so `npx deadset-ts` and `import("@cplieger/deadset-ts")` both run on plain Node.js 24 or later, with no loader and no flag. It carries the TypeScript source as well, which is what a TypeScript consumer's own compiler resolves. That consumer sets `allowImportingTsExtensions`, because the source names each import with its `.ts` extension. The JSR package ships source only, and Deno compiles it.
|
|
23
|
+
The npm package carries the command and the library as JavaScript that the compiler emits at publish, so `npx deadset-ts` and `import("@cplieger/deadset-ts")` both run on plain Node.js 24 or later, with no loader and no flag. It carries the TypeScript source as well, which is what a TypeScript consumer's own compiler resolves. That consumer sets `allowImportingTsExtensions`, because the source names each import with its `.ts` extension. The JSR package ships source only, and Deno compiles it: a Deno program imports and type-checks the library, but the compiler's synchronous session does not open under Deno, so running an analysis needs Node.
|
|
24
24
|
|
|
25
25
|
## Usage
|
|
26
26
|
|
|
@@ -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/inventory.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isClassDeclaration, isComputedPropertyName, isEnumDeclaration, isEnumMember, isExportAssignment, isExportDeclaration, isFunctionDeclaration, isGetAccessorDeclaration, isIdentifier, isInterfaceDeclaration, isIntersectionTypeNode, isMethodDeclaration, isMethodSignatureDeclaration, isModuleBlock, isModuleDeclaration, isNamespaceExport, isPrivateIdentifier, isPropertyDeclaration, isPropertySignatureDeclaration, isSetAccessorDeclaration, isTypeAliasDeclaration, isTypeLiteralNode, isUnionTypeNode, isVariableStatement, ModifierFlags, } from "@typescript/native/unstable/ast";
|
|
1
|
+
import { isClassDeclaration, isComputedPropertyName, isEnumDeclaration, isEnumMember, isExportAssignment, isExportDeclaration, isFunctionDeclaration, isGetAccessorDeclaration, isIdentifier, isInterfaceDeclaration, isIntersectionTypeNode, isMethodDeclaration, isMethodSignatureDeclaration, isModuleBlock, isModuleDeclaration, isNamespaceExport, isParenthesizedTypeNode, isPrivateIdentifier, isPropertyDeclaration, isPropertySignatureDeclaration, isSetAccessorDeclaration, isTypeAliasDeclaration, isTypeLiteralNode, isUnionTypeNode, isVariableStatement, ModifierFlags, } from "@typescript/native/unstable/ast";
|
|
2
2
|
import { dirnamePath, joinPath, relativePath } from "./paths.js";
|
|
3
3
|
import { byPosition, positionKey, renderPosition } from "./position.js";
|
|
4
4
|
import { computedComponent, nameComponent, renderRef } from "./ref.js";
|
|
@@ -104,6 +104,27 @@ function isStringOrNumericName(name) {
|
|
|
104
104
|
function memberKey(component, isStatic) {
|
|
105
105
|
return `${component.computed ? "[" : ""}${component.text}${isStatic ? ":static" : ""}`;
|
|
106
106
|
}
|
|
107
|
+
/** The type one node is, through however many parentheses are written around it. */
|
|
108
|
+
function unparenthesizedType(type) {
|
|
109
|
+
let held = type;
|
|
110
|
+
while (isParenthesizedTypeNode(held)) {
|
|
111
|
+
held = held.type;
|
|
112
|
+
}
|
|
113
|
+
return held;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* The direct constituents of one type. Parentheses are syntax and are not a
|
|
117
|
+
* constituent, so a parenthesized type contributes the constituents it holds: the
|
|
118
|
+
* constituents of `(A | B) & C` are `A`, `B` and `C`. A union or an intersection
|
|
119
|
+
* written without them stays one constituent.
|
|
120
|
+
*/
|
|
121
|
+
function constituentsOf(type) {
|
|
122
|
+
const held = unparenthesizedType(type);
|
|
123
|
+
if (!isUnionTypeNode(held) && !isIntersectionTypeNode(held)) {
|
|
124
|
+
return [held];
|
|
125
|
+
}
|
|
126
|
+
return held.types.flatMap((member) => isParenthesizedTypeNode(member) ? constituentsOf(member) : [member]);
|
|
127
|
+
}
|
|
107
128
|
/**
|
|
108
129
|
* The members one type alias declares: the members of the object type it writes, and
|
|
109
130
|
* of every object type that is a direct constituent of a union or an intersection it
|
|
@@ -115,11 +136,7 @@ function memberKey(component, isStatic) {
|
|
|
115
136
|
* neither of them is the one a reference to it would name.
|
|
116
137
|
*/
|
|
117
138
|
function aliasMembers(type) {
|
|
118
|
-
const literals =
|
|
119
|
-
? [type]
|
|
120
|
-
: isUnionTypeNode(type) || isIntersectionTypeNode(type)
|
|
121
|
-
? type.types.filter(isTypeLiteralNode)
|
|
122
|
-
: [];
|
|
139
|
+
const literals = constituentsOf(type).filter(isTypeLiteralNode);
|
|
123
140
|
if (literals.length < 2) {
|
|
124
141
|
return literals[0]?.members ?? [];
|
|
125
142
|
}
|
package/dist/src/version.js
CHANGED
package/jsr.json
CHANGED
package/package.json
CHANGED
package/src/inventory.ts
CHANGED
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
isModuleBlock,
|
|
16
16
|
isModuleDeclaration,
|
|
17
17
|
isNamespaceExport,
|
|
18
|
+
isParenthesizedTypeNode,
|
|
18
19
|
isPrivateIdentifier,
|
|
19
20
|
isPropertyDeclaration,
|
|
20
21
|
isPropertySignatureDeclaration,
|
|
@@ -327,6 +328,31 @@ function memberKey(component: Component, isStatic: boolean): string {
|
|
|
327
328
|
return `${component.computed ? "[" : ""}${component.text}${isStatic ? ":static" : ""}`;
|
|
328
329
|
}
|
|
329
330
|
|
|
331
|
+
/** The type one node is, through however many parentheses are written around it. */
|
|
332
|
+
function unparenthesizedType(type: Node): Node {
|
|
333
|
+
let held = type;
|
|
334
|
+
while (isParenthesizedTypeNode(held)) {
|
|
335
|
+
held = held.type;
|
|
336
|
+
}
|
|
337
|
+
return held;
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* The direct constituents of one type. Parentheses are syntax and are not a
|
|
342
|
+
* constituent, so a parenthesized type contributes the constituents it holds: the
|
|
343
|
+
* constituents of `(A | B) & C` are `A`, `B` and `C`. A union or an intersection
|
|
344
|
+
* written without them stays one constituent.
|
|
345
|
+
*/
|
|
346
|
+
function constituentsOf(type: Node): readonly Node[] {
|
|
347
|
+
const held = unparenthesizedType(type);
|
|
348
|
+
if (!isUnionTypeNode(held) && !isIntersectionTypeNode(held)) {
|
|
349
|
+
return [held];
|
|
350
|
+
}
|
|
351
|
+
return held.types.flatMap((member) =>
|
|
352
|
+
isParenthesizedTypeNode(member) ? constituentsOf(member) : [member],
|
|
353
|
+
);
|
|
354
|
+
}
|
|
355
|
+
|
|
330
356
|
/**
|
|
331
357
|
* The members one type alias declares: the members of the object type it writes, and
|
|
332
358
|
* of every object type that is a direct constituent of a union or an intersection it
|
|
@@ -338,11 +364,7 @@ function memberKey(component: Component, isStatic: boolean): string {
|
|
|
338
364
|
* neither of them is the one a reference to it would name.
|
|
339
365
|
*/
|
|
340
366
|
function aliasMembers(type: Node): readonly Node[] {
|
|
341
|
-
const literals =
|
|
342
|
-
? [type]
|
|
343
|
-
: isUnionTypeNode(type) || isIntersectionTypeNode(type)
|
|
344
|
-
? type.types.filter(isTypeLiteralNode)
|
|
345
|
-
: [];
|
|
367
|
+
const literals = constituentsOf(type).filter(isTypeLiteralNode);
|
|
346
368
|
if (literals.length < 2) {
|
|
347
369
|
return literals[0]?.members ?? [];
|
|
348
370
|
}
|
package/src/version.ts
CHANGED