@openrewrite/rewrite 8.62.4 → 8.62.6

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 (110) hide show
  1. package/dist/java/tree.d.ts +12 -6
  2. package/dist/java/tree.d.ts.map +1 -1
  3. package/dist/java/tree.js +12 -5
  4. package/dist/java/tree.js.map +1 -1
  5. package/dist/java/type.d.ts +2 -0
  6. package/dist/java/type.d.ts.map +1 -1
  7. package/dist/java/type.js +12 -0
  8. package/dist/java/type.js.map +1 -1
  9. package/dist/java/visitor.d.ts +8 -0
  10. package/dist/java/visitor.d.ts.map +1 -1
  11. package/dist/java/visitor.js +23 -1
  12. package/dist/java/visitor.js.map +1 -1
  13. package/dist/javascript/index.d.ts +3 -0
  14. package/dist/javascript/index.d.ts.map +1 -1
  15. package/dist/javascript/index.js +3 -0
  16. package/dist/javascript/index.js.map +1 -1
  17. package/dist/javascript/method-matcher.d.ts +16 -0
  18. package/dist/javascript/method-matcher.d.ts.map +1 -0
  19. package/dist/javascript/method-matcher.js +222 -0
  20. package/dist/javascript/method-matcher.js.map +1 -0
  21. package/dist/javascript/parser.js +1 -1
  22. package/dist/javascript/parser.js.map +1 -1
  23. package/dist/javascript/preconditions.d.ts +6 -0
  24. package/dist/javascript/preconditions.d.ts.map +1 -0
  25. package/dist/javascript/preconditions.js +58 -0
  26. package/dist/javascript/preconditions.js.map +1 -0
  27. package/dist/javascript/remove-import.d.ts +56 -0
  28. package/dist/javascript/remove-import.d.ts.map +1 -0
  29. package/dist/javascript/remove-import.js +715 -0
  30. package/dist/javascript/remove-import.js.map +1 -0
  31. package/dist/javascript/rpc.js +2 -2
  32. package/dist/javascript/rpc.js.map +1 -1
  33. package/dist/javascript/search/index.d.ts +3 -0
  34. package/dist/javascript/search/index.d.ts.map +1 -0
  35. package/dist/javascript/search/index.js +19 -0
  36. package/dist/javascript/search/index.js.map +1 -0
  37. package/dist/javascript/search/uses-method.d.ts +8 -0
  38. package/dist/javascript/search/uses-method.d.ts.map +1 -0
  39. package/dist/javascript/search/uses-method.js +35 -0
  40. package/dist/javascript/search/uses-method.js.map +1 -0
  41. package/dist/javascript/search/uses-type.d.ts +8 -0
  42. package/dist/javascript/search/uses-type.d.ts.map +1 -0
  43. package/dist/javascript/search/uses-type.js +71 -0
  44. package/dist/javascript/search/uses-type.js.map +1 -0
  45. package/dist/javascript/templating.d.ts +1 -1
  46. package/dist/javascript/templating.d.ts.map +1 -1
  47. package/dist/javascript/templating.js +1 -1
  48. package/dist/javascript/templating.js.map +1 -1
  49. package/dist/javascript/tree.d.ts +3 -3
  50. package/dist/javascript/tree.d.ts.map +1 -1
  51. package/dist/javascript/tree.js +28 -0
  52. package/dist/javascript/tree.js.map +1 -1
  53. package/dist/javascript/type-mapping.d.ts +4 -0
  54. package/dist/javascript/type-mapping.d.ts.map +1 -1
  55. package/dist/javascript/type-mapping.js +92 -46
  56. package/dist/javascript/type-mapping.js.map +1 -1
  57. package/dist/javascript/visitor.js +1 -1
  58. package/dist/javascript/visitor.js.map +1 -1
  59. package/dist/print.d.ts +1 -0
  60. package/dist/print.d.ts.map +1 -1
  61. package/dist/print.js +6 -0
  62. package/dist/print.js.map +1 -1
  63. package/dist/rpc/rewrite-rpc.d.ts +1 -1
  64. package/dist/rpc/rewrite-rpc.d.ts.map +1 -1
  65. package/dist/rpc/rewrite-rpc.js +0 -3
  66. package/dist/rpc/rewrite-rpc.js.map +1 -1
  67. package/dist/search/index.d.ts +2 -0
  68. package/dist/search/index.d.ts.map +1 -0
  69. package/dist/search/index.js +18 -0
  70. package/dist/search/index.js.map +1 -0
  71. package/dist/search/is-source-file.d.ts +8 -0
  72. package/dist/search/is-source-file.d.ts.map +1 -0
  73. package/dist/search/is-source-file.js +70 -0
  74. package/dist/search/is-source-file.js.map +1 -0
  75. package/dist/test/rewrite-test.d.ts.map +1 -1
  76. package/dist/test/rewrite-test.js +3 -0
  77. package/dist/test/rewrite-test.js.map +1 -1
  78. package/dist/util.d.ts +1 -0
  79. package/dist/util.d.ts.map +1 -1
  80. package/dist/util.js +13 -0
  81. package/dist/util.js.map +1 -1
  82. package/dist/version.txt +1 -1
  83. package/dist/visitor.d.ts +1 -1
  84. package/dist/visitor.d.ts.map +1 -1
  85. package/dist/visitor.js +3 -2
  86. package/dist/visitor.js.map +1 -1
  87. package/package.json +3 -1
  88. package/src/java/tree.ts +19 -11
  89. package/src/java/type.ts +14 -0
  90. package/src/java/visitor.ts +28 -8
  91. package/src/javascript/index.ts +4 -0
  92. package/src/javascript/method-matcher.ts +250 -0
  93. package/src/javascript/parser.ts +1 -1
  94. package/src/javascript/preconditions.ts +40 -0
  95. package/src/javascript/remove-import.ts +780 -0
  96. package/src/javascript/rpc.ts +2 -2
  97. package/src/javascript/search/index.ts +2 -0
  98. package/src/javascript/search/uses-method.ts +21 -0
  99. package/src/javascript/search/uses-type.ts +27 -0
  100. package/src/javascript/templating.ts +4 -3
  101. package/src/javascript/tree.ts +47 -3
  102. package/src/javascript/type-mapping.ts +113 -50
  103. package/src/javascript/visitor.ts +125 -125
  104. package/src/print.ts +9 -3
  105. package/src/rpc/rewrite-rpc.ts +1 -4
  106. package/src/search/index.ts +1 -0
  107. package/src/search/is-source-file.ts +26 -0
  108. package/src/test/rewrite-test.ts +4 -1
  109. package/src/util.ts +19 -4
  110. package/src/visitor.ts +3 -3
@@ -0,0 +1,715 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.RemoveImport = void 0;
13
+ exports.maybeRemoveImport = maybeRemoveImport;
14
+ const visitor_1 = require("./visitor");
15
+ const java_1 = require("../java");
16
+ const tree_1 = require("./tree");
17
+ const util_1 = require("../util");
18
+ /**
19
+ * @param visitor The visitor to add the import removal to
20
+ * @param target Either the module name (e.g., 'fs') to remove specific members from,
21
+ * or the name of the import to remove entirely
22
+ * @param member Optionally, the specific member to remove from the import.
23
+ * If not specified, removes the import matching `target`
24
+ */
25
+ function maybeRemoveImport(visitor, target, member) {
26
+ for (const v of visitor.afterVisit || []) {
27
+ if (v instanceof RemoveImport && v.target === target && v.member === member) {
28
+ return;
29
+ }
30
+ }
31
+ visitor.afterVisit.push(new RemoveImport(target, member));
32
+ }
33
+ class RemoveImport extends visitor_1.JavaScriptVisitor {
34
+ /**
35
+ * @param target Either the module name (e.g., 'fs') to remove specific members from,
36
+ * or the name of the import to remove entirely
37
+ * @param member Optionally, the specific member to remove from the import.
38
+ * If not specified, removes the import matching `target`
39
+ */
40
+ constructor(target, member) {
41
+ super();
42
+ this.target = target;
43
+ this.member = member;
44
+ }
45
+ /**
46
+ * Generic helper to filter elements from a RightPadded array while preserving formatting.
47
+ * When removing elements, the prefix from the first removed element is applied to the
48
+ * first remaining element to maintain proper spacing.
49
+ */
50
+ filterElementsWithPrefixPreservation(elements, shouldKeep, updatePrefix, _p) {
51
+ return __awaiter(this, void 0, void 0, function* () {
52
+ const filtered = [];
53
+ let removedPrefix;
54
+ for (const elem of elements) {
55
+ if (elem.element && shouldKeep(elem.element)) {
56
+ // If we removed the previous element and this is the first kept element,
57
+ // apply the removed element's prefix to maintain formatting
58
+ if (removedPrefix && filtered.length === 0) {
59
+ const updatedElement = yield updatePrefix(elem.element, removedPrefix);
60
+ filtered.push(Object.assign(Object.assign({}, elem), { element: updatedElement }));
61
+ removedPrefix = undefined;
62
+ }
63
+ else {
64
+ filtered.push(elem);
65
+ }
66
+ }
67
+ else if (elem.element) {
68
+ // Store the prefix of the first removed element
69
+ if (filtered.length === 0 && !removedPrefix) {
70
+ removedPrefix = elem.element.prefix;
71
+ }
72
+ }
73
+ else {
74
+ // Keep non-element entries (shouldn't happen but be safe)
75
+ filtered.push(elem);
76
+ }
77
+ }
78
+ return {
79
+ filtered,
80
+ allRemoved: filtered.length === 0
81
+ };
82
+ });
83
+ }
84
+ /**
85
+ * Helper to update an import clause by removing specific bindings
86
+ */
87
+ updateImportClause(jsImport, importClause, updateFn, p) {
88
+ return __awaiter(this, void 0, void 0, function* () {
89
+ return this.produceJavaScript(jsImport, p, (draft) => __awaiter(this, void 0, void 0, function* () {
90
+ if (draft.importClause) {
91
+ draft.importClause = yield this.produceJavaScript(importClause, p, (clauseDraft) => __awaiter(this, void 0, void 0, function* () { return updateFn(clauseDraft); }));
92
+ }
93
+ }));
94
+ });
95
+ }
96
+ visitJsCompilationUnit(compilationUnit, p) {
97
+ return __awaiter(this, void 0, void 0, function* () {
98
+ // First, collect all used identifiers in the file
99
+ const usedIdentifiers = new Set();
100
+ const usedTypes = new Set();
101
+ // Traverse the AST to collect used identifiers
102
+ yield this.collectUsedIdentifiers(compilationUnit, usedIdentifiers, usedTypes);
103
+ // Now process imports with knowledge of what's used
104
+ return this.produceJavaScript(compilationUnit, p, (draft) => __awaiter(this, void 0, void 0, function* () {
105
+ let nextStatementPrefix;
106
+ draft.statements = yield (0, util_1.mapAsync)(compilationUnit.statements, (stmt, index) => __awaiter(this, void 0, void 0, function* () {
107
+ const statement = stmt.element;
108
+ // Handle ES6 imports
109
+ if ((statement === null || statement === void 0 ? void 0 : statement.kind) === tree_1.JS.Kind.Import) {
110
+ const jsImport = statement;
111
+ const result = yield this.processImport(jsImport, usedIdentifiers, usedTypes, p);
112
+ if (result === undefined) {
113
+ // Store the prefix for the next statement to avoid leaving blank lines
114
+ if (index < compilationUnit.statements.length - 1) {
115
+ const nextStmt = compilationUnit.statements[index + 1];
116
+ if (nextStmt === null || nextStmt === void 0 ? void 0 : nextStmt.element) {
117
+ nextStatementPrefix = jsImport.prefix;
118
+ }
119
+ }
120
+ // Remove the entire import
121
+ return undefined;
122
+ }
123
+ return Object.assign(Object.assign({}, stmt), { element: result });
124
+ }
125
+ // Handle CommonJS require statements
126
+ // Note: const fs = require() comes as J.VariableDeclarations, not ScopedVariableDeclarations
127
+ if ((statement === null || statement === void 0 ? void 0 : statement.kind) === java_1.J.Kind.VariableDeclarations) {
128
+ const varDecl = statement;
129
+ const result = yield this.processRequireFromVarDecls(varDecl, usedIdentifiers, p);
130
+ if (result === undefined) {
131
+ // Store the prefix for the next statement to avoid leaving blank lines
132
+ if (index < compilationUnit.statements.length - 1) {
133
+ const nextStmt = compilationUnit.statements[index + 1];
134
+ if (nextStmt === null || nextStmt === void 0 ? void 0 : nextStmt.element) {
135
+ nextStatementPrefix = varDecl.prefix;
136
+ }
137
+ }
138
+ // Remove the entire require statement
139
+ return undefined;
140
+ }
141
+ return Object.assign(Object.assign({}, stmt), { element: result });
142
+ }
143
+ // Apply stored prefix if this statement follows a removed import
144
+ if (nextStatementPrefix && statement) {
145
+ const updatedStatement = yield this.visit(statement, p);
146
+ if (updatedStatement) {
147
+ updatedStatement.prefix = nextStatementPrefix;
148
+ nextStatementPrefix = undefined;
149
+ return Object.assign(Object.assign({}, stmt), { element: updatedStatement });
150
+ }
151
+ }
152
+ return stmt;
153
+ }));
154
+ // Filter out undefined (removed) statements
155
+ draft.statements = draft.statements.filter(s => s !== undefined);
156
+ draft.eof = yield this.visitSpace(compilationUnit.eof, p);
157
+ }));
158
+ });
159
+ }
160
+ processImport(jsImport, usedIdentifiers, usedTypes, p) {
161
+ return __awaiter(this, void 0, void 0, function* () {
162
+ // Check if this import is from the target module
163
+ if (!this.isTargetModule(jsImport)) {
164
+ return jsImport;
165
+ }
166
+ const importClause = jsImport.importClause;
167
+ if (!importClause) {
168
+ // Side-effect import like: import 'module'
169
+ if (this.member === '*') {
170
+ return undefined; // Remove the entire import
171
+ }
172
+ return jsImport;
173
+ }
174
+ // Process default import
175
+ if (importClause.name) {
176
+ const defaultName = importClause.name.element;
177
+ if (defaultName && defaultName.kind === java_1.J.Kind.Identifier) {
178
+ const identifier = defaultName;
179
+ const name = identifier.simpleName;
180
+ if (this.shouldRemoveImport(name, usedIdentifiers, usedTypes)) {
181
+ // If there are no named imports, remove the entire import
182
+ if (!importClause.namedBindings) {
183
+ return undefined;
184
+ }
185
+ // Otherwise, just remove the default import
186
+ return this.updateImportClause(jsImport, importClause, draft => {
187
+ draft.name = undefined;
188
+ }, p);
189
+ }
190
+ }
191
+ }
192
+ // Process named imports
193
+ if (importClause.namedBindings) {
194
+ const namedBindings = importClause.namedBindings;
195
+ // Handle namespace import: import * as X from 'module'
196
+ if (namedBindings.kind === java_1.J.Kind.Identifier) {
197
+ const identifier = namedBindings;
198
+ const name = identifier.simpleName;
199
+ if (this.shouldRemoveImport(name, usedIdentifiers, usedTypes)) {
200
+ // If there's no default import, remove the entire import
201
+ if (!importClause.name) {
202
+ return undefined;
203
+ }
204
+ // Otherwise, just remove the namespace import
205
+ return this.updateImportClause(jsImport, importClause, draft => {
206
+ draft.namedBindings = undefined;
207
+ }, p);
208
+ }
209
+ }
210
+ else if (namedBindings.kind === tree_1.JS.Kind.Alias) {
211
+ // Handle import * as X from 'module' - represented as Alias with propertyName = "*"
212
+ const alias = namedBindings;
213
+ const aliasName = alias.alias.simpleName;
214
+ if (this.shouldRemoveImport(aliasName, usedIdentifiers, usedTypes)) {
215
+ // If there's no default import, remove the entire import
216
+ if (!importClause.name) {
217
+ return undefined;
218
+ }
219
+ // Otherwise, just remove the namespace import
220
+ return this.updateImportClause(jsImport, importClause, draft => {
221
+ draft.namedBindings = undefined;
222
+ }, p);
223
+ }
224
+ }
225
+ // Handle named imports: import { a, b } from 'module'
226
+ if (namedBindings.kind === tree_1.JS.Kind.NamedImports) {
227
+ const namedImports = namedBindings;
228
+ const updatedImports = yield this.processNamedImports(namedImports, usedIdentifiers, usedTypes, p);
229
+ if (updatedImports === undefined) {
230
+ // All named imports were removed
231
+ if (!importClause.name) {
232
+ // No default import either, remove the entire import
233
+ return undefined;
234
+ }
235
+ // Keep the import with just the default import
236
+ return this.updateImportClause(jsImport, importClause, draft => {
237
+ draft.namedBindings = undefined;
238
+ }, p);
239
+ }
240
+ else if (updatedImports !== namedImports) {
241
+ // Some named imports were removed
242
+ return this.updateImportClause(jsImport, importClause, draft => {
243
+ draft.namedBindings = updatedImports;
244
+ }, p);
245
+ }
246
+ }
247
+ }
248
+ return jsImport;
249
+ });
250
+ }
251
+ processNamedImports(namedImports, usedIdentifiers, usedTypes, p) {
252
+ return __awaiter(this, void 0, void 0, function* () {
253
+ const { filtered, allRemoved } = yield this.filterElementsWithPrefixPreservation(namedImports.elements.elements, (elem) => {
254
+ if (elem.kind === tree_1.JS.Kind.ImportSpecifier) {
255
+ const importName = this.getImportName(elem);
256
+ return !this.shouldRemoveImport(importName, usedIdentifiers, usedTypes);
257
+ }
258
+ return true; // Keep non-ImportSpecifier elements
259
+ }, (elem, prefix) => __awaiter(this, void 0, void 0, function* () {
260
+ if (elem.kind === tree_1.JS.Kind.ImportSpecifier) {
261
+ return this.produceJavaScript(elem, p, (draft) => __awaiter(this, void 0, void 0, function* () {
262
+ draft.prefix = prefix;
263
+ }));
264
+ }
265
+ return elem;
266
+ }), p);
267
+ if (allRemoved) {
268
+ return undefined;
269
+ }
270
+ if (filtered.length === namedImports.elements.elements.length) {
271
+ return namedImports; // No changes
272
+ }
273
+ // Create updated named imports with filtered elements
274
+ return this.produceJavaScript(namedImports, p, (draft) => __awaiter(this, void 0, void 0, function* () {
275
+ draft.elements = Object.assign(Object.assign({}, namedImports.elements), { elements: filtered });
276
+ }));
277
+ });
278
+ }
279
+ processRequireFromVarDecls(varDecls, usedIdentifiers, p) {
280
+ return __awaiter(this, void 0, void 0, function* () {
281
+ var _a, _b;
282
+ // Check if this is a require() call
283
+ if (varDecls.variables.length !== 1) {
284
+ return varDecls;
285
+ }
286
+ const namedVar = varDecls.variables[0].element;
287
+ if (!namedVar) {
288
+ return varDecls;
289
+ }
290
+ const initializer = (_a = namedVar.initializer) === null || _a === void 0 ? void 0 : _a.element;
291
+ if (!initializer || initializer.kind !== java_1.J.Kind.MethodInvocation) {
292
+ return varDecls;
293
+ }
294
+ const methodInv = initializer;
295
+ if (((_b = methodInv.name) === null || _b === void 0 ? void 0 : _b.kind) !== java_1.J.Kind.Identifier || methodInv.name.simpleName !== 'require') {
296
+ return varDecls;
297
+ }
298
+ // This is a require() statement
299
+ const pattern = namedVar.name;
300
+ if (!pattern) {
301
+ return varDecls;
302
+ }
303
+ // Handle: const fs = require('fs')
304
+ if (pattern.kind === java_1.J.Kind.Identifier) {
305
+ const varName = pattern.simpleName;
306
+ if (this.shouldRemoveImport(varName, usedIdentifiers, new Set())) {
307
+ return undefined; // Remove the entire require statement
308
+ }
309
+ }
310
+ // Handle: const { readFile } = require('fs')
311
+ if (pattern.kind === tree_1.JS.Kind.ObjectBindingPattern && this.member !== undefined) {
312
+ const objectPattern = pattern;
313
+ const updatedPattern = yield this.processObjectBindingPattern(objectPattern, usedIdentifiers, p);
314
+ if (updatedPattern === undefined) {
315
+ return undefined; // Remove entire require
316
+ }
317
+ else if (updatedPattern !== objectPattern) {
318
+ // Update with filtered bindings
319
+ return this.produceJava(varDecls, p, (draft) => __awaiter(this, void 0, void 0, function* () {
320
+ const updatedNamedVar = yield this.produceJava(namedVar, p, (namedDraft) => __awaiter(this, void 0, void 0, function* () {
321
+ namedDraft.name = updatedPattern;
322
+ }));
323
+ draft.variables = [Object.assign(Object.assign({}, varDecls.variables[0]), { element: updatedNamedVar })];
324
+ }));
325
+ }
326
+ }
327
+ return varDecls;
328
+ });
329
+ }
330
+ processObjectBindingPattern(pattern, usedIdentifiers, p) {
331
+ return __awaiter(this, void 0, void 0, function* () {
332
+ const { filtered, allRemoved } = yield this.filterElementsWithPrefixPreservation(pattern.bindings.elements, (elem) => {
333
+ if (elem.kind === tree_1.JS.Kind.BindingElement) {
334
+ const name = this.getBindingElementName(elem);
335
+ return !this.shouldRemoveImport(name, usedIdentifiers, new Set());
336
+ }
337
+ else if (elem.kind === java_1.J.Kind.Identifier) {
338
+ const name = elem.simpleName;
339
+ return !this.shouldRemoveImport(name, usedIdentifiers, new Set());
340
+ }
341
+ return true; // Keep other element types
342
+ }, (elem, prefix) => __awaiter(this, void 0, void 0, function* () {
343
+ if (elem.kind === java_1.J.Kind.Identifier) {
344
+ return this.produceJava(elem, p, (draft) => __awaiter(this, void 0, void 0, function* () {
345
+ draft.prefix = prefix;
346
+ }));
347
+ }
348
+ else if (elem.kind === tree_1.JS.Kind.BindingElement) {
349
+ return this.produceJavaScript(elem, p, (draft) => __awaiter(this, void 0, void 0, function* () {
350
+ draft.prefix = prefix;
351
+ }));
352
+ }
353
+ return elem;
354
+ }), p);
355
+ if (allRemoved) {
356
+ return undefined;
357
+ }
358
+ if (filtered.length === pattern.bindings.elements.length) {
359
+ return pattern;
360
+ }
361
+ return this.produceJavaScript(pattern, p, (draft) => __awaiter(this, void 0, void 0, function* () {
362
+ draft.bindings = Object.assign(Object.assign({}, pattern.bindings), { elements: filtered });
363
+ }));
364
+ });
365
+ }
366
+ getImportName(specifier) {
367
+ const spec = specifier.specifier;
368
+ if ((spec === null || spec === void 0 ? void 0 : spec.kind) === tree_1.JS.Kind.Alias) {
369
+ // Handle aliased import: import { foo as bar }
370
+ const alias = spec;
371
+ const propertyName = alias.propertyName.element;
372
+ if ((propertyName === null || propertyName === void 0 ? void 0 : propertyName.kind) === java_1.J.Kind.Identifier) {
373
+ return propertyName.simpleName;
374
+ }
375
+ }
376
+ else if ((spec === null || spec === void 0 ? void 0 : spec.kind) === java_1.J.Kind.Identifier) {
377
+ // Handle regular import: import { foo }
378
+ return spec.simpleName;
379
+ }
380
+ return '';
381
+ }
382
+ getBindingElementName(bindingElement) {
383
+ const name = bindingElement.name;
384
+ if ((name === null || name === void 0 ? void 0 : name.kind) === java_1.J.Kind.Identifier) {
385
+ return name.simpleName;
386
+ }
387
+ return '';
388
+ }
389
+ shouldRemoveImport(name, usedIdentifiers, usedTypes) {
390
+ // If member is specified, we're removing a specific member from a module
391
+ if (this.member !== undefined) {
392
+ // Only remove if this is the specific member we're looking for
393
+ if (this.member !== name) {
394
+ return false;
395
+ }
396
+ }
397
+ else {
398
+ // If no member specified, we're removing based on the import name itself
399
+ if (this.target !== name) {
400
+ return false;
401
+ }
402
+ }
403
+ // Check if it's used
404
+ return !(usedIdentifiers.has(name) || usedTypes.has(name));
405
+ }
406
+ isTargetModule(jsImport) {
407
+ var _a, _b;
408
+ // If member is specified, we're looking for imports from a specific module
409
+ if (this.member !== undefined) {
410
+ const moduleSpecifier = (_a = jsImport.moduleSpecifier) === null || _a === void 0 ? void 0 : _a.element;
411
+ if (!moduleSpecifier || moduleSpecifier.kind !== java_1.J.Kind.Literal) {
412
+ return false;
413
+ }
414
+ const literal = moduleSpecifier;
415
+ const moduleName = (_b = literal.value) === null || _b === void 0 ? void 0 : _b.toString().replace(/['"`]/g, '');
416
+ // Match the module name
417
+ return moduleName === this.target;
418
+ }
419
+ // If no member specified, we process all imports to check their names
420
+ return true;
421
+ }
422
+ /**
423
+ * Helper to traverse parameters from various node types
424
+ */
425
+ traverseParameters(params, usedIdentifiers, usedTypes) {
426
+ return __awaiter(this, void 0, void 0, function* () {
427
+ if (!params || typeof params !== 'object')
428
+ return;
429
+ if (Array.isArray(params)) {
430
+ for (const p of params) {
431
+ yield this.collectUsedIdentifiers(p, usedIdentifiers, usedTypes);
432
+ }
433
+ }
434
+ else if (params.elements) {
435
+ for (const p of params.elements) {
436
+ if (p.element) {
437
+ yield this.collectUsedIdentifiers(p.element, usedIdentifiers, usedTypes);
438
+ }
439
+ }
440
+ }
441
+ else if (params.parameters) {
442
+ for (const p of params.parameters) {
443
+ const elem = p.element || p;
444
+ yield this.collectUsedIdentifiers(elem, usedIdentifiers, usedTypes);
445
+ }
446
+ }
447
+ });
448
+ }
449
+ /**
450
+ * Helper to traverse statements from various node types
451
+ */
452
+ traverseStatements(statements, usedIdentifiers, usedTypes) {
453
+ return __awaiter(this, void 0, void 0, function* () {
454
+ if (!statements)
455
+ return;
456
+ if (Array.isArray(statements)) {
457
+ for (const stmt of statements) {
458
+ const element = stmt.element || stmt;
459
+ if (element) {
460
+ yield this.collectUsedIdentifiers(element, usedIdentifiers, usedTypes);
461
+ }
462
+ }
463
+ }
464
+ });
465
+ }
466
+ /**
467
+ * Helper to check for type expressions and collect type usage
468
+ */
469
+ checkTypeExpression(node, usedTypes) {
470
+ return __awaiter(this, void 0, void 0, function* () {
471
+ if (node.typeExpression) {
472
+ yield this.collectTypeUsage(node.typeExpression, usedTypes);
473
+ }
474
+ });
475
+ }
476
+ collectUsedIdentifiers(node, usedIdentifiers, usedTypes) {
477
+ return __awaiter(this, void 0, void 0, function* () {
478
+ // This is a simplified version - in a real implementation,
479
+ // we'd need to traverse the entire AST and collect all identifier usages
480
+ // For now, we'll implement a basic traversal
481
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
482
+ if (node.kind === java_1.J.Kind.Identifier) {
483
+ const identifier = node;
484
+ usedIdentifiers.add(identifier.simpleName);
485
+ }
486
+ else if (node.kind === java_1.J.Kind.MethodInvocation) {
487
+ const methodInv = node;
488
+ // Check if this is a member access pattern like fs.readFileSync
489
+ if (((_b = (_a = methodInv.select) === null || _a === void 0 ? void 0 : _a.element) === null || _b === void 0 ? void 0 : _b.kind) === java_1.J.Kind.FieldAccess) {
490
+ const fieldAccess = methodInv.select.element;
491
+ if (((_c = fieldAccess.target) === null || _c === void 0 ? void 0 : _c.kind) === java_1.J.Kind.Identifier) {
492
+ usedIdentifiers.add(fieldAccess.target.simpleName);
493
+ }
494
+ }
495
+ else if (((_e = (_d = methodInv.select) === null || _d === void 0 ? void 0 : _d.element) === null || _e === void 0 ? void 0 : _e.kind) === java_1.J.Kind.Identifier) {
496
+ // Direct identifier like fs in fs.method() - though this is rare
497
+ usedIdentifiers.add(methodInv.select.element.simpleName);
498
+ }
499
+ // Collect method name
500
+ if (methodInv.name && methodInv.name.kind === java_1.J.Kind.Identifier) {
501
+ usedIdentifiers.add(methodInv.name.simpleName);
502
+ }
503
+ // Recursively check arguments
504
+ if (methodInv.arguments) {
505
+ for (const arg of methodInv.arguments.elements) {
506
+ if (arg.element) {
507
+ yield this.collectUsedIdentifiers(arg.element, usedIdentifiers, usedTypes);
508
+ }
509
+ }
510
+ }
511
+ // Check select (object being called on)
512
+ if ((_f = methodInv.select) === null || _f === void 0 ? void 0 : _f.element) {
513
+ yield this.collectUsedIdentifiers(methodInv.select.element, usedIdentifiers, usedTypes);
514
+ }
515
+ }
516
+ else if (node.kind === java_1.J.Kind.MemberReference) {
517
+ const memberRef = node;
518
+ if (memberRef.containing && ((_g = memberRef.containing.element) === null || _g === void 0 ? void 0 : _g.kind) === java_1.J.Kind.Identifier) {
519
+ usedIdentifiers.add(memberRef.containing.element.simpleName);
520
+ }
521
+ }
522
+ else if (node.kind === java_1.J.Kind.FieldAccess) {
523
+ // Handle field access like fs.readFileSync
524
+ const fieldAccess = node;
525
+ if (((_h = fieldAccess.target) === null || _h === void 0 ? void 0 : _h.kind) === java_1.J.Kind.Identifier) {
526
+ usedIdentifiers.add(fieldAccess.target.simpleName);
527
+ }
528
+ // Recursively check the target
529
+ if (fieldAccess.target) {
530
+ yield this.collectUsedIdentifiers(fieldAccess.target, usedIdentifiers, usedTypes);
531
+ }
532
+ }
533
+ else if (node.kind === tree_1.JS.Kind.CompilationUnit) {
534
+ const cu = node;
535
+ for (const stmt of cu.statements) {
536
+ if (stmt.element && stmt.element.kind !== tree_1.JS.Kind.Import) {
537
+ // Skip require() statements at the top level
538
+ if (stmt.element.kind === java_1.J.Kind.VariableDeclarations) {
539
+ const varDecls = stmt.element;
540
+ // Check if this is a require() statement
541
+ let isRequire = false;
542
+ for (const v of varDecls.variables) {
543
+ const namedVar = v.element;
544
+ if (((_k = (_j = namedVar === null || namedVar === void 0 ? void 0 : namedVar.initializer) === null || _j === void 0 ? void 0 : _j.element) === null || _k === void 0 ? void 0 : _k.kind) === java_1.J.Kind.MethodInvocation) {
545
+ const methodInv = namedVar.initializer.element;
546
+ if (((_l = methodInv.name) === null || _l === void 0 ? void 0 : _l.kind) === java_1.J.Kind.Identifier &&
547
+ methodInv.name.simpleName === 'require') {
548
+ isRequire = true;
549
+ break;
550
+ }
551
+ }
552
+ }
553
+ if (!isRequire) {
554
+ // Not a require statement, process normally
555
+ yield this.collectUsedIdentifiers(stmt.element, usedIdentifiers, usedTypes);
556
+ }
557
+ }
558
+ else if (stmt.element.kind !== tree_1.JS.Kind.ScopedVariableDeclarations) {
559
+ // Process other non-import, non-require statements normally
560
+ yield this.collectUsedIdentifiers(stmt.element, usedIdentifiers, usedTypes);
561
+ }
562
+ }
563
+ }
564
+ }
565
+ else if (node.kind === java_1.J.Kind.Return) {
566
+ // Handle return statements
567
+ const returnStmt = node;
568
+ if (returnStmt.expression) {
569
+ yield this.collectUsedIdentifiers(returnStmt.expression, usedIdentifiers, usedTypes);
570
+ }
571
+ }
572
+ else if (node.kind === java_1.J.Kind.Block) {
573
+ const block = node;
574
+ for (const stmt of block.statements) {
575
+ if (stmt.element) {
576
+ yield this.collectUsedIdentifiers(stmt.element, usedIdentifiers, usedTypes);
577
+ }
578
+ }
579
+ }
580
+ else if (node.kind === java_1.J.Kind.MethodDeclaration) {
581
+ const method = node;
582
+ // Check parameters for type usage
583
+ if (method.parameters) {
584
+ for (const param of method.parameters.elements) {
585
+ // Parameters can be various types, handle them recursively
586
+ if (param.element) {
587
+ yield this.collectUsedIdentifiers(param.element, usedIdentifiers, usedTypes);
588
+ }
589
+ }
590
+ }
591
+ // Check body
592
+ if (method.body) {
593
+ yield this.collectUsedIdentifiers(method.body, usedIdentifiers, usedTypes);
594
+ }
595
+ }
596
+ else if (node.typeExpression) {
597
+ // Handle nodes with type expressions (parameters, variables, etc.)
598
+ yield this.checkTypeExpression(node, usedTypes);
599
+ // Continue traversing other parts
600
+ if (node.name) {
601
+ yield this.collectUsedIdentifiers(node.name, usedIdentifiers, usedTypes);
602
+ }
603
+ if (node.initializer) {
604
+ yield this.collectUsedIdentifiers(node.initializer, usedIdentifiers, usedTypes);
605
+ }
606
+ }
607
+ else if (node.kind === tree_1.JS.Kind.ArrowFunction || node.kind === java_1.J.Kind.Lambda) {
608
+ // Handle arrow functions and lambdas
609
+ const func = node;
610
+ if (func.parameters) {
611
+ yield this.collectUsedIdentifiers(func.parameters, usedIdentifiers, usedTypes);
612
+ }
613
+ if (func.lambda) {
614
+ yield this.collectUsedIdentifiers(func.lambda, usedIdentifiers, usedTypes);
615
+ }
616
+ if (func.body) {
617
+ yield this.collectUsedIdentifiers(func.body, usedIdentifiers, usedTypes);
618
+ }
619
+ }
620
+ else if (node.kind === java_1.J.Kind.Lambda) {
621
+ const lambda = node;
622
+ if ((_m = lambda.parameters) === null || _m === void 0 ? void 0 : _m.parameters) {
623
+ for (const param of lambda.parameters.parameters) {
624
+ if (param.element) {
625
+ yield this.collectUsedIdentifiers(param.element, usedIdentifiers, usedTypes);
626
+ }
627
+ }
628
+ }
629
+ if (lambda.body) {
630
+ yield this.collectUsedIdentifiers(lambda.body, usedIdentifiers, usedTypes);
631
+ }
632
+ }
633
+ else if (node.kind === java_1.J.Kind.VariableDeclarations) {
634
+ const varDecls = node;
635
+ // Check the type expression on the VariableDeclarations itself
636
+ yield this.checkTypeExpression(varDecls, usedTypes);
637
+ for (const v of varDecls.variables) {
638
+ const namedVar = v.element;
639
+ if (namedVar) {
640
+ // Check type annotation on the variable
641
+ yield this.checkTypeExpression(namedVar, usedTypes);
642
+ // Check the variable name
643
+ if (namedVar.name) {
644
+ yield this.collectUsedIdentifiers(namedVar.name, usedIdentifiers, usedTypes);
645
+ }
646
+ // Check the initializer
647
+ if (namedVar.initializer && namedVar.initializer.element) {
648
+ yield this.collectUsedIdentifiers(namedVar.initializer.element, usedIdentifiers, usedTypes);
649
+ }
650
+ }
651
+ }
652
+ }
653
+ else if (node.statements) {
654
+ // Generic handler for nodes with statements
655
+ yield this.traverseStatements(node.statements, usedIdentifiers, usedTypes);
656
+ }
657
+ else if (node.body) {
658
+ // Generic handler for nodes with body
659
+ yield this.collectUsedIdentifiers(node.body, usedIdentifiers, usedTypes);
660
+ }
661
+ else if (node.parameters) {
662
+ // Handle anything with parameters (functions, methods, etc.)
663
+ yield this.traverseParameters(node.parameters, usedIdentifiers, usedTypes);
664
+ // Continue with the body if it exists
665
+ if (node.body) {
666
+ yield this.collectUsedIdentifiers(node.body, usedIdentifiers, usedTypes);
667
+ }
668
+ }
669
+ });
670
+ }
671
+ collectTypeUsage(typeExpr, usedTypes) {
672
+ return __awaiter(this, void 0, void 0, function* () {
673
+ if (typeExpr.kind === java_1.J.Kind.Identifier) {
674
+ usedTypes.add(typeExpr.simpleName);
675
+ }
676
+ else if (typeExpr.kind === java_1.J.Kind.ParameterizedType) {
677
+ const paramType = typeExpr;
678
+ // In TypeScript AST, ParameterizedType might have a different structure
679
+ // We'll need to handle the type parameters appropriately
680
+ if (paramType.typeParameters) {
681
+ for (const typeParam of paramType.typeParameters.elements) {
682
+ if (typeParam.element) {
683
+ yield this.collectTypeUsage(typeParam.element, usedTypes);
684
+ }
685
+ }
686
+ }
687
+ }
688
+ else if (typeExpr.kind === tree_1.JS.Kind.TypeTreeExpression) {
689
+ // Handle TypeTreeExpression which wraps type identifiers
690
+ const typeTree = typeExpr;
691
+ if (typeTree.expression) {
692
+ yield this.collectTypeUsage(typeTree.expression, usedTypes);
693
+ }
694
+ }
695
+ else if (typeExpr.kind === tree_1.JS.Kind.TypeInfo) {
696
+ // Handle TypeInfo which contains type identifiers
697
+ const typeInfo = typeExpr;
698
+ if (typeInfo.typeIdentifier) {
699
+ yield this.collectTypeUsage(typeInfo.typeIdentifier, usedTypes);
700
+ }
701
+ }
702
+ else if (typeExpr.expression) {
703
+ // Generic handler for nodes with expression property
704
+ yield this.collectTypeUsage(typeExpr.expression, usedTypes);
705
+ }
706
+ else if (typeExpr.typeIdentifier) {
707
+ // Generic handler for nodes with typeIdentifier property
708
+ yield this.collectTypeUsage(typeExpr.typeIdentifier, usedTypes);
709
+ }
710
+ // Add more type expression handlers as needed
711
+ });
712
+ }
713
+ }
714
+ exports.RemoveImport = RemoveImport;
715
+ //# sourceMappingURL=remove-import.js.map