@cplieger/deadset-ts 8.0.0-dev.14 → 8.0.0-dev.15

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.
Files changed (46) hide show
  1. package/dist/src/alias-chain.js +2 -2
  2. package/dist/src/analysis.js +2 -1
  3. package/dist/src/conformance-record.js +1 -1
  4. package/dist/src/consumers.js +1 -1
  5. package/dist/src/contract/contract.generated.js +1 -0
  6. package/dist/src/dependencies.js +2 -1
  7. package/dist/src/entry-points.js +26 -95
  8. package/dist/src/file-facts.js +1 -1
  9. package/dist/src/graph.js +0 -1
  10. package/dist/src/inventory/commonjs.js +462 -0
  11. package/dist/src/inventory/enumerate.js +166 -0
  12. package/dist/src/inventory/syntax.js +236 -0
  13. package/dist/src/inventory.js +305 -705
  14. package/dist/src/load/discover.js +1 -1
  15. package/dist/src/load/package-scope.js +56 -0
  16. package/dist/src/own-body.js +28 -0
  17. package/dist/src/position.js +41 -0
  18. package/dist/src/ref.js +11 -20
  19. package/dist/src/references.js +91 -30
  20. package/dist/src/session.js +3 -0
  21. package/dist/src/suppress-inline.js +33 -81
  22. package/dist/src/unseen-loads.js +106 -17
  23. package/jsr.json +1 -1
  24. package/package.json +2 -2
  25. package/src/alias-chain.ts +2 -2
  26. package/src/analysis.ts +2 -1
  27. package/src/conformance-record.ts +1 -1
  28. package/src/consumers.ts +1 -1
  29. package/src/contract/contract.generated.ts +1 -0
  30. package/src/dependencies.ts +2 -1
  31. package/src/entry-points.ts +30 -107
  32. package/src/file-facts.ts +1 -1
  33. package/src/graph.ts +0 -1
  34. package/src/inventory/commonjs.ts +611 -0
  35. package/src/inventory/enumerate.ts +202 -0
  36. package/src/inventory/syntax.ts +311 -0
  37. package/src/inventory.ts +424 -878
  38. package/src/load/discover.ts +1 -1
  39. package/src/load/package-scope.ts +74 -0
  40. package/src/own-body.ts +42 -0
  41. package/src/position.ts +42 -0
  42. package/src/ref.ts +11 -20
  43. package/src/references.ts +116 -53
  44. package/src/session.ts +17 -1
  45. package/src/suppress-inline.ts +53 -89
  46. package/src/unseen-loads.ts +166 -18
@@ -5,7 +5,7 @@
5
5
  */
6
6
  import { isExportAssignment, isExportSpecifier, isIdentifier, isImportClause, isImportSpecifier, isNamespaceExport, isNamespaceImport, } from "@typescript/native/ast";
7
7
  import { SymbolFlags } from "@typescript/native/sync";
8
- import { declarationsByName, isParameterProperty, nodeKey } from "./inventory.js";
8
+ import { isParameterProperty, nodeKey } from "./inventory.js";
9
9
  import { UNANSWERED } from "./query.js";
10
10
  /**
11
11
  * The chain walks over one project, against the declarations of `held`, the same
@@ -83,7 +83,7 @@ export function aliasChains(project, held) {
83
83
  names.add(node.expression.text);
84
84
  }
85
85
  }
86
- const byName = declarationsByName(held);
86
+ const byName = held.byName;
87
87
  const ids = [...names].flatMap((name) => byName.get(name) ?? []);
88
88
  return [...new Set([...ids, ...(module ? files : [])])].map((id) => ({
89
89
  id,
@@ -30,7 +30,8 @@ import { implementations, mergeImplementations } from "./implementations.js";
30
30
  import { injectionContainer } from "./injection-container.js";
31
31
  import { interfaceSatisfaction, settledSatisfaction } from "./interface-satisfaction.js";
32
32
  import { intraFunctionFacts, projectParts } from "./intra-function-parts.js";
33
- import { inventory } from "./inventory.js";
33
+ import {} from "./inventory.js";
34
+ import { inventory } from "./inventory/enumerate.js";
34
35
  import { readManifest } from "./manifest.js";
35
36
  import { liveFilesAt, matrixOf, referenceKey, sweepMatrix, } from "./matrix.js";
36
37
  import { ancestors, dirnamePath, extensionOf, joinPath, relativePath, resolvePath, } from "./paths.js";
@@ -4,7 +4,7 @@ export const RECORD = {
4
4
  conformance: {
5
5
  corpusVersion: "6.0.0",
6
6
  result: "pass",
7
- digest: "sha256:58ac31fa90fcbefdbbcbcbd6d2c7a8af6dd4cd883c04d79abfe96f979ffe10e1",
7
+ digest: "sha256:4a66f7f01b0f1a23cf843b77ef48d762f2dcf486153e665560f107f10b0ea838",
8
8
  },
9
9
  gaps: [],
10
10
  };
@@ -1,4 +1,4 @@
1
- import { inventory } from "./inventory.js";
1
+ import { inventory } from "./inventory/enumerate.js";
2
2
  import { relativePath } from "./paths.js";
3
3
  import { references } from "./references.js";
4
4
  import { narrowedTo } from "./session.js";
@@ -1233,6 +1233,7 @@ export const FAILURE_CLASSES = {
1233
1233
  "unreadable-document": "setup",
1234
1234
  "missing-import-path": "setup",
1235
1235
  "binding-undecodable": "setup",
1236
+ "unsupported-language": "setup",
1236
1237
  "unwritten-output": "run",
1237
1238
  "unreportable-path": "run",
1238
1239
  "memory-exhausted": "run",
@@ -9,7 +9,8 @@
9
9
  import { isArrayLiteralExpression, isCallExpression, isExportDeclaration, isExpressionStatement, isExternalModuleReference, isIdentifier, isImportDeclaration, isImportEqualsDeclaration, isMetaProperty, isNamespaceExport, isObjectLiteralExpression, isPropertyAccessExpression, isPropertyAssignment, isShorthandPropertyAssignment, isStringLiteral, isNoSubstitutionTemplateLiteral, SyntaxKind, } from "@typescript/native/ast";
10
10
  import { automaticTypes } from "./automatic-types.js";
11
11
  import { configurationFiles, declaredIn as declaredBeside, dependenciesNamed, moduleStrings, outsideChain, } from "./configuration-files.js";
12
- import { nodeKey, packageScope } from "./inventory.js";
12
+ import { nodeKey } from "./inventory.js";
13
+ import { packageScope } from "./load/package-scope.js";
13
14
  import { ancestors, dirnamePath, isAbsolutePath, joinPath, relativePath, resolvePath, } from "./paths.js";
14
15
  import { UNANSWERED } from "./query.js";
15
16
  import { sourceFilesOf } from "./source-files.js";
@@ -1,24 +1,17 @@
1
1
  /**
2
- * The files a tool or the platform enters without any import naming them: the
3
- * configuration files a tool loads by their file name and the files their strings
4
- * name, the test files the runner executes, and a worker a call addresses by a string
5
- * literal.
6
- *
7
- * Each rule is read from the program and nothing else: a file name the tool
8
- * itself looks for, a literal written in a configuration file, or a literal
9
- * argument of a call the checker resolves to the platform's own declaration. A
10
- * value that is not a literal is not evaluated and not guessed, so a file it would
11
- * have named is entered by nothing here.
2
+ * The files a tool or the platform enters without any import naming them, each by a name
3
+ * the tool looks for or a literal it reads. A value that is not a literal is not evaluated
4
+ * or guessed, so a file it would have named is entered by nothing here.
12
5
  */
13
- import { isArrayLiteralExpression, isCallExpression, isExportAssignment, isIdentifier, isMetaProperty, isNewExpression, isNoSubstitutionTemplateLiteral, isObjectLiteralExpression, isPropertyAccessExpression, isPropertyAssignment, isStringLiteral, SyntaxKind, } from "@typescript/native/ast";
6
+ import { isArrayLiteralExpression, isCallExpression, isExportAssignment, isIdentifier, isMetaProperty, isNewExpression, isNoSubstitutionTemplateLiteral, isObjectLiteralExpression, isPropertyAccessExpression, isPropertyAssignment, isStringLiteral, } from "@typescript/native/ast";
14
7
  import { SymbolFlags } from "@typescript/native/sync";
15
8
  import { configurationFiles, filesNamedBy, moduleStrings, } from "./configuration-files.js";
16
9
  import { buildScriptEntries } from "./build-scripts.js";
17
10
  import { htmlEntries } from "./html-entries.js";
18
11
  import { documentEntries } from "./mdx-entries.js";
12
+ import { hasOwnBody } from "./own-body.js";
19
13
  import { dirnamePath, relativePath, resolvePath } from "./paths.js";
20
14
  import { UNANSWERED } from "./query.js";
21
- import { computedLoadDirectory, leadingLiteral } from "./unseen-loads.js";
22
15
  import { workflowEntries } from "./workflow-steps.js";
23
16
  import { unwrapped } from "./unwrap.js";
24
17
  import { globExpression } from "./text/glob.js";
@@ -118,7 +111,7 @@ function memberOf(object, name) {
118
111
  * The strings one member holds, when it is written as a literal or an array of
119
112
  * literals. `undefined` is a value the text does not state.
120
113
  */
121
- function literalsOf(value) {
114
+ export function literalsOf(value) {
122
115
  const at = unwrapped(value);
123
116
  const single = literalOf(at);
124
117
  if (single !== undefined) {
@@ -144,10 +137,6 @@ function literalsOf(value) {
144
137
  function isRelative(text) {
145
138
  return text !== "" && !text.startsWith("/") && !URL_SCHEME.test(text);
146
139
  }
147
- /** Whether a module specifier is relative, which a bare name is not: it names a package. */
148
- function isModuleRelative(text) {
149
- return text.startsWith("./") || text.startsWith("../");
150
- }
151
140
  /** A URL reference with its query and its fragment removed, which name no part of the file. */
152
141
  function pathPart(text) {
153
142
  const cut = text.search(/[?#]/u);
@@ -291,7 +280,7 @@ function workerAddress(argument) {
291
280
  const at = unwrapped(argument);
292
281
  const literal = literalOf(at);
293
282
  if (literal !== undefined) {
294
- return { literal, names: [] };
283
+ return { literal, url: undefined };
295
284
  }
296
285
  if (!isNewExpression(at) || !isIdentifier(at.expression) || at.expression.text !== "URL") {
297
286
  return undefined;
@@ -308,7 +297,7 @@ function workerAddress(argument) {
308
297
  meta.name.text !== "url") {
309
298
  return undefined;
310
299
  }
311
- return { literal: text, names: [at.expression] };
300
+ return { literal: text, url: at.expression };
312
301
  }
313
302
  /**
314
303
  * Every call one file writes that addresses a worker: `new Worker(...)`,
@@ -325,7 +314,8 @@ function workerSitesOf(file) {
325
314
  if (address !== undefined) {
326
315
  found.push({
327
316
  literal: address.literal,
328
- platformNames: [node.expression, ...address.names],
317
+ platformNames: [node.expression],
318
+ url: address.url,
329
319
  });
330
320
  }
331
321
  }
@@ -343,7 +333,8 @@ function workerSitesOf(file) {
343
333
  if (address !== undefined) {
344
334
  found.push({
345
335
  literal: address.literal,
346
- platformNames: [callee.expression.expression, ...address.names],
336
+ platformNames: [callee.expression.expression],
337
+ url: address.url,
347
338
  });
348
339
  }
349
340
  }
@@ -354,10 +345,10 @@ function workerSitesOf(file) {
354
345
  return found;
355
346
  }
356
347
  /**
357
- * The workers one file addresses. A call's names must resolve to a symbol the platform
358
- * declares, which a file of the target may augment and no import brings in; a name only
359
- * the target declares is the target's own constructor or object, which addresses no
360
- * worker this rule knows. One batch per file that writes such a call.
348
+ * The workers one file addresses. A call's `Worker`, `SharedWorker` or `navigator` must
349
+ * resolve to a symbol the platform declares, which a file of the target may augment and no
350
+ * import brings in; a name only the target declares is the target's own constructor or
351
+ * object, which addresses no worker this rule knows. One batch per file that writes such a call.
361
352
  */
362
353
  function workersOf(project, file, files) {
363
354
  const sites = workerSitesOf(file);
@@ -365,7 +356,8 @@ function workersOf(project, file, files) {
365
356
  return [];
366
357
  }
367
358
  const names = sites.flatMap((site) => site.platformNames);
368
- const symbols = project.symbolsAt(names.map((name) => project.handle(name)));
359
+ const urls = sites.flatMap((site) => site.url ?? []);
360
+ const symbols = project.symbolsAt([...names, ...urls].map((name) => project.handle(name)));
369
361
  const platform = new Set();
370
362
  // A name the checker could not resolve is read as the platform's, so a worker it
371
363
  // stands on is rooted rather than reported.
@@ -381,10 +373,17 @@ function workersOf(project, file, files) {
381
373
  platform.add(name);
382
374
  }
383
375
  });
376
+ urls.forEach((url, index) => {
377
+ const symbol = symbols[names.length + index];
378
+ if (typeof symbol !== "object" || !hasOwnBody(project, symbol)) {
379
+ platform.add(url);
380
+ }
381
+ });
384
382
  const dir = dirnamePath(file.fileName);
385
383
  const found = [];
386
384
  for (const site of sites) {
387
- if (!site.platformNames.every((name) => platform.has(name))) {
385
+ if (!site.platformNames.every((name) => platform.has(name)) ||
386
+ (site.url !== undefined && !platform.has(site.url))) {
388
387
  continue;
389
388
  }
390
389
  for (const named of filesNamed(files, dir, site.literal)) {
@@ -393,73 +392,6 @@ function workersOf(project, file, files) {
393
392
  }
394
393
  return found;
395
394
  }
396
- /** Whether one call is `import.meta.glob(...)`. */
397
- function isMetaGlob(node) {
398
- if (!isCallExpression(node) || !isPropertyAccessExpression(node.expression)) {
399
- return false;
400
- }
401
- const { expression, name } = node.expression;
402
- return (isIdentifier(name) &&
403
- name.text === "glob" &&
404
- isMetaProperty(expression) &&
405
- expression.keywordToken === SyntaxKind.ImportKeyword);
406
- }
407
- /**
408
- * The files one file loads by a computed path, each with what exports: every own file
409
- * below the directory a relative literal start of an `import()` or `require()` argument
410
- * names, other than the calling file's own directory or one holding it, which would name
411
- * every sibling, and
412
- * every own file a relative literal glob of `import.meta.glob` matches, both read against
413
- * the calling file's directory, as a bundler's context module reads them.
414
- */
415
- function computedImportsOf(file, files) {
416
- const dir = dirnamePath(file.fileName);
417
- const found = [];
418
- const below = (prefix) => {
419
- const target = computedLoadDirectory(dir, prefix);
420
- if (target === undefined) {
421
- return;
422
- }
423
- for (const candidate of files.byName.values()) {
424
- if (candidate !== file && relativePath(target, candidate.fileName) !== undefined) {
425
- found.push({ file: candidate, rule: "computed-import", source: prefix, exports: true });
426
- }
427
- }
428
- };
429
- const globbed = (pattern) => {
430
- if (!isModuleRelative(pattern)) {
431
- return;
432
- }
433
- const expression = globExpression(resolvePath(dir, pattern));
434
- for (const candidate of files.byName.values()) {
435
- if (candidate !== file && expression.test(candidate.fileName)) {
436
- found.push({ file: candidate, rule: "computed-import", source: pattern, exports: true });
437
- }
438
- }
439
- };
440
- const visit = (node) => {
441
- if (isCallExpression(node)) {
442
- const [first] = node.arguments;
443
- const callee = node.expression;
444
- const loads = callee.kind === SyntaxKind.ImportKeyword ||
445
- (isIdentifier(callee) && callee.text === "require");
446
- if (loads && first !== undefined) {
447
- const prefix = leadingLiteral(first);
448
- if (prefix !== undefined) {
449
- below(prefix);
450
- }
451
- }
452
- else if (isMetaGlob(node) && first !== undefined) {
453
- for (const pattern of literalsOf(first) ?? []) {
454
- globbed(pattern);
455
- }
456
- }
457
- }
458
- node.forEachChild(visit);
459
- };
460
- file.forEachChild(visit);
461
- return found;
462
- }
463
395
  /**
464
396
  * Every file of one project the rules enter, in no particular order and possibly more
465
397
  * than once: a file two rules enter appears once per rule.
@@ -489,7 +421,6 @@ export function entryPoints(project, files, testFiles, host, targetRoot, parse,
489
421
  }
490
422
  }
491
423
  found.push(...workersOf(project, file, files));
492
- found.push(...computedImportsOf(file, files));
493
424
  }
494
425
  for (const { file, source } of htmlEntries(host, targetRoot, files, parse)) {
495
426
  found.push({ file, rule: "html-entry", source, exports: true });
@@ -3,7 +3,7 @@
3
3
  * file below the target root, whether or not a project includes it, and the files a
4
4
  * program holds by inclusion rather than by an import.
5
5
  */
6
- import { packageScope } from "./inventory.js";
6
+ import { packageScope } from "./load/package-scope.js";
7
7
  import { dirnamePath, joinPath, relativePath, resolvePath } from "./paths.js";
8
8
  import { renderRef } from "./ref.js";
9
9
  import { filesBelow } from "./fs/tree.js";
package/dist/src/graph.js CHANGED
@@ -58,7 +58,6 @@ const NAMES_A_CALLER = {
58
58
  worker: true,
59
59
  "html-entry": true,
60
60
  "workflow-step": true,
61
- "computed-import": true,
62
61
  "document-import": true,
63
62
  };
64
63
  /** Whether the sweep judges a declaration of one kind. */