@cplieger/deadset-ts 2.2.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.
@@ -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 declaration handle carries the file it is in and the syntax it is written as, so
307
- * both questions the walk asks of a declaration are answered before it is resolved: a
308
- * declaration outside the project's own files belongs to another program and is never
309
- * read, which is what keeps the pass from fetching a library file to discover that the
310
- * inventory does not hold what is in it.
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
- let alias = false;
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/jsr.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cplieger/deadset-ts",
3
- "version": "2.2.0",
3
+ "version": "2.2.1",
4
4
  "license": "GPL-3.0-or-later",
5
5
  "exports": {
6
6
  ".": "./src/index.ts"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cplieger/deadset-ts",
3
- "version": "2.2.0",
3
+ "version": "2.2.1",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "description": "Deterministic dead-code analysis for TypeScript, class and type members included",
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 { Symbol as TSSymbol } from "@typescript/native/unstable/sync";
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 declaration handle carries the file it is in and the syntax it is written as, so
483
- * both questions the walk asks of a declaration are answered before it is resolved: a
484
- * declaration outside the project's own files belongs to another program and is never
485
- * read, which is what keeps the pass from fetching a library file to discover that the
486
- * inventory does not hold what is in it.
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
- let alias = false;
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
  }