@angular-modernizer/api 0.1.3 → 0.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/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/investigation/call-graph-builder.d.ts +95 -8
- package/dist/investigation/call-graph-builder.d.ts.map +1 -1
- package/dist/investigation/call-graph-builder.js +424 -81
- package/dist/investigation/call-graph-builder.js.map +1 -1
- package/dist/investigation/codebase-searcher.d.ts +68 -0
- package/dist/investigation/codebase-searcher.d.ts.map +1 -1
- package/dist/investigation/codebase-searcher.js +154 -10
- package/dist/investigation/codebase-searcher.js.map +1 -1
- package/dist/investigation/template-usage-finder.d.ts +64 -0
- package/dist/investigation/template-usage-finder.d.ts.map +1 -0
- package/dist/investigation/template-usage-finder.js +279 -0
- package/dist/investigation/template-usage-finder.js.map +1 -0
- package/dist/investigation/template-usage-scanner.d.ts +69 -0
- package/dist/investigation/template-usage-scanner.d.ts.map +1 -0
- package/dist/investigation/template-usage-scanner.js +375 -0
- package/dist/investigation/template-usage-scanner.js.map +1 -0
- package/dist/investigation/usage-finder.d.ts +51 -5
- package/dist/investigation/usage-finder.d.ts.map +1 -1
- package/dist/investigation/usage-finder.js +129 -36
- package/dist/investigation/usage-finder.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +16 -0
- package/src/investigation/call-graph-builder.ts +528 -103
- package/src/investigation/codebase-searcher.ts +240 -11
- package/src/investigation/template-usage-finder.ts +389 -0
- package/src/investigation/template-usage-scanner.ts +529 -0
- package/src/investigation/usage-finder.ts +194 -54
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @angular-modernizer/api - Template Usage Scanner
|
|
3
|
+
*
|
|
4
|
+
* Parses a single Angular template with `@angular/compiler` and reports
|
|
5
|
+
* where a selector, pipe, class member, or input/output binding is used.
|
|
6
|
+
* Positions are returned as offsets into the template text so callers can
|
|
7
|
+
* map them to external `.html` files or to inline `template:` literals.
|
|
8
|
+
*
|
|
9
|
+
* @remarks
|
|
10
|
+
* Pure function over template text; it knows nothing about ts-morph. The
|
|
11
|
+
* project-level lookup (which templates belong to which class, selector and
|
|
12
|
+
* pipe resolution) lives in `TemplateUsageFinder`.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```typescript
|
|
16
|
+
* const hits = scanTemplate('<app-user (saved)="onSave()"></app-user>', {
|
|
17
|
+
* selector: 'app-user',
|
|
18
|
+
* memberName: 'onSave',
|
|
19
|
+
* });
|
|
20
|
+
* // [{ kind: 'element', ... }, { kind: 'method-call', implicitReceiver: true, ... }]
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
import { CssSelector, ImplicitReceiver, PropertyRead, RecursiveAstVisitor, SelectorMatcher, TmplAstBoundAttribute, TmplAstBoundDeferredTrigger, TmplAstElement, TmplAstRecursiveVisitor, createCssSelectorFromNode, parseTemplate, tmplAstVisitAll, } from '@angular/compiler';
|
|
24
|
+
function isImplicit(receiver) {
|
|
25
|
+
return receiver instanceof ImplicitReceiver;
|
|
26
|
+
}
|
|
27
|
+
function createMatcher(selector) {
|
|
28
|
+
if (selector === undefined || selector.trim() === '') {
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
31
|
+
let parsed;
|
|
32
|
+
try {
|
|
33
|
+
parsed = CssSelector.parse(selector);
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
const matcher = new SelectorMatcher();
|
|
39
|
+
matcher.addSelectables(parsed, selector);
|
|
40
|
+
const elementNames = new Set(parsed.map((s) => s.element).filter((e) => e !== null));
|
|
41
|
+
return {
|
|
42
|
+
elementNames,
|
|
43
|
+
matches: (node) => {
|
|
44
|
+
let matched = false;
|
|
45
|
+
matcher.match(createCssSelectorFromNode(node), () => {
|
|
46
|
+
matched = true;
|
|
47
|
+
});
|
|
48
|
+
return matched;
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Builds the visitor classes on first use instead of at module load.
|
|
54
|
+
*
|
|
55
|
+
* Several packages replace `@angular/compiler` with a minimal Jest mock that
|
|
56
|
+
* lacks the visitor base classes; extending them at module scope would make
|
|
57
|
+
* every import of `@angular-modernizer/api` throw. When the base classes are
|
|
58
|
+
* missing, template scanning is disabled (returns no hits).
|
|
59
|
+
*/
|
|
60
|
+
function createHitCollectorClass() {
|
|
61
|
+
const compilerAvailable = typeof RecursiveAstVisitor === 'function' &&
|
|
62
|
+
typeof TmplAstRecursiveVisitor === 'function';
|
|
63
|
+
if (!compilerAvailable) {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Walks template expressions (bindings, interpolations, block expressions).
|
|
68
|
+
*/
|
|
69
|
+
class ExpressionHitCollector extends RecursiveAstVisitor {
|
|
70
|
+
query;
|
|
71
|
+
content;
|
|
72
|
+
hits;
|
|
73
|
+
callReceivers = new Set();
|
|
74
|
+
constructor(query, content, hits) {
|
|
75
|
+
super();
|
|
76
|
+
this.query = query;
|
|
77
|
+
this.content = content;
|
|
78
|
+
this.hits = hits;
|
|
79
|
+
}
|
|
80
|
+
nameOffset(span, name) {
|
|
81
|
+
const found = this.content.indexOf(name, span.start);
|
|
82
|
+
return found !== -1 && found < span.end ? found : span.start;
|
|
83
|
+
}
|
|
84
|
+
recordMember(kind, name, span, implicitReceiver) {
|
|
85
|
+
this.hits.push({
|
|
86
|
+
offset: this.nameOffset(span, name),
|
|
87
|
+
kind,
|
|
88
|
+
name,
|
|
89
|
+
implicitReceiver,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
checkCallee(receiver) {
|
|
93
|
+
const member = this.query.memberName;
|
|
94
|
+
if (member === undefined) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const isRead = receiver instanceof PropertyRead;
|
|
98
|
+
const readName = isRead ? receiver.name : undefined;
|
|
99
|
+
if (!isRead || readName !== member) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
this.callReceivers.add(receiver);
|
|
103
|
+
this.recordMember('method-call', member, receiver.nameSpan, isImplicit(receiver.receiver));
|
|
104
|
+
}
|
|
105
|
+
visitCall(ast, context) {
|
|
106
|
+
this.checkCallee(ast.receiver);
|
|
107
|
+
super.visitCall(ast, context);
|
|
108
|
+
}
|
|
109
|
+
visitSafeCall(ast, context) {
|
|
110
|
+
this.checkCallee(ast.receiver);
|
|
111
|
+
super.visitSafeCall(ast, context);
|
|
112
|
+
}
|
|
113
|
+
visitPropertyRead(ast, context) {
|
|
114
|
+
const isMember = ast.name === this.query.memberName && !this.callReceivers.has(ast);
|
|
115
|
+
if (isMember) {
|
|
116
|
+
this.recordMember('property-read', ast.name, ast.nameSpan, isImplicit(ast.receiver));
|
|
117
|
+
}
|
|
118
|
+
super.visitPropertyRead(ast, context);
|
|
119
|
+
}
|
|
120
|
+
visitSafePropertyRead(ast, context) {
|
|
121
|
+
if (ast.name === this.query.memberName) {
|
|
122
|
+
this.recordMember('property-read', ast.name, ast.nameSpan, false);
|
|
123
|
+
}
|
|
124
|
+
super.visitSafePropertyRead(ast, context);
|
|
125
|
+
}
|
|
126
|
+
visitPropertyWrite(ast, context) {
|
|
127
|
+
if (ast.name === this.query.memberName) {
|
|
128
|
+
this.recordMember('property-write', ast.name, ast.nameSpan, isImplicit(ast.receiver));
|
|
129
|
+
}
|
|
130
|
+
super.visitPropertyWrite(ast, context);
|
|
131
|
+
}
|
|
132
|
+
visitPipe(ast, context) {
|
|
133
|
+
if (ast.name === this.query.pipeName) {
|
|
134
|
+
this.hits.push({
|
|
135
|
+
offset: this.nameOffset(ast.nameSpan, ast.name),
|
|
136
|
+
kind: 'pipe',
|
|
137
|
+
name: ast.name,
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
super.visitPipe(ast, context);
|
|
141
|
+
}
|
|
142
|
+
scan(ast) {
|
|
143
|
+
if (ast === null || ast === undefined) {
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
ast.visit(this);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Walks the template node tree: selector matches, bindings, and every
|
|
151
|
+
* embedded expression (delegated to {@link ExpressionHitCollector}).
|
|
152
|
+
*/
|
|
153
|
+
class TemplateHitCollector extends TmplAstRecursiveVisitor {
|
|
154
|
+
query;
|
|
155
|
+
hits;
|
|
156
|
+
selectorMatcher;
|
|
157
|
+
bindingMatcher;
|
|
158
|
+
expressions;
|
|
159
|
+
constructor(query, content, hits) {
|
|
160
|
+
super();
|
|
161
|
+
this.query = query;
|
|
162
|
+
this.hits = hits;
|
|
163
|
+
this.selectorMatcher = createMatcher(query.selector);
|
|
164
|
+
this.bindingMatcher = createMatcher(query.bindingSelector);
|
|
165
|
+
this.expressions = new ExpressionHitCollector(query, content, hits);
|
|
166
|
+
}
|
|
167
|
+
selectorHit(node) {
|
|
168
|
+
const matcher = this.selectorMatcher;
|
|
169
|
+
if (!matcher?.matches(node)) {
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
const isElement = node instanceof TmplAstElement && matcher.elementNames.has(node.name);
|
|
173
|
+
const selector = this.query.selector ?? '';
|
|
174
|
+
this.hits.push({
|
|
175
|
+
offset: isElement
|
|
176
|
+
? node.startSourceSpan.start.offset + 1
|
|
177
|
+
: this.attributeOffset(node),
|
|
178
|
+
kind: isElement ? 'element' : 'attribute',
|
|
179
|
+
name: selector,
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
/** Offset of the first attribute/binding named in the selector, else the tag. */
|
|
183
|
+
attributeOffset(node) {
|
|
184
|
+
const attrNames = new Set();
|
|
185
|
+
try {
|
|
186
|
+
for (const s of CssSelector.parse(this.query.selector ?? '')) {
|
|
187
|
+
for (let i = 0; i < s.attrs.length; i += 2) {
|
|
188
|
+
const attr = s.attrs[i];
|
|
189
|
+
if (attr !== undefined) {
|
|
190
|
+
attrNames.add(attr);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
catch {
|
|
196
|
+
// fall through to the tag offset
|
|
197
|
+
}
|
|
198
|
+
const candidates = [
|
|
199
|
+
...node.attributes,
|
|
200
|
+
...node.inputs,
|
|
201
|
+
...node.outputs,
|
|
202
|
+
...('templateAttrs' in node ? node.templateAttrs : []),
|
|
203
|
+
];
|
|
204
|
+
const hit = candidates.find((a) => attrNames.has(a.name));
|
|
205
|
+
return hit?.keySpan?.start.offset ?? node.startSourceSpan.start.offset;
|
|
206
|
+
}
|
|
207
|
+
bindingAllowed(node) {
|
|
208
|
+
if (this.query.bindingName === undefined) {
|
|
209
|
+
return false;
|
|
210
|
+
}
|
|
211
|
+
return this.bindingMatcher === null || this.bindingMatcher.matches(node);
|
|
212
|
+
}
|
|
213
|
+
bindingHits(node) {
|
|
214
|
+
const name = this.query.bindingName;
|
|
215
|
+
if (name === undefined || !this.bindingAllowed(node)) {
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
for (const input of node.inputs) {
|
|
219
|
+
if (input.name === name) {
|
|
220
|
+
this.hits.push({
|
|
221
|
+
offset: input.keySpan.start.offset,
|
|
222
|
+
kind: 'input-binding',
|
|
223
|
+
name,
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
for (const attr of node.attributes) {
|
|
228
|
+
if (attr.name === name) {
|
|
229
|
+
this.hits.push({
|
|
230
|
+
offset: attr.keySpan?.start.offset ?? attr.sourceSpan.start.offset,
|
|
231
|
+
kind: 'input-binding',
|
|
232
|
+
name,
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
for (const output of node.outputs) {
|
|
237
|
+
if (output.name === name) {
|
|
238
|
+
this.hits.push({
|
|
239
|
+
offset: output.keySpan.start.offset,
|
|
240
|
+
kind: 'output-binding',
|
|
241
|
+
name,
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
visitElement(element) {
|
|
247
|
+
this.selectorHit(element);
|
|
248
|
+
this.bindingHits(element);
|
|
249
|
+
super.visitElement(element);
|
|
250
|
+
}
|
|
251
|
+
visitTemplate(template) {
|
|
252
|
+
this.selectorHit(template);
|
|
253
|
+
this.bindingHits(template);
|
|
254
|
+
// The base visitor skips `*directive="expr"` attributes.
|
|
255
|
+
for (const attr of template.templateAttrs) {
|
|
256
|
+
if (attr instanceof TmplAstBoundAttribute) {
|
|
257
|
+
this.expressions.scan(attr.value);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
super.visitTemplate(template);
|
|
261
|
+
}
|
|
262
|
+
visitBoundAttribute(attribute) {
|
|
263
|
+
this.expressions.scan(attribute.value);
|
|
264
|
+
}
|
|
265
|
+
visitBoundEvent(event) {
|
|
266
|
+
this.expressions.scan(event.handler);
|
|
267
|
+
}
|
|
268
|
+
visitBoundText(text) {
|
|
269
|
+
this.expressions.scan(text.value);
|
|
270
|
+
}
|
|
271
|
+
visitIfBlockBranch(block) {
|
|
272
|
+
this.expressions.scan(block.expression);
|
|
273
|
+
super.visitIfBlockBranch(block);
|
|
274
|
+
}
|
|
275
|
+
visitForLoopBlock(block) {
|
|
276
|
+
this.expressions.scan(block.expression);
|
|
277
|
+
this.expressions.scan(block.trackBy);
|
|
278
|
+
super.visitForLoopBlock(block);
|
|
279
|
+
}
|
|
280
|
+
visitSwitchBlock(block) {
|
|
281
|
+
this.expressions.scan(block.expression);
|
|
282
|
+
super.visitSwitchBlock(block);
|
|
283
|
+
}
|
|
284
|
+
visitSwitchBlockCase(block) {
|
|
285
|
+
this.expressions.scan(block.expression);
|
|
286
|
+
super.visitSwitchBlockCase(block);
|
|
287
|
+
}
|
|
288
|
+
visitDeferredTrigger(trigger) {
|
|
289
|
+
if (trigger instanceof TmplAstBoundDeferredTrigger) {
|
|
290
|
+
this.expressions.scan(trigger.value);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
return TemplateHitCollector;
|
|
295
|
+
}
|
|
296
|
+
let hitCollectorClass;
|
|
297
|
+
function getHitCollectorClass() {
|
|
298
|
+
if (hitCollectorClass === undefined) {
|
|
299
|
+
hitCollectorClass = createHitCollectorClass();
|
|
300
|
+
}
|
|
301
|
+
return hitCollectorClass;
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Cheap pre-check: can the template possibly contain a hit for `query`?
|
|
305
|
+
* Avoids parsing templates that do not mention any searched token.
|
|
306
|
+
*/
|
|
307
|
+
export function templateMayMatch(content, query) {
|
|
308
|
+
const tokens = [];
|
|
309
|
+
if (query.pipeName !== undefined) {
|
|
310
|
+
tokens.push(query.pipeName);
|
|
311
|
+
}
|
|
312
|
+
if (query.memberName !== undefined) {
|
|
313
|
+
tokens.push(query.memberName);
|
|
314
|
+
}
|
|
315
|
+
if (query.bindingName !== undefined) {
|
|
316
|
+
tokens.push(query.bindingName);
|
|
317
|
+
}
|
|
318
|
+
if (query.selector !== undefined) {
|
|
319
|
+
try {
|
|
320
|
+
for (const s of CssSelector.parse(query.selector)) {
|
|
321
|
+
if (s.element !== null && s.element !== '*') {
|
|
322
|
+
tokens.push(s.element);
|
|
323
|
+
}
|
|
324
|
+
for (let i = 0; i < s.attrs.length; i += 2) {
|
|
325
|
+
const attr = s.attrs[i];
|
|
326
|
+
if (attr !== undefined && attr !== '') {
|
|
327
|
+
tokens.push(attr);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
tokens.push(...s.classNames);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
catch {
|
|
334
|
+
return true;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
return tokens.some((t) => content.includes(t));
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Scans one template for usages described by `query`.
|
|
341
|
+
*
|
|
342
|
+
* @param content - Raw template text.
|
|
343
|
+
* @param query - What to look for.
|
|
344
|
+
* @returns Hits ordered by offset. Returns `[]` when the template cannot be
|
|
345
|
+
* parsed at all.
|
|
346
|
+
*/
|
|
347
|
+
export function scanTemplate(content, query) {
|
|
348
|
+
const Collector = getHitCollectorClass();
|
|
349
|
+
if (Collector === null || !templateMayMatch(content, query)) {
|
|
350
|
+
return [];
|
|
351
|
+
}
|
|
352
|
+
let nodes;
|
|
353
|
+
try {
|
|
354
|
+
nodes = parseTemplate(content, 'template.html', {
|
|
355
|
+
preserveWhitespaces: true,
|
|
356
|
+
}).nodes;
|
|
357
|
+
}
|
|
358
|
+
catch {
|
|
359
|
+
return [];
|
|
360
|
+
}
|
|
361
|
+
const hits = [];
|
|
362
|
+
tmplAstVisitAll(new Collector(query, content, hits), nodes);
|
|
363
|
+
const seen = new Set();
|
|
364
|
+
return hits
|
|
365
|
+
.filter((h) => {
|
|
366
|
+
const key = `${h.offset}:${h.kind}`;
|
|
367
|
+
if (seen.has(key)) {
|
|
368
|
+
return false;
|
|
369
|
+
}
|
|
370
|
+
seen.add(key);
|
|
371
|
+
return true;
|
|
372
|
+
})
|
|
373
|
+
.sort((a, b) => a.offset - b.offset);
|
|
374
|
+
}
|
|
375
|
+
//# sourceMappingURL=template-usage-scanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"template-usage-scanner.js","sourceRoot":"","sources":["../../src/investigation/template-usage-scanner.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,6 +9,14 @@
|
|
|
9
9
|
* Uses ts-morph `findReferences()` under the hood. The project must already have
|
|
10
10
|
* the relevant source files added before calling `findUsages`.
|
|
11
11
|
*
|
|
12
|
+
* Two additional sources close gaps that would otherwise produce a false
|
|
13
|
+
* "0 usages" all-clear:
|
|
14
|
+
* - `unresolved`: same-name identifiers whose symbol does not resolve (e.g. a
|
|
15
|
+
* class still used as a type after its import was removed, TS2304).
|
|
16
|
+
* - `template`: Angular template usages (component/directive selectors, pipe
|
|
17
|
+
* names, member reads/calls/bindings) in `templateUrl` files and inline
|
|
18
|
+
* templates, see `TemplateUsageFinder`.
|
|
19
|
+
*
|
|
12
20
|
* @example
|
|
13
21
|
* ```typescript
|
|
14
22
|
* const finder = new UsageFinder(project);
|
|
@@ -16,9 +24,17 @@
|
|
|
16
24
|
* // usages[0] → { file, line, col, snippet, usageType: 'read' }
|
|
17
25
|
* ```
|
|
18
26
|
*/
|
|
19
|
-
import type
|
|
20
|
-
|
|
21
|
-
|
|
27
|
+
import { type Project } from 'ts-morph';
|
|
28
|
+
import { type TemplateMatch } from './template-usage-finder.js';
|
|
29
|
+
import { type TemplateUsageKind } from './template-usage-scanner.js';
|
|
30
|
+
/**
|
|
31
|
+
* Classification of how a symbol is used at a given location.
|
|
32
|
+
*
|
|
33
|
+
* - `read` / `write` / `call`: resolved TypeScript references
|
|
34
|
+
* - `template`: usage inside an Angular template (see `templateKind`)
|
|
35
|
+
* - `unresolved`: same-name identifier whose symbol does not resolve
|
|
36
|
+
*/
|
|
37
|
+
export type UsageType = 'read' | 'write' | 'call' | 'template' | 'unresolved';
|
|
22
38
|
/** A single resolved symbol usage. */
|
|
23
39
|
export interface SymbolUsage {
|
|
24
40
|
/** Absolute file path containing the usage. */
|
|
@@ -31,12 +47,25 @@ export interface SymbolUsage {
|
|
|
31
47
|
snippet: string;
|
|
32
48
|
/** How the symbol is used at this location. */
|
|
33
49
|
usageType: UsageType;
|
|
50
|
+
/** Explanation for `unresolved` and unverified `template` usages. */
|
|
51
|
+
note?: string;
|
|
52
|
+
/** For `template` usages: what kind of template construct matched. */
|
|
53
|
+
templateKind?: TemplateUsageKind;
|
|
54
|
+
/**
|
|
55
|
+
* For `template` usages: `verified` when the hit certainly refers to the
|
|
56
|
+
* searched symbol, `template-unverified` for same-name matches that could
|
|
57
|
+
* not be tied to it.
|
|
58
|
+
*/
|
|
59
|
+
templateMatch?: TemplateMatch;
|
|
60
|
+
/** For `template` usages: the component whose template contains the hit. */
|
|
61
|
+
component?: string;
|
|
34
62
|
}
|
|
35
63
|
/** Options for narrowing `findUsages` results. */
|
|
36
64
|
export interface FindUsagesOptions {
|
|
37
65
|
/**
|
|
38
|
-
* Restrict
|
|
39
|
-
*
|
|
66
|
+
* Restrict reported usages to a single file (absolute path; a `.ts` source
|
|
67
|
+
* file or an external `.html` template). Declarations are still looked up
|
|
68
|
+
* across the whole project.
|
|
40
69
|
*/
|
|
41
70
|
file?: string;
|
|
42
71
|
/**
|
|
@@ -44,6 +73,10 @@ export interface FindUsagesOptions {
|
|
|
44
73
|
* When omitted, all usage types are returned.
|
|
45
74
|
*/
|
|
46
75
|
usageType?: UsageType;
|
|
76
|
+
/** Include Angular template usages. Defaults to `true`. */
|
|
77
|
+
includeTemplates?: boolean;
|
|
78
|
+
/** Include same-name identifiers that do not resolve to a symbol. Defaults to `true`. */
|
|
79
|
+
includeUnresolved?: boolean;
|
|
47
80
|
}
|
|
48
81
|
/**
|
|
49
82
|
* Finds all references to named symbols across a ts-morph Project.
|
|
@@ -62,6 +95,19 @@ export declare class UsageFinder {
|
|
|
62
95
|
* @returns Array of resolved usages, sorted by file path then line number.
|
|
63
96
|
*/
|
|
64
97
|
findUsages(symbol: string, options?: FindUsagesOptions): SymbolUsage[];
|
|
98
|
+
private findReferenceUsages;
|
|
99
|
+
/**
|
|
100
|
+
* Same-name identifiers whose symbol does not resolve. The language
|
|
101
|
+
* service cannot link them to any declaration, so `findReferences` never
|
|
102
|
+
* returns them; without this pass a removed import looks like "0 usages".
|
|
103
|
+
*/
|
|
104
|
+
private findUnresolvedUsages;
|
|
105
|
+
private findTemplateUsages;
|
|
106
|
+
/**
|
|
107
|
+
* Declaration-like nodes named `symbol`. Expressions that merely carry a
|
|
108
|
+
* name (`svc.getUser` property accesses) are not declarations and would
|
|
109
|
+
* make `findReferences` resolve their receiver instead.
|
|
110
|
+
*/
|
|
65
111
|
private findSymbolNodes;
|
|
66
112
|
private classifyUsage;
|
|
67
113
|
private deduplicate;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"usage-finder.d.ts","sourceRoot":"","sources":["../../src/investigation/usage-finder.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"usage-finder.d.ts","sourceRoot":"","sources":["../../src/investigation/usage-finder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAQ,KAAK,OAAO,EAAmB,MAAM,UAAU,CAAC;AAC/D,OAAO,EAEL,KAAK,aAAa,EACnB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,KAAK,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAErE;;;;;;GAMG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,GAAG,UAAU,GAAG,YAAY,CAAC;AAE9E,sCAAsC;AACtC,MAAM,WAAW,WAAW;IAC1B,+CAA+C;IAC/C,IAAI,EAAE,MAAM,CAAC;IAEb,2BAA2B;IAC3B,IAAI,EAAE,MAAM,CAAC;IAEb,6BAA6B;IAC7B,GAAG,EAAE,MAAM,CAAC;IAEZ,4CAA4C;IAC5C,OAAO,EAAE,MAAM,CAAC;IAEhB,+CAA+C;IAC/C,SAAS,EAAE,SAAS,CAAC;IAErB,qEAAqE;IACrE,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,sEAAsE;IACtE,YAAY,CAAC,EAAE,iBAAiB,CAAC;IAEjC;;;;OAIG;IACH,aAAa,CAAC,EAAE,aAAa,CAAC;IAE9B,4EAA4E;IAC5E,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,kDAAkD;AAClD,MAAM,WAAW,iBAAiB;IAChC;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;;OAGG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IAEtB,2DAA2D;IAC3D,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B,yFAAyF;IACzF,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;GAEG;AACH,qBAAa,WAAW;IAIV,OAAO,CAAC,QAAQ,CAAC,OAAO;IAHpC;;OAEG;gBAC0B,OAAO,EAAE,OAAO;IAE7C;;;;;;OAMG;IACH,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAsB,GAAG,WAAW,EAAE;IA8B1E,OAAO,CAAC,mBAAmB;IA0B3B;;;;OAIG;IACH,OAAO,CAAC,oBAAoB;IAqC5B,OAAO,CAAC,kBAAkB;IAgB1B;;;;OAIG;IACH,OAAO,CAAC,eAAe;IAuBvB,OAAO,CAAC,aAAa;IAoCrB,OAAO,CAAC,WAAW;CAWpB"}
|