@cplieger/deadset-ts 8.0.0-dev.16 → 8.0.0-dev.17

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 (131) hide show
  1. package/dist/src/alias-chain.js +0 -5
  2. package/dist/src/amd.js +81 -0
  3. package/dist/src/analysis.js +58 -22
  4. package/dist/src/augmentations.js +23 -24
  5. package/dist/src/bindings.js +382 -0
  6. package/dist/src/calls.js +25 -8
  7. package/dist/src/commands/tools.js +5 -9
  8. package/dist/src/component-files.js +3 -2
  9. package/dist/src/conformance-record.js +1 -1
  10. package/dist/src/consumers.js +6 -9
  11. package/dist/src/contextual-uses.js +1 -17
  12. package/dist/src/contract/config.generated.js +4 -1
  13. package/dist/src/contract/report.generated.js +6 -2
  14. package/dist/src/dependencies.js +25 -29
  15. package/dist/src/destructuring.js +1 -19
  16. package/dist/src/element-access.js +179 -164
  17. package/dist/src/entries/build-scripts.js +2 -2
  18. package/dist/src/entries/configuration-files.js +3 -7
  19. package/dist/src/entries/conventions.js +2 -2
  20. package/dist/src/entries/html-entries.js +7 -10
  21. package/dist/src/entries/mdx-entries.js +2 -2
  22. package/dist/src/entries/static-module.js +2 -1
  23. package/dist/src/facts.js +4 -4
  24. package/dist/src/findings/completion.js +40 -4
  25. package/dist/src/{implementations.js → findings/implementations.js} +3 -3
  26. package/dist/src/{in-operands.js → findings/in-operands.js} +2 -2
  27. package/dist/src/framework-lifecycle.js +41 -14
  28. package/dist/src/graph.js +12 -4
  29. package/dist/src/import-bindings.js +73 -28
  30. package/dist/src/index/sites.js +557 -0
  31. package/dist/src/indexed-access.js +523 -478
  32. package/dist/src/interface-satisfaction.js +1 -1
  33. package/dist/src/keyof-comparisons.js +124 -103
  34. package/dist/src/load/expected-module.js +2 -2
  35. package/dist/src/load/specifiers.js +2 -4
  36. package/dist/src/load/synthesize.js +5 -0
  37. package/dist/src/load/workspace-resolution.js +2 -2
  38. package/dist/src/matrix.js +6 -4
  39. package/dist/src/module-declarations.js +70 -85
  40. package/dist/src/overrides.js +134 -112
  41. package/dist/src/paths.js +46 -7
  42. package/dist/src/platform-calls.js +2 -2
  43. package/dist/src/platform-symbols.js +13 -19
  44. package/dist/src/references/read-rule.js +1 -0
  45. package/dist/src/references/read-rules.js +48 -0
  46. package/dist/src/references/sink.js +151 -0
  47. package/dist/src/references/sources.js +450 -0
  48. package/dist/src/references.js +110 -1285
  49. package/dist/src/roots/configured-declarations.js +3 -0
  50. package/dist/src/roots/root-set.js +1 -1
  51. package/dist/src/roots/unseen-loads.js +38 -10
  52. package/dist/src/serialization-contract.js +8 -3
  53. package/dist/src/stores.js +4 -2
  54. package/dist/src/sweep.js +25 -13
  55. package/dist/src/symbol-keys.js +89 -83
  56. package/dist/src/tests/file-class.js +76 -0
  57. package/dist/src/{outside-tests.js → tests/outside.js} +7 -7
  58. package/dist/src/{test-support.js → tests/support.js} +2 -11
  59. package/dist/src/type-parameter-reads.js +178 -139
  60. package/dist/src/unimplemented-callees.js +262 -242
  61. package/dist/src/verbs/analyze.js +3 -3
  62. package/dist/src/verbs/explain.js +50 -28
  63. package/dist/src/verbs/print-retained.js +2 -2
  64. package/jsr.json +1 -1
  65. package/package.json +2 -2
  66. package/src/alias-chain.ts +0 -7
  67. package/src/amd.ts +130 -0
  68. package/src/analysis.ts +86 -23
  69. package/src/augmentations.ts +41 -27
  70. package/src/bindings.ts +460 -0
  71. package/src/calls.ts +25 -7
  72. package/src/commands/tools.ts +5 -11
  73. package/src/component-files.ts +4 -2
  74. package/src/conformance-record.ts +1 -1
  75. package/src/consumers.ts +8 -11
  76. package/src/contextual-uses.ts +2 -22
  77. package/src/contract/config.generated.ts +4 -1
  78. package/src/contract/report.generated.ts +6 -2
  79. package/src/dependencies.ts +27 -28
  80. package/src/destructuring.ts +1 -31
  81. package/src/element-access.ts +188 -182
  82. package/src/entries/build-scripts.ts +2 -2
  83. package/src/entries/configuration-files.ts +11 -8
  84. package/src/entries/conventions.ts +2 -1
  85. package/src/entries/html-entries.ts +15 -14
  86. package/src/entries/mdx-entries.ts +2 -2
  87. package/src/entries/static-module.ts +2 -1
  88. package/src/facts.ts +5 -3
  89. package/src/findings/boundary.ts +2 -0
  90. package/src/findings/completion.ts +43 -4
  91. package/src/findings/emitter.ts +1 -1
  92. package/src/{implementations.ts → findings/implementations.ts} +4 -4
  93. package/src/{in-operands.ts → findings/in-operands.ts} +3 -3
  94. package/src/framework-lifecycle.ts +42 -14
  95. package/src/graph.ts +24 -6
  96. package/src/import-bindings.ts +98 -29
  97. package/src/index/sites.ts +781 -0
  98. package/src/indexed-access.ts +570 -527
  99. package/src/interface-satisfaction.ts +1 -1
  100. package/src/keyof-comparisons.ts +131 -116
  101. package/src/load/expected-module.ts +8 -2
  102. package/src/load/specifiers.ts +8 -5
  103. package/src/load/synthesize.ts +6 -0
  104. package/src/load/workspace-resolution.ts +9 -2
  105. package/src/matrix.ts +6 -3
  106. package/src/module-declarations.ts +74 -98
  107. package/src/overrides.ts +162 -134
  108. package/src/paths.ts +54 -8
  109. package/src/platform-calls.ts +3 -3
  110. package/src/platform-symbols.ts +11 -27
  111. package/src/references/read-rule.ts +60 -0
  112. package/src/references/read-rules.ts +55 -0
  113. package/src/references/sink.ts +213 -0
  114. package/src/references/sources.ts +632 -0
  115. package/src/references.ts +168 -1733
  116. package/src/report.ts +1 -1
  117. package/src/roots/configured-declarations.ts +3 -0
  118. package/src/roots/root-set.ts +1 -1
  119. package/src/roots/unseen-loads.ts +49 -11
  120. package/src/serialization-contract.ts +8 -3
  121. package/src/stores.ts +13 -2
  122. package/src/sweep.ts +37 -14
  123. package/src/symbol-keys.ts +102 -102
  124. package/src/tests/file-class.ts +118 -0
  125. package/src/{outside-tests.ts → tests/outside.ts} +16 -10
  126. package/src/{test-support.ts → tests/support.ts} +9 -20
  127. package/src/type-parameter-reads.ts +187 -158
  128. package/src/unimplemented-callees.ts +297 -280
  129. package/src/verbs/analyze.ts +3 -2
  130. package/src/verbs/explain.ts +74 -31
  131. package/src/verbs/print-retained.ts +2 -2
@@ -19,19 +19,25 @@ import {
19
19
  type Node,
20
20
  type SourceFile,
21
21
  } from "@typescript/native/ast";
22
- import { RESOLVED_EXTENSIONS, type ParseFile } from "./entries/configuration-files.ts";
23
- import { emittedFrom } from "./load/emit-map.ts";
24
- import type { Host } from "./host.ts";
25
- import type { Inventory } from "./inventory.ts";
26
- import { namesImported } from "./module-declarations.ts";
27
- import { dirnamePath, joinPath, normalizePath, queriedModulePath } from "./paths.ts";
28
- import { renderPosition } from "./position.ts";
29
- import { nameComponent } from "./ref.ts";
30
- import type { Reference } from "./references.ts";
22
+ import { RESOLVED_EXTENSIONS, type ParseFile } from "../entries/configuration-files.ts";
23
+ import { emittedFrom } from "../load/emit-map.ts";
24
+ import type { Host } from "../host.ts";
25
+ import type { Inventory } from "../inventory.ts";
26
+ import { namesImported } from "../import-bindings.ts";
27
+ import {
28
+ dirnamePath,
29
+ joinPath,
30
+ normalizePath,
31
+ queriedModulePath,
32
+ startsRelativePath,
33
+ } from "../paths.ts";
34
+ import { renderPosition } from "../position.ts";
35
+ import { nameComponent } from "../ref.ts";
36
+ import type { Reference } from "../references.ts";
31
37
 
32
38
  /** The paths below the target root one relative specifier may name, written path first. */
33
39
  function candidates(dir: string, specifier: string): readonly string[] {
34
- if (!specifier.startsWith("./") && !specifier.startsWith("../")) {
40
+ if (!startsRelativePath(specifier)) {
35
41
  return [];
36
42
  }
37
43
  const path = normalizePath(dir === "" ? specifier : `${dir}/${specifier}`);
@@ -6,11 +6,15 @@
6
6
  * test code.
7
7
  */
8
8
 
9
- import { CONVENTION_ROWS, TEST_LIBRARIES, TEST_LIBRARY_SCOPES } from "./entries/convention-rows.ts";
10
- import { packageOfSpecifier } from "./dependencies.ts";
11
- import type { InventorySymbol } from "./inventory.ts";
12
- import type { Reference } from "./references.ts";
13
- import type { Root } from "./roots/root-set.ts";
9
+ import {
10
+ CONVENTION_ROWS,
11
+ TEST_LIBRARIES,
12
+ TEST_LIBRARY_SCOPES,
13
+ } from "../entries/convention-rows.ts";
14
+ import { packageOfSpecifier } from "../dependencies.ts";
15
+ import type { InventorySymbol } from "../inventory.ts";
16
+ import type { Reference } from "../references.ts";
17
+ import type { Root } from "../roots/root-set.ts";
14
18
 
15
19
  /** The root kind that never takes a file out of test-support code: the skip only withholds. */
16
20
  const SKIP_ROOT = "type-error";
@@ -214,18 +218,3 @@ export function testSupportFiles(
214
218
  );
215
219
  return { support, testUsed: new Set([...onlyTests].filter((path) => !support.has(path))) };
216
220
  }
217
-
218
- /** The references with every one a test-support file makes counted as a test reference. */
219
- export function supportReferences(
220
- references: readonly Reference[],
221
- support: ReadonlySet<string>,
222
- ): readonly Reference[] {
223
- if (support.size === 0) {
224
- return references;
225
- }
226
- return references.map((reference) =>
227
- !reference.test && support.has(reference.position.path)
228
- ? { ...reference, test: true }
229
- : reference,
230
- );
231
- }
@@ -12,6 +12,7 @@ import {
12
12
  isIdentifier,
13
13
  isNewExpression,
14
14
  isPropertyAccessExpression,
15
+ isSourceFile,
15
16
  isTypeParameterDeclaration,
16
17
  SyntaxKind,
17
18
  type CallExpression,
@@ -21,12 +22,8 @@ import {
21
22
  type SourceFile,
22
23
  } from "@typescript/native/ast";
23
24
  import { SymbolFlags, type Type } from "@typescript/native/sync";
24
- import type { AliasChains } from "./alias-chain.ts";
25
- import { nodeKey, type Inventory } from "./inventory.ts";
26
- import { renderPosition } from "./position.ts";
27
- import { isAnswered } from "./query.ts";
28
- import type { Reference } from "./references.ts";
29
- import type { ProjectView } from "./session.ts";
25
+ import { isAnswered, UNANSWERED } from "./query.ts";
26
+ import type { Read as RuleRead, ReadRule } from "./references/read-rule.ts";
30
27
 
31
28
  /** How deep a parameter's type is matched against the type a call passes: `readonly T[]` is one level. */
32
29
  const MATCH_DEPTH = 3;
@@ -61,167 +58,199 @@ function assignedTo(access: PropertyAccessExpression): boolean {
61
58
  );
62
59
  }
63
60
 
64
- /**
65
- * The references the reads through type-parameter-typed values of one project's own files
66
- * make to the members of the types its calls pass, each made by the declaration holding
67
- * the read.
68
- */
69
- export function typeParameterReads<Brand>(
70
- project: ProjectView<Brand>,
71
- held: Inventory,
72
- chains: AliasChains,
73
- root: string,
74
- testFiles: ReadonlySet<string>,
75
- ): readonly Reference[] {
76
- const queries = project.queries;
77
- const reads: Read[] = [];
78
- const calls: (CallExpression | NewExpression)[] = [];
79
- for (const file of project.ownSourceFiles()) {
80
- const fileId = held.declarations.get(nodeKey(file, file));
81
- if (fileId === undefined) {
82
- continue;
61
+ /** Whether one node is written inside a declaration that declares type parameters, itself included. */
62
+ function inGeneric(node: Node): boolean {
63
+ for (let at = node; !isSourceFile(at); at = at.parent) {
64
+ if ((at as { readonly typeParameters?: readonly Node[] }).typeParameters !== undefined) {
65
+ return true;
83
66
  }
84
- const visit = (node: Node, from: string, generic: boolean): void => {
85
- const holder = held.declarations.get(nodeKey(file, node)) ?? from;
86
- const inside =
87
- generic ||
88
- (node as { readonly typeParameters?: readonly Node[] }).typeParameters !== undefined;
89
- if (
90
- inside &&
91
- isPropertyAccessExpression(node) &&
92
- isIdentifier(node.name) &&
93
- !assignedTo(node)
94
- ) {
95
- reads.push({ file, from: holder, access: node });
96
- }
97
- if (isCallExpression(node) || isNewExpression(node)) {
98
- calls.push(node);
99
- }
100
- node.forEachChild((child) => {
101
- visit(child, holder, inside);
102
- });
103
- };
104
- file.forEachChild((child) => {
105
- visit(child, fileId, false);
106
- });
107
- }
108
- if (reads.length === 0) {
109
- return [];
110
67
  }
68
+ return false;
69
+ }
111
70
 
112
- // The reads whose receiver the checker types as a type parameter, by the generic declaring it.
113
- const receivers = queries.typesAt(reads.map((read) => read.access.expression));
114
- const byGeneric = new Map<Generic, { read: Read; parameter: Type }[]>();
115
- reads.forEach((read, at) => {
116
- const type = receivers[at];
117
- if (type === undefined || !isAnswered(type) || !type.isTypeParameter()) {
118
- return;
119
- }
120
- const symbol = queries.symbolOfType(type);
121
- const declaration =
122
- symbol === undefined || !isAnswered(symbol)
123
- ? undefined
124
- : symbol.declarations
125
- .map((handle) => project.declarationAt(handle)?.node)
126
- .find((node) => node !== undefined && isTypeParameterDeclaration(node));
127
- const generic = declaration?.parent as Generic | undefined;
128
- if (generic !== undefined) {
129
- byGeneric.set(generic, [...(byGeneric.get(generic) ?? []), { read, parameter: type }]);
130
- }
131
- });
132
- if (byGeneric.size === 0) {
133
- return [];
134
- }
71
+ /**
72
+ * The reads the reads through type-parameter-typed values of a side's files make of the
73
+ * members of the types its calls pass, each made by the declaration holding the read. A
74
+ * question the checker leaves unanswered holds every member the read's name spells.
75
+ */
76
+ export const typeParameterReads: ReadRule = {
77
+ start() {
78
+ const reads: Read[] = [];
79
+ const calls: (CallExpression | NewExpression)[] = [];
80
+ return {
81
+ visit(node, { file, from }) {
82
+ if (
83
+ isPropertyAccessExpression(node) &&
84
+ isIdentifier(node.name) &&
85
+ !assignedTo(node) &&
86
+ inGeneric(node)
87
+ ) {
88
+ reads.push({ file, from, access: node });
89
+ }
90
+ if (isCallExpression(node) || isNewExpression(node)) {
91
+ calls.push(node);
92
+ }
93
+ },
94
+ reads({ project, chains }) {
95
+ const out: RuleRead[] = [];
96
+ if (reads.length === 0) {
97
+ return out;
98
+ }
99
+ const queries = project.queries;
100
+ const hold = (read: Read): void => {
101
+ out.push({ kind: "held", from: read.from, names: [read.access.name.text] });
102
+ };
103
+ // The reads whose receiver the checker types as a type parameter, by the generic declaring it.
104
+ const receivers = queries.typesAt(reads.map((read) => read.access.expression));
105
+ const byGeneric = new Map<Generic, { read: Read; parameter: Type }[]>();
106
+ reads.forEach((read, at) => {
107
+ const type = receivers[at];
108
+ if (type === UNANSWERED) {
109
+ hold(read);
110
+ return;
111
+ }
112
+ if (type?.isTypeParameter() !== true) {
113
+ return;
114
+ }
115
+ const symbol = queries.symbolOfType(type);
116
+ if (symbol === UNANSWERED) {
117
+ hold(read);
118
+ return;
119
+ }
120
+ const declaration =
121
+ symbol === undefined
122
+ ? undefined
123
+ : symbol.declarations
124
+ .map((handle) => project.declarationAt(handle)?.node)
125
+ .find((node) => node !== undefined && isTypeParameterDeclaration(node));
126
+ const generic = declaration?.parent as Generic | undefined;
127
+ if (generic !== undefined) {
128
+ byGeneric.set(generic, [...(byGeneric.get(generic) ?? []), { read, parameter: type }]);
129
+ }
130
+ });
131
+ if (byGeneric.size === 0) {
132
+ return out;
133
+ }
135
134
 
136
- /** The types `instantiated` holds where `declared` holds `parameter`, matched part for part. */
137
- const passedFor = (
138
- parameter: Type,
139
- declared: Type,
140
- instantiated: Type,
141
- depth: number,
142
- ): readonly Type[] => {
143
- if (declared.id === parameter.id) {
144
- return [instantiated];
145
- }
146
- if (depth >= MATCH_DEPTH) {
147
- return [];
148
- }
149
- const a = queries.typeArguments(declared);
150
- const b = queries.typeArguments(instantiated);
151
- if (!isAnswered(a) || !isAnswered(b) || a.length !== b.length) {
152
- return [];
153
- }
154
- return a.flatMap((one, at) => {
155
- const other = b[at];
156
- return other === undefined ? [] : passedFor(parameter, one, other, depth + 1);
157
- });
158
- };
135
+ /** The types `instantiated` holds where `declared` holds `parameter`, matched part for part. */
136
+ const passedFor = (
137
+ read: Read,
138
+ parameter: Type,
139
+ declared: Type,
140
+ instantiated: Type,
141
+ depth: number,
142
+ ): readonly Type[] => {
143
+ if (declared.id === parameter.id) {
144
+ return [instantiated];
145
+ }
146
+ if (depth >= MATCH_DEPTH) {
147
+ return [];
148
+ }
149
+ const a = queries.typeArguments(declared);
150
+ const b = queries.typeArguments(instantiated);
151
+ if (!isAnswered(a) || !isAnswered(b)) {
152
+ hold(read);
153
+ return [];
154
+ }
155
+ if (a.length !== b.length) {
156
+ return [];
157
+ }
158
+ return a.flatMap((one, at) => {
159
+ const other = b[at];
160
+ return other === undefined ? [] : passedFor(read, parameter, one, other, depth + 1);
161
+ });
162
+ };
159
163
 
160
- // Only a call spelling a generic's name is resolved: one request each.
161
- const spelled = new Set([...byGeneric.keys()].flatMap((generic) => nameOf(generic) ?? []));
162
- const found = new Map<string, Reference>();
163
- for (const call of calls) {
164
- const callee = call.expression;
165
- const written = isIdentifier(callee)
166
- ? callee.text
167
- : isPropertyAccessExpression(callee) && isIdentifier(callee.name)
168
- ? callee.name.text
169
- : undefined;
170
- if (written === undefined || !spelled.has(written)) {
171
- continue;
172
- }
173
- const resolved = queries.resolvedSignature(call);
174
- if (resolved === undefined || !isAnswered(resolved) || resolved.declaration === undefined) {
175
- continue;
176
- }
177
- const generic = project.declarationAt(resolved.declaration)?.node as Generic | undefined;
178
- const pending = generic === undefined ? undefined : byGeneric.get(generic);
179
- const declared = pending === undefined ? undefined : queries.genericOf(resolved);
180
- if (pending === undefined || declared === undefined || !isAnswered(declared)) {
181
- continue;
182
- }
183
- const count = (generic?.parameters ?? []).length;
184
- for (const { read, parameter } of pending) {
185
- const passed: Type[] = [];
186
- for (let at = 0; at < count; at += 1) {
187
- const own = queries.parameterType(declared, at);
188
- const given = queries.typeAtPosition(resolved, at);
189
- if (own !== undefined && isAnswered(own) && isAnswered(given)) {
190
- passed.push(...passedFor(parameter, own, given, 0));
164
+ // Only a call spelling a generic's name is resolved: one request each.
165
+ const bySpelling = new Map<string, Read[]>();
166
+ for (const [generic, pending] of byGeneric) {
167
+ const name = nameOf(generic);
168
+ if (name !== undefined) {
169
+ bySpelling.set(name, [
170
+ ...(bySpelling.get(name) ?? []),
171
+ ...pending.map((one) => one.read),
172
+ ]);
173
+ }
191
174
  }
192
- }
193
- const name = read.access.name.text;
194
- const position = renderPosition(read.file, root, read.access.name.getStart());
195
- for (const type of passed) {
196
- const parts = type.isUnionType() ? queries.constituents(type) : [type];
197
- for (const part of isAnswered(parts) ? parts : []) {
198
- const owner = queries.symbolOfType(part);
199
- if (
200
- !isAnswered(owner) ||
201
- owner === undefined ||
202
- (owner.flags & SymbolFlags.Class) !== 0
203
- ) {
175
+ const found = new Map<string, RuleRead>();
176
+ for (const call of calls) {
177
+ const callee = call.expression;
178
+ const written = isIdentifier(callee)
179
+ ? callee.text
180
+ : isPropertyAccessExpression(callee) && isIdentifier(callee.name)
181
+ ? callee.name.text
182
+ : undefined;
183
+ const spelledBy = written === undefined ? undefined : bySpelling.get(written);
184
+ if (spelledBy === undefined) {
204
185
  continue;
205
186
  }
206
- const properties = queries.propertiesOf(part);
207
- for (const property of isAnswered(properties) ? properties : []) {
208
- if (property.name !== name) {
209
- continue;
187
+ const resolved = queries.resolvedSignature(call);
188
+ if (resolved === UNANSWERED) {
189
+ spelledBy.forEach(hold);
190
+ continue;
191
+ }
192
+ if (resolved?.declaration === undefined) {
193
+ continue;
194
+ }
195
+ const generic = project.declarationAt(resolved.declaration)?.node as Generic | undefined;
196
+ const pending = generic === undefined ? undefined : byGeneric.get(generic);
197
+ const declared = pending === undefined ? undefined : queries.genericOf(resolved);
198
+ if (declared === UNANSWERED) {
199
+ pending?.forEach((one) => {
200
+ hold(one.read);
201
+ });
202
+ continue;
203
+ }
204
+ if (pending === undefined || declared === undefined) {
205
+ continue;
206
+ }
207
+ const count = (generic?.parameters ?? []).length;
208
+ for (const { read, parameter } of pending) {
209
+ const passed: Type[] = [];
210
+ for (let at = 0; at < count; at += 1) {
211
+ const own = queries.parameterType(declared, at);
212
+ const given = queries.typeAtPosition(resolved, at);
213
+ if (own === UNANSWERED || given === UNANSWERED) {
214
+ hold(read);
215
+ } else if (own !== undefined) {
216
+ passed.push(...passedFor(read, parameter, own, given, 0));
217
+ }
210
218
  }
211
- for (const to of chains.declarationsOf(property)) {
212
- found.set(`${read.from}\u0000${to}\u0000${String(read.access.name.pos)}`, {
213
- from: read.from,
214
- to,
215
- position,
216
- use: "read",
217
- resolution: "batch",
218
- test: testFiles.has(position.path),
219
- });
219
+ const name = read.access.name.text;
220
+ for (const type of passed) {
221
+ const parts = type.isUnionType() ? queries.constituents(type) : [type];
222
+ for (const part of isAnswered(parts) ? parts : [type]) {
223
+ const owner = queries.symbolOfType(part);
224
+ const properties = queries.propertiesOf(part);
225
+ if (owner === UNANSWERED || properties === UNANSWERED) {
226
+ hold(read);
227
+ continue;
228
+ }
229
+ if (owner === undefined || (owner.flags & SymbolFlags.Class) !== 0) {
230
+ continue;
231
+ }
232
+ for (const property of properties) {
233
+ if (property.name !== name) {
234
+ continue;
235
+ }
236
+ for (const to of chains.declarationsOf(property)) {
237
+ found.set(`${read.from}\u0000${to}\u0000${String(read.access.name.pos)}`, {
238
+ kind: "named",
239
+ from: read.from,
240
+ to,
241
+ file: read.file,
242
+ at: read.access.name,
243
+ use: "read",
244
+ via: "batch",
245
+ });
246
+ }
247
+ }
248
+ }
220
249
  }
221
250
  }
222
251
  }
223
- }
224
- }
225
- }
226
- return [...found.values()];
227
- }
252
+ return [...out, ...found.values()];
253
+ },
254
+ };
255
+ },
256
+ };