@openrewrite/rewrite 8.66.0-SNAPSHOT → 8.66.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/dist/javascript/comparator.d.ts +91 -5
  2. package/dist/javascript/comparator.d.ts.map +1 -1
  3. package/dist/javascript/comparator.js +679 -3091
  4. package/dist/javascript/comparator.js.map +1 -1
  5. package/dist/javascript/format.d.ts.map +1 -1
  6. package/dist/javascript/format.js +4 -3
  7. package/dist/javascript/format.js.map +1 -1
  8. package/dist/javascript/index.d.ts +1 -1
  9. package/dist/javascript/index.d.ts.map +1 -1
  10. package/dist/javascript/index.js +1 -1
  11. package/dist/javascript/index.js.map +1 -1
  12. package/dist/javascript/parser.d.ts.map +1 -1
  13. package/dist/javascript/parser.js +22 -21
  14. package/dist/javascript/parser.js.map +1 -1
  15. package/dist/javascript/print.d.ts +2 -2
  16. package/dist/javascript/print.d.ts.map +1 -1
  17. package/dist/javascript/print.js +4 -4
  18. package/dist/javascript/print.js.map +1 -1
  19. package/dist/javascript/templating/capture.d.ts +226 -0
  20. package/dist/javascript/templating/capture.d.ts.map +1 -0
  21. package/dist/javascript/templating/capture.js +371 -0
  22. package/dist/javascript/templating/capture.js.map +1 -0
  23. package/dist/javascript/templating/comparator.d.ts +61 -0
  24. package/dist/javascript/templating/comparator.d.ts.map +1 -0
  25. package/dist/javascript/templating/comparator.js +393 -0
  26. package/dist/javascript/templating/comparator.js.map +1 -0
  27. package/dist/javascript/templating/engine.d.ts +75 -0
  28. package/dist/javascript/templating/engine.d.ts.map +1 -0
  29. package/dist/javascript/templating/engine.js +228 -0
  30. package/dist/javascript/templating/engine.js.map +1 -0
  31. package/dist/javascript/templating/index.d.ts +6 -0
  32. package/dist/javascript/templating/index.d.ts.map +1 -0
  33. package/dist/javascript/templating/index.js +42 -0
  34. package/dist/javascript/templating/index.js.map +1 -0
  35. package/dist/javascript/templating/pattern.d.ts +171 -0
  36. package/dist/javascript/templating/pattern.d.ts.map +1 -0
  37. package/dist/javascript/templating/pattern.js +681 -0
  38. package/dist/javascript/templating/pattern.js.map +1 -0
  39. package/dist/javascript/templating/placeholder-replacement.d.ts +58 -0
  40. package/dist/javascript/templating/placeholder-replacement.d.ts.map +1 -0
  41. package/dist/javascript/templating/placeholder-replacement.js +365 -0
  42. package/dist/javascript/templating/placeholder-replacement.js.map +1 -0
  43. package/dist/javascript/templating/rewrite.d.ts +39 -0
  44. package/dist/javascript/templating/rewrite.d.ts.map +1 -0
  45. package/dist/javascript/templating/rewrite.js +81 -0
  46. package/dist/javascript/templating/rewrite.js.map +1 -0
  47. package/dist/javascript/templating/template.d.ts +204 -0
  48. package/dist/javascript/templating/template.d.ts.map +1 -0
  49. package/dist/javascript/templating/template.js +293 -0
  50. package/dist/javascript/templating/template.js.map +1 -0
  51. package/dist/javascript/templating/types.d.ts +263 -0
  52. package/dist/javascript/templating/types.d.ts.map +1 -0
  53. package/dist/javascript/templating/types.js +3 -0
  54. package/dist/javascript/templating/types.js.map +1 -0
  55. package/dist/javascript/templating/utils.d.ts +118 -0
  56. package/dist/javascript/templating/utils.d.ts.map +1 -0
  57. package/dist/javascript/templating/utils.js +253 -0
  58. package/dist/javascript/templating/utils.js.map +1 -0
  59. package/dist/test/rewrite-test.d.ts.map +1 -1
  60. package/dist/test/rewrite-test.js +65 -9
  61. package/dist/test/rewrite-test.js.map +1 -1
  62. package/dist/version.txt +1 -1
  63. package/package.json +2 -2
  64. package/src/javascript/comparator.ts +721 -3607
  65. package/src/javascript/format.ts +3 -2
  66. package/src/javascript/index.ts +1 -1
  67. package/src/javascript/parser.ts +23 -22
  68. package/src/javascript/print.ts +6 -6
  69. package/src/javascript/templating/capture.ts +503 -0
  70. package/src/javascript/templating/comparator.ts +430 -0
  71. package/src/javascript/templating/engine.ts +252 -0
  72. package/src/javascript/templating/index.ts +60 -0
  73. package/src/javascript/templating/pattern.ts +727 -0
  74. package/src/javascript/templating/placeholder-replacement.ts +372 -0
  75. package/src/javascript/templating/rewrite.ts +95 -0
  76. package/src/javascript/templating/template.ts +326 -0
  77. package/src/javascript/templating/types.ts +300 -0
  78. package/src/javascript/templating/utils.ts +284 -0
  79. package/src/test/rewrite-test.ts +65 -1
  80. package/dist/javascript/templating.d.ts +0 -265
  81. package/dist/javascript/templating.d.ts.map +0 -1
  82. package/dist/javascript/templating.js +0 -1069
  83. package/dist/javascript/templating.js.map +0 -1
  84. package/src/javascript/templating.ts +0 -1277
@@ -9,7 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.JavaScriptComparatorVisitor = void 0;
12
+ exports.JavaScriptSemanticComparatorVisitor = exports.JavaScriptComparatorVisitor = void 0;
13
13
  /*
14
14
  * Copyright 2025 the original author or authors.
15
15
  * <p>
@@ -27,18 +27,15 @@ exports.JavaScriptComparatorVisitor = void 0;
27
27
  */
28
28
  const visitor_1 = require("./visitor");
29
29
  const java_1 = require("../java");
30
- const tree_1 = require("./tree");
30
+ const tree_1 = require("../tree");
31
31
  /**
32
32
  * A visitor that compares two AST trees in lock step.
33
33
  * It takes another `J` instance as context and visits both trees simultaneously.
34
34
  * The visit operation is aborted when the nodes don't match.
35
35
  */
36
36
  class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
37
- /**
38
- * Creates a new comparator visitor.
39
- */
40
37
  constructor() {
41
- super();
38
+ super(...arguments);
42
39
  /**
43
40
  * Flag indicating whether the trees match so far
44
41
  */
@@ -71,8 +68,105 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
71
68
  /**
72
69
  * Aborts the visit operation by setting the match flag to false.
73
70
  */
74
- abort() {
71
+ abort(t) {
75
72
  this.match = false;
73
+ return t;
74
+ }
75
+ /**
76
+ * Generic method to visit a property value using the appropriate visitor method.
77
+ * This ensures wrappers (RightPadded, LeftPadded, Container) are properly tracked on the cursor.
78
+ *
79
+ * @param j The property value from the first tree
80
+ * @param other The corresponding property value from the second tree
81
+ * @returns The visited property value from the first tree
82
+ */
83
+ visitProperty(j, other) {
84
+ return __awaiter(this, void 0, void 0, function* () {
85
+ // Handle null/undefined (but not other falsy values like 0, false, '')
86
+ if (j == null || other == null) {
87
+ if (j !== other) {
88
+ this.abort(j);
89
+ }
90
+ return j;
91
+ }
92
+ const kind = j.kind;
93
+ // Check wrappers by kind
94
+ if (kind === java_1.J.Kind.RightPadded) {
95
+ return yield this.visitRightPadded(j, other);
96
+ }
97
+ if (kind === java_1.J.Kind.LeftPadded) {
98
+ return yield this.visitLeftPadded(j, other);
99
+ }
100
+ if (kind === java_1.J.Kind.Container) {
101
+ return yield this.visitContainer(j, other);
102
+ }
103
+ // Check if it's a Space (skip comparison)
104
+ if (kind === java_1.J.Kind.Space) {
105
+ return j;
106
+ }
107
+ // Check if it's a Tree node (has a kind property with a string value)
108
+ if (kind !== undefined && typeof kind === 'string') {
109
+ // Check if it's a Type node (starts with "org.openrewrite.java.tree.JavaType$")
110
+ if (kind.startsWith('org.openrewrite.java.tree.JavaType$')) {
111
+ return yield this.visitType(j, other);
112
+ }
113
+ return yield this.visit(j, other);
114
+ }
115
+ // For primitive values, compare directly
116
+ if (j !== other) {
117
+ this.abort(j);
118
+ }
119
+ return j;
120
+ });
121
+ }
122
+ /**
123
+ * Generic method to visit all properties of an element, calling visitProperty for each.
124
+ * This automatically handles wrappers and ensures proper cursor tracking.
125
+ * Also checks that both elements have the same kind.
126
+ *
127
+ * @param j The element from the first tree
128
+ * @param other The corresponding element from the second tree
129
+ * @returns The visited element from the first tree
130
+ */
131
+ visitElement(j, other) {
132
+ return __awaiter(this, void 0, void 0, function* () {
133
+ if (!this.match) {
134
+ return j;
135
+ }
136
+ // Check if kinds match
137
+ if (j.kind !== other.kind) {
138
+ return this.abort(j);
139
+ }
140
+ // Iterate over all properties
141
+ for (const key of Object.keys(j)) {
142
+ // Skip internal/private properties, id property, and markers property
143
+ if (key.startsWith('_') || key === 'id' || key === 'markers') {
144
+ continue;
145
+ }
146
+ const jValue = j[key];
147
+ const otherValue = other[key];
148
+ // Handle arrays - compare element by element
149
+ if (Array.isArray(jValue)) {
150
+ if (!Array.isArray(otherValue) || jValue.length !== otherValue.length) {
151
+ return this.abort(j);
152
+ }
153
+ for (let i = 0; i < jValue.length; i++) {
154
+ yield this.visitProperty(jValue[i], otherValue[i]);
155
+ if (!this.match) {
156
+ return j;
157
+ }
158
+ }
159
+ }
160
+ else {
161
+ // Visit the property (which will handle wrappers, trees, primitives, etc.)
162
+ yield this.visitProperty(jValue, otherValue);
163
+ if (!this.match) {
164
+ return j;
165
+ }
166
+ }
167
+ }
168
+ return j;
169
+ });
76
170
  }
77
171
  visit(j, p, parent) {
78
172
  const _super = Object.create(null, {
@@ -85,13 +179,99 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
85
179
  }
86
180
  // Check if the nodes have the same kind
87
181
  if (!this.hasSameKind(j, p)) {
88
- this.abort();
89
- return j;
182
+ return this.abort(j);
90
183
  }
91
184
  // Continue with normal visitation, passing the other node as context
92
185
  return _super.visit.call(this, j, p);
93
186
  });
94
187
  }
188
+ /**
189
+ * Override visitRightPadded to compare only the elements, not markers or spacing.
190
+ * The context parameter p contains the corresponding element from the other tree.
191
+ * Pushes the wrapper onto the cursor stack so captures can access it.
192
+ */
193
+ visitRightPadded(right, p) {
194
+ return __awaiter(this, void 0, void 0, function* () {
195
+ if (!this.match) {
196
+ return right;
197
+ }
198
+ // Extract the other element if it's also a RightPadded
199
+ const otherElement = p.kind === java_1.J.Kind.RightPadded
200
+ ? p.element
201
+ : p;
202
+ // Push wrapper onto cursor, then compare only the elements, not markers or spacing
203
+ const savedCursor = this.cursor;
204
+ this.cursor = new tree_1.Cursor(right, this.cursor);
205
+ try {
206
+ yield this.visitProperty(right.element, otherElement);
207
+ }
208
+ finally {
209
+ this.cursor = savedCursor;
210
+ }
211
+ return right;
212
+ });
213
+ }
214
+ /**
215
+ * Override visitLeftPadded to compare only the elements, not markers or spacing.
216
+ * The context parameter p contains the corresponding element from the other tree.
217
+ * Pushes the wrapper onto the cursor stack so captures can access it.
218
+ */
219
+ visitLeftPadded(left, p) {
220
+ return __awaiter(this, void 0, void 0, function* () {
221
+ if (!this.match) {
222
+ return left;
223
+ }
224
+ // Extract the other element if it's also a LeftPadded
225
+ const otherElement = p.kind === java_1.J.Kind.LeftPadded
226
+ ? p.element
227
+ : p;
228
+ // Push wrapper onto cursor, then compare only the elements, not markers or spacing
229
+ const savedCursor = this.cursor;
230
+ this.cursor = new tree_1.Cursor(left, this.cursor);
231
+ try {
232
+ yield this.visitProperty(left.element, otherElement);
233
+ }
234
+ finally {
235
+ this.cursor = savedCursor;
236
+ }
237
+ return left;
238
+ });
239
+ }
240
+ /**
241
+ * Override visitContainer to compare only the elements, not markers or spacing.
242
+ * The context parameter p contains the corresponding element from the other tree.
243
+ * Pushes the wrapper onto the cursor stack so captures can access it.
244
+ */
245
+ visitContainer(container, p) {
246
+ return __awaiter(this, void 0, void 0, function* () {
247
+ if (!this.match) {
248
+ return container;
249
+ }
250
+ // Extract the other elements if it's also a Container
251
+ const otherElements = p.kind === java_1.J.Kind.Container
252
+ ? p.elements
253
+ : p;
254
+ // Compare elements array length
255
+ if (container.elements.length !== otherElements.length) {
256
+ return this.abort(container);
257
+ }
258
+ // Push wrapper onto cursor, then compare each element
259
+ const savedCursor = this.cursor;
260
+ this.cursor = new tree_1.Cursor(container, this.cursor);
261
+ try {
262
+ for (let i = 0; i < container.elements.length; i++) {
263
+ yield this.visitProperty(container.elements[i], otherElements[i]);
264
+ if (!this.match) {
265
+ return this.abort(container);
266
+ }
267
+ }
268
+ }
269
+ finally {
270
+ this.cursor = savedCursor;
271
+ }
272
+ return container;
273
+ });
274
+ }
95
275
  /**
96
276
  * Overrides the visitBinary method to compare binary expressions.
97
277
  *
@@ -101,21 +281,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
101
281
  */
102
282
  visitBinary(binary, other) {
103
283
  return __awaiter(this, void 0, void 0, function* () {
104
- if (!this.match || other.kind !== java_1.J.Kind.Binary) {
105
- this.abort();
106
- return binary;
107
- }
108
- const otherBinary = other;
109
- if (binary.operator.element !== otherBinary.operator.element) {
110
- this.abort();
111
- return binary;
112
- }
113
- // Visit left and right operands in lock step
114
- yield this.visit(binary.left, otherBinary.left);
115
- if (!this.match)
116
- return binary;
117
- yield this.visit(binary.right, otherBinary.right);
118
- return binary;
284
+ return this.visitElement(binary, other);
119
285
  });
120
286
  }
121
287
  /**
@@ -127,15 +293,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
127
293
  */
128
294
  visitIdentifier(identifier, other) {
129
295
  return __awaiter(this, void 0, void 0, function* () {
130
- if (!this.match || other.kind !== java_1.J.Kind.Identifier) {
131
- this.abort();
132
- return identifier;
133
- }
134
- const otherIdentifier = other;
135
- if (identifier.simpleName !== otherIdentifier.simpleName) {
136
- this.abort();
137
- }
138
- return identifier;
296
+ return this.visitElement(identifier, other);
139
297
  });
140
298
  }
141
299
  /**
@@ -147,15 +305,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
147
305
  */
148
306
  visitLiteral(literal, other) {
149
307
  return __awaiter(this, void 0, void 0, function* () {
150
- if (!this.match || other.kind !== java_1.J.Kind.Literal) {
151
- this.abort();
152
- return literal;
153
- }
154
- const otherLiteral = other;
155
- if (literal.valueSource !== otherLiteral.valueSource) {
156
- this.abort();
157
- }
158
- return literal;
308
+ return this.visitElement(literal, other);
159
309
  });
160
310
  }
161
311
  /**
@@ -167,22 +317,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
167
317
  */
168
318
  visitBlock(block, other) {
169
319
  return __awaiter(this, void 0, void 0, function* () {
170
- if (!this.match || other.kind !== java_1.J.Kind.Block) {
171
- this.abort();
172
- return block;
173
- }
174
- const otherBlock = other;
175
- if (block.statements.length !== otherBlock.statements.length) {
176
- this.abort();
177
- return block;
178
- }
179
- // Visit each statement in lock step
180
- for (let i = 0; i < block.statements.length; i++) {
181
- yield this.visit(block.statements[i].element, otherBlock.statements[i].element);
182
- if (!this.match)
183
- break;
184
- }
185
- return block;
320
+ return this.visitElement(block, other);
186
321
  });
187
322
  }
188
323
  /**
@@ -194,22 +329,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
194
329
  */
195
330
  visitJsCompilationUnit(compilationUnit, other) {
196
331
  return __awaiter(this, void 0, void 0, function* () {
197
- if (!this.match || other.kind !== tree_1.JS.Kind.CompilationUnit) {
198
- this.abort();
199
- return compilationUnit;
200
- }
201
- const otherCompilationUnit = other;
202
- if (compilationUnit.statements.length !== otherCompilationUnit.statements.length) {
203
- this.abort();
204
- return compilationUnit;
205
- }
206
- // Visit each statement in lock step
207
- for (let i = 0; i < compilationUnit.statements.length; i++) {
208
- yield this.visit(compilationUnit.statements[i].element, otherCompilationUnit.statements[i].element);
209
- if (!this.match)
210
- break;
211
- }
212
- return compilationUnit;
332
+ return this.visitElement(compilationUnit, other);
213
333
  });
214
334
  }
215
335
  /**
@@ -221,17 +341,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
221
341
  */
222
342
  visitAlias(alias, other) {
223
343
  return __awaiter(this, void 0, void 0, function* () {
224
- if (!this.match || other.kind !== tree_1.JS.Kind.Alias) {
225
- this.abort();
226
- return alias;
227
- }
228
- const otherAlias = other;
229
- // Visit property name and alias in lock step
230
- yield this.visit(alias.propertyName.element, otherAlias.propertyName.element);
231
- if (!this.match)
232
- return alias;
233
- yield this.visit(alias.alias, otherAlias.alias);
234
- return alias;
344
+ return this.visitElement(alias, other);
235
345
  });
236
346
  }
237
347
  /**
@@ -243,45 +353,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
243
353
  */
244
354
  visitArrowFunction(arrowFunction, other) {
245
355
  return __awaiter(this, void 0, void 0, function* () {
246
- if (!this.match || other.kind !== tree_1.JS.Kind.ArrowFunction) {
247
- this.abort();
248
- return arrowFunction;
249
- }
250
- const otherArrowFunction = other;
251
- // Compare modifiers
252
- if (arrowFunction.modifiers.length !== otherArrowFunction.modifiers.length) {
253
- this.abort();
254
- return arrowFunction;
255
- }
256
- // Visit modifiers in lock step
257
- for (let i = 0; i < arrowFunction.modifiers.length; i++) {
258
- yield this.visit(arrowFunction.modifiers[i], otherArrowFunction.modifiers[i]);
259
- if (!this.match)
260
- return arrowFunction;
261
- }
262
- // Visit type parameters if present
263
- if (!!arrowFunction.typeParameters !== !!otherArrowFunction.typeParameters) {
264
- this.abort();
265
- return arrowFunction;
266
- }
267
- if (arrowFunction.typeParameters) {
268
- yield this.visit(arrowFunction.typeParameters, otherArrowFunction.typeParameters);
269
- if (!this.match)
270
- return arrowFunction;
271
- }
272
- // Visit lambda
273
- yield this.visit(arrowFunction.lambda, otherArrowFunction.lambda);
274
- if (!this.match)
275
- return arrowFunction;
276
- // Visit return type expression if present
277
- if (!!arrowFunction.returnTypeExpression !== !!otherArrowFunction.returnTypeExpression) {
278
- this.abort();
279
- return arrowFunction;
280
- }
281
- if (arrowFunction.returnTypeExpression) {
282
- yield this.visit(arrowFunction.returnTypeExpression, otherArrowFunction.returnTypeExpression);
283
- }
284
- return arrowFunction;
356
+ return this.visitElement(arrowFunction, other);
285
357
  });
286
358
  }
287
359
  /**
@@ -293,14 +365,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
293
365
  */
294
366
  visitAwait(await_, other) {
295
367
  return __awaiter(this, void 0, void 0, function* () {
296
- if (!this.match || other.kind !== tree_1.JS.Kind.Await) {
297
- this.abort();
298
- return await_;
299
- }
300
- const otherAwait = other;
301
- // Visit expression
302
- yield this.visit(await_.expression, otherAwait.expression);
303
- return await_;
368
+ return this.visitElement(await_, other);
304
369
  });
305
370
  }
306
371
  /**
@@ -312,57 +377,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
312
377
  */
313
378
  visitJsxTag(element, other) {
314
379
  return __awaiter(this, void 0, void 0, function* () {
315
- if (!this.match || other.kind !== tree_1.JS.Kind.JsxTag) {
316
- this.abort();
317
- return element;
318
- }
319
- const otherElement = other;
320
- // Visit open name
321
- yield this.visit(element.openName.element, otherElement.openName.element);
322
- if (!this.match)
323
- return element;
324
- // Compare attributes
325
- if (element.attributes.length !== otherElement.attributes.length) {
326
- this.abort();
327
- return element;
328
- }
329
- // Visit attributes in lock step
330
- for (let i = 0; i < element.attributes.length; i++) {
331
- yield this.visit(element.attributes[i].element, otherElement.attributes[i].element);
332
- if (!this.match)
333
- return element;
334
- }
335
- // Compare self-closing
336
- if (!!element.selfClosing !== !!otherElement.selfClosing) {
337
- this.abort();
338
- return element;
339
- }
340
- // Compare children
341
- if (!!element.children !== !!otherElement.children) {
342
- this.abort();
343
- return element;
344
- }
345
- if (element.children) {
346
- if (element.children.length !== otherElement.children.length) {
347
- this.abort();
348
- return element;
349
- }
350
- // Visit children in lock step
351
- for (let i = 0; i < element.children.length; i++) {
352
- yield this.visit(element.children[i], otherElement.children[i]);
353
- if (!this.match)
354
- return element;
355
- }
356
- }
357
- // Compare closing name
358
- if (!!element.closingName !== !!otherElement.closingName) {
359
- this.abort();
360
- return element;
361
- }
362
- if (element.closingName) {
363
- yield this.visit(element.closingName.element, otherElement.closingName.element);
364
- }
365
- return element;
380
+ return this.visitElement(element, other);
366
381
  });
367
382
  }
368
383
  /**
@@ -374,24 +389,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
374
389
  */
375
390
  visitJsxAttribute(attribute, other) {
376
391
  return __awaiter(this, void 0, void 0, function* () {
377
- if (!this.match || other.kind !== tree_1.JS.Kind.JsxAttribute) {
378
- this.abort();
379
- return attribute;
380
- }
381
- const otherAttribute = other;
382
- // Visit key
383
- yield this.visit(attribute.key, otherAttribute.key);
384
- if (!this.match)
385
- return attribute;
386
- // Compare value
387
- if (!!attribute.value !== !!otherAttribute.value) {
388
- this.abort();
389
- return attribute;
390
- }
391
- if (attribute.value) {
392
- yield this.visit(attribute.value.element, otherAttribute.value.element);
393
- }
394
- return attribute;
392
+ return this.visitElement(attribute, other);
395
393
  });
396
394
  }
397
395
  /**
@@ -403,14 +401,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
403
401
  */
404
402
  visitJsxSpreadAttribute(spread, other) {
405
403
  return __awaiter(this, void 0, void 0, function* () {
406
- if (!this.match || other.kind !== tree_1.JS.Kind.JsxSpreadAttribute) {
407
- this.abort();
408
- return spread;
409
- }
410
- const otherSpread = other;
411
- // Visit expression
412
- yield this.visit(spread.expression.element, otherSpread.expression.element);
413
- return spread;
404
+ return this.visitElement(spread, other);
414
405
  });
415
406
  }
416
407
  /**
@@ -422,14 +413,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
422
413
  */
423
414
  visitJsxEmbeddedExpression(expr, other) {
424
415
  return __awaiter(this, void 0, void 0, function* () {
425
- if (!this.match || other.kind !== tree_1.JS.Kind.JsxEmbeddedExpression) {
426
- this.abort();
427
- return expr;
428
- }
429
- const otherExpr = other;
430
- // Visit expression
431
- yield this.visit(expr.expression.element, otherExpr.expression.element);
432
- return expr;
416
+ return this.visitElement(expr, other);
433
417
  });
434
418
  }
435
419
  /**
@@ -441,18 +425,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
441
425
  */
442
426
  visitJsxNamespacedName(ns, other) {
443
427
  return __awaiter(this, void 0, void 0, function* () {
444
- if (!this.match || other.kind !== tree_1.JS.Kind.JsxNamespacedName) {
445
- this.abort();
446
- return ns;
447
- }
448
- const otherNs = other;
449
- // Visit namespace
450
- yield this.visit(ns.namespace, otherNs.namespace);
451
- if (!this.match)
452
- return ns;
453
- // Visit name
454
- yield this.visit(ns.name.element, otherNs.name.element);
455
- return ns;
428
+ return this.visitElement(ns, other);
456
429
  });
457
430
  }
458
431
  /**
@@ -464,18 +437,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
464
437
  */
465
438
  visitConditionalType(conditionalType, other) {
466
439
  return __awaiter(this, void 0, void 0, function* () {
467
- if (!this.match || other.kind !== tree_1.JS.Kind.ConditionalType) {
468
- this.abort();
469
- return conditionalType;
470
- }
471
- const otherConditionalType = other;
472
- // Visit check type
473
- yield this.visit(conditionalType.checkType, otherConditionalType.checkType);
474
- if (!this.match)
475
- return conditionalType;
476
- // Visit condition
477
- yield this.visit(conditionalType.condition.element, otherConditionalType.condition.element);
478
- return conditionalType;
440
+ return this.visitElement(conditionalType, other);
479
441
  });
480
442
  }
481
443
  /**
@@ -487,14 +449,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
487
449
  */
488
450
  visitDelete(delete_, other) {
489
451
  return __awaiter(this, void 0, void 0, function* () {
490
- if (!this.match || other.kind !== tree_1.JS.Kind.Delete) {
491
- this.abort();
492
- return delete_;
493
- }
494
- const otherDelete = other;
495
- // Visit expression
496
- yield this.visit(delete_.expression, otherDelete.expression);
497
- return delete_;
452
+ return this.visitElement(delete_, other);
498
453
  });
499
454
  }
500
455
  /**
@@ -506,14 +461,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
506
461
  */
507
462
  visitExpressionStatement(expressionStatement, other) {
508
463
  return __awaiter(this, void 0, void 0, function* () {
509
- if (!this.match || other.kind !== tree_1.JS.Kind.ExpressionStatement) {
510
- this.abort();
511
- return expressionStatement;
512
- }
513
- const otherExpressionStatement = other;
514
- // Visit expression
515
- yield this.visit(expressionStatement.expression, otherExpressionStatement.expression);
516
- return expressionStatement;
464
+ return this.visitElement(expressionStatement, other);
517
465
  });
518
466
  }
519
467
  /**
@@ -525,33 +473,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
525
473
  */
526
474
  visitExpressionWithTypeArguments(expressionWithTypeArguments, other) {
527
475
  return __awaiter(this, void 0, void 0, function* () {
528
- if (!this.match || other.kind !== tree_1.JS.Kind.ExpressionWithTypeArguments) {
529
- this.abort();
530
- return expressionWithTypeArguments;
531
- }
532
- const otherExpressionWithTypeArguments = other;
533
- // Visit class
534
- yield this.visit(expressionWithTypeArguments.clazz, otherExpressionWithTypeArguments.clazz);
535
- if (!this.match)
536
- return expressionWithTypeArguments;
537
- // Compare type arguments
538
- if (!!expressionWithTypeArguments.typeArguments !== !!otherExpressionWithTypeArguments.typeArguments) {
539
- this.abort();
540
- return expressionWithTypeArguments;
541
- }
542
- if (expressionWithTypeArguments.typeArguments) {
543
- if (expressionWithTypeArguments.typeArguments.elements.length !== otherExpressionWithTypeArguments.typeArguments.elements.length) {
544
- this.abort();
545
- return expressionWithTypeArguments;
546
- }
547
- // Visit type arguments in lock step
548
- for (let i = 0; i < expressionWithTypeArguments.typeArguments.elements.length; i++) {
549
- yield this.visit(expressionWithTypeArguments.typeArguments.elements[i].element, otherExpressionWithTypeArguments.typeArguments.elements[i].element);
550
- if (!this.match)
551
- return expressionWithTypeArguments;
552
- }
553
- }
554
- return expressionWithTypeArguments;
476
+ return this.visitElement(expressionWithTypeArguments, other);
555
477
  });
556
478
  }
557
479
  /**
@@ -563,52 +485,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
563
485
  */
564
486
  visitFunctionCall(functionCall, other) {
565
487
  return __awaiter(this, void 0, void 0, function* () {
566
- if (!this.match || other.kind !== tree_1.JS.Kind.FunctionCall) {
567
- this.abort();
568
- return functionCall;
569
- }
570
- const otherFunctionCall = other;
571
- // Compare function
572
- if ((functionCall.function === undefined) !== (otherFunctionCall.function === undefined)) {
573
- this.abort();
574
- return functionCall;
575
- }
576
- // Visit function if present
577
- if (functionCall.function && otherFunctionCall.function) {
578
- yield this.visit(functionCall.function.element, otherFunctionCall.function.element);
579
- if (!this.match)
580
- return functionCall;
581
- }
582
- // Compare typeParameters
583
- if ((functionCall.typeParameters === undefined) !== (otherFunctionCall.typeParameters === undefined)) {
584
- this.abort();
585
- return functionCall;
586
- }
587
- // Visit typeParameters if present
588
- if (functionCall.typeParameters && otherFunctionCall.typeParameters) {
589
- if (functionCall.typeParameters.elements.length !== otherFunctionCall.typeParameters.elements.length) {
590
- this.abort();
591
- return functionCall;
592
- }
593
- // Visit each type parameter in lock step
594
- for (let i = 0; i < functionCall.typeParameters.elements.length; i++) {
595
- yield this.visit(functionCall.typeParameters.elements[i].element, otherFunctionCall.typeParameters.elements[i].element);
596
- if (!this.match)
597
- return functionCall;
598
- }
599
- }
600
- // Compare arguments
601
- if (functionCall.arguments.elements.length !== otherFunctionCall.arguments.elements.length) {
602
- this.abort();
603
- return functionCall;
604
- }
605
- // Visit each argument in lock step
606
- for (let i = 0; i < functionCall.arguments.elements.length; i++) {
607
- yield this.visit(functionCall.arguments.elements[i].element, otherFunctionCall.arguments.elements[i].element);
608
- if (!this.match)
609
- return functionCall;
610
- }
611
- return functionCall;
488
+ return this.visitElement(functionCall, other);
612
489
  });
613
490
  }
614
491
  /**
@@ -620,46 +497,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
620
497
  */
621
498
  visitFunctionType(functionType, other) {
622
499
  return __awaiter(this, void 0, void 0, function* () {
623
- if (!this.match || other.kind !== tree_1.JS.Kind.FunctionType) {
624
- this.abort();
625
- return functionType;
626
- }
627
- const otherFunctionType = other;
628
- // Compare constructor type
629
- if (!!functionType.constructorType.element !== !!otherFunctionType.constructorType.element) {
630
- this.abort();
631
- return functionType;
632
- }
633
- if (functionType.constructorType.element) {
634
- if (functionType.constructorType.element !== otherFunctionType.constructorType.element) {
635
- this.abort();
636
- return functionType;
637
- }
638
- }
639
- // Compare type parameters
640
- if (!!functionType.typeParameters !== !!otherFunctionType.typeParameters) {
641
- this.abort();
642
- return functionType;
643
- }
644
- if (functionType.typeParameters) {
645
- yield this.visit(functionType.typeParameters, otherFunctionType.typeParameters);
646
- if (!this.match)
647
- return functionType;
648
- }
649
- // Compare parameters
650
- if (functionType.parameters.elements.length !== otherFunctionType.parameters.elements.length) {
651
- this.abort();
652
- return functionType;
653
- }
654
- // Visit parameters in lock step
655
- for (let i = 0; i < functionType.parameters.elements.length; i++) {
656
- yield this.visit(functionType.parameters.elements[i].element, otherFunctionType.parameters.elements[i].element);
657
- if (!this.match)
658
- return functionType;
659
- }
660
- // Compare return type
661
- yield this.visit(functionType.returnType.element, otherFunctionType.returnType.element);
662
- return functionType;
500
+ return this.visitElement(functionType, other);
663
501
  });
664
502
  }
665
503
  /**
@@ -671,14 +509,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
671
509
  */
672
510
  visitInferType(inferType, other) {
673
511
  return __awaiter(this, void 0, void 0, function* () {
674
- if (!this.match || other.kind !== tree_1.JS.Kind.InferType) {
675
- this.abort();
676
- return inferType;
677
- }
678
- const otherInferType = other;
679
- // Visit type parameter
680
- yield this.visit(inferType.typeParameter.element, otherInferType.typeParameter.element);
681
- return inferType;
512
+ return this.visitElement(inferType, other);
682
513
  });
683
514
  }
684
515
  /**
@@ -690,55 +521,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
690
521
  */
691
522
  visitImportType(importType, other) {
692
523
  return __awaiter(this, void 0, void 0, function* () {
693
- if (!this.match || other.kind !== tree_1.JS.Kind.ImportType) {
694
- this.abort();
695
- return importType;
696
- }
697
- const otherImportType = other;
698
- // Compare has typeof
699
- if (importType.hasTypeof.element !== otherImportType.hasTypeof.element) {
700
- this.abort();
701
- return importType;
702
- }
703
- // Compare argument and attributes
704
- if (importType.argumentAndAttributes.elements.length !== otherImportType.argumentAndAttributes.elements.length) {
705
- this.abort();
706
- return importType;
707
- }
708
- // Visit argument and attributes in lock step
709
- for (let i = 0; i < importType.argumentAndAttributes.elements.length; i++) {
710
- yield this.visit(importType.argumentAndAttributes.elements[i].element, otherImportType.argumentAndAttributes.elements[i].element);
711
- if (!this.match)
712
- return importType;
713
- }
714
- // Compare qualifier
715
- if (!!importType.qualifier !== !!otherImportType.qualifier) {
716
- this.abort();
717
- return importType;
718
- }
719
- if (importType.qualifier) {
720
- yield this.visit(importType.qualifier.element, otherImportType.qualifier.element);
721
- if (!this.match)
722
- return importType;
723
- }
724
- // Compare type arguments
725
- if (!!importType.typeArguments !== !!otherImportType.typeArguments) {
726
- this.abort();
727
- return importType;
728
- }
729
- if (importType.typeArguments) {
730
- if (importType.typeArguments.elements.length !== otherImportType.typeArguments.elements.length) {
731
- this.abort();
732
- return importType;
733
- }
734
- // Visit type arguments in lock step
735
- for (let i = 0; i < importType.typeArguments.elements.length; i++) {
736
- yield this.visit(importType.typeArguments.elements[i].element, otherImportType.typeArguments.elements[i].element);
737
- if (!this.match)
738
- return importType;
739
- }
740
- }
741
- return importType;
524
+ return this.visitElement(importType, other);
742
525
  });
743
526
  }
744
527
  /**
@@ -750,53 +533,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
750
533
  */
751
534
  visitImportDeclaration(jsImport, other) {
752
535
  return __awaiter(this, void 0, void 0, function* () {
753
- if (!this.match || other.kind !== tree_1.JS.Kind.Import) {
754
- this.abort();
755
- return jsImport;
756
- }
757
- const otherImport = other;
758
- // Compare modifiers
759
- if (jsImport.modifiers.length !== otherImport.modifiers.length) {
760
- this.abort();
761
- return jsImport;
762
- }
763
- // Visit each modifier in lock step
764
- for (let i = 0; i < jsImport.modifiers.length; i++) {
765
- yield this.visit(jsImport.modifiers[i], otherImport.modifiers[i]);
766
- if (!this.match)
767
- return jsImport;
768
- }
769
- // Compare import clause
770
- if (!!jsImport.importClause !== !!otherImport.importClause) {
771
- this.abort();
772
- return jsImport;
773
- }
774
- if (jsImport.importClause) {
775
- yield this.visit(jsImport.importClause, otherImport.importClause);
776
- if (!this.match)
777
- return jsImport;
778
- }
779
- // Visit module specifier
780
- if (jsImport.moduleSpecifier) {
781
- yield this.visit(jsImport.moduleSpecifier.element, otherImport.moduleSpecifier.element);
782
- if (!this.match)
783
- return jsImport;
784
- }
785
- // Compare attributes
786
- if (!!jsImport.attributes !== !!otherImport.attributes) {
787
- this.abort();
788
- return jsImport;
789
- }
790
- if (jsImport.attributes) {
791
- yield this.visit(jsImport.attributes, otherImport.attributes);
792
- }
793
- // Compare initializer
794
- if (jsImport.initializer) {
795
- yield this.visit(jsImport.initializer.element, otherImport.initializer.element);
796
- if (!this.match)
797
- return jsImport;
798
- }
799
- return jsImport;
536
+ return this.visitElement(jsImport, other);
800
537
  });
801
538
  }
802
539
  /**
@@ -808,30 +545,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
808
545
  */
809
546
  visitImportClause(importClause, other) {
810
547
  return __awaiter(this, void 0, void 0, function* () {
811
- if (!this.match || other.kind !== tree_1.JS.Kind.ImportClause) {
812
- this.abort();
813
- return importClause;
814
- }
815
- const otherImportClause = other;
816
- // Compare name
817
- if (!!importClause.name !== !!otherImportClause.name) {
818
- this.abort();
819
- return importClause;
820
- }
821
- if (importClause.name) {
822
- yield this.visit(importClause.name.element, otherImportClause.name.element);
823
- if (!this.match)
824
- return importClause;
825
- }
826
- // Compare named bindings
827
- if (!!importClause.namedBindings !== !!otherImportClause.namedBindings) {
828
- this.abort();
829
- return importClause;
830
- }
831
- if (importClause.namedBindings) {
832
- yield this.visit(importClause.namedBindings, otherImportClause.namedBindings);
833
- }
834
- return importClause;
548
+ return this.visitElement(importClause, other);
835
549
  });
836
550
  }
837
551
  /**
@@ -843,23 +557,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
843
557
  */
844
558
  visitNamedImports(namedImports, other) {
845
559
  return __awaiter(this, void 0, void 0, function* () {
846
- if (!this.match || other.kind !== tree_1.JS.Kind.NamedImports) {
847
- this.abort();
848
- return namedImports;
849
- }
850
- const otherNamedImports = other;
851
- // Compare elements
852
- if (namedImports.elements.elements.length !== otherNamedImports.elements.elements.length) {
853
- this.abort();
854
- return namedImports;
855
- }
856
- // Visit elements in lock step
857
- for (let i = 0; i < namedImports.elements.elements.length; i++) {
858
- yield this.visit(namedImports.elements.elements[i].element, otherNamedImports.elements.elements[i].element);
859
- if (!this.match)
860
- return namedImports;
861
- }
862
- return namedImports;
560
+ return this.visitElement(namedImports, other);
863
561
  });
864
562
  }
865
563
  /**
@@ -871,25 +569,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
871
569
  */
872
570
  visitImportSpecifier(importSpecifier, other) {
873
571
  return __awaiter(this, void 0, void 0, function* () {
874
- if (!this.match || other.kind !== tree_1.JS.Kind.ImportSpecifier) {
875
- this.abort();
876
- return importSpecifier;
877
- }
878
- const otherImportSpecifier = other;
879
- // Compare import type
880
- if (!!importSpecifier.importType.element !== !!otherImportSpecifier.importType.element) {
881
- this.abort();
882
- return importSpecifier;
883
- }
884
- if (importSpecifier.importType.element) {
885
- if (importSpecifier.importType.element !== otherImportSpecifier.importType.element) {
886
- this.abort();
887
- return importSpecifier;
888
- }
889
- }
890
- // Visit specifier
891
- yield this.visit(importSpecifier.specifier, otherImportSpecifier.specifier);
892
- return importSpecifier;
572
+ return this.visitElement(importSpecifier, other);
893
573
  });
894
574
  }
895
575
  /**
@@ -901,23 +581,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
901
581
  */
902
582
  visitImportAttributes(importAttributes, other) {
903
583
  return __awaiter(this, void 0, void 0, function* () {
904
- if (!this.match || other.kind !== tree_1.JS.Kind.ImportAttributes) {
905
- this.abort();
906
- return importAttributes;
907
- }
908
- const otherImportAttributes = other;
909
- // Compare elements
910
- if (importAttributes.elements.elements.length !== otherImportAttributes.elements.elements.length) {
911
- this.abort();
912
- return importAttributes;
913
- }
914
- // Visit elements in lock step
915
- for (let i = 0; i < importAttributes.elements.elements.length; i++) {
916
- yield this.visit(importAttributes.elements.elements[i].element, otherImportAttributes.elements.elements[i].element);
917
- if (!this.match)
918
- return importAttributes;
919
- }
920
- return importAttributes;
584
+ return this.visitElement(importAttributes, other);
921
585
  });
922
586
  }
923
587
  /**
@@ -929,27 +593,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
929
593
  */
930
594
  visitImportTypeAttributes(importTypeAttributes, other) {
931
595
  return __awaiter(this, void 0, void 0, function* () {
932
- if (!this.match || other.kind !== tree_1.JS.Kind.ImportTypeAttributes) {
933
- this.abort();
934
- return importTypeAttributes;
935
- }
936
- const otherImportTypeAttributes = other;
937
- // Compare token
938
- yield this.visit(importTypeAttributes.token.element, otherImportTypeAttributes.token.element);
939
- if (!this.match)
940
- return importTypeAttributes;
941
- // Compare elements
942
- if (importTypeAttributes.elements.elements.length !== otherImportTypeAttributes.elements.elements.length) {
943
- this.abort();
944
- return importTypeAttributes;
945
- }
946
- // Visit elements in lock step
947
- for (let i = 0; i < importTypeAttributes.elements.elements.length; i++) {
948
- yield this.visit(importTypeAttributes.elements.elements[i].element, otherImportTypeAttributes.elements.elements[i].element);
949
- if (!this.match)
950
- return importTypeAttributes;
951
- }
952
- return importTypeAttributes;
596
+ return this.visitElement(importTypeAttributes, other);
953
597
  });
954
598
  }
955
599
  /**
@@ -961,18 +605,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
961
605
  */
962
606
  visitImportAttribute(importAttribute, other) {
963
607
  return __awaiter(this, void 0, void 0, function* () {
964
- if (!this.match || other.kind !== tree_1.JS.Kind.ImportAttribute) {
965
- this.abort();
966
- return importAttribute;
967
- }
968
- const otherImportAttribute = other;
969
- // Visit name
970
- yield this.visit(importAttribute.name, otherImportAttribute.name);
971
- if (!this.match)
972
- return importAttribute;
973
- // Visit value
974
- yield this.visit(importAttribute.value.element, otherImportAttribute.value.element);
975
- return importAttribute;
608
+ return this.visitElement(importAttribute, other);
976
609
  });
977
610
  }
978
611
  /**
@@ -984,23 +617,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
984
617
  */
985
618
  visitBinaryExtensions(jsBinary, other) {
986
619
  return __awaiter(this, void 0, void 0, function* () {
987
- if (!this.match || other.kind !== tree_1.JS.Kind.Binary) {
988
- this.abort();
989
- return jsBinary;
990
- }
991
- const otherBinary = other;
992
- // Visit left operand
993
- yield this.visit(jsBinary.left, otherBinary.left);
994
- if (!this.match)
995
- return jsBinary;
996
- // Compare operator
997
- if (jsBinary.operator.element !== otherBinary.operator.element) {
998
- this.abort();
999
- return jsBinary;
1000
- }
1001
- // Visit right operand
1002
- yield this.visit(jsBinary.right, otherBinary.right);
1003
- return jsBinary;
620
+ return this.visitElement(jsBinary, other);
1004
621
  });
1005
622
  }
1006
623
  /**
@@ -1012,14 +629,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
1012
629
  */
1013
630
  visitLiteralType(literalType, other) {
1014
631
  return __awaiter(this, void 0, void 0, function* () {
1015
- if (!this.match || other.kind !== tree_1.JS.Kind.LiteralType) {
1016
- this.abort();
1017
- return literalType;
1018
- }
1019
- const otherLiteralType = other;
1020
- // Visit literal
1021
- yield this.visit(literalType.literal, otherLiteralType.literal);
1022
- return literalType;
632
+ return this.visitElement(literalType, other);
1023
633
  });
1024
634
  }
1025
635
  /**
@@ -1031,57 +641,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
1031
641
  */
1032
642
  visitMappedType(mappedType, other) {
1033
643
  return __awaiter(this, void 0, void 0, function* () {
1034
- if (!this.match || other.kind !== tree_1.JS.Kind.MappedType) {
1035
- this.abort();
1036
- return mappedType;
1037
- }
1038
- const otherMappedType = other;
1039
- // Compare prefix token
1040
- if (!!mappedType.prefixToken !== !!otherMappedType.prefixToken) {
1041
- this.abort();
1042
- return mappedType;
1043
- }
1044
- if (mappedType.prefixToken) {
1045
- yield this.visit(mappedType.prefixToken.element, otherMappedType.prefixToken.element);
1046
- if (!this.match)
1047
- return mappedType;
1048
- }
1049
- // Compare has readonly
1050
- if (mappedType.hasReadonly.element !== otherMappedType.hasReadonly.element) {
1051
- this.abort();
1052
- return mappedType;
1053
- }
1054
- // Visit keys remapping
1055
- yield this.visit(mappedType.keysRemapping, otherMappedType.keysRemapping);
1056
- if (!this.match)
1057
- return mappedType;
1058
- // Compare suffix token
1059
- if (!!mappedType.suffixToken !== !!otherMappedType.suffixToken) {
1060
- this.abort();
1061
- return mappedType;
1062
- }
1063
- if (mappedType.suffixToken) {
1064
- yield this.visit(mappedType.suffixToken.element, otherMappedType.suffixToken.element);
1065
- if (!this.match)
1066
- return mappedType;
1067
- }
1068
- // Compare has question token
1069
- if (mappedType.hasQuestionToken.element !== otherMappedType.hasQuestionToken.element) {
1070
- this.abort();
1071
- return mappedType;
1072
- }
1073
- // Compare value type
1074
- if (mappedType.valueType.elements.length !== otherMappedType.valueType.elements.length) {
1075
- this.abort();
1076
- return mappedType;
1077
- }
1078
- // Visit value type elements in lock step
1079
- for (let i = 0; i < mappedType.valueType.elements.length; i++) {
1080
- yield this.visit(mappedType.valueType.elements[i].element, otherMappedType.valueType.elements[i].element);
1081
- if (!this.match)
1082
- return mappedType;
1083
- }
1084
- return mappedType;
644
+ return this.visitElement(mappedType, other);
1085
645
  });
1086
646
  }
1087
647
  /**
@@ -1093,24 +653,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
1093
653
  */
1094
654
  visitMappedTypeKeysRemapping(keysRemapping, other) {
1095
655
  return __awaiter(this, void 0, void 0, function* () {
1096
- if (!this.match || other.kind !== tree_1.JS.Kind.MappedTypeKeysRemapping) {
1097
- this.abort();
1098
- return keysRemapping;
1099
- }
1100
- const otherKeysRemapping = other;
1101
- // Visit type parameter
1102
- yield this.visit(keysRemapping.typeParameter.element, otherKeysRemapping.typeParameter.element);
1103
- if (!this.match)
1104
- return keysRemapping;
1105
- // Compare name type
1106
- if (!!keysRemapping.nameType !== !!otherKeysRemapping.nameType) {
1107
- this.abort();
1108
- return keysRemapping;
1109
- }
1110
- if (keysRemapping.nameType) {
1111
- yield this.visit(keysRemapping.nameType.element, otherKeysRemapping.nameType.element);
1112
- }
1113
- return keysRemapping;
656
+ return this.visitElement(keysRemapping, other);
1114
657
  });
1115
658
  }
1116
659
  /**
@@ -1122,18 +665,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
1122
665
  */
1123
666
  visitMappedTypeParameter(mappedTypeParameter, other) {
1124
667
  return __awaiter(this, void 0, void 0, function* () {
1125
- if (!this.match || other.kind !== tree_1.JS.Kind.MappedTypeParameter) {
1126
- this.abort();
1127
- return mappedTypeParameter;
1128
- }
1129
- const otherMappedTypeParameter = other;
1130
- // Visit name
1131
- yield this.visit(mappedTypeParameter.name, otherMappedTypeParameter.name);
1132
- if (!this.match)
1133
- return mappedTypeParameter;
1134
- // Visit iterate type
1135
- yield this.visit(mappedTypeParameter.iterateType.element, otherMappedTypeParameter.iterateType.element);
1136
- return mappedTypeParameter;
668
+ return this.visitElement(mappedTypeParameter, other);
1137
669
  });
1138
670
  }
1139
671
  /**
@@ -1145,63 +677,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
1145
677
  */
1146
678
  visitObjectBindingPattern(objectBindingPattern, other) {
1147
679
  return __awaiter(this, void 0, void 0, function* () {
1148
- if (!this.match || other.kind !== tree_1.JS.Kind.ObjectBindingPattern) {
1149
- this.abort();
1150
- return objectBindingPattern;
1151
- }
1152
- const otherObjectBindingPattern = other;
1153
- // Compare leading annotations
1154
- if (objectBindingPattern.leadingAnnotations.length !== otherObjectBindingPattern.leadingAnnotations.length) {
1155
- this.abort();
1156
- return objectBindingPattern;
1157
- }
1158
- // Visit leading annotations in lock step
1159
- for (let i = 0; i < objectBindingPattern.leadingAnnotations.length; i++) {
1160
- yield this.visit(objectBindingPattern.leadingAnnotations[i], otherObjectBindingPattern.leadingAnnotations[i]);
1161
- if (!this.match)
1162
- return objectBindingPattern;
1163
- }
1164
- // Compare modifiers
1165
- if (objectBindingPattern.modifiers.length !== otherObjectBindingPattern.modifiers.length) {
1166
- this.abort();
1167
- return objectBindingPattern;
1168
- }
1169
- // Visit modifiers in lock step
1170
- for (let i = 0; i < objectBindingPattern.modifiers.length; i++) {
1171
- yield this.visit(objectBindingPattern.modifiers[i], otherObjectBindingPattern.modifiers[i]);
1172
- if (!this.match)
1173
- return objectBindingPattern;
1174
- }
1175
- // Compare type expression
1176
- if (!!objectBindingPattern.typeExpression !== !!otherObjectBindingPattern.typeExpression) {
1177
- this.abort();
1178
- return objectBindingPattern;
1179
- }
1180
- if (objectBindingPattern.typeExpression) {
1181
- yield this.visit(objectBindingPattern.typeExpression, otherObjectBindingPattern.typeExpression);
1182
- if (!this.match)
1183
- return objectBindingPattern;
1184
- }
1185
- // Compare bindings
1186
- if (objectBindingPattern.bindings.elements.length !== otherObjectBindingPattern.bindings.elements.length) {
1187
- this.abort();
1188
- return objectBindingPattern;
1189
- }
1190
- // Visit bindings in lock step
1191
- for (let i = 0; i < objectBindingPattern.bindings.elements.length; i++) {
1192
- yield this.visit(objectBindingPattern.bindings.elements[i].element, otherObjectBindingPattern.bindings.elements[i].element);
1193
- if (!this.match)
1194
- return objectBindingPattern;
1195
- }
1196
- // Compare initializer
1197
- if (!!objectBindingPattern.initializer !== !!otherObjectBindingPattern.initializer) {
1198
- this.abort();
1199
- return objectBindingPattern;
1200
- }
1201
- if (objectBindingPattern.initializer) {
1202
- yield this.visit(objectBindingPattern.initializer.element, otherObjectBindingPattern.initializer.element);
1203
- }
1204
- return objectBindingPattern;
680
+ return this.visitElement(objectBindingPattern, other);
1205
681
  });
1206
682
  }
1207
683
  /**
@@ -1213,24 +689,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
1213
689
  */
1214
690
  visitPropertyAssignment(propertyAssignment, other) {
1215
691
  return __awaiter(this, void 0, void 0, function* () {
1216
- if (!this.match || other.kind !== tree_1.JS.Kind.PropertyAssignment) {
1217
- this.abort();
1218
- return propertyAssignment;
1219
- }
1220
- const otherPropertyAssignment = other;
1221
- // Visit name
1222
- yield this.visit(propertyAssignment.name.element, otherPropertyAssignment.name.element);
1223
- if (!this.match)
1224
- return propertyAssignment;
1225
- // Compare initializer
1226
- if (!!propertyAssignment.initializer !== !!otherPropertyAssignment.initializer) {
1227
- this.abort();
1228
- return propertyAssignment;
1229
- }
1230
- if (propertyAssignment.initializer) {
1231
- yield this.visit(propertyAssignment.initializer, otherPropertyAssignment.initializer);
1232
- }
1233
- return propertyAssignment;
692
+ return this.visitElement(propertyAssignment, other);
1234
693
  });
1235
694
  }
1236
695
  /**
@@ -1242,18 +701,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
1242
701
  */
1243
702
  visitSatisfiesExpression(satisfiesExpression, other) {
1244
703
  return __awaiter(this, void 0, void 0, function* () {
1245
- if (!this.match || other.kind !== tree_1.JS.Kind.SatisfiesExpression) {
1246
- this.abort();
1247
- return satisfiesExpression;
1248
- }
1249
- const otherSatisfiesExpression = other;
1250
- // Visit expression
1251
- yield this.visit(satisfiesExpression.expression, otherSatisfiesExpression.expression);
1252
- if (!this.match)
1253
- return satisfiesExpression;
1254
- // Visit satisfies type
1255
- yield this.visit(satisfiesExpression.satisfiesType.element, otherSatisfiesExpression.satisfiesType.element);
1256
- return satisfiesExpression;
704
+ return this.visitElement(satisfiesExpression, other);
1257
705
  });
1258
706
  }
1259
707
  /**
@@ -1265,34 +713,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
1265
713
  */
1266
714
  visitScopedVariableDeclarations(scopedVariableDeclarations, other) {
1267
715
  return __awaiter(this, void 0, void 0, function* () {
1268
- if (!this.match || other.kind !== tree_1.JS.Kind.ScopedVariableDeclarations) {
1269
- this.abort();
1270
- return scopedVariableDeclarations;
1271
- }
1272
- const otherScopedVariableDeclarations = other;
1273
- // Compare modifiers
1274
- if (scopedVariableDeclarations.modifiers.length !== otherScopedVariableDeclarations.modifiers.length) {
1275
- this.abort();
1276
- return scopedVariableDeclarations;
1277
- }
1278
- // Visit modifiers in lock step
1279
- for (let i = 0; i < scopedVariableDeclarations.modifiers.length; i++) {
1280
- yield this.visit(scopedVariableDeclarations.modifiers[i], otherScopedVariableDeclarations.modifiers[i]);
1281
- if (!this.match)
1282
- return scopedVariableDeclarations;
1283
- }
1284
- // Compare variables
1285
- if (scopedVariableDeclarations.variables.length !== otherScopedVariableDeclarations.variables.length) {
1286
- this.abort();
1287
- return scopedVariableDeclarations;
1288
- }
1289
- // Visit variables in lock step
1290
- for (let i = 0; i < scopedVariableDeclarations.variables.length; i++) {
1291
- yield this.visit(scopedVariableDeclarations.variables[i].element, otherScopedVariableDeclarations.variables[i].element);
1292
- if (!this.match)
1293
- return scopedVariableDeclarations;
1294
- }
1295
- return scopedVariableDeclarations;
716
+ return this.visitElement(scopedVariableDeclarations, other);
1296
717
  });
1297
718
  }
1298
719
  /**
@@ -1304,14 +725,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
1304
725
  */
1305
726
  visitStatementExpression(statementExpression, other) {
1306
727
  return __awaiter(this, void 0, void 0, function* () {
1307
- if (!this.match || other.kind !== tree_1.JS.Kind.StatementExpression) {
1308
- this.abort();
1309
- return statementExpression;
1310
- }
1311
- const otherStatementExpression = other;
1312
- // Visit statement
1313
- yield this.visit(statementExpression.statement, otherStatementExpression.statement);
1314
- return statementExpression;
728
+ return this.visitElement(statementExpression, other);
1315
729
  });
1316
730
  }
1317
731
  /**
@@ -1323,41 +737,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
1323
737
  */
1324
738
  visitTaggedTemplateExpression(taggedTemplateExpression, other) {
1325
739
  return __awaiter(this, void 0, void 0, function* () {
1326
- if (!this.match || other.kind !== tree_1.JS.Kind.TaggedTemplateExpression) {
1327
- this.abort();
1328
- return taggedTemplateExpression;
1329
- }
1330
- const otherTaggedTemplateExpression = other;
1331
- // Compare tag
1332
- if (!!taggedTemplateExpression.tag !== !!otherTaggedTemplateExpression.tag) {
1333
- this.abort();
1334
- return taggedTemplateExpression;
1335
- }
1336
- if (taggedTemplateExpression.tag) {
1337
- yield this.visit(taggedTemplateExpression.tag.element, otherTaggedTemplateExpression.tag.element);
1338
- if (!this.match)
1339
- return taggedTemplateExpression;
1340
- }
1341
- // Compare type arguments
1342
- if (!!taggedTemplateExpression.typeArguments !== !!otherTaggedTemplateExpression.typeArguments) {
1343
- this.abort();
1344
- return taggedTemplateExpression;
1345
- }
1346
- if (taggedTemplateExpression.typeArguments) {
1347
- if (taggedTemplateExpression.typeArguments.elements.length !== otherTaggedTemplateExpression.typeArguments.elements.length) {
1348
- this.abort();
1349
- return taggedTemplateExpression;
1350
- }
1351
- // Visit type arguments in lock step
1352
- for (let i = 0; i < taggedTemplateExpression.typeArguments.elements.length; i++) {
1353
- yield this.visit(taggedTemplateExpression.typeArguments.elements[i].element, otherTaggedTemplateExpression.typeArguments.elements[i].element);
1354
- if (!this.match)
1355
- return taggedTemplateExpression;
1356
- }
1357
- }
1358
- // Visit template expression
1359
- yield this.visit(taggedTemplateExpression.templateExpression, otherTaggedTemplateExpression.templateExpression);
1360
- return taggedTemplateExpression;
740
+ return this.visitElement(taggedTemplateExpression, other);
1361
741
  });
1362
742
  }
1363
743
  /**
@@ -1369,27 +749,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
1369
749
  */
1370
750
  visitTemplateExpression(templateExpression, other) {
1371
751
  return __awaiter(this, void 0, void 0, function* () {
1372
- if (!this.match || other.kind !== tree_1.JS.Kind.TemplateExpression) {
1373
- this.abort();
1374
- return templateExpression;
1375
- }
1376
- const otherTemplateExpression = other;
1377
- // Visit head
1378
- yield this.visit(templateExpression.head, otherTemplateExpression.head);
1379
- if (!this.match)
1380
- return templateExpression;
1381
- // Compare spans
1382
- if (templateExpression.spans.length !== otherTemplateExpression.spans.length) {
1383
- this.abort();
1384
- return templateExpression;
1385
- }
1386
- // Visit spans in lock step
1387
- for (let i = 0; i < templateExpression.spans.length; i++) {
1388
- yield this.visit(templateExpression.spans[i].element, otherTemplateExpression.spans[i].element);
1389
- if (!this.match)
1390
- return templateExpression;
1391
- }
1392
- return templateExpression;
752
+ return this.visitElement(templateExpression, other);
1393
753
  });
1394
754
  }
1395
755
  /**
@@ -1401,18 +761,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
1401
761
  */
1402
762
  visitTemplateExpressionSpan(span, other) {
1403
763
  return __awaiter(this, void 0, void 0, function* () {
1404
- if (!this.match || other.kind !== tree_1.JS.Kind.TemplateExpressionSpan) {
1405
- this.abort();
1406
- return span;
1407
- }
1408
- const otherSpan = other;
1409
- // Visit expression
1410
- yield this.visit(span.expression, otherSpan.expression);
1411
- if (!this.match)
1412
- return span;
1413
- // Visit tail
1414
- yield this.visit(span.tail, otherSpan.tail);
1415
- return span;
764
+ return this.visitElement(span, other);
1416
765
  });
1417
766
  }
1418
767
  /**
@@ -1424,23 +773,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
1424
773
  */
1425
774
  visitTuple(tuple, other) {
1426
775
  return __awaiter(this, void 0, void 0, function* () {
1427
- if (!this.match || other.kind !== tree_1.JS.Kind.Tuple) {
1428
- this.abort();
1429
- return tuple;
1430
- }
1431
- const otherTuple = other;
1432
- // Compare elements
1433
- if (tuple.elements.elements.length !== otherTuple.elements.elements.length) {
1434
- this.abort();
1435
- return tuple;
1436
- }
1437
- // Visit elements in lock step
1438
- for (let i = 0; i < tuple.elements.elements.length; i++) {
1439
- yield this.visit(tuple.elements.elements[i].element, otherTuple.elements.elements[i].element);
1440
- if (!this.match)
1441
- return tuple;
1442
- }
1443
- return tuple;
776
+ return this.visitElement(tuple, other);
1444
777
  });
1445
778
  }
1446
779
  /**
@@ -1452,39 +785,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
1452
785
  */
1453
786
  visitTypeDeclaration(typeDeclaration, other) {
1454
787
  return __awaiter(this, void 0, void 0, function* () {
1455
- if (!this.match || other.kind !== tree_1.JS.Kind.TypeDeclaration) {
1456
- this.abort();
1457
- return typeDeclaration;
1458
- }
1459
- const otherTypeDeclaration = other;
1460
- // Compare modifiers
1461
- if (typeDeclaration.modifiers.length !== otherTypeDeclaration.modifiers.length) {
1462
- this.abort();
1463
- return typeDeclaration;
1464
- }
1465
- // Visit modifiers in lock step
1466
- for (let i = 0; i < typeDeclaration.modifiers.length; i++) {
1467
- yield this.visit(typeDeclaration.modifiers[i], otherTypeDeclaration.modifiers[i]);
1468
- if (!this.match)
1469
- return typeDeclaration;
1470
- }
1471
- // Visit name
1472
- yield this.visit(typeDeclaration.name.element, otherTypeDeclaration.name.element);
1473
- if (!this.match)
1474
- return typeDeclaration;
1475
- // Compare type parameters
1476
- if (!!typeDeclaration.typeParameters !== !!otherTypeDeclaration.typeParameters) {
1477
- this.abort();
1478
- return typeDeclaration;
1479
- }
1480
- if (typeDeclaration.typeParameters) {
1481
- yield this.visit(typeDeclaration.typeParameters, otherTypeDeclaration.typeParameters);
1482
- if (!this.match)
1483
- return typeDeclaration;
1484
- }
1485
- // Visit initializer
1486
- yield this.visit(typeDeclaration.initializer.element, otherTypeDeclaration.initializer.element);
1487
- return typeDeclaration;
788
+ return this.visitElement(typeDeclaration, other);
1488
789
  });
1489
790
  }
1490
791
  /**
@@ -1496,14 +797,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
1496
797
  */
1497
798
  visitTypeOf(typeOf, other) {
1498
799
  return __awaiter(this, void 0, void 0, function* () {
1499
- if (!this.match || other.kind !== tree_1.JS.Kind.TypeOf) {
1500
- this.abort();
1501
- return typeOf;
1502
- }
1503
- const otherTypeOf = other;
1504
- // Visit expression
1505
- yield this.visit(typeOf.expression, otherTypeOf.expression);
1506
- return typeOf;
800
+ return this.visitElement(typeOf, other);
1507
801
  });
1508
802
  }
1509
803
  /**
@@ -1515,14 +809,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
1515
809
  */
1516
810
  visitTypeTreeExpression(typeTreeExpression, other) {
1517
811
  return __awaiter(this, void 0, void 0, function* () {
1518
- if (!this.match || other.kind !== tree_1.JS.Kind.TypeTreeExpression) {
1519
- this.abort();
1520
- return typeTreeExpression;
1521
- }
1522
- const otherTypeTreeExpression = other;
1523
- // Visit expression
1524
- yield this.visit(typeTreeExpression.expression, otherTypeTreeExpression.expression);
1525
- return typeTreeExpression;
812
+ return this.visitElement(typeTreeExpression, other);
1526
813
  });
1527
814
  }
1528
815
  /**
@@ -1534,17 +821,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
1534
821
  */
1535
822
  visitAs(as_, other) {
1536
823
  return __awaiter(this, void 0, void 0, function* () {
1537
- if (!this.match || other.kind !== tree_1.JS.Kind.As) {
1538
- this.abort();
1539
- return as_;
1540
- }
1541
- const otherAs = other;
1542
- // Visit left and right operands in lock step
1543
- yield this.visit(as_.left.element, otherAs.left.element);
1544
- if (!this.match)
1545
- return as_;
1546
- yield this.visit(as_.right, otherAs.right);
1547
- return as_;
824
+ return this.visitElement(as_, other);
1548
825
  });
1549
826
  }
1550
827
  /**
@@ -1556,23 +833,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
1556
833
  */
1557
834
  visitAssignmentOperationExtensions(assignmentOperation, other) {
1558
835
  return __awaiter(this, void 0, void 0, function* () {
1559
- if (!this.match || other.kind !== tree_1.JS.Kind.AssignmentOperation) {
1560
- this.abort();
1561
- return assignmentOperation;
1562
- }
1563
- const otherAssignmentOperation = other;
1564
- // Visit variable
1565
- yield this.visit(assignmentOperation.variable, otherAssignmentOperation.variable);
1566
- if (!this.match)
1567
- return assignmentOperation;
1568
- // Compare operator
1569
- if (assignmentOperation.operator.element !== otherAssignmentOperation.operator.element) {
1570
- this.abort();
1571
- return assignmentOperation;
1572
- }
1573
- // Visit assignment
1574
- yield this.visit(assignmentOperation.assignment, otherAssignmentOperation.assignment);
1575
- return assignmentOperation;
836
+ return this.visitElement(assignmentOperation, other);
1576
837
  });
1577
838
  }
1578
839
  /**
@@ -1584,18 +845,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
1584
845
  */
1585
846
  visitIndexedAccessType(indexedAccessType, other) {
1586
847
  return __awaiter(this, void 0, void 0, function* () {
1587
- if (!this.match || other.kind !== tree_1.JS.Kind.IndexedAccessType) {
1588
- this.abort();
1589
- return indexedAccessType;
1590
- }
1591
- const otherIndexedAccessType = other;
1592
- // Visit object type
1593
- yield this.visit(indexedAccessType.objectType, otherIndexedAccessType.objectType);
1594
- if (!this.match)
1595
- return indexedAccessType;
1596
- // Visit index type
1597
- yield this.visit(indexedAccessType.indexType, otherIndexedAccessType.indexType);
1598
- return indexedAccessType;
848
+ return this.visitElement(indexedAccessType, other);
1599
849
  });
1600
850
  }
1601
851
  /**
@@ -1607,14 +857,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
1607
857
  */
1608
858
  visitIndexedAccessTypeIndexType(indexType, other) {
1609
859
  return __awaiter(this, void 0, void 0, function* () {
1610
- if (!this.match || other.kind !== tree_1.JS.Kind.IndexType) {
1611
- this.abort();
1612
- return indexType;
1613
- }
1614
- const otherIndexType = other;
1615
- // Visit element
1616
- yield this.visit(indexType.element.element, otherIndexType.element.element);
1617
- return indexType;
860
+ return this.visitElement(indexType, other);
1618
861
  });
1619
862
  }
1620
863
  /**
@@ -1626,33 +869,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
1626
869
  */
1627
870
  visitTypeQuery(typeQuery, other) {
1628
871
  return __awaiter(this, void 0, void 0, function* () {
1629
- if (!this.match || other.kind !== tree_1.JS.Kind.TypeQuery) {
1630
- this.abort();
1631
- return typeQuery;
1632
- }
1633
- const otherTypeQuery = other;
1634
- // Visit type expression
1635
- yield this.visit(typeQuery.typeExpression, otherTypeQuery.typeExpression);
1636
- if (!this.match)
1637
- return typeQuery;
1638
- // Compare type arguments
1639
- if (!!typeQuery.typeArguments !== !!otherTypeQuery.typeArguments) {
1640
- this.abort();
1641
- return typeQuery;
1642
- }
1643
- if (typeQuery.typeArguments) {
1644
- if (typeQuery.typeArguments.elements.length !== otherTypeQuery.typeArguments.elements.length) {
1645
- this.abort();
1646
- return typeQuery;
1647
- }
1648
- // Visit type arguments in lock step
1649
- for (let i = 0; i < typeQuery.typeArguments.elements.length; i++) {
1650
- yield this.visit(typeQuery.typeArguments.elements[i].element, otherTypeQuery.typeArguments.elements[i].element);
1651
- if (!this.match)
1652
- return typeQuery;
1653
- }
1654
- }
1655
- return typeQuery;
872
+ return this.visitElement(typeQuery, other);
1656
873
  });
1657
874
  }
1658
875
  /**
@@ -1664,14 +881,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
1664
881
  */
1665
882
  visitTypeInfo(typeInfo, other) {
1666
883
  return __awaiter(this, void 0, void 0, function* () {
1667
- if (!this.match || other.kind !== tree_1.JS.Kind.TypeInfo) {
1668
- this.abort();
1669
- return typeInfo;
1670
- }
1671
- const otherTypeInfo = other;
1672
- // Visit type identifier
1673
- yield this.visit(typeInfo.typeIdentifier, otherTypeInfo.typeIdentifier);
1674
- return typeInfo;
884
+ return this.visitElement(typeInfo, other);
1675
885
  });
1676
886
  }
1677
887
  /**
@@ -1683,14 +893,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
1683
893
  */
1684
894
  visitComputedPropertyName(computedPropertyName, other) {
1685
895
  return __awaiter(this, void 0, void 0, function* () {
1686
- if (!this.match || other.kind !== tree_1.JS.Kind.ComputedPropertyName) {
1687
- this.abort();
1688
- return computedPropertyName;
1689
- }
1690
- const otherComputedPropertyName = other;
1691
- // Visit expression
1692
- yield this.visit(computedPropertyName.expression.element, otherComputedPropertyName.expression.element);
1693
- return computedPropertyName;
896
+ return this.visitElement(computedPropertyName, other);
1694
897
  });
1695
898
  }
1696
899
  /**
@@ -1702,14 +905,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
1702
905
  */
1703
906
  visitTypeOperator(typeOperator, other) {
1704
907
  return __awaiter(this, void 0, void 0, function* () {
1705
- if (!this.match || other.kind !== tree_1.JS.Kind.TypeOperator) {
1706
- this.abort();
1707
- return typeOperator;
1708
- }
1709
- const otherTypeOperator = other;
1710
- // Visit expression
1711
- yield this.visit(typeOperator.expression.element, otherTypeOperator.expression.element);
1712
- return typeOperator;
908
+ return this.visitElement(typeOperator, other);
1713
909
  });
1714
910
  }
1715
911
  /**
@@ -1721,29 +917,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
1721
917
  */
1722
918
  visitTypePredicate(typePredicate, other) {
1723
919
  return __awaiter(this, void 0, void 0, function* () {
1724
- if (!this.match || other.kind !== tree_1.JS.Kind.TypePredicate) {
1725
- this.abort();
1726
- return typePredicate;
1727
- }
1728
- const otherTypePredicate = other;
1729
- // Compare asserts
1730
- if (typePredicate.asserts.element !== otherTypePredicate.asserts.element) {
1731
- this.abort();
1732
- return typePredicate;
1733
- }
1734
- // Visit parameter name
1735
- yield this.visit(typePredicate.parameterName, otherTypePredicate.parameterName);
1736
- if (!this.match)
1737
- return typePredicate;
1738
- // Compare expression
1739
- if (!!typePredicate.expression !== !!otherTypePredicate.expression) {
1740
- this.abort();
1741
- return typePredicate;
1742
- }
1743
- if (typePredicate.expression) {
1744
- yield this.visit(typePredicate.expression.element, otherTypePredicate.expression.element);
1745
- }
1746
- return typePredicate;
920
+ return this.visitElement(typePredicate, other);
1747
921
  });
1748
922
  }
1749
923
  /**
@@ -1755,23 +929,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
1755
929
  */
1756
930
  visitUnion(union, other) {
1757
931
  return __awaiter(this, void 0, void 0, function* () {
1758
- if (!this.match || other.kind !== tree_1.JS.Kind.Union) {
1759
- this.abort();
1760
- return union;
1761
- }
1762
- const otherUnion = other;
1763
- // Compare types
1764
- if (union.types.length !== otherUnion.types.length) {
1765
- this.abort();
1766
- return union;
1767
- }
1768
- // Visit types in lock step
1769
- for (let i = 0; i < union.types.length; i++) {
1770
- yield this.visit(union.types[i].element, otherUnion.types[i].element);
1771
- if (!this.match)
1772
- return union;
1773
- }
1774
- return union;
932
+ return this.visitElement(union, other);
1775
933
  });
1776
934
  }
1777
935
  /**
@@ -1783,23 +941,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
1783
941
  */
1784
942
  visitIntersection(intersection, other) {
1785
943
  return __awaiter(this, void 0, void 0, function* () {
1786
- if (!this.match || other.kind !== tree_1.JS.Kind.Intersection) {
1787
- this.abort();
1788
- return intersection;
1789
- }
1790
- const otherIntersection = other;
1791
- // Compare types
1792
- if (intersection.types.length !== otherIntersection.types.length) {
1793
- this.abort();
1794
- return intersection;
1795
- }
1796
- // Visit types in lock step
1797
- for (let i = 0; i < intersection.types.length; i++) {
1798
- yield this.visit(intersection.types[i].element, otherIntersection.types[i].element);
1799
- if (!this.match)
1800
- return intersection;
1801
- }
1802
- return intersection;
944
+ return this.visitElement(intersection, other);
1803
945
  });
1804
946
  }
1805
947
  /**
@@ -1811,25 +953,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
1811
953
  */
1812
954
  visitAnnotatedType(annotatedType, other) {
1813
955
  return __awaiter(this, void 0, void 0, function* () {
1814
- if (!this.match || other.kind !== java_1.J.Kind.AnnotatedType) {
1815
- this.abort();
1816
- return annotatedType;
1817
- }
1818
- const otherAnnotatedType = other;
1819
- // Compare annotations
1820
- if (annotatedType.annotations.length !== otherAnnotatedType.annotations.length) {
1821
- this.abort();
1822
- return annotatedType;
1823
- }
1824
- // Visit each annotation in lock step
1825
- for (let i = 0; i < annotatedType.annotations.length; i++) {
1826
- yield this.visit(annotatedType.annotations[i], otherAnnotatedType.annotations[i]);
1827
- if (!this.match)
1828
- return annotatedType;
1829
- }
1830
- // Visit type expression
1831
- yield this.visit(annotatedType.typeExpression, otherAnnotatedType.typeExpression);
1832
- return annotatedType;
956
+ return this.visitElement(annotatedType, other);
1833
957
  });
1834
958
  }
1835
959
  /**
@@ -1841,34 +965,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
1841
965
  */
1842
966
  visitAnnotation(annotation, other) {
1843
967
  return __awaiter(this, void 0, void 0, function* () {
1844
- if (!this.match || other.kind !== java_1.J.Kind.Annotation) {
1845
- this.abort();
1846
- return annotation;
1847
- }
1848
- const otherAnnotation = other;
1849
- // Visit annotation type
1850
- yield this.visit(annotation.annotationType, otherAnnotation.annotationType);
1851
- if (!this.match)
1852
- return annotation;
1853
- // Compare arguments
1854
- if ((annotation.arguments === undefined) !== (otherAnnotation.arguments === undefined)) {
1855
- this.abort();
1856
- return annotation;
1857
- }
1858
- // If both have arguments, visit them
1859
- if (annotation.arguments && otherAnnotation.arguments) {
1860
- if (annotation.arguments.elements.length !== otherAnnotation.arguments.elements.length) {
1861
- this.abort();
1862
- return annotation;
1863
- }
1864
- // Visit each argument in lock step
1865
- for (let i = 0; i < annotation.arguments.elements.length; i++) {
1866
- yield this.visit(annotation.arguments.elements[i].element, otherAnnotation.arguments.elements[i].element);
1867
- if (!this.match)
1868
- return annotation;
1869
- }
1870
- }
1871
- return annotation;
968
+ return this.visitElement(annotation, other);
1872
969
  });
1873
970
  }
1874
971
  /**
@@ -1880,18 +977,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
1880
977
  */
1881
978
  visitArrayAccess(arrayAccess, other) {
1882
979
  return __awaiter(this, void 0, void 0, function* () {
1883
- if (!this.match || other.kind !== java_1.J.Kind.ArrayAccess) {
1884
- this.abort();
1885
- return arrayAccess;
1886
- }
1887
- const otherArrayAccess = other;
1888
- // Visit indexed expression
1889
- yield this.visit(arrayAccess.indexed, otherArrayAccess.indexed);
1890
- if (!this.match)
1891
- return arrayAccess;
1892
- // Visit dimension
1893
- yield this.visit(arrayAccess.dimension, otherArrayAccess.dimension);
1894
- return arrayAccess;
980
+ return this.visitElement(arrayAccess, other);
1895
981
  });
1896
982
  }
1897
983
  /**
@@ -1903,20 +989,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
1903
989
  */
1904
990
  visitArrayDimension(arrayDimension, other) {
1905
991
  return __awaiter(this, void 0, void 0, function* () {
1906
- if (!this.match || other.kind !== java_1.J.Kind.ArrayDimension) {
1907
- this.abort();
1908
- return arrayDimension;
1909
- }
1910
- const otherArrayDimension = other;
1911
- // Visit index
1912
- if (arrayDimension.index && otherArrayDimension.index) {
1913
- yield this.visit(arrayDimension.index.element, otherArrayDimension.index.element);
1914
- }
1915
- else if (arrayDimension.index !== otherArrayDimension.index) {
1916
- // One has an index and the other doesn't
1917
- this.abort();
1918
- }
1919
- return arrayDimension;
992
+ return this.visitElement(arrayDimension, other);
1920
993
  });
1921
994
  }
1922
995
  /**
@@ -1928,30 +1001,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
1928
1001
  */
1929
1002
  visitArrayType(arrayType, other) {
1930
1003
  return __awaiter(this, void 0, void 0, function* () {
1931
- var _a, _b;
1932
- if (!this.match || other.kind !== java_1.J.Kind.ArrayType) {
1933
- this.abort();
1934
- return arrayType;
1935
- }
1936
- const otherArrayType = other;
1937
- // Visit element type
1938
- yield this.visit(arrayType.elementType, otherArrayType.elementType);
1939
- if (!this.match)
1940
- return arrayType;
1941
- // Compare annotations
1942
- if ((((_a = arrayType.annotations) === null || _a === void 0 ? void 0 : _a.length) || 0) !== (((_b = otherArrayType.annotations) === null || _b === void 0 ? void 0 : _b.length) || 0)) {
1943
- this.abort();
1944
- return arrayType;
1945
- }
1946
- // Visit annotations if they exist
1947
- if (arrayType.annotations && otherArrayType.annotations) {
1948
- for (let i = 0; i < arrayType.annotations.length; i++) {
1949
- yield this.visit(arrayType.annotations[i], otherArrayType.annotations[i]);
1950
- if (!this.match)
1951
- return arrayType;
1952
- }
1953
- }
1954
- return arrayType;
1004
+ return this.visitElement(arrayType, other);
1955
1005
  });
1956
1006
  }
1957
1007
  /**
@@ -1963,25 +1013,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
1963
1013
  */
1964
1014
  visitAssert(anAssert, other) {
1965
1015
  return __awaiter(this, void 0, void 0, function* () {
1966
- if (!this.match || other.kind !== java_1.J.Kind.Assert) {
1967
- this.abort();
1968
- return anAssert;
1969
- }
1970
- const otherAssert = other;
1971
- // Visit condition
1972
- yield this.visit(anAssert.condition, otherAssert.condition);
1973
- if (!this.match)
1974
- return anAssert;
1975
- // Compare detail
1976
- if ((anAssert.detail !== undefined) !== (otherAssert.detail !== undefined)) {
1977
- this.abort();
1978
- return anAssert;
1979
- }
1980
- // Visit detail if it exists
1981
- if (anAssert.detail && otherAssert.detail) {
1982
- yield this.visit(anAssert.detail.element, otherAssert.detail.element);
1983
- }
1984
- return anAssert;
1016
+ return this.visitElement(anAssert, other);
1985
1017
  });
1986
1018
  }
1987
1019
  /**
@@ -1993,24 +1025,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
1993
1025
  */
1994
1026
  visitAssignment(assignment, other) {
1995
1027
  return __awaiter(this, void 0, void 0, function* () {
1996
- if (!this.match || other.kind !== java_1.J.Kind.Assignment) {
1997
- this.abort();
1998
- return assignment;
1999
- }
2000
- const otherAssignment = other;
2001
- // Visit variable
2002
- yield this.visit(assignment.variable, otherAssignment.variable);
2003
- if (!this.match)
2004
- return assignment;
2005
- // Visit assignment
2006
- if (assignment.assignment && otherAssignment.assignment) {
2007
- yield this.visit(assignment.assignment.element, otherAssignment.assignment.element);
2008
- }
2009
- else if (assignment.assignment !== otherAssignment.assignment) {
2010
- // One has an assignment and the other doesn't
2011
- this.abort();
2012
- }
2013
- return assignment;
1028
+ return this.visitElement(assignment, other);
2014
1029
  });
2015
1030
  }
2016
1031
  /**
@@ -2022,23 +1037,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
2022
1037
  */
2023
1038
  visitAssignmentOperation(assignOp, other) {
2024
1039
  return __awaiter(this, void 0, void 0, function* () {
2025
- if (!this.match || other.kind !== java_1.J.Kind.AssignmentOperation) {
2026
- this.abort();
2027
- return assignOp;
2028
- }
2029
- const otherAssignOp = other;
2030
- // Visit variable
2031
- yield this.visit(assignOp.variable, otherAssignOp.variable);
2032
- if (!this.match)
2033
- return assignOp;
2034
- // Compare operator
2035
- if (assignOp.operator.element !== otherAssignOp.operator.element) {
2036
- this.abort();
2037
- return assignOp;
2038
- }
2039
- // Visit assignment
2040
- yield this.visit(assignOp.assignment, otherAssignOp.assignment);
2041
- return assignOp;
1040
+ return this.visitElement(assignOp, other);
2042
1041
  });
2043
1042
  }
2044
1043
  /**
@@ -2050,21 +1049,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
2050
1049
  */
2051
1050
  visitBreak(breakStatement, other) {
2052
1051
  return __awaiter(this, void 0, void 0, function* () {
2053
- if (!this.match || other.kind !== java_1.J.Kind.Break) {
2054
- this.abort();
2055
- return breakStatement;
2056
- }
2057
- const otherBreak = other;
2058
- // Compare label presence
2059
- if ((breakStatement.label !== undefined) !== (otherBreak.label !== undefined)) {
2060
- this.abort();
2061
- return breakStatement;
2062
- }
2063
- // Visit label if it exists
2064
- if (breakStatement.label && otherBreak.label) {
2065
- yield this.visit(breakStatement.label, otherBreak.label);
2066
- }
2067
- return breakStatement;
1052
+ return this.visitElement(breakStatement, other);
2068
1053
  });
2069
1054
  }
2070
1055
  /**
@@ -2076,54 +1061,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
2076
1061
  */
2077
1062
  visitCase(aCase, other) {
2078
1063
  return __awaiter(this, void 0, void 0, function* () {
2079
- if (!this.match || other.kind !== java_1.J.Kind.Case) {
2080
- this.abort();
2081
- return aCase;
2082
- }
2083
- const otherCase = other;
2084
- // Compare case labels
2085
- if (aCase.caseLabels.elements.length !== otherCase.caseLabels.elements.length) {
2086
- this.abort();
2087
- return aCase;
2088
- }
2089
- // Visit each case label in lock step
2090
- for (let i = 0; i < aCase.caseLabels.elements.length; i++) {
2091
- yield this.visit(aCase.caseLabels.elements[i].element, otherCase.caseLabels.elements[i].element);
2092
- if (!this.match)
2093
- return aCase;
2094
- }
2095
- // Compare statements
2096
- if (aCase.statements.elements.length !== otherCase.statements.elements.length) {
2097
- this.abort();
2098
- return aCase;
2099
- }
2100
- // Visit each statement in lock step
2101
- for (let i = 0; i < aCase.statements.elements.length; i++) {
2102
- yield this.visit(aCase.statements.elements[i].element, otherCase.statements.elements[i].element);
2103
- if (!this.match)
2104
- return aCase;
2105
- }
2106
- // Compare body presence
2107
- if ((aCase.body !== undefined) !== (otherCase.body !== undefined)) {
2108
- this.abort();
2109
- return aCase;
2110
- }
2111
- // Visit body if it exists
2112
- if (aCase.body && otherCase.body) {
2113
- yield this.visit(aCase.body.element, otherCase.body.element);
2114
- if (!this.match)
2115
- return aCase;
2116
- }
2117
- // Compare guard presence
2118
- if ((aCase.guard !== undefined) !== (otherCase.guard !== undefined)) {
2119
- this.abort();
2120
- return aCase;
2121
- }
2122
- // Visit guard if it exists
2123
- if (aCase.guard && otherCase.guard) {
2124
- yield this.visit(aCase.guard, otherCase.guard);
2125
- }
2126
- return aCase;
1064
+ return this.visitElement(aCase, other);
2127
1065
  });
2128
1066
  }
2129
1067
  /**
@@ -2135,127 +1073,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
2135
1073
  */
2136
1074
  visitClassDeclaration(classDecl, other) {
2137
1075
  return __awaiter(this, void 0, void 0, function* () {
2138
- if (!this.match || other.kind !== java_1.J.Kind.ClassDeclaration) {
2139
- this.abort();
2140
- return classDecl;
2141
- }
2142
- const otherClassDecl = other;
2143
- // Compare leading annotations
2144
- if (classDecl.leadingAnnotations.length !== otherClassDecl.leadingAnnotations.length) {
2145
- this.abort();
2146
- return classDecl;
2147
- }
2148
- // Visit each leading annotation in lock step
2149
- for (let i = 0; i < classDecl.leadingAnnotations.length; i++) {
2150
- yield this.visit(classDecl.leadingAnnotations[i], otherClassDecl.leadingAnnotations[i]);
2151
- if (!this.match)
2152
- return classDecl;
2153
- }
2154
- // Compare modifiers
2155
- if (classDecl.modifiers.length !== otherClassDecl.modifiers.length) {
2156
- this.abort();
2157
- return classDecl;
2158
- }
2159
- // Visit each modifier in lock step
2160
- for (let i = 0; i < classDecl.modifiers.length; i++) {
2161
- yield this.visit(classDecl.modifiers[i], otherClassDecl.modifiers[i]);
2162
- if (!this.match)
2163
- return classDecl;
2164
- }
2165
- // Visit class kind
2166
- yield this.visit(classDecl.classKind, otherClassDecl.classKind);
2167
- if (!this.match)
2168
- return classDecl;
2169
- // Visit name
2170
- yield this.visit(classDecl.name, otherClassDecl.name);
2171
- if (!this.match)
2172
- return classDecl;
2173
- // Compare type parameters presence
2174
- if ((classDecl.typeParameters !== undefined) !== (otherClassDecl.typeParameters !== undefined)) {
2175
- this.abort();
2176
- return classDecl;
2177
- }
2178
- // Visit type parameters if they exist
2179
- if (classDecl.typeParameters && otherClassDecl.typeParameters) {
2180
- if (classDecl.typeParameters.elements.length !== otherClassDecl.typeParameters.elements.length) {
2181
- this.abort();
2182
- return classDecl;
2183
- }
2184
- // Visit each type parameter in lock step
2185
- for (let i = 0; i < classDecl.typeParameters.elements.length; i++) {
2186
- yield this.visit(classDecl.typeParameters.elements[i].element, otherClassDecl.typeParameters.elements[i].element);
2187
- if (!this.match)
2188
- return classDecl;
2189
- }
2190
- }
2191
- // Compare primary constructor presence
2192
- if ((classDecl.primaryConstructor !== undefined) !== (otherClassDecl.primaryConstructor !== undefined)) {
2193
- this.abort();
2194
- return classDecl;
2195
- }
2196
- // Visit primary constructor if it exists
2197
- if (classDecl.primaryConstructor && otherClassDecl.primaryConstructor) {
2198
- if (classDecl.primaryConstructor.elements.length !== otherClassDecl.primaryConstructor.elements.length) {
2199
- this.abort();
2200
- return classDecl;
2201
- }
2202
- // Visit each primary constructor element in lock step
2203
- for (let i = 0; i < classDecl.primaryConstructor.elements.length; i++) {
2204
- yield this.visit(classDecl.primaryConstructor.elements[i].element, otherClassDecl.primaryConstructor.elements[i].element);
2205
- if (!this.match)
2206
- return classDecl;
2207
- }
2208
- }
2209
- // Compare extends presence
2210
- if ((classDecl.extends !== undefined) !== (otherClassDecl.extends !== undefined)) {
2211
- this.abort();
2212
- return classDecl;
2213
- }
2214
- // Visit extends if it exists
2215
- if (classDecl.extends && otherClassDecl.extends) {
2216
- yield this.visit(classDecl.extends.element, otherClassDecl.extends.element);
2217
- if (!this.match)
2218
- return classDecl;
2219
- }
2220
- // Compare implements presence
2221
- if ((classDecl.implements !== undefined) !== (otherClassDecl.implements !== undefined)) {
2222
- this.abort();
2223
- return classDecl;
2224
- }
2225
- // Visit implements if it exists
2226
- if (classDecl.implements && otherClassDecl.implements) {
2227
- if (classDecl.implements.elements.length !== otherClassDecl.implements.elements.length) {
2228
- this.abort();
2229
- return classDecl;
2230
- }
2231
- // Visit each implements element in lock step
2232
- for (let i = 0; i < classDecl.implements.elements.length; i++) {
2233
- yield this.visit(classDecl.implements.elements[i].element, otherClassDecl.implements.elements[i].element);
2234
- if (!this.match)
2235
- return classDecl;
2236
- }
2237
- }
2238
- // Compare permitting presence
2239
- if ((classDecl.permitting !== undefined) !== (otherClassDecl.permitting !== undefined)) {
2240
- this.abort();
2241
- return classDecl;
2242
- }
2243
- // Visit permitting if it exists
2244
- if (classDecl.permitting && otherClassDecl.permitting) {
2245
- if (classDecl.permitting.elements.length !== otherClassDecl.permitting.elements.length) {
2246
- this.abort();
2247
- return classDecl;
2248
- }
2249
- // Visit each permitting element in lock step
2250
- for (let i = 0; i < classDecl.permitting.elements.length; i++) {
2251
- yield this.visit(classDecl.permitting.elements[i].element, otherClassDecl.permitting.elements[i].element);
2252
- if (!this.match)
2253
- return classDecl;
2254
- }
2255
- }
2256
- // Visit body
2257
- yield this.visit(classDecl.body, otherClassDecl.body);
2258
- return classDecl;
1076
+ return this.visitElement(classDecl, other);
2259
1077
  });
2260
1078
  }
2261
1079
  /**
@@ -2267,23 +1085,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
2267
1085
  */
2268
1086
  visitClassDeclarationKind(kind, other) {
2269
1087
  return __awaiter(this, void 0, void 0, function* () {
2270
- if (!this.match || other.kind !== java_1.J.Kind.ClassDeclarationKind) {
2271
- this.abort();
2272
- return kind;
2273
- }
2274
- const otherKind = other;
2275
- // Compare annotations
2276
- if (kind.annotations.length !== otherKind.annotations.length) {
2277
- this.abort();
2278
- return kind;
2279
- }
2280
- // Visit each annotation in lock step
2281
- for (let i = 0; i < kind.annotations.length; i++) {
2282
- yield this.visit(kind.annotations[i], otherKind.annotations[i]);
2283
- if (!this.match)
2284
- return kind;
2285
- }
2286
- return kind;
1088
+ return this.visitElement(kind, other);
2287
1089
  });
2288
1090
  }
2289
1091
  /**
@@ -2295,45 +1097,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
2295
1097
  */
2296
1098
  visitCompilationUnit(compilationUnit, other) {
2297
1099
  return __awaiter(this, void 0, void 0, function* () {
2298
- if (!this.match || other.kind !== java_1.J.Kind.CompilationUnit) {
2299
- this.abort();
2300
- return compilationUnit;
2301
- }
2302
- const otherCompilationUnit = other;
2303
- // Compare package declaration presence
2304
- if ((compilationUnit.packageDeclaration !== undefined) !== (otherCompilationUnit.packageDeclaration !== undefined)) {
2305
- this.abort();
2306
- return compilationUnit;
2307
- }
2308
- // Visit package declaration if it exists
2309
- if (compilationUnit.packageDeclaration && otherCompilationUnit.packageDeclaration) {
2310
- yield this.visit(compilationUnit.packageDeclaration.element, otherCompilationUnit.packageDeclaration.element);
2311
- if (!this.match)
2312
- return compilationUnit;
2313
- }
2314
- // Compare imports
2315
- if (compilationUnit.imports.length !== otherCompilationUnit.imports.length) {
2316
- this.abort();
2317
- return compilationUnit;
2318
- }
2319
- // Visit each import in lock step
2320
- for (let i = 0; i < compilationUnit.imports.length; i++) {
2321
- yield this.visit(compilationUnit.imports[i].element, otherCompilationUnit.imports[i].element);
2322
- if (!this.match)
2323
- return compilationUnit;
2324
- }
2325
- // Compare classes
2326
- if (compilationUnit.classes.length !== otherCompilationUnit.classes.length) {
2327
- this.abort();
2328
- return compilationUnit;
2329
- }
2330
- // Visit each class in lock step
2331
- for (let i = 0; i < compilationUnit.classes.length; i++) {
2332
- yield this.visit(compilationUnit.classes[i], otherCompilationUnit.classes[i]);
2333
- if (!this.match)
2334
- return compilationUnit;
2335
- }
2336
- return compilationUnit;
1100
+ return this.visitElement(compilationUnit, other);
2337
1101
  });
2338
1102
  }
2339
1103
  /**
@@ -2345,21 +1109,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
2345
1109
  */
2346
1110
  visitContinue(continueStatement, other) {
2347
1111
  return __awaiter(this, void 0, void 0, function* () {
2348
- if (!this.match || other.kind !== java_1.J.Kind.Continue) {
2349
- this.abort();
2350
- return continueStatement;
2351
- }
2352
- const otherContinue = other;
2353
- // Compare label presence
2354
- if ((continueStatement.label !== undefined) !== (otherContinue.label !== undefined)) {
2355
- this.abort();
2356
- return continueStatement;
2357
- }
2358
- // Visit label if it exists
2359
- if (continueStatement.label && otherContinue.label) {
2360
- yield this.visit(continueStatement.label, otherContinue.label);
2361
- }
2362
- return continueStatement;
1112
+ return this.visitElement(continueStatement, other);
2363
1113
  });
2364
1114
  }
2365
1115
  /**
@@ -2371,14 +1121,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
2371
1121
  */
2372
1122
  visitControlParentheses(controlParens, other) {
2373
1123
  return __awaiter(this, void 0, void 0, function* () {
2374
- if (!this.match || other.kind !== java_1.J.Kind.ControlParentheses) {
2375
- this.abort();
2376
- return controlParens;
2377
- }
2378
- const otherControlParens = other;
2379
- // Visit tree
2380
- yield this.visit(controlParens.tree.element, otherControlParens.tree.element);
2381
- return controlParens;
1124
+ return this.visitElement(controlParens, other);
2382
1125
  });
2383
1126
  }
2384
1127
  /**
@@ -2390,27 +1133,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
2390
1133
  */
2391
1134
  visitDeconstructionPattern(pattern, other) {
2392
1135
  return __awaiter(this, void 0, void 0, function* () {
2393
- if (!this.match || other.kind !== java_1.J.Kind.DeconstructionPattern) {
2394
- this.abort();
2395
- return pattern;
2396
- }
2397
- const otherPattern = other;
2398
- // Visit deconstructor
2399
- yield this.visit(pattern.deconstructor, otherPattern.deconstructor);
2400
- if (!this.match)
2401
- return pattern;
2402
- // Compare nested elements
2403
- if (pattern.nested.elements.length !== otherPattern.nested.elements.length) {
2404
- this.abort();
2405
- return pattern;
2406
- }
2407
- // Visit each nested element in lock step
2408
- for (let i = 0; i < pattern.nested.elements.length; i++) {
2409
- yield this.visit(pattern.nested.elements[i].element, otherPattern.nested.elements[i].element);
2410
- if (!this.match)
2411
- return pattern;
2412
- }
2413
- return pattern;
1136
+ return this.visitElement(pattern, other);
2414
1137
  });
2415
1138
  }
2416
1139
  /**
@@ -2422,18 +1145,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
2422
1145
  */
2423
1146
  visitDoWhileLoop(doWhileLoop, other) {
2424
1147
  return __awaiter(this, void 0, void 0, function* () {
2425
- if (!this.match || other.kind !== java_1.J.Kind.DoWhileLoop) {
2426
- this.abort();
2427
- return doWhileLoop;
2428
- }
2429
- const otherDoWhileLoop = other;
2430
- // Visit body
2431
- yield this.visit(doWhileLoop.body.element, otherDoWhileLoop.body.element);
2432
- if (!this.match)
2433
- return doWhileLoop;
2434
- // Visit while condition
2435
- yield this.visit(doWhileLoop.whileCondition.element, otherDoWhileLoop.whileCondition.element);
2436
- return doWhileLoop;
1148
+ return this.visitElement(doWhileLoop, other);
2437
1149
  });
2438
1150
  }
2439
1151
  /**
@@ -2445,12 +1157,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
2445
1157
  */
2446
1158
  visitEmpty(empty, other) {
2447
1159
  return __awaiter(this, void 0, void 0, function* () {
2448
- if (!this.match || other.kind !== java_1.J.Kind.Empty) {
2449
- this.abort();
2450
- return empty;
2451
- }
2452
- // Empty statements have no properties to compare, so we just check the kind
2453
- return empty;
1160
+ return this.visitElement(empty, other);
2454
1161
  });
2455
1162
  }
2456
1163
  /**
@@ -2462,36 +1169,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
2462
1169
  */
2463
1170
  visitEnumValue(enumValue, other) {
2464
1171
  return __awaiter(this, void 0, void 0, function* () {
2465
- if (!this.match || other.kind !== java_1.J.Kind.EnumValue) {
2466
- this.abort();
2467
- return enumValue;
2468
- }
2469
- const otherEnumValue = other;
2470
- // Compare annotations
2471
- if (enumValue.annotations.length !== otherEnumValue.annotations.length) {
2472
- this.abort();
2473
- return enumValue;
2474
- }
2475
- // Visit each annotation in lock step
2476
- for (let i = 0; i < enumValue.annotations.length; i++) {
2477
- yield this.visit(enumValue.annotations[i], otherEnumValue.annotations[i]);
2478
- if (!this.match)
2479
- return enumValue;
2480
- }
2481
- // Visit name
2482
- yield this.visit(enumValue.name, otherEnumValue.name);
2483
- if (!this.match)
2484
- return enumValue;
2485
- // Compare initializer presence
2486
- if ((enumValue.initializer !== undefined) !== (otherEnumValue.initializer !== undefined)) {
2487
- this.abort();
2488
- return enumValue;
2489
- }
2490
- // Visit initializer if it exists
2491
- if (enumValue.initializer && otherEnumValue.initializer) {
2492
- yield this.visit(enumValue.initializer, otherEnumValue.initializer);
2493
- }
2494
- return enumValue;
1172
+ return this.visitElement(enumValue, other);
2495
1173
  });
2496
1174
  }
2497
1175
  /**
@@ -2503,23 +1181,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
2503
1181
  */
2504
1182
  visitEnumValueSet(enumValueSet, other) {
2505
1183
  return __awaiter(this, void 0, void 0, function* () {
2506
- if (!this.match || other.kind !== java_1.J.Kind.EnumValueSet) {
2507
- this.abort();
2508
- return enumValueSet;
2509
- }
2510
- const otherEnumValueSet = other;
2511
- // Compare enums
2512
- if (enumValueSet.enums.length !== otherEnumValueSet.enums.length) {
2513
- this.abort();
2514
- return enumValueSet;
2515
- }
2516
- // Visit each enum in lock step
2517
- for (let i = 0; i < enumValueSet.enums.length; i++) {
2518
- yield this.visit(enumValueSet.enums[i].element, otherEnumValueSet.enums[i].element);
2519
- if (!this.match)
2520
- return enumValueSet;
2521
- }
2522
- return enumValueSet;
1184
+ return this.visitElement(enumValueSet, other);
2523
1185
  });
2524
1186
  }
2525
1187
  /**
@@ -2531,17 +1193,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
2531
1193
  */
2532
1194
  visitErroneous(erroneous, other) {
2533
1195
  return __awaiter(this, void 0, void 0, function* () {
2534
- if (!this.match || other.kind !== java_1.J.Kind.Erroneous) {
2535
- this.abort();
2536
- return erroneous;
2537
- }
2538
- const otherErroneous = other;
2539
- // Compare text
2540
- if (erroneous.text !== otherErroneous.text) {
2541
- this.abort();
2542
- return erroneous;
2543
- }
2544
- return erroneous;
1196
+ return this.visitElement(erroneous, other);
2545
1197
  });
2546
1198
  }
2547
1199
  /**
@@ -2553,20 +1205,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
2553
1205
  */
2554
1206
  visitFieldAccess(fieldAccess, other) {
2555
1207
  return __awaiter(this, void 0, void 0, function* () {
2556
- if (!this.match || other.kind !== java_1.J.Kind.FieldAccess) {
2557
- this.abort();
2558
- return fieldAccess;
2559
- }
2560
- const otherFieldAccess = other;
2561
- // Visit target
2562
- yield this.visit(fieldAccess.target, otherFieldAccess.target);
2563
- if (!this.match)
2564
- return fieldAccess;
2565
- // Visit name
2566
- yield this.visit(fieldAccess.name.element, otherFieldAccess.name.element);
2567
- if (!this.match)
2568
- return fieldAccess;
2569
- return fieldAccess;
1208
+ return this.visitElement(fieldAccess, other);
2570
1209
  });
2571
1210
  }
2572
1211
  /**
@@ -2578,20 +1217,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
2578
1217
  */
2579
1218
  visitForEachLoop(forEachLoop, other) {
2580
1219
  return __awaiter(this, void 0, void 0, function* () {
2581
- if (!this.match || other.kind !== java_1.J.Kind.ForEachLoop) {
2582
- this.abort();
2583
- return forEachLoop;
2584
- }
2585
- const otherForEachLoop = other;
2586
- // Visit control
2587
- yield this.visit(forEachLoop.control, otherForEachLoop.control);
2588
- if (!this.match)
2589
- return forEachLoop;
2590
- // Visit body
2591
- yield this.visit(forEachLoop.body.element, otherForEachLoop.body.element);
2592
- if (!this.match)
2593
- return forEachLoop;
2594
- return forEachLoop;
1220
+ return this.visitElement(forEachLoop, other);
2595
1221
  });
2596
1222
  }
2597
1223
  /**
@@ -2603,20 +1229,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
2603
1229
  */
2604
1230
  visitForEachLoopControl(control, other) {
2605
1231
  return __awaiter(this, void 0, void 0, function* () {
2606
- if (!this.match || other.kind !== java_1.J.Kind.ForEachLoopControl) {
2607
- this.abort();
2608
- return control;
2609
- }
2610
- const otherControl = other;
2611
- // Visit variable
2612
- yield this.visit(control.variable.element, otherControl.variable.element);
2613
- if (!this.match)
2614
- return control;
2615
- // Visit iterable
2616
- yield this.visit(control.iterable.element, otherControl.iterable.element);
2617
- if (!this.match)
2618
- return control;
2619
- return control;
1232
+ return this.visitElement(control, other);
2620
1233
  });
2621
1234
  }
2622
1235
  /**
@@ -2628,20 +1241,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
2628
1241
  */
2629
1242
  visitForLoop(forLoop, other) {
2630
1243
  return __awaiter(this, void 0, void 0, function* () {
2631
- if (!this.match || other.kind !== java_1.J.Kind.ForLoop) {
2632
- this.abort();
2633
- return forLoop;
2634
- }
2635
- const otherForLoop = other;
2636
- // Visit control
2637
- yield this.visit(forLoop.control, otherForLoop.control);
2638
- if (!this.match)
2639
- return forLoop;
2640
- // Visit body
2641
- yield this.visit(forLoop.body.element, otherForLoop.body.element);
2642
- if (!this.match)
2643
- return forLoop;
2644
- return forLoop;
1244
+ return this.visitElement(forLoop, other);
2645
1245
  });
2646
1246
  }
2647
1247
  /**
@@ -2653,45 +1253,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
2653
1253
  */
2654
1254
  visitForLoopControl(control, other) {
2655
1255
  return __awaiter(this, void 0, void 0, function* () {
2656
- if (!this.match || other.kind !== java_1.J.Kind.ForLoopControl) {
2657
- this.abort();
2658
- return control;
2659
- }
2660
- const otherControl = other;
2661
- // Compare init statements
2662
- if (control.init.length !== otherControl.init.length) {
2663
- this.abort();
2664
- return control;
2665
- }
2666
- // Visit each init statement in lock step
2667
- for (let i = 0; i < control.init.length; i++) {
2668
- yield this.visit(control.init[i].element, otherControl.init[i].element);
2669
- if (!this.match)
2670
- return control;
2671
- }
2672
- // Compare condition
2673
- if ((control.condition === undefined) !== (otherControl.condition === undefined)) {
2674
- this.abort();
2675
- return control;
2676
- }
2677
- // Visit condition if present
2678
- if (control.condition && otherControl.condition) {
2679
- yield this.visit(control.condition.element, otherControl.condition.element);
2680
- if (!this.match)
2681
- return control;
2682
- }
2683
- // Compare update statements
2684
- if (control.update.length !== otherControl.update.length) {
2685
- this.abort();
2686
- return control;
2687
- }
2688
- // Visit each update statement in lock step
2689
- for (let i = 0; i < control.update.length; i++) {
2690
- yield this.visit(control.update[i].element, otherControl.update[i].element);
2691
- if (!this.match)
2692
- return control;
2693
- }
2694
- return control;
1256
+ return this.visitElement(control, other);
2695
1257
  });
2696
1258
  }
2697
1259
  /**
@@ -2703,31 +1265,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
2703
1265
  */
2704
1266
  visitIf(ifStatement, other) {
2705
1267
  return __awaiter(this, void 0, void 0, function* () {
2706
- if (!this.match || other.kind !== java_1.J.Kind.If) {
2707
- this.abort();
2708
- return ifStatement;
2709
- }
2710
- const otherIfStatement = other;
2711
- // Visit condition
2712
- yield this.visit(ifStatement.ifCondition, otherIfStatement.ifCondition);
2713
- if (!this.match)
2714
- return ifStatement;
2715
- // Visit then part
2716
- yield this.visit(ifStatement.thenPart.element, otherIfStatement.thenPart.element);
2717
- if (!this.match)
2718
- return ifStatement;
2719
- // Compare else part
2720
- if ((ifStatement.elsePart === undefined) !== (otherIfStatement.elsePart === undefined)) {
2721
- this.abort();
2722
- return ifStatement;
2723
- }
2724
- // Visit else part if present
2725
- if (ifStatement.elsePart && otherIfStatement.elsePart) {
2726
- yield this.visit(ifStatement.elsePart, otherIfStatement.elsePart);
2727
- if (!this.match)
2728
- return ifStatement;
2729
- }
2730
- return ifStatement;
1268
+ return this.visitElement(ifStatement, other);
2731
1269
  });
2732
1270
  }
2733
1271
  /**
@@ -2739,16 +1277,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
2739
1277
  */
2740
1278
  visitElse(elseStatement, other) {
2741
1279
  return __awaiter(this, void 0, void 0, function* () {
2742
- if (!this.match || other.kind !== java_1.J.Kind.IfElse) {
2743
- this.abort();
2744
- return elseStatement;
2745
- }
2746
- const otherElseStatement = other;
2747
- // Visit body
2748
- yield this.visit(elseStatement.body.element, otherElseStatement.body.element);
2749
- if (!this.match)
2750
- return elseStatement;
2751
- return elseStatement;
1280
+ return this.visitElement(elseStatement, other);
2752
1281
  });
2753
1282
  }
2754
1283
  /**
@@ -2760,32 +1289,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
2760
1289
  */
2761
1290
  visitImport(importStatement, other) {
2762
1291
  return __awaiter(this, void 0, void 0, function* () {
2763
- if (!this.match || other.kind !== java_1.J.Kind.Import) {
2764
- this.abort();
2765
- return importStatement;
2766
- }
2767
- const otherImportStatement = other;
2768
- // Compare static
2769
- if (importStatement.static.element !== otherImportStatement.static.element) {
2770
- this.abort();
2771
- return importStatement;
2772
- }
2773
- // Visit qualid
2774
- yield this.visit(importStatement.qualid, otherImportStatement.qualid);
2775
- if (!this.match)
2776
- return importStatement;
2777
- // Compare alias
2778
- if ((importStatement.alias === undefined) !== (otherImportStatement.alias === undefined)) {
2779
- this.abort();
2780
- return importStatement;
2781
- }
2782
- // Visit alias if present
2783
- if (importStatement.alias && otherImportStatement.alias) {
2784
- yield this.visit(importStatement.alias.element, otherImportStatement.alias.element);
2785
- if (!this.match)
2786
- return importStatement;
2787
- }
2788
- return importStatement;
1292
+ return this.visitElement(importStatement, other);
2789
1293
  });
2790
1294
  }
2791
1295
  /**
@@ -2797,42 +1301,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
2797
1301
  */
2798
1302
  visitInstanceOf(instanceOf, other) {
2799
1303
  return __awaiter(this, void 0, void 0, function* () {
2800
- if (!this.match || other.kind !== java_1.J.Kind.InstanceOf) {
2801
- this.abort();
2802
- return instanceOf;
2803
- }
2804
- const otherInstanceOf = other;
2805
- // Visit expression
2806
- yield this.visit(instanceOf.expression.element, otherInstanceOf.expression.element);
2807
- if (!this.match)
2808
- return instanceOf;
2809
- // Visit class
2810
- yield this.visit(instanceOf.class, otherInstanceOf.class);
2811
- if (!this.match)
2812
- return instanceOf;
2813
- // Compare pattern
2814
- if ((instanceOf.pattern === undefined) !== (otherInstanceOf.pattern === undefined)) {
2815
- this.abort();
2816
- return instanceOf;
2817
- }
2818
- // Visit pattern if present
2819
- if (instanceOf.pattern && otherInstanceOf.pattern) {
2820
- yield this.visit(instanceOf.pattern, otherInstanceOf.pattern);
2821
- if (!this.match)
2822
- return instanceOf;
2823
- }
2824
- // Compare modifier
2825
- if ((instanceOf.modifier === undefined) !== (otherInstanceOf.modifier === undefined)) {
2826
- this.abort();
2827
- return instanceOf;
2828
- }
2829
- // Visit modifier if present
2830
- if (instanceOf.modifier && otherInstanceOf.modifier) {
2831
- yield this.visit(instanceOf.modifier, otherInstanceOf.modifier);
2832
- if (!this.match)
2833
- return instanceOf;
2834
- }
2835
- return instanceOf;
1304
+ return this.visitElement(instanceOf, other);
2836
1305
  });
2837
1306
  }
2838
1307
  /**
@@ -2844,23 +1313,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
2844
1313
  */
2845
1314
  visitIntersectionType(intersectionType, other) {
2846
1315
  return __awaiter(this, void 0, void 0, function* () {
2847
- if (!this.match || other.kind !== java_1.J.Kind.IntersectionType) {
2848
- this.abort();
2849
- return intersectionType;
2850
- }
2851
- const otherIntersectionType = other;
2852
- // Compare bounds
2853
- if (intersectionType.bounds.elements.length !== otherIntersectionType.bounds.elements.length) {
2854
- this.abort();
2855
- return intersectionType;
2856
- }
2857
- // Visit each bound in lock step
2858
- for (let i = 0; i < intersectionType.bounds.elements.length; i++) {
2859
- yield this.visit(intersectionType.bounds.elements[i].element, otherIntersectionType.bounds.elements[i].element);
2860
- if (!this.match)
2861
- return intersectionType;
2862
- }
2863
- return intersectionType;
1316
+ return this.visitElement(intersectionType, other);
2864
1317
  });
2865
1318
  }
2866
1319
  /**
@@ -2872,20 +1325,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
2872
1325
  */
2873
1326
  visitLabel(label, other) {
2874
1327
  return __awaiter(this, void 0, void 0, function* () {
2875
- if (!this.match || other.kind !== java_1.J.Kind.Label) {
2876
- this.abort();
2877
- return label;
2878
- }
2879
- const otherLabel = other;
2880
- // Visit label identifier
2881
- yield this.visit(label.label.element, otherLabel.label.element);
2882
- if (!this.match)
2883
- return label;
2884
- // Visit statement
2885
- yield this.visit(label.statement, otherLabel.statement);
2886
- if (!this.match)
2887
- return label;
2888
- return label;
1328
+ return this.visitElement(label, other);
2889
1329
  });
2890
1330
  }
2891
1331
  /**
@@ -2897,20 +1337,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
2897
1337
  */
2898
1338
  visitLambda(lambda, other) {
2899
1339
  return __awaiter(this, void 0, void 0, function* () {
2900
- if (!this.match || other.kind !== java_1.J.Kind.Lambda) {
2901
- this.abort();
2902
- return lambda;
2903
- }
2904
- const otherLambda = other;
2905
- // Visit parameters
2906
- yield this.visit(lambda.parameters, otherLambda.parameters);
2907
- if (!this.match)
2908
- return lambda;
2909
- // Visit body
2910
- yield this.visit(lambda.body, otherLambda.body);
2911
- if (!this.match)
2912
- return lambda;
2913
- return lambda;
1340
+ return this.visitElement(lambda, other);
2914
1341
  });
2915
1342
  }
2916
1343
  /**
@@ -2922,28 +1349,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
2922
1349
  */
2923
1350
  visitLambdaParameters(parameters, other) {
2924
1351
  return __awaiter(this, void 0, void 0, function* () {
2925
- if (!this.match || other.kind !== java_1.J.Kind.LambdaParameters) {
2926
- this.abort();
2927
- return parameters;
2928
- }
2929
- const otherParameters = other;
2930
- // Compare parenthesized
2931
- if (parameters.parenthesized !== otherParameters.parenthesized) {
2932
- this.abort();
2933
- return parameters;
2934
- }
2935
- // Compare parameters
2936
- if (parameters.parameters.length !== otherParameters.parameters.length) {
2937
- this.abort();
2938
- return parameters;
2939
- }
2940
- // Visit each parameter in lock step
2941
- for (let i = 0; i < parameters.parameters.length; i++) {
2942
- yield this.visit(parameters.parameters[i].element, otherParameters.parameters[i].element);
2943
- if (!this.match)
2944
- return parameters;
2945
- }
2946
- return parameters;
1352
+ return this.visitElement(parameters, other);
2947
1353
  });
2948
1354
  }
2949
1355
  /**
@@ -2955,38 +1361,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
2955
1361
  */
2956
1362
  visitMemberReference(memberReference, other) {
2957
1363
  return __awaiter(this, void 0, void 0, function* () {
2958
- if (!this.match || other.kind !== java_1.J.Kind.MemberReference) {
2959
- this.abort();
2960
- return memberReference;
2961
- }
2962
- const otherMemberReference = other;
2963
- // Visit containing
2964
- yield this.visit(memberReference.containing.element, otherMemberReference.containing.element);
2965
- if (!this.match)
2966
- return memberReference;
2967
- // Compare typeParameters
2968
- if ((memberReference.typeParameters === undefined) !== (otherMemberReference.typeParameters === undefined)) {
2969
- this.abort();
2970
- return memberReference;
2971
- }
2972
- // Visit typeParameters if present
2973
- if (memberReference.typeParameters && otherMemberReference.typeParameters) {
2974
- if (memberReference.typeParameters.elements.length !== otherMemberReference.typeParameters.elements.length) {
2975
- this.abort();
2976
- return memberReference;
2977
- }
2978
- // Visit each type parameter in lock step
2979
- for (let i = 0; i < memberReference.typeParameters.elements.length; i++) {
2980
- yield this.visit(memberReference.typeParameters.elements[i].element, otherMemberReference.typeParameters.elements[i].element);
2981
- if (!this.match)
2982
- return memberReference;
2983
- }
2984
- }
2985
- // Visit reference
2986
- yield this.visit(memberReference.reference.element, otherMemberReference.reference.element);
2987
- if (!this.match)
2988
- return memberReference;
2989
- return memberReference;
1364
+ return this.visitElement(memberReference, other);
2990
1365
  });
2991
1366
  }
2992
1367
  /**
@@ -2998,122 +1373,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
2998
1373
  */
2999
1374
  visitMethodDeclaration(methodDeclaration, other) {
3000
1375
  return __awaiter(this, void 0, void 0, function* () {
3001
- if (!this.match || other.kind !== java_1.J.Kind.MethodDeclaration) {
3002
- this.abort();
3003
- return methodDeclaration;
3004
- }
3005
- const otherMethodDeclaration = other;
3006
- // Compare leadingAnnotations
3007
- if (methodDeclaration.leadingAnnotations.length !== otherMethodDeclaration.leadingAnnotations.length) {
3008
- this.abort();
3009
- return methodDeclaration;
3010
- }
3011
- // Visit each leading annotation in lock step
3012
- for (let i = 0; i < methodDeclaration.leadingAnnotations.length; i++) {
3013
- yield this.visit(methodDeclaration.leadingAnnotations[i], otherMethodDeclaration.leadingAnnotations[i]);
3014
- if (!this.match)
3015
- return methodDeclaration;
3016
- }
3017
- // Compare modifiers
3018
- if (methodDeclaration.modifiers.length !== otherMethodDeclaration.modifiers.length) {
3019
- this.abort();
3020
- return methodDeclaration;
3021
- }
3022
- // Visit each modifier in lock step
3023
- for (let i = 0; i < methodDeclaration.modifiers.length; i++) {
3024
- yield this.visit(methodDeclaration.modifiers[i], otherMethodDeclaration.modifiers[i]);
3025
- if (!this.match)
3026
- return methodDeclaration;
3027
- }
3028
- // Compare typeParameters
3029
- if ((methodDeclaration.typeParameters === undefined) !== (otherMethodDeclaration.typeParameters === undefined)) {
3030
- this.abort();
3031
- return methodDeclaration;
3032
- }
3033
- // Visit typeParameters if present
3034
- if (methodDeclaration.typeParameters && otherMethodDeclaration.typeParameters) {
3035
- yield this.visit(methodDeclaration.typeParameters, otherMethodDeclaration.typeParameters);
3036
- if (!this.match)
3037
- return methodDeclaration;
3038
- }
3039
- // Compare returnTypeExpression
3040
- if ((methodDeclaration.returnTypeExpression === undefined) !== (otherMethodDeclaration.returnTypeExpression === undefined)) {
3041
- this.abort();
3042
- return methodDeclaration;
3043
- }
3044
- // Visit returnTypeExpression if present
3045
- if (methodDeclaration.returnTypeExpression && otherMethodDeclaration.returnTypeExpression) {
3046
- yield this.visit(methodDeclaration.returnTypeExpression, otherMethodDeclaration.returnTypeExpression);
3047
- if (!this.match)
3048
- return methodDeclaration;
3049
- }
3050
- // Compare nameAnnotations
3051
- if (methodDeclaration.nameAnnotations.length !== otherMethodDeclaration.nameAnnotations.length) {
3052
- this.abort();
3053
- return methodDeclaration;
3054
- }
3055
- // Visit each name annotation in lock step
3056
- for (let i = 0; i < methodDeclaration.nameAnnotations.length; i++) {
3057
- yield this.visit(methodDeclaration.nameAnnotations[i], otherMethodDeclaration.nameAnnotations[i]);
3058
- if (!this.match)
3059
- return methodDeclaration;
3060
- }
3061
- // Visit name
3062
- yield this.visit(methodDeclaration.name, otherMethodDeclaration.name);
3063
- if (!this.match)
3064
- return methodDeclaration;
3065
- // Compare parameters
3066
- if (methodDeclaration.parameters.elements.length !== otherMethodDeclaration.parameters.elements.length) {
3067
- this.abort();
3068
- return methodDeclaration;
3069
- }
3070
- // Visit each parameter in lock step
3071
- for (let i = 0; i < methodDeclaration.parameters.elements.length; i++) {
3072
- yield this.visit(methodDeclaration.parameters.elements[i].element, otherMethodDeclaration.parameters.elements[i].element);
3073
- if (!this.match)
3074
- return methodDeclaration;
3075
- }
3076
- // Compare throws
3077
- if ((methodDeclaration.throws === undefined) !== (otherMethodDeclaration.throws === undefined)) {
3078
- this.abort();
3079
- return methodDeclaration;
3080
- }
3081
- // Visit throws if present
3082
- if (methodDeclaration.throws && otherMethodDeclaration.throws) {
3083
- if (methodDeclaration.throws.elements.length !== otherMethodDeclaration.throws.elements.length) {
3084
- this.abort();
3085
- return methodDeclaration;
3086
- }
3087
- // Visit each throw in lock step
3088
- for (let i = 0; i < methodDeclaration.throws.elements.length; i++) {
3089
- yield this.visit(methodDeclaration.throws.elements[i].element, otherMethodDeclaration.throws.elements[i].element);
3090
- if (!this.match)
3091
- return methodDeclaration;
3092
- }
3093
- }
3094
- // Compare body
3095
- if ((methodDeclaration.body === undefined) !== (otherMethodDeclaration.body === undefined)) {
3096
- this.abort();
3097
- return methodDeclaration;
3098
- }
3099
- // Visit body if present
3100
- if (methodDeclaration.body && otherMethodDeclaration.body) {
3101
- yield this.visit(methodDeclaration.body, otherMethodDeclaration.body);
3102
- if (!this.match)
3103
- return methodDeclaration;
3104
- }
3105
- // Compare defaultValue
3106
- if ((methodDeclaration.defaultValue === undefined) !== (otherMethodDeclaration.defaultValue === undefined)) {
3107
- this.abort();
3108
- return methodDeclaration;
3109
- }
3110
- // Visit defaultValue if present
3111
- if (methodDeclaration.defaultValue && otherMethodDeclaration.defaultValue) {
3112
- yield this.visit(methodDeclaration.defaultValue.element, otherMethodDeclaration.defaultValue.element);
3113
- if (!this.match)
3114
- return methodDeclaration;
3115
- }
3116
- return methodDeclaration;
1376
+ return this.visitElement(methodDeclaration, other);
3117
1377
  });
3118
1378
  }
3119
1379
  /**
@@ -3125,56 +1385,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
3125
1385
  */
3126
1386
  visitMethodInvocation(methodInvocation, other) {
3127
1387
  return __awaiter(this, void 0, void 0, function* () {
3128
- if (!this.match || other.kind !== java_1.J.Kind.MethodInvocation) {
3129
- this.abort();
3130
- return methodInvocation;
3131
- }
3132
- const otherMethodInvocation = other;
3133
- // Compare select
3134
- if ((methodInvocation.select === undefined) !== (otherMethodInvocation.select === undefined)) {
3135
- this.abort();
3136
- return methodInvocation;
3137
- }
3138
- // Visit select if present
3139
- if (methodInvocation.select && otherMethodInvocation.select) {
3140
- yield this.visit(methodInvocation.select.element, otherMethodInvocation.select.element);
3141
- if (!this.match)
3142
- return methodInvocation;
3143
- }
3144
- // Compare typeParameters
3145
- if ((methodInvocation.typeParameters === undefined) !== (otherMethodInvocation.typeParameters === undefined)) {
3146
- this.abort();
3147
- return methodInvocation;
3148
- }
3149
- // Visit typeParameters if present
3150
- if (methodInvocation.typeParameters && otherMethodInvocation.typeParameters) {
3151
- if (methodInvocation.typeParameters.elements.length !== otherMethodInvocation.typeParameters.elements.length) {
3152
- this.abort();
3153
- return methodInvocation;
3154
- }
3155
- // Visit each type parameter in lock step
3156
- for (let i = 0; i < methodInvocation.typeParameters.elements.length; i++) {
3157
- yield this.visit(methodInvocation.typeParameters.elements[i].element, otherMethodInvocation.typeParameters.elements[i].element);
3158
- if (!this.match)
3159
- return methodInvocation;
3160
- }
3161
- }
3162
- // Visit name
3163
- yield this.visit(methodInvocation.name, otherMethodInvocation.name);
3164
- if (!this.match)
3165
- return methodInvocation;
3166
- // Compare arguments
3167
- if (methodInvocation.arguments.elements.length !== otherMethodInvocation.arguments.elements.length) {
3168
- this.abort();
3169
- return methodInvocation;
3170
- }
3171
- // Visit each argument in lock step
3172
- for (let i = 0; i < methodInvocation.arguments.elements.length; i++) {
3173
- yield this.visit(methodInvocation.arguments.elements[i].element, otherMethodInvocation.arguments.elements[i].element);
3174
- if (!this.match)
3175
- return methodInvocation;
3176
- }
3177
- return methodInvocation;
1388
+ return this.visitElement(methodInvocation, other);
3178
1389
  });
3179
1390
  }
3180
1391
  /**
@@ -3186,33 +1397,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
3186
1397
  */
3187
1398
  visitModifier(modifier, other) {
3188
1399
  return __awaiter(this, void 0, void 0, function* () {
3189
- if (!this.match || other.kind !== java_1.J.Kind.Modifier) {
3190
- this.abort();
3191
- return modifier;
3192
- }
3193
- const otherModifier = other;
3194
- // Compare keyword
3195
- if (modifier.keyword !== otherModifier.keyword) {
3196
- this.abort();
3197
- return modifier;
3198
- }
3199
- // Compare type
3200
- if (modifier.type !== otherModifier.type) {
3201
- this.abort();
3202
- return modifier;
3203
- }
3204
- // Compare annotations
3205
- if (modifier.annotations.length !== otherModifier.annotations.length) {
3206
- this.abort();
3207
- return modifier;
3208
- }
3209
- // Visit each annotation in lock step
3210
- for (let i = 0; i < modifier.annotations.length; i++) {
3211
- yield this.visit(modifier.annotations[i], otherModifier.annotations[i]);
3212
- if (!this.match)
3213
- return modifier;
3214
- }
3215
- return modifier;
1400
+ return this.visitElement(modifier, other);
3216
1401
  });
3217
1402
  }
3218
1403
  /**
@@ -3224,23 +1409,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
3224
1409
  */
3225
1410
  visitMultiCatch(multiCatch, other) {
3226
1411
  return __awaiter(this, void 0, void 0, function* () {
3227
- if (!this.match || other.kind !== java_1.J.Kind.MultiCatch) {
3228
- this.abort();
3229
- return multiCatch;
3230
- }
3231
- const otherMultiCatch = other;
3232
- // Compare alternatives
3233
- if (multiCatch.alternatives.length !== otherMultiCatch.alternatives.length) {
3234
- this.abort();
3235
- return multiCatch;
3236
- }
3237
- // Visit each alternative in lock step
3238
- for (let i = 0; i < multiCatch.alternatives.length; i++) {
3239
- yield this.visit(multiCatch.alternatives[i].element, otherMultiCatch.alternatives[i].element);
3240
- if (!this.match)
3241
- return multiCatch;
3242
- }
3243
- return multiCatch;
1412
+ return this.visitElement(multiCatch, other);
3244
1413
  });
3245
1414
  }
3246
1415
  /**
@@ -3252,52 +1421,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
3252
1421
  */
3253
1422
  visitNewArray(newArray, other) {
3254
1423
  return __awaiter(this, void 0, void 0, function* () {
3255
- if (!this.match || other.kind !== java_1.J.Kind.NewArray) {
3256
- this.abort();
3257
- return newArray;
3258
- }
3259
- const otherNewArray = other;
3260
- // Compare typeExpression
3261
- if ((newArray.typeExpression === undefined) !== (otherNewArray.typeExpression === undefined)) {
3262
- this.abort();
3263
- return newArray;
3264
- }
3265
- // Visit typeExpression if present
3266
- if (newArray.typeExpression && otherNewArray.typeExpression) {
3267
- yield this.visit(newArray.typeExpression, otherNewArray.typeExpression);
3268
- if (!this.match)
3269
- return newArray;
3270
- }
3271
- // Compare dimensions
3272
- if (newArray.dimensions.length !== otherNewArray.dimensions.length) {
3273
- this.abort();
3274
- return newArray;
3275
- }
3276
- // Visit each dimension in lock step
3277
- for (let i = 0; i < newArray.dimensions.length; i++) {
3278
- yield this.visit(newArray.dimensions[i], otherNewArray.dimensions[i]);
3279
- if (!this.match)
3280
- return newArray;
3281
- }
3282
- // Compare initializer
3283
- if ((newArray.initializer === undefined) !== (otherNewArray.initializer === undefined)) {
3284
- this.abort();
3285
- return newArray;
3286
- }
3287
- // Visit initializer if present
3288
- if (newArray.initializer && otherNewArray.initializer) {
3289
- if (newArray.initializer.elements.length !== otherNewArray.initializer.elements.length) {
3290
- this.abort();
3291
- return newArray;
3292
- }
3293
- // Visit each initializer element in lock step
3294
- for (let i = 0; i < newArray.initializer.elements.length; i++) {
3295
- yield this.visit(newArray.initializer.elements[i].element, otherNewArray.initializer.elements[i].element);
3296
- if (!this.match)
3297
- return newArray;
3298
- }
3299
- }
3300
- return newArray;
1424
+ return this.visitElement(newArray, other);
3301
1425
  });
3302
1426
  }
3303
1427
  /**
@@ -3309,56 +1433,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
3309
1433
  */
3310
1434
  visitNewClass(newClass, other) {
3311
1435
  return __awaiter(this, void 0, void 0, function* () {
3312
- if (!this.match || other.kind !== java_1.J.Kind.NewClass) {
3313
- this.abort();
3314
- return newClass;
3315
- }
3316
- const otherNewClass = other;
3317
- // Compare enclosing
3318
- if ((newClass.enclosing === undefined) !== (otherNewClass.enclosing === undefined)) {
3319
- this.abort();
3320
- return newClass;
3321
- }
3322
- // Visit enclosing if present
3323
- if (newClass.enclosing && otherNewClass.enclosing) {
3324
- yield this.visit(newClass.enclosing.element, otherNewClass.enclosing.element);
3325
- if (!this.match)
3326
- return newClass;
3327
- }
3328
- // Compare class
3329
- if ((newClass.class === undefined) !== (otherNewClass.class === undefined)) {
3330
- this.abort();
3331
- return newClass;
3332
- }
3333
- // Visit class if present
3334
- if (newClass.class && otherNewClass.class) {
3335
- yield this.visit(newClass.class, otherNewClass.class);
3336
- if (!this.match)
3337
- return newClass;
3338
- }
3339
- // Compare arguments
3340
- if (newClass.arguments.elements.length !== otherNewClass.arguments.elements.length) {
3341
- this.abort();
3342
- return newClass;
3343
- }
3344
- // Visit each argument in lock step
3345
- for (let i = 0; i < newClass.arguments.elements.length; i++) {
3346
- yield this.visit(newClass.arguments.elements[i].element, otherNewClass.arguments.elements[i].element);
3347
- if (!this.match)
3348
- return newClass;
3349
- }
3350
- // Compare body
3351
- if ((newClass.body === undefined) !== (otherNewClass.body === undefined)) {
3352
- this.abort();
3353
- return newClass;
3354
- }
3355
- // Visit body if present
3356
- if (newClass.body && otherNewClass.body) {
3357
- yield this.visit(newClass.body, otherNewClass.body);
3358
- if (!this.match)
3359
- return newClass;
3360
- }
3361
- return newClass;
1436
+ return this.visitElement(newClass, other);
3362
1437
  });
3363
1438
  }
3364
1439
  /**
@@ -3370,27 +1445,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
3370
1445
  */
3371
1446
  visitNullableType(nullableType, other) {
3372
1447
  return __awaiter(this, void 0, void 0, function* () {
3373
- if (!this.match || other.kind !== java_1.J.Kind.NullableType) {
3374
- this.abort();
3375
- return nullableType;
3376
- }
3377
- const otherNullableType = other;
3378
- // Compare annotations
3379
- if (nullableType.annotations.length !== otherNullableType.annotations.length) {
3380
- this.abort();
3381
- return nullableType;
3382
- }
3383
- // Visit each annotation in lock step
3384
- for (let i = 0; i < nullableType.annotations.length; i++) {
3385
- yield this.visit(nullableType.annotations[i], otherNullableType.annotations[i]);
3386
- if (!this.match)
3387
- return nullableType;
3388
- }
3389
- // Visit typeTree
3390
- yield this.visit(nullableType.typeTree.element, otherNullableType.typeTree.element);
3391
- if (!this.match)
3392
- return nullableType;
3393
- return nullableType;
1448
+ return this.visitElement(nullableType, other);
3394
1449
  });
3395
1450
  }
3396
1451
  /**
@@ -3402,34 +1457,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
3402
1457
  */
3403
1458
  visitPackage(packageDeclaration, other) {
3404
1459
  return __awaiter(this, void 0, void 0, function* () {
3405
- if (!this.match || other.kind !== java_1.J.Kind.Package) {
3406
- this.abort();
3407
- return packageDeclaration;
3408
- }
3409
- const otherPackageDeclaration = other;
3410
- // Visit expression
3411
- yield this.visit(packageDeclaration.expression, otherPackageDeclaration.expression);
3412
- if (!this.match)
3413
- return packageDeclaration;
3414
- // Compare annotations
3415
- if ((packageDeclaration.annotations === undefined) !== (otherPackageDeclaration.annotations === undefined)) {
3416
- this.abort();
3417
- return packageDeclaration;
3418
- }
3419
- // Visit annotations if present
3420
- if (packageDeclaration.annotations && otherPackageDeclaration.annotations) {
3421
- if (packageDeclaration.annotations.length !== otherPackageDeclaration.annotations.length) {
3422
- this.abort();
3423
- return packageDeclaration;
3424
- }
3425
- // Visit each annotation in lock step
3426
- for (let i = 0; i < packageDeclaration.annotations.length; i++) {
3427
- yield this.visit(packageDeclaration.annotations[i], otherPackageDeclaration.annotations[i]);
3428
- if (!this.match)
3429
- return packageDeclaration;
3430
- }
3431
- }
3432
- return packageDeclaration;
1460
+ return this.visitElement(packageDeclaration, other);
3433
1461
  });
3434
1462
  }
3435
1463
  /**
@@ -3441,34 +1469,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
3441
1469
  */
3442
1470
  visitParameterizedType(parameterizedType, other) {
3443
1471
  return __awaiter(this, void 0, void 0, function* () {
3444
- if (!this.match || other.kind !== java_1.J.Kind.ParameterizedType) {
3445
- this.abort();
3446
- return parameterizedType;
3447
- }
3448
- const otherParameterizedType = other;
3449
- // Visit class
3450
- yield this.visit(parameterizedType.class, otherParameterizedType.class);
3451
- if (!this.match)
3452
- return parameterizedType;
3453
- // Compare typeParameters
3454
- if ((parameterizedType.typeParameters === undefined) !== (otherParameterizedType.typeParameters === undefined)) {
3455
- this.abort();
3456
- return parameterizedType;
3457
- }
3458
- // Visit typeParameters if present
3459
- if (parameterizedType.typeParameters && otherParameterizedType.typeParameters) {
3460
- if (parameterizedType.typeParameters.elements.length !== otherParameterizedType.typeParameters.elements.length) {
3461
- this.abort();
3462
- return parameterizedType;
3463
- }
3464
- // Visit each type parameter in lock step
3465
- for (let i = 0; i < parameterizedType.typeParameters.elements.length; i++) {
3466
- yield this.visit(parameterizedType.typeParameters.elements[i].element, otherParameterizedType.typeParameters.elements[i].element);
3467
- if (!this.match)
3468
- return parameterizedType;
3469
- }
3470
- }
3471
- return parameterizedType;
1472
+ return this.visitElement(parameterizedType, other);
3472
1473
  });
3473
1474
  }
3474
1475
  /**
@@ -3480,16 +1481,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
3480
1481
  */
3481
1482
  visitParentheses(parentheses, other) {
3482
1483
  return __awaiter(this, void 0, void 0, function* () {
3483
- if (!this.match || other.kind !== java_1.J.Kind.Parentheses) {
3484
- this.abort();
3485
- return parentheses;
3486
- }
3487
- const otherParentheses = other;
3488
- // Visit tree
3489
- yield this.visit(parentheses.tree.element, otherParentheses.tree.element);
3490
- if (!this.match)
3491
- return parentheses;
3492
- return parentheses;
1484
+ return this.visitElement(parentheses, other);
3493
1485
  });
3494
1486
  }
3495
1487
  /**
@@ -3501,27 +1493,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
3501
1493
  */
3502
1494
  visitParenthesizedTypeTree(parenthesizedTypeTree, other) {
3503
1495
  return __awaiter(this, void 0, void 0, function* () {
3504
- if (!this.match || other.kind !== java_1.J.Kind.ParenthesizedTypeTree) {
3505
- this.abort();
3506
- return parenthesizedTypeTree;
3507
- }
3508
- const otherParenthesizedTypeTree = other;
3509
- // Compare annotations
3510
- if (parenthesizedTypeTree.annotations.length !== otherParenthesizedTypeTree.annotations.length) {
3511
- this.abort();
3512
- return parenthesizedTypeTree;
3513
- }
3514
- // Visit each annotation in lock step
3515
- for (let i = 0; i < parenthesizedTypeTree.annotations.length; i++) {
3516
- yield this.visit(parenthesizedTypeTree.annotations[i], otherParenthesizedTypeTree.annotations[i]);
3517
- if (!this.match)
3518
- return parenthesizedTypeTree;
3519
- }
3520
- // Visit parenthesizedType
3521
- yield this.visit(parenthesizedTypeTree.parenthesizedType, otherParenthesizedTypeTree.parenthesizedType);
3522
- if (!this.match)
3523
- return parenthesizedTypeTree;
3524
- return parenthesizedTypeTree;
1496
+ return this.visitElement(parenthesizedTypeTree, other);
3525
1497
  });
3526
1498
  }
3527
1499
  /**
@@ -3533,17 +1505,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
3533
1505
  */
3534
1506
  visitPrimitive(primitive, other) {
3535
1507
  return __awaiter(this, void 0, void 0, function* () {
3536
- if (!this.match || other.kind !== java_1.J.Kind.Primitive) {
3537
- this.abort();
3538
- return primitive;
3539
- }
3540
- const otherPrimitive = other;
3541
- // Compare type
3542
- if (primitive.type.kind !== otherPrimitive.type.kind) {
3543
- this.abort();
3544
- return primitive;
3545
- }
3546
- return primitive;
1508
+ return this.visitElement(primitive, other);
3547
1509
  });
3548
1510
  }
3549
1511
  /**
@@ -3555,23 +1517,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
3555
1517
  */
3556
1518
  visitReturn(returnStatement, other) {
3557
1519
  return __awaiter(this, void 0, void 0, function* () {
3558
- if (!this.match || other.kind !== java_1.J.Kind.Return) {
3559
- this.abort();
3560
- return returnStatement;
3561
- }
3562
- const otherReturnStatement = other;
3563
- // Compare expression
3564
- if ((returnStatement.expression === undefined) !== (otherReturnStatement.expression === undefined)) {
3565
- this.abort();
3566
- return returnStatement;
3567
- }
3568
- // Visit expression if present
3569
- if (returnStatement.expression && otherReturnStatement.expression) {
3570
- yield this.visit(returnStatement.expression, otherReturnStatement.expression);
3571
- if (!this.match)
3572
- return returnStatement;
3573
- }
3574
- return returnStatement;
1520
+ return this.visitElement(returnStatement, other);
3575
1521
  });
3576
1522
  }
3577
1523
  /**
@@ -3583,20 +1529,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
3583
1529
  */
3584
1530
  visitSwitch(switchStatement, other) {
3585
1531
  return __awaiter(this, void 0, void 0, function* () {
3586
- if (!this.match || other.kind !== java_1.J.Kind.Switch) {
3587
- this.abort();
3588
- return switchStatement;
3589
- }
3590
- const otherSwitchStatement = other;
3591
- // Visit selector
3592
- yield this.visit(switchStatement.selector, otherSwitchStatement.selector);
3593
- if (!this.match)
3594
- return switchStatement;
3595
- // Visit cases
3596
- yield this.visit(switchStatement.cases, otherSwitchStatement.cases);
3597
- if (!this.match)
3598
- return switchStatement;
3599
- return switchStatement;
1532
+ return this.visitElement(switchStatement, other);
3600
1533
  });
3601
1534
  }
3602
1535
  /**
@@ -3608,20 +1541,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
3608
1541
  */
3609
1542
  visitSwitchExpression(switchExpression, other) {
3610
1543
  return __awaiter(this, void 0, void 0, function* () {
3611
- if (!this.match || other.kind !== java_1.J.Kind.SwitchExpression) {
3612
- this.abort();
3613
- return switchExpression;
3614
- }
3615
- const otherSwitchExpression = other;
3616
- // Visit selector
3617
- yield this.visit(switchExpression.selector, otherSwitchExpression.selector);
3618
- if (!this.match)
3619
- return switchExpression;
3620
- // Visit cases
3621
- yield this.visit(switchExpression.cases, otherSwitchExpression.cases);
3622
- if (!this.match)
3623
- return switchExpression;
3624
- return switchExpression;
1544
+ return this.visitElement(switchExpression, other);
3625
1545
  });
3626
1546
  }
3627
1547
  /**
@@ -3633,20 +1553,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
3633
1553
  */
3634
1554
  visitSynchronized(synchronizedStatement, other) {
3635
1555
  return __awaiter(this, void 0, void 0, function* () {
3636
- if (!this.match || other.kind !== java_1.J.Kind.Synchronized) {
3637
- this.abort();
3638
- return synchronizedStatement;
3639
- }
3640
- const otherSynchronizedStatement = other;
3641
- // Visit lock
3642
- yield this.visit(synchronizedStatement.lock, otherSynchronizedStatement.lock);
3643
- if (!this.match)
3644
- return synchronizedStatement;
3645
- // Visit body
3646
- yield this.visit(synchronizedStatement.body, otherSynchronizedStatement.body);
3647
- if (!this.match)
3648
- return synchronizedStatement;
3649
- return synchronizedStatement;
1556
+ return this.visitElement(synchronizedStatement, other);
3650
1557
  });
3651
1558
  }
3652
1559
  /**
@@ -3658,24 +1565,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
3658
1565
  */
3659
1566
  visitTernary(ternary, other) {
3660
1567
  return __awaiter(this, void 0, void 0, function* () {
3661
- if (!this.match || other.kind !== java_1.J.Kind.Ternary) {
3662
- this.abort();
3663
- return ternary;
3664
- }
3665
- const otherTernary = other;
3666
- // Visit condition
3667
- yield this.visit(ternary.condition, otherTernary.condition);
3668
- if (!this.match)
3669
- return ternary;
3670
- // Visit truePart
3671
- yield this.visit(ternary.truePart.element, otherTernary.truePart.element);
3672
- if (!this.match)
3673
- return ternary;
3674
- // Visit falsePart
3675
- yield this.visit(ternary.falsePart.element, otherTernary.falsePart.element);
3676
- if (!this.match)
3677
- return ternary;
3678
- return ternary;
1568
+ return this.visitElement(ternary, other);
3679
1569
  });
3680
1570
  }
3681
1571
  /**
@@ -3687,16 +1577,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
3687
1577
  */
3688
1578
  visitThrow(throwStatement, other) {
3689
1579
  return __awaiter(this, void 0, void 0, function* () {
3690
- if (!this.match || other.kind !== java_1.J.Kind.Throw) {
3691
- this.abort();
3692
- return throwStatement;
3693
- }
3694
- const otherThrowStatement = other;
3695
- // Visit exception
3696
- yield this.visit(throwStatement.exception, otherThrowStatement.exception);
3697
- if (!this.match)
3698
- return throwStatement;
3699
- return throwStatement;
1580
+ return this.visitElement(throwStatement, other);
3700
1581
  });
3701
1582
  }
3702
1583
  /**
@@ -3708,56 +1589,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
3708
1589
  */
3709
1590
  visitTry(tryStatement, other) {
3710
1591
  return __awaiter(this, void 0, void 0, function* () {
3711
- if (!this.match || other.kind !== java_1.J.Kind.Try) {
3712
- this.abort();
3713
- return tryStatement;
3714
- }
3715
- const otherTryStatement = other;
3716
- // Compare resources
3717
- if ((tryStatement.resources === undefined) !== (otherTryStatement.resources === undefined)) {
3718
- this.abort();
3719
- return tryStatement;
3720
- }
3721
- // Visit resources if present
3722
- if (tryStatement.resources && otherTryStatement.resources) {
3723
- if (tryStatement.resources.elements.length !== otherTryStatement.resources.elements.length) {
3724
- this.abort();
3725
- return tryStatement;
3726
- }
3727
- // Visit each resource in lock step
3728
- for (let i = 0; i < tryStatement.resources.elements.length; i++) {
3729
- yield this.visit(tryStatement.resources.elements[i].element, otherTryStatement.resources.elements[i].element);
3730
- if (!this.match)
3731
- return tryStatement;
3732
- }
3733
- }
3734
- // Visit body
3735
- yield this.visit(tryStatement.body, otherTryStatement.body);
3736
- if (!this.match)
3737
- return tryStatement;
3738
- // Compare catches
3739
- if (tryStatement.catches.length !== otherTryStatement.catches.length) {
3740
- this.abort();
3741
- return tryStatement;
3742
- }
3743
- // Visit each catch in lock step
3744
- for (let i = 0; i < tryStatement.catches.length; i++) {
3745
- yield this.visit(tryStatement.catches[i], otherTryStatement.catches[i]);
3746
- if (!this.match)
3747
- return tryStatement;
3748
- }
3749
- // Compare finally
3750
- if ((tryStatement.finally === undefined) !== (otherTryStatement.finally === undefined)) {
3751
- this.abort();
3752
- return tryStatement;
3753
- }
3754
- // Visit finally if present
3755
- if (tryStatement.finally && otherTryStatement.finally) {
3756
- yield this.visit(tryStatement.finally.element, otherTryStatement.finally.element);
3757
- if (!this.match)
3758
- return tryStatement;
3759
- }
3760
- return tryStatement;
1592
+ return this.visitElement(tryStatement, other);
3761
1593
  });
3762
1594
  }
3763
1595
  /**
@@ -3769,21 +1601,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
3769
1601
  */
3770
1602
  visitTryResource(resource, other) {
3771
1603
  return __awaiter(this, void 0, void 0, function* () {
3772
- if (!this.match || other.kind !== java_1.J.Kind.TryResource) {
3773
- this.abort();
3774
- return resource;
3775
- }
3776
- const otherResource = other;
3777
- // Visit variableDeclarations
3778
- yield this.visit(resource.variableDeclarations, otherResource.variableDeclarations);
3779
- if (!this.match)
3780
- return resource;
3781
- // Compare terminatedWithSemicolon
3782
- if (resource.terminatedWithSemicolon !== otherResource.terminatedWithSemicolon) {
3783
- this.abort();
3784
- return resource;
3785
- }
3786
- return resource;
1604
+ return this.visitElement(resource, other);
3787
1605
  });
3788
1606
  }
3789
1607
  /**
@@ -3795,20 +1613,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
3795
1613
  */
3796
1614
  visitTryCatch(tryCatch, other) {
3797
1615
  return __awaiter(this, void 0, void 0, function* () {
3798
- if (!this.match || other.kind !== java_1.J.Kind.TryCatch) {
3799
- this.abort();
3800
- return tryCatch;
3801
- }
3802
- const otherTryCatch = other;
3803
- // Visit parameter
3804
- yield this.visit(tryCatch.parameter, otherTryCatch.parameter);
3805
- if (!this.match)
3806
- return tryCatch;
3807
- // Visit body
3808
- yield this.visit(tryCatch.body, otherTryCatch.body);
3809
- if (!this.match)
3810
- return tryCatch;
3811
- return tryCatch;
1616
+ return this.visitElement(tryCatch, other);
3812
1617
  });
3813
1618
  }
3814
1619
  /**
@@ -3820,20 +1625,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
3820
1625
  */
3821
1626
  visitTypeCast(typeCast, other) {
3822
1627
  return __awaiter(this, void 0, void 0, function* () {
3823
- if (!this.match || other.kind !== java_1.J.Kind.TypeCast) {
3824
- this.abort();
3825
- return typeCast;
3826
- }
3827
- const otherTypeCast = other;
3828
- // Visit class
3829
- yield this.visit(typeCast.class, otherTypeCast.class);
3830
- if (!this.match)
3831
- return typeCast;
3832
- // Visit expression
3833
- yield this.visit(typeCast.expression, otherTypeCast.expression);
3834
- if (!this.match)
3835
- return typeCast;
3836
- return typeCast;
1628
+ return this.visitElement(typeCast, other);
3837
1629
  });
3838
1630
  }
3839
1631
  /**
@@ -3845,56 +1637,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
3845
1637
  */
3846
1638
  visitTypeParameter(typeParameter, other) {
3847
1639
  return __awaiter(this, void 0, void 0, function* () {
3848
- if (!this.match || other.kind !== java_1.J.Kind.TypeParameter) {
3849
- this.abort();
3850
- return typeParameter;
3851
- }
3852
- const otherTypeParameter = other;
3853
- // Compare annotations
3854
- if (typeParameter.annotations.length !== otherTypeParameter.annotations.length) {
3855
- this.abort();
3856
- return typeParameter;
3857
- }
3858
- // Visit each annotation in lock step
3859
- for (let i = 0; i < typeParameter.annotations.length; i++) {
3860
- yield this.visit(typeParameter.annotations[i], otherTypeParameter.annotations[i]);
3861
- if (!this.match)
3862
- return typeParameter;
3863
- }
3864
- // Compare modifiers
3865
- if (typeParameter.modifiers.length !== otherTypeParameter.modifiers.length) {
3866
- this.abort();
3867
- return typeParameter;
3868
- }
3869
- // Visit each modifier in lock step
3870
- for (let i = 0; i < typeParameter.modifiers.length; i++) {
3871
- yield this.visit(typeParameter.modifiers[i], otherTypeParameter.modifiers[i]);
3872
- if (!this.match)
3873
- return typeParameter;
3874
- }
3875
- // Visit name
3876
- yield this.visit(typeParameter.name, otherTypeParameter.name);
3877
- if (!this.match)
3878
- return typeParameter;
3879
- // Compare bounds
3880
- if ((typeParameter.bounds === undefined) !== (otherTypeParameter.bounds === undefined)) {
3881
- this.abort();
3882
- return typeParameter;
3883
- }
3884
- // Visit bounds if present
3885
- if (typeParameter.bounds && otherTypeParameter.bounds) {
3886
- if (typeParameter.bounds.elements.length !== otherTypeParameter.bounds.elements.length) {
3887
- this.abort();
3888
- return typeParameter;
3889
- }
3890
- // Visit each bound in lock step
3891
- for (let i = 0; i < typeParameter.bounds.elements.length; i++) {
3892
- yield this.visit(typeParameter.bounds.elements[i].element, otherTypeParameter.bounds.elements[i].element);
3893
- if (!this.match)
3894
- return typeParameter;
3895
- }
3896
- }
3897
- return typeParameter;
1640
+ return this.visitElement(typeParameter, other);
3898
1641
  });
3899
1642
  }
3900
1643
  /**
@@ -3906,34 +1649,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
3906
1649
  */
3907
1650
  visitTypeParameters(typeParameters, other) {
3908
1651
  return __awaiter(this, void 0, void 0, function* () {
3909
- if (!this.match || other.kind !== java_1.J.Kind.TypeParameters) {
3910
- this.abort();
3911
- return typeParameters;
3912
- }
3913
- const otherTypeParameters = other;
3914
- // Compare annotations
3915
- if (typeParameters.annotations.length !== otherTypeParameters.annotations.length) {
3916
- this.abort();
3917
- return typeParameters;
3918
- }
3919
- // Visit each annotation in lock step
3920
- for (let i = 0; i < typeParameters.annotations.length; i++) {
3921
- yield this.visit(typeParameters.annotations[i], otherTypeParameters.annotations[i]);
3922
- if (!this.match)
3923
- return typeParameters;
3924
- }
3925
- // Compare typeParameters
3926
- if (typeParameters.typeParameters.length !== otherTypeParameters.typeParameters.length) {
3927
- this.abort();
3928
- return typeParameters;
3929
- }
3930
- // Visit each type parameter in lock step
3931
- for (let i = 0; i < typeParameters.typeParameters.length; i++) {
3932
- yield this.visit(typeParameters.typeParameters[i].element, otherTypeParameters.typeParameters[i].element);
3933
- if (!this.match)
3934
- return typeParameters;
3935
- }
3936
- return typeParameters;
1652
+ return this.visitElement(typeParameters, other);
3937
1653
  });
3938
1654
  }
3939
1655
  /**
@@ -3945,21 +1661,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
3945
1661
  */
3946
1662
  visitUnary(unary, other) {
3947
1663
  return __awaiter(this, void 0, void 0, function* () {
3948
- if (!this.match || other.kind !== java_1.J.Kind.Unary) {
3949
- this.abort();
3950
- return unary;
3951
- }
3952
- const otherUnary = other;
3953
- // Compare operator
3954
- if (unary.operator.element !== otherUnary.operator.element) {
3955
- this.abort();
3956
- return unary;
3957
- }
3958
- // Visit expression
3959
- yield this.visit(unary.expression, otherUnary.expression);
3960
- if (!this.match)
3961
- return unary;
3962
- return unary;
1664
+ return this.visitElement(unary, other);
3963
1665
  });
3964
1666
  }
3965
1667
  /**
@@ -3971,16 +1673,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
3971
1673
  */
3972
1674
  visitUnknown(unknown, other) {
3973
1675
  return __awaiter(this, void 0, void 0, function* () {
3974
- if (!this.match || other.kind !== java_1.J.Kind.Unknown) {
3975
- this.abort();
3976
- return unknown;
3977
- }
3978
- const otherUnknown = other;
3979
- // Visit source
3980
- yield this.visit(unknown.source, otherUnknown.source);
3981
- if (!this.match)
3982
- return unknown;
3983
- return unknown;
1676
+ return this.visitElement(unknown, other);
3984
1677
  });
3985
1678
  }
3986
1679
  /**
@@ -3992,17 +1685,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
3992
1685
  */
3993
1686
  visitUnknownSource(unknownSource, other) {
3994
1687
  return __awaiter(this, void 0, void 0, function* () {
3995
- if (!this.match || other.kind !== java_1.J.Kind.UnknownSource) {
3996
- this.abort();
3997
- return unknownSource;
3998
- }
3999
- const otherUnknownSource = other;
4000
- // Compare text
4001
- if (unknownSource.text !== otherUnknownSource.text) {
4002
- this.abort();
4003
- return unknownSource;
4004
- }
4005
- return unknownSource;
1688
+ return this.visitElement(unknownSource, other);
4006
1689
  });
4007
1690
  }
4008
1691
  /**
@@ -4014,61 +1697,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
4014
1697
  */
4015
1698
  visitVariableDeclarations(variableDeclarations, other) {
4016
1699
  return __awaiter(this, void 0, void 0, function* () {
4017
- if (!this.match || other.kind !== java_1.J.Kind.VariableDeclarations) {
4018
- this.abort();
4019
- return variableDeclarations;
4020
- }
4021
- const otherVariableDeclarations = other;
4022
- // Compare leadingAnnotations
4023
- if (variableDeclarations.leadingAnnotations.length !== otherVariableDeclarations.leadingAnnotations.length) {
4024
- this.abort();
4025
- return variableDeclarations;
4026
- }
4027
- // Visit each leading annotation in lock step
4028
- for (let i = 0; i < variableDeclarations.leadingAnnotations.length; i++) {
4029
- yield this.visit(variableDeclarations.leadingAnnotations[i], otherVariableDeclarations.leadingAnnotations[i]);
4030
- if (!this.match)
4031
- return variableDeclarations;
4032
- }
4033
- // Compare modifiers
4034
- if (variableDeclarations.modifiers.length !== otherVariableDeclarations.modifiers.length) {
4035
- this.abort();
4036
- return variableDeclarations;
4037
- }
4038
- // Visit each modifier in lock step
4039
- for (let i = 0; i < variableDeclarations.modifiers.length; i++) {
4040
- yield this.visit(variableDeclarations.modifiers[i], otherVariableDeclarations.modifiers[i]);
4041
- if (!this.match)
4042
- return variableDeclarations;
4043
- }
4044
- // Compare typeExpression
4045
- if ((variableDeclarations.typeExpression === undefined) !== (otherVariableDeclarations.typeExpression === undefined)) {
4046
- this.abort();
4047
- return variableDeclarations;
4048
- }
4049
- // Visit typeExpression if present
4050
- if (variableDeclarations.typeExpression && otherVariableDeclarations.typeExpression) {
4051
- yield this.visit(variableDeclarations.typeExpression, otherVariableDeclarations.typeExpression);
4052
- if (!this.match)
4053
- return variableDeclarations;
4054
- }
4055
- // Compare varargs
4056
- if ((variableDeclarations.varargs === undefined) !== (otherVariableDeclarations.varargs === undefined)) {
4057
- this.abort();
4058
- return variableDeclarations;
4059
- }
4060
- // Compare variables
4061
- if (variableDeclarations.variables.length !== otherVariableDeclarations.variables.length) {
4062
- this.abort();
4063
- return variableDeclarations;
4064
- }
4065
- // Visit each variable in lock step
4066
- for (let i = 0; i < variableDeclarations.variables.length; i++) {
4067
- yield this.visit(variableDeclarations.variables[i].element, otherVariableDeclarations.variables[i].element);
4068
- if (!this.match)
4069
- return variableDeclarations;
4070
- }
4071
- return variableDeclarations;
1700
+ return this.visitElement(variableDeclarations, other);
4072
1701
  });
4073
1702
  }
4074
1703
  /**
@@ -4080,32 +1709,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
4080
1709
  */
4081
1710
  visitVariable(variable, other) {
4082
1711
  return __awaiter(this, void 0, void 0, function* () {
4083
- if (!this.match || other.kind !== java_1.J.Kind.NamedVariable) {
4084
- this.abort();
4085
- return variable;
4086
- }
4087
- const otherVariable = other;
4088
- // Visit name
4089
- yield this.visit(variable.name, otherVariable.name);
4090
- if (!this.match)
4091
- return variable;
4092
- // Compare dimensionsAfterName
4093
- if (variable.dimensionsAfterName.length !== otherVariable.dimensionsAfterName.length) {
4094
- this.abort();
4095
- return variable;
4096
- }
4097
- // Compare initializer
4098
- if ((variable.initializer === undefined) !== (otherVariable.initializer === undefined)) {
4099
- this.abort();
4100
- return variable;
4101
- }
4102
- // Visit initializer if present
4103
- if (variable.initializer && otherVariable.initializer) {
4104
- yield this.visit(variable.initializer.element, otherVariable.initializer.element);
4105
- if (!this.match)
4106
- return variable;
4107
- }
4108
- return variable;
1712
+ return this.visitElement(variable, other);
4109
1713
  });
4110
1714
  }
4111
1715
  /**
@@ -4117,20 +1721,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
4117
1721
  */
4118
1722
  visitWhileLoop(whileLoop, other) {
4119
1723
  return __awaiter(this, void 0, void 0, function* () {
4120
- if (!this.match || other.kind !== java_1.J.Kind.WhileLoop) {
4121
- this.abort();
4122
- return whileLoop;
4123
- }
4124
- const otherWhileLoop = other;
4125
- // Visit condition
4126
- yield this.visit(whileLoop.condition, otherWhileLoop.condition);
4127
- if (!this.match)
4128
- return whileLoop;
4129
- // Visit body
4130
- yield this.visit(whileLoop.body.element, otherWhileLoop.body.element);
4131
- if (!this.match)
4132
- return whileLoop;
4133
- return whileLoop;
1724
+ return this.visitElement(whileLoop, other);
4134
1725
  });
4135
1726
  }
4136
1727
  /**
@@ -4142,35 +1733,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
4142
1733
  */
4143
1734
  visitWildcard(wildcard, other) {
4144
1735
  return __awaiter(this, void 0, void 0, function* () {
4145
- if (!this.match || other.kind !== java_1.J.Kind.Wildcard) {
4146
- this.abort();
4147
- return wildcard;
4148
- }
4149
- const otherWildcard = other;
4150
- // Compare bound
4151
- if ((wildcard.bound === undefined) !== (otherWildcard.bound === undefined)) {
4152
- this.abort();
4153
- return wildcard;
4154
- }
4155
- // Compare bound if present
4156
- if (wildcard.bound && otherWildcard.bound) {
4157
- if (wildcard.bound.element !== otherWildcard.bound.element) {
4158
- this.abort();
4159
- return wildcard;
4160
- }
4161
- }
4162
- // Compare boundedType
4163
- if ((wildcard.boundedType === undefined) !== (otherWildcard.boundedType === undefined)) {
4164
- this.abort();
4165
- return wildcard;
4166
- }
4167
- // Visit boundedType if present
4168
- if (wildcard.boundedType && otherWildcard.boundedType) {
4169
- yield this.visit(wildcard.boundedType, otherWildcard.boundedType);
4170
- if (!this.match)
4171
- return wildcard;
4172
- }
4173
- return wildcard;
1736
+ return this.visitElement(wildcard, other);
4174
1737
  });
4175
1738
  }
4176
1739
  /**
@@ -4182,21 +1745,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
4182
1745
  */
4183
1746
  visitYield(yieldStatement, other) {
4184
1747
  return __awaiter(this, void 0, void 0, function* () {
4185
- if (!this.match || other.kind !== java_1.J.Kind.Yield) {
4186
- this.abort();
4187
- return yieldStatement;
4188
- }
4189
- const otherYieldStatement = other;
4190
- // Compare implicit
4191
- if (yieldStatement.implicit !== otherYieldStatement.implicit) {
4192
- this.abort();
4193
- return yieldStatement;
4194
- }
4195
- // Visit value
4196
- yield this.visit(yieldStatement.value, otherYieldStatement.value);
4197
- if (!this.match)
4198
- return yieldStatement;
4199
- return yieldStatement;
1748
+ return this.visitElement(yieldStatement, other);
4200
1749
  });
4201
1750
  }
4202
1751
  /**
@@ -4208,14 +1757,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
4208
1757
  */
4209
1758
  visitVoid(void_, other) {
4210
1759
  return __awaiter(this, void 0, void 0, function* () {
4211
- if (!this.match || other.kind !== tree_1.JS.Kind.Void) {
4212
- this.abort();
4213
- return void_;
4214
- }
4215
- const otherVoid = other;
4216
- // Visit expression
4217
- yield this.visit(void_.expression, otherVoid.expression);
4218
- return void_;
1760
+ return this.visitElement(void_, other);
4219
1761
  });
4220
1762
  }
4221
1763
  /**
@@ -4227,18 +1769,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
4227
1769
  */
4228
1770
  visitWithStatement(withStatement, other) {
4229
1771
  return __awaiter(this, void 0, void 0, function* () {
4230
- if (!this.match || other.kind !== tree_1.JS.Kind.WithStatement) {
4231
- this.abort();
4232
- return withStatement;
4233
- }
4234
- const otherWithStatement = other;
4235
- // Visit expression
4236
- yield this.visit(withStatement.expression, otherWithStatement.expression);
4237
- if (!this.match)
4238
- return withStatement;
4239
- // Visit body
4240
- yield this.visit(withStatement.body.element, otherWithStatement.body.element);
4241
- return withStatement;
1772
+ return this.visitElement(withStatement, other);
4242
1773
  });
4243
1774
  }
4244
1775
  /**
@@ -4250,36 +1781,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
4250
1781
  */
4251
1782
  visitIndexSignatureDeclaration(indexSignatureDeclaration, other) {
4252
1783
  return __awaiter(this, void 0, void 0, function* () {
4253
- if (!this.match || other.kind !== tree_1.JS.Kind.IndexSignatureDeclaration) {
4254
- this.abort();
4255
- return indexSignatureDeclaration;
4256
- }
4257
- const otherIndexSignatureDeclaration = other;
4258
- // Compare modifiers
4259
- if (indexSignatureDeclaration.modifiers.length !== otherIndexSignatureDeclaration.modifiers.length) {
4260
- this.abort();
4261
- return indexSignatureDeclaration;
4262
- }
4263
- // Visit modifiers in lock step
4264
- for (let i = 0; i < indexSignatureDeclaration.modifiers.length; i++) {
4265
- yield this.visit(indexSignatureDeclaration.modifiers[i], otherIndexSignatureDeclaration.modifiers[i]);
4266
- if (!this.match)
4267
- return indexSignatureDeclaration;
4268
- }
4269
- // Compare parameters
4270
- if (indexSignatureDeclaration.parameters.elements.length !== otherIndexSignatureDeclaration.parameters.elements.length) {
4271
- this.abort();
4272
- return indexSignatureDeclaration;
4273
- }
4274
- // Visit parameters in lock step
4275
- for (let i = 0; i < indexSignatureDeclaration.parameters.elements.length; i++) {
4276
- yield this.visit(indexSignatureDeclaration.parameters.elements[i].element, otherIndexSignatureDeclaration.parameters.elements[i].element);
4277
- if (!this.match)
4278
- return indexSignatureDeclaration;
4279
- }
4280
- // Visit type expression
4281
- yield this.visit(indexSignatureDeclaration.typeExpression.element, otherIndexSignatureDeclaration.typeExpression.element);
4282
- return indexSignatureDeclaration;
1784
+ return this.visitElement(indexSignatureDeclaration, other);
4283
1785
  });
4284
1786
  }
4285
1787
  /**
@@ -4291,21 +1793,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
4291
1793
  */
4292
1794
  visitForOfLoop(forOfLoop, other) {
4293
1795
  return __awaiter(this, void 0, void 0, function* () {
4294
- if (!this.match || other.kind !== tree_1.JS.Kind.ForOfLoop) {
4295
- this.abort();
4296
- return forOfLoop;
4297
- }
4298
- const otherForOfLoop = other;
4299
- // Compare await
4300
- if ((forOfLoop.await === undefined) !== (otherForOfLoop.await === undefined)) {
4301
- this.abort();
4302
- return forOfLoop;
4303
- }
4304
- // Visit loop
4305
- yield this.visit(forOfLoop.loop, otherForOfLoop.loop);
4306
- if (!this.match)
4307
- return forOfLoop;
4308
- return forOfLoop;
1796
+ return this.visitElement(forOfLoop, other);
4309
1797
  });
4310
1798
  }
4311
1799
  /**
@@ -4317,20 +1805,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
4317
1805
  */
4318
1806
  visitForInLoop(forInLoop, other) {
4319
1807
  return __awaiter(this, void 0, void 0, function* () {
4320
- if (!this.match || other.kind !== tree_1.JS.Kind.ForInLoop) {
4321
- this.abort();
4322
- return forInLoop;
4323
- }
4324
- const otherForInLoop = other;
4325
- // Visit control
4326
- yield this.visit(forInLoop.control, otherForInLoop.control);
4327
- if (!this.match)
4328
- return forInLoop;
4329
- // Visit body
4330
- yield this.visit(forInLoop.body.element, otherForInLoop.body.element);
4331
- if (!this.match)
4332
- return forInLoop;
4333
- return forInLoop;
1808
+ return this.visitElement(forInLoop, other);
4334
1809
  });
4335
1810
  }
4336
1811
  /**
@@ -4342,43 +1817,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
4342
1817
  */
4343
1818
  visitNamespaceDeclaration(namespaceDeclaration, other) {
4344
1819
  return __awaiter(this, void 0, void 0, function* () {
4345
- if (!this.match || other.kind !== tree_1.JS.Kind.NamespaceDeclaration) {
4346
- this.abort();
4347
- return namespaceDeclaration;
4348
- }
4349
- const otherNamespaceDeclaration = other;
4350
- // Compare modifiers
4351
- if (namespaceDeclaration.modifiers.length !== otherNamespaceDeclaration.modifiers.length) {
4352
- this.abort();
4353
- return namespaceDeclaration;
4354
- }
4355
- // Visit each modifier in lock step
4356
- for (let i = 0; i < namespaceDeclaration.modifiers.length; i++) {
4357
- yield this.visit(namespaceDeclaration.modifiers[i], otherNamespaceDeclaration.modifiers[i]);
4358
- if (!this.match)
4359
- return namespaceDeclaration;
4360
- }
4361
- // Compare keywordType
4362
- if (namespaceDeclaration.keywordType.element !== otherNamespaceDeclaration.keywordType.element) {
4363
- this.abort();
4364
- return namespaceDeclaration;
4365
- }
4366
- // Visit name
4367
- yield this.visit(namespaceDeclaration.name.element, otherNamespaceDeclaration.name.element);
4368
- if (!this.match)
4369
- return namespaceDeclaration;
4370
- // Compare body
4371
- if ((namespaceDeclaration.body === undefined) !== (otherNamespaceDeclaration.body === undefined)) {
4372
- this.abort();
4373
- return namespaceDeclaration;
4374
- }
4375
- // Visit body if present
4376
- if (namespaceDeclaration.body && otherNamespaceDeclaration.body) {
4377
- yield this.visit(namespaceDeclaration.body, otherNamespaceDeclaration.body);
4378
- if (!this.match)
4379
- return namespaceDeclaration;
4380
- }
4381
- return namespaceDeclaration;
1820
+ return this.visitElement(namespaceDeclaration, other);
4382
1821
  });
4383
1822
  }
4384
1823
  /**
@@ -4390,16 +1829,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
4390
1829
  */
4391
1830
  visitTypeLiteral(typeLiteral, other) {
4392
1831
  return __awaiter(this, void 0, void 0, function* () {
4393
- if (!this.match || other.kind !== tree_1.JS.Kind.TypeLiteral) {
4394
- this.abort();
4395
- return typeLiteral;
4396
- }
4397
- const otherTypeLiteral = other;
4398
- // Visit members
4399
- yield this.visit(typeLiteral.members, otherTypeLiteral.members);
4400
- if (!this.match)
4401
- return typeLiteral;
4402
- return typeLiteral;
1832
+ return this.visitElement(typeLiteral, other);
4403
1833
  });
4404
1834
  }
4405
1835
  /**
@@ -4411,38 +1841,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
4411
1841
  */
4412
1842
  visitBindingElement(bindingElement, other) {
4413
1843
  return __awaiter(this, void 0, void 0, function* () {
4414
- if (!this.match || other.kind !== tree_1.JS.Kind.BindingElement) {
4415
- this.abort();
4416
- return bindingElement;
4417
- }
4418
- const otherBindingElement = other;
4419
- // Compare propertyName
4420
- if ((bindingElement.propertyName === undefined) !== (otherBindingElement.propertyName === undefined)) {
4421
- this.abort();
4422
- return bindingElement;
4423
- }
4424
- // Visit propertyName if present
4425
- if (bindingElement.propertyName && otherBindingElement.propertyName) {
4426
- yield this.visit(bindingElement.propertyName.element, otherBindingElement.propertyName.element);
4427
- if (!this.match)
4428
- return bindingElement;
4429
- }
4430
- // Visit name
4431
- yield this.visit(bindingElement.name, otherBindingElement.name);
4432
- if (!this.match)
4433
- return bindingElement;
4434
- // Compare initializer
4435
- if ((bindingElement.initializer === undefined) !== (otherBindingElement.initializer === undefined)) {
4436
- this.abort();
4437
- return bindingElement;
4438
- }
4439
- // Visit initializer if present
4440
- if (bindingElement.initializer && otherBindingElement.initializer) {
4441
- yield this.visit(bindingElement.initializer.element, otherBindingElement.initializer.element);
4442
- if (!this.match)
4443
- return bindingElement;
4444
- }
4445
- return bindingElement;
1844
+ return this.visitElement(bindingElement, other);
4446
1845
  });
4447
1846
  }
4448
1847
  /**
@@ -4454,23 +1853,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
4454
1853
  */
4455
1854
  visitArrayBindingPattern(arrayBindingPattern, other) {
4456
1855
  return __awaiter(this, void 0, void 0, function* () {
4457
- if (!this.match || other.kind !== tree_1.JS.Kind.ArrayBindingPattern) {
4458
- this.abort();
4459
- return arrayBindingPattern;
4460
- }
4461
- const otherArrayBindingPattern = other;
4462
- // Compare elements
4463
- if (arrayBindingPattern.elements.elements.length !== otherArrayBindingPattern.elements.elements.length) {
4464
- this.abort();
4465
- return arrayBindingPattern;
4466
- }
4467
- // Visit each element in lock step
4468
- for (let i = 0; i < arrayBindingPattern.elements.elements.length; i++) {
4469
- yield this.visit(arrayBindingPattern.elements.elements[i].element, otherArrayBindingPattern.elements.elements[i].element);
4470
- if (!this.match)
4471
- return arrayBindingPattern;
4472
- }
4473
- return arrayBindingPattern;
1856
+ return this.visitElement(arrayBindingPattern, other);
4474
1857
  });
4475
1858
  }
4476
1859
  /**
@@ -4482,61 +1865,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
4482
1865
  */
4483
1866
  visitExportDeclaration(exportDeclaration, other) {
4484
1867
  return __awaiter(this, void 0, void 0, function* () {
4485
- if (!this.match || other.kind !== tree_1.JS.Kind.ExportDeclaration) {
4486
- this.abort();
4487
- return exportDeclaration;
4488
- }
4489
- const otherExportDeclaration = other;
4490
- // Compare modifiers
4491
- if (exportDeclaration.modifiers.length !== otherExportDeclaration.modifiers.length) {
4492
- this.abort();
4493
- return exportDeclaration;
4494
- }
4495
- // Visit each modifier in lock step
4496
- for (let i = 0; i < exportDeclaration.modifiers.length; i++) {
4497
- yield this.visit(exportDeclaration.modifiers[i], otherExportDeclaration.modifiers[i]);
4498
- if (!this.match)
4499
- return exportDeclaration;
4500
- }
4501
- // Compare typeOnly
4502
- if (exportDeclaration.typeOnly.element !== otherExportDeclaration.typeOnly.element) {
4503
- this.abort();
4504
- return exportDeclaration;
4505
- }
4506
- // Compare exportClause
4507
- if ((exportDeclaration.exportClause === undefined) !== (otherExportDeclaration.exportClause === undefined)) {
4508
- this.abort();
4509
- return exportDeclaration;
4510
- }
4511
- // Visit exportClause if present
4512
- if (exportDeclaration.exportClause && otherExportDeclaration.exportClause) {
4513
- yield this.visit(exportDeclaration.exportClause, otherExportDeclaration.exportClause);
4514
- if (!this.match)
4515
- return exportDeclaration;
4516
- }
4517
- // Compare moduleSpecifier
4518
- if ((exportDeclaration.moduleSpecifier === undefined) !== (otherExportDeclaration.moduleSpecifier === undefined)) {
4519
- this.abort();
4520
- return exportDeclaration;
4521
- }
4522
- // Visit moduleSpecifier if present
4523
- if (exportDeclaration.moduleSpecifier && otherExportDeclaration.moduleSpecifier) {
4524
- yield this.visit(exportDeclaration.moduleSpecifier.element, otherExportDeclaration.moduleSpecifier.element);
4525
- if (!this.match)
4526
- return exportDeclaration;
4527
- }
4528
- // Compare attributes
4529
- if ((exportDeclaration.attributes === undefined) !== (otherExportDeclaration.attributes === undefined)) {
4530
- this.abort();
4531
- return exportDeclaration;
4532
- }
4533
- // Visit attributes if present
4534
- if (exportDeclaration.attributes && otherExportDeclaration.attributes) {
4535
- yield this.visit(exportDeclaration.attributes, otherExportDeclaration.attributes);
4536
- if (!this.match)
4537
- return exportDeclaration;
4538
- }
4539
- return exportDeclaration;
1868
+ return this.visitElement(exportDeclaration, other);
4540
1869
  });
4541
1870
  }
4542
1871
  /**
@@ -4548,21 +1877,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
4548
1877
  */
4549
1878
  visitExportAssignment(exportAssignment, other) {
4550
1879
  return __awaiter(this, void 0, void 0, function* () {
4551
- if (!this.match || other.kind !== tree_1.JS.Kind.ExportAssignment) {
4552
- this.abort();
4553
- return exportAssignment;
4554
- }
4555
- const otherExportAssignment = other;
4556
- // Compare exportEquals
4557
- if (exportAssignment.exportEquals !== otherExportAssignment.exportEquals) {
4558
- this.abort();
4559
- return exportAssignment;
4560
- }
4561
- // Visit expression
4562
- yield this.visit(exportAssignment.expression.element, otherExportAssignment.expression.element);
4563
- if (!this.match)
4564
- return exportAssignment;
4565
- return exportAssignment;
1880
+ return this.visitElement(exportAssignment, other);
4566
1881
  });
4567
1882
  }
4568
1883
  /**
@@ -4574,23 +1889,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
4574
1889
  */
4575
1890
  visitNamedExports(namedExports, other) {
4576
1891
  return __awaiter(this, void 0, void 0, function* () {
4577
- if (!this.match || other.kind !== tree_1.JS.Kind.NamedExports) {
4578
- this.abort();
4579
- return namedExports;
4580
- }
4581
- const otherNamedExports = other;
4582
- // Compare elements
4583
- if (namedExports.elements.elements.length !== otherNamedExports.elements.elements.length) {
4584
- this.abort();
4585
- return namedExports;
4586
- }
4587
- // Visit each element in lock step
4588
- for (let i = 0; i < namedExports.elements.elements.length; i++) {
4589
- yield this.visit(namedExports.elements.elements[i].element, otherNamedExports.elements.elements[i].element);
4590
- if (!this.match)
4591
- return namedExports;
4592
- }
4593
- return namedExports;
1892
+ return this.visitElement(namedExports, other);
4594
1893
  });
4595
1894
  }
4596
1895
  /**
@@ -4602,21 +1901,7 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
4602
1901
  */
4603
1902
  visitExportSpecifier(exportSpecifier, other) {
4604
1903
  return __awaiter(this, void 0, void 0, function* () {
4605
- if (!this.match || other.kind !== tree_1.JS.Kind.ExportSpecifier) {
4606
- this.abort();
4607
- return exportSpecifier;
4608
- }
4609
- const otherExportSpecifier = other;
4610
- // Compare typeOnly
4611
- if (exportSpecifier.typeOnly.element !== otherExportSpecifier.typeOnly.element) {
4612
- this.abort();
4613
- return exportSpecifier;
4614
- }
4615
- // Visit specifier
4616
- yield this.visit(exportSpecifier.specifier, otherExportSpecifier.specifier);
4617
- if (!this.match)
4618
- return exportSpecifier;
4619
- return exportSpecifier;
1904
+ return this.visitElement(exportSpecifier, other);
4620
1905
  });
4621
1906
  }
4622
1907
  /**
@@ -4628,79 +1913,382 @@ class JavaScriptComparatorVisitor extends visitor_1.JavaScriptVisitor {
4628
1913
  */
4629
1914
  visitComputedPropertyMethodDeclaration(computedPropMethod, other) {
4630
1915
  return __awaiter(this, void 0, void 0, function* () {
4631
- if (!this.match || other.kind !== tree_1.JS.Kind.ComputedPropertyMethodDeclaration) {
4632
- this.abort();
4633
- return computedPropMethod;
1916
+ return this.visitElement(computedPropMethod, other);
1917
+ });
1918
+ }
1919
+ }
1920
+ exports.JavaScriptComparatorVisitor = JavaScriptComparatorVisitor;
1921
+ /**
1922
+ * A comparator visitor that checks semantic equality including type attribution.
1923
+ * This ensures comparisons account for type information, allowing semantically
1924
+ * equivalent code to match even when structurally different (e.g., `foo()` vs `module.foo()`
1925
+ * when both refer to the same method).
1926
+ */
1927
+ class JavaScriptSemanticComparatorVisitor extends JavaScriptComparatorVisitor {
1928
+ /**
1929
+ * Creates a new semantic comparator visitor.
1930
+ *
1931
+ * @param lenientTypeMatching If true, allows matching between nodes with and without type annotations
1932
+ */
1933
+ constructor(lenientTypeMatching = false) {
1934
+ super();
1935
+ this.lenientTypeMatching = lenientTypeMatching;
1936
+ }
1937
+ /**
1938
+ * Override visitProperty to allow lenient type matching.
1939
+ * When lenientTypeMatching is enabled, null vs Type comparisons are allowed
1940
+ * (where one value is null/undefined and the other is a Type object).
1941
+ */
1942
+ visitProperty(j, other) {
1943
+ const _super = Object.create(null, {
1944
+ visitProperty: { get: () => super.visitProperty }
1945
+ });
1946
+ return __awaiter(this, void 0, void 0, function* () {
1947
+ // Handle null/undefined with lenient type matching
1948
+ if (this.lenientTypeMatching && (j == null || other == null)) {
1949
+ if (j !== other) {
1950
+ // Don't abort if one is null and the other is a Type
1951
+ const jKind = j === null || j === void 0 ? void 0 : j.kind;
1952
+ const otherKind = other === null || other === void 0 ? void 0 : other.kind;
1953
+ const isTypeComparison = (jKind && typeof jKind === 'string' && jKind.startsWith('org.openrewrite.java.tree.JavaType$')) ||
1954
+ (otherKind && typeof otherKind === 'string' && otherKind.startsWith('org.openrewrite.java.tree.JavaType$'));
1955
+ if (!isTypeComparison) {
1956
+ this.abort(j);
1957
+ }
1958
+ }
1959
+ return j;
1960
+ }
1961
+ // Otherwise, use base class behavior
1962
+ return _super.visitProperty.call(this, j, other);
1963
+ });
1964
+ }
1965
+ /**
1966
+ * Checks if two types are semantically equal.
1967
+ * For method types, this checks that the declaring type and method name match.
1968
+ * With lenient type matching, undefined types on either side are considered compatible.
1969
+ */
1970
+ isOfType(target, source) {
1971
+ if (!target || !source) {
1972
+ // Lenient mode: if either type is undefined, allow the match
1973
+ return this.lenientTypeMatching ? true : target === source;
1974
+ }
1975
+ if (target.kind !== source.kind) {
1976
+ return false;
1977
+ }
1978
+ // For method types, check declaring type
1979
+ // Note: We don't check the name field because it might not be fully resolved in patterns
1980
+ // The method invocation visitor already checks that simple names match
1981
+ if (target.kind === java_1.Type.Kind.Method && source.kind === java_1.Type.Kind.Method) {
1982
+ const targetMethod = target;
1983
+ const sourceMethod = source;
1984
+ // Check if declaring types match
1985
+ const declaringTypesMatch = this.isOfType(targetMethod.declaringType, sourceMethod.declaringType);
1986
+ if (declaringTypesMatch) {
1987
+ return true;
1988
+ }
1989
+ // If declaring types don't match exactly, check if they might be semantically equivalent
1990
+ // (e.g., 'react' module vs 'React' namespace importing from 'react')
1991
+ // In this case, we check if the method signatures are otherwise identical
1992
+ if (targetMethod.declaringType && sourceMethod.declaringType &&
1993
+ java_1.Type.isFullyQualified(targetMethod.declaringType) && java_1.Type.isFullyQualified(sourceMethod.declaringType)) {
1994
+ const targetDeclType = targetMethod.declaringType;
1995
+ const sourceDeclType = sourceMethod.declaringType;
1996
+ // Check if the declaring type names could represent the same module
1997
+ // (e.g., 'react' and 'React', where React is a namespace alias)
1998
+ const targetFQN = java_1.Type.FullyQualified.getFullyQualifiedName(targetDeclType);
1999
+ const sourceFQN = java_1.Type.FullyQualified.getFullyQualifiedName(sourceDeclType);
2000
+ // If the names differ only in case and one appears to be a module name
2001
+ // (all lowercase) while the other is capitalized (namespace alias),
2002
+ // check if the method signatures match
2003
+ if (targetFQN.toLowerCase() === sourceFQN.toLowerCase()) {
2004
+ // Method signatures should match: return type and parameters
2005
+ if (!this.isOfType(targetMethod.returnType, sourceMethod.returnType)) {
2006
+ return false;
2007
+ }
2008
+ if (targetMethod.parameterTypes.length !== sourceMethod.parameterTypes.length) {
2009
+ return false;
2010
+ }
2011
+ for (let i = 0; i < targetMethod.parameterTypes.length; i++) {
2012
+ if (!this.isOfType(targetMethod.parameterTypes[i], sourceMethod.parameterTypes[i])) {
2013
+ return false;
2014
+ }
2015
+ }
2016
+ return true;
2017
+ }
2018
+ }
2019
+ return false;
2020
+ }
2021
+ // For fully qualified types, check the fully qualified name
2022
+ if (java_1.Type.isFullyQualified(target) && java_1.Type.isFullyQualified(source)) {
2023
+ return java_1.Type.FullyQualified.getFullyQualifiedName(target) ===
2024
+ java_1.Type.FullyQualified.getFullyQualifiedName(source);
2025
+ }
2026
+ // Default: types are equal if they're the same kind
2027
+ return true;
2028
+ }
2029
+ /**
2030
+ * Override method invocation comparison to include type attribution checking.
2031
+ * When types match semantically, we allow matching even if one has a receiver
2032
+ * and the other doesn't (e.g., `isDate(x)` vs `util.isDate(x)`).
2033
+ */
2034
+ visitMethodInvocation(method, other) {
2035
+ const _super = Object.create(null, {
2036
+ visitMethodInvocation: { get: () => super.visitMethodInvocation }
2037
+ });
2038
+ return __awaiter(this, void 0, void 0, function* () {
2039
+ if (other.kind !== java_1.J.Kind.MethodInvocation) {
2040
+ return this.abort(method);
2041
+ }
2042
+ const otherMethod = other;
2043
+ // Check basic structural equality first
2044
+ if (method.name.simpleName !== otherMethod.name.simpleName ||
2045
+ method.arguments.elements.length !== otherMethod.arguments.elements.length) {
2046
+ return this.abort(method);
2047
+ }
2048
+ // Check type attribution
2049
+ // Both must have method types for semantic equality
2050
+ if (!method.methodType || !otherMethod.methodType) {
2051
+ // Lenient mode: if either has no type, allow structural matching
2052
+ if (this.lenientTypeMatching) {
2053
+ return _super.visitMethodInvocation.call(this, method, other);
2054
+ }
2055
+ // Strict mode: if one has type but the other doesn't, they don't match
2056
+ if (method.methodType || otherMethod.methodType) {
2057
+ return this.abort(method);
2058
+ }
2059
+ // If neither has type, fall through to structural comparison
2060
+ return _super.visitMethodInvocation.call(this, method, other);
2061
+ }
2062
+ // Both have types - check they match semantically
2063
+ const typesMatch = this.isOfType(method.methodType, otherMethod.methodType);
2064
+ if (!typesMatch) {
2065
+ // Types don't match - abort comparison
2066
+ return this.abort(method);
2067
+ }
2068
+ // Types match! Now check if we can ignore receiver differences.
2069
+ // We can only ignore receiver differences when one or both receivers are identifiers
2070
+ // that represent module/namespace imports (e.g., `util` in `util.isDate()`).
2071
+ // For other receivers (e.g., variables, expressions), we must compare them.
2072
+ const canIgnoreReceiverDifference =
2073
+ // Case 1: One has no select (direct call like `forwardRef()`), other has select (namespace like `React.forwardRef()`)
2074
+ (!method.select && otherMethod.select) ||
2075
+ (method.select && !otherMethod.select);
2076
+ if (!canIgnoreReceiverDifference) {
2077
+ // Both have selects or both don't - must compare them structurally
2078
+ if ((method.select === undefined) !== (otherMethod.select === undefined)) {
2079
+ return this.abort(method);
2080
+ }
2081
+ if (method.select && otherMethod.select) {
2082
+ yield this.visit(method.select.element, otherMethod.select.element);
2083
+ }
2084
+ }
2085
+ // Compare type parameters
2086
+ if ((method.typeParameters === undefined) !== (otherMethod.typeParameters === undefined)) {
2087
+ return this.abort(method);
2088
+ }
2089
+ if (method.typeParameters && otherMethod.typeParameters) {
2090
+ if (method.typeParameters.elements.length !== otherMethod.typeParameters.elements.length) {
2091
+ return this.abort(method);
2092
+ }
2093
+ for (let i = 0; i < method.typeParameters.elements.length; i++) {
2094
+ yield this.visit(method.typeParameters.elements[i].element, otherMethod.typeParameters.elements[i].element);
2095
+ if (!this.match) {
2096
+ return this.abort(method);
2097
+ }
2098
+ }
2099
+ }
2100
+ // Compare name (already checked simpleName above, but visit for markers/prefix)
2101
+ yield this.visit(method.name, otherMethod.name);
2102
+ if (!this.match) {
2103
+ return this.abort(method);
2104
+ }
2105
+ // Compare arguments
2106
+ for (let i = 0; i < method.arguments.elements.length; i++) {
2107
+ yield this.visit(method.arguments.elements[i].element, otherMethod.arguments.elements[i].element);
2108
+ if (!this.match) {
2109
+ return this.abort(method);
2110
+ }
2111
+ }
2112
+ return method;
2113
+ });
2114
+ }
2115
+ /**
2116
+ * Override identifier comparison to include type checking for field access.
2117
+ */
2118
+ visitIdentifier(identifier, other) {
2119
+ const _super = Object.create(null, {
2120
+ visitIdentifier: { get: () => super.visitIdentifier }
2121
+ });
2122
+ return __awaiter(this, void 0, void 0, function* () {
2123
+ if (other.kind !== java_1.J.Kind.Identifier) {
2124
+ return this.abort(identifier);
4634
2125
  }
4635
- const otherComputedPropMethod = other;
4636
- // Compare leading annotations
4637
- if (computedPropMethod.leadingAnnotations.length !== otherComputedPropMethod.leadingAnnotations.length) {
4638
- this.abort();
4639
- return computedPropMethod;
2126
+ const otherIdentifier = other;
2127
+ // Check name matches
2128
+ if (identifier.simpleName !== otherIdentifier.simpleName) {
2129
+ return this.abort(identifier);
2130
+ }
2131
+ // For identifiers with field types, check type attribution
2132
+ if (identifier.fieldType && otherIdentifier.fieldType) {
2133
+ if (!this.isOfType(identifier.fieldType, otherIdentifier.fieldType)) {
2134
+ return this.abort(identifier);
2135
+ }
4640
2136
  }
4641
- // Visit leading annotations in lock step
4642
- for (let i = 0; i < computedPropMethod.leadingAnnotations.length; i++) {
4643
- yield this.visit(computedPropMethod.leadingAnnotations[i], otherComputedPropMethod.leadingAnnotations[i]);
2137
+ else if (identifier.fieldType || otherIdentifier.fieldType) {
2138
+ // Lenient mode: if either has no type, allow structural matching
2139
+ if (!this.lenientTypeMatching) {
2140
+ // Strict mode: if only one has a type, they don't match
2141
+ return this.abort(identifier);
2142
+ }
2143
+ }
2144
+ return _super.visitIdentifier.call(this, identifier, other);
2145
+ });
2146
+ }
2147
+ /**
2148
+ * Override variable declarations comparison to handle lenient type matching.
2149
+ * When lenientTypeMatching is true, patterns without typeExpression can match
2150
+ * code with typeExpression.
2151
+ */
2152
+ visitVariableDeclarations(variableDeclarations, other) {
2153
+ return __awaiter(this, void 0, void 0, function* () {
2154
+ const otherVariableDeclarations = other;
2155
+ // Visit leading annotations
2156
+ if (variableDeclarations.leadingAnnotations.length !== otherVariableDeclarations.leadingAnnotations.length) {
2157
+ return this.abort(variableDeclarations);
2158
+ }
2159
+ for (let i = 0; i < variableDeclarations.leadingAnnotations.length; i++) {
2160
+ yield this.visit(variableDeclarations.leadingAnnotations[i], otherVariableDeclarations.leadingAnnotations[i]);
4644
2161
  if (!this.match)
4645
- return computedPropMethod;
2162
+ return variableDeclarations;
4646
2163
  }
4647
- // Compare modifiers
4648
- if (computedPropMethod.modifiers.length !== otherComputedPropMethod.modifiers.length) {
4649
- this.abort();
4650
- return computedPropMethod;
2164
+ // Visit modifiers
2165
+ if (variableDeclarations.modifiers.length !== otherVariableDeclarations.modifiers.length) {
2166
+ return this.abort(variableDeclarations);
4651
2167
  }
4652
- // Visit modifiers in lock step
4653
- for (let i = 0; i < computedPropMethod.modifiers.length; i++) {
4654
- yield this.visit(computedPropMethod.modifiers[i], otherComputedPropMethod.modifiers[i]);
2168
+ for (let i = 0; i < variableDeclarations.modifiers.length; i++) {
2169
+ yield this.visit(variableDeclarations.modifiers[i], otherVariableDeclarations.modifiers[i]);
4655
2170
  if (!this.match)
4656
- return computedPropMethod;
2171
+ return variableDeclarations;
4657
2172
  }
4658
- // Compare type parameters
4659
- if (!!computedPropMethod.typeParameters !== !!otherComputedPropMethod.typeParameters) {
4660
- this.abort();
4661
- return computedPropMethod;
2173
+ // Compare typeExpression - lenient matching allows one to be undefined
2174
+ if ((variableDeclarations.typeExpression === undefined) !== (otherVariableDeclarations.typeExpression === undefined)) {
2175
+ if (!this.lenientTypeMatching) {
2176
+ return this.abort(variableDeclarations);
2177
+ }
2178
+ // In lenient mode, skip type comparison and continue
4662
2179
  }
4663
- if (computedPropMethod.typeParameters) {
4664
- yield this.visit(computedPropMethod.typeParameters, otherComputedPropMethod.typeParameters);
2180
+ else if (variableDeclarations.typeExpression && otherVariableDeclarations.typeExpression) {
2181
+ // Both have typeExpression, visit them
2182
+ yield this.visit(variableDeclarations.typeExpression, otherVariableDeclarations.typeExpression);
4665
2183
  if (!this.match)
4666
- return computedPropMethod;
2184
+ return variableDeclarations;
4667
2185
  }
4668
- // Compare return type expression
4669
- if (!!computedPropMethod.returnTypeExpression !== !!otherComputedPropMethod.returnTypeExpression) {
4670
- this.abort();
4671
- return computedPropMethod;
2186
+ // Compare varargs
2187
+ if ((variableDeclarations.varargs === undefined) !== (otherVariableDeclarations.varargs === undefined)) {
2188
+ return this.abort(variableDeclarations);
2189
+ }
2190
+ // Compare variables
2191
+ if (variableDeclarations.variables.length !== otherVariableDeclarations.variables.length) {
2192
+ return this.abort(variableDeclarations);
4672
2193
  }
4673
- if (computedPropMethod.returnTypeExpression) {
4674
- yield this.visit(computedPropMethod.returnTypeExpression, otherComputedPropMethod.returnTypeExpression);
2194
+ // Visit each variable in lock step
2195
+ for (let i = 0; i < variableDeclarations.variables.length; i++) {
2196
+ yield this.visit(variableDeclarations.variables[i].element, otherVariableDeclarations.variables[i].element);
4675
2197
  if (!this.match)
4676
- return computedPropMethod;
2198
+ return variableDeclarations;
2199
+ }
2200
+ return variableDeclarations;
2201
+ });
2202
+ }
2203
+ /**
2204
+ * Override method declaration comparison to handle lenient type matching.
2205
+ * When lenientTypeMatching is true, patterns without returnTypeExpression can match
2206
+ * code with returnTypeExpression.
2207
+ */
2208
+ visitMethodDeclaration(methodDeclaration, other) {
2209
+ return __awaiter(this, void 0, void 0, function* () {
2210
+ const otherMethodDeclaration = other;
2211
+ // Visit leading annotations
2212
+ if (methodDeclaration.leadingAnnotations.length !== otherMethodDeclaration.leadingAnnotations.length) {
2213
+ return this.abort(methodDeclaration);
2214
+ }
2215
+ for (let i = 0; i < methodDeclaration.leadingAnnotations.length; i++) {
2216
+ yield this.visit(methodDeclaration.leadingAnnotations[i], otherMethodDeclaration.leadingAnnotations[i]);
2217
+ if (!this.match)
2218
+ return methodDeclaration;
2219
+ }
2220
+ // Visit modifiers
2221
+ if (methodDeclaration.modifiers.length !== otherMethodDeclaration.modifiers.length) {
2222
+ return this.abort(methodDeclaration);
2223
+ }
2224
+ for (let i = 0; i < methodDeclaration.modifiers.length; i++) {
2225
+ yield this.visit(methodDeclaration.modifiers[i], otherMethodDeclaration.modifiers[i]);
2226
+ if (!this.match)
2227
+ return methodDeclaration;
2228
+ }
2229
+ // Visit type parameters if present
2230
+ if (!!methodDeclaration.typeParameters !== !!otherMethodDeclaration.typeParameters) {
2231
+ return this.abort(methodDeclaration);
2232
+ }
2233
+ if (methodDeclaration.typeParameters && otherMethodDeclaration.typeParameters) {
2234
+ yield this.visit(methodDeclaration.typeParameters, otherMethodDeclaration.typeParameters);
2235
+ if (!this.match)
2236
+ return methodDeclaration;
2237
+ }
2238
+ // Compare returnTypeExpression - lenient matching allows one to be undefined
2239
+ if ((methodDeclaration.returnTypeExpression === undefined) !== (otherMethodDeclaration.returnTypeExpression === undefined)) {
2240
+ if (!this.lenientTypeMatching) {
2241
+ return this.abort(methodDeclaration);
2242
+ }
2243
+ // In lenient mode, skip type comparison and continue
2244
+ }
2245
+ else if (methodDeclaration.returnTypeExpression && otherMethodDeclaration.returnTypeExpression) {
2246
+ // Both have returnTypeExpression, visit them
2247
+ yield this.visit(methodDeclaration.returnTypeExpression, otherMethodDeclaration.returnTypeExpression);
2248
+ if (!this.match)
2249
+ return methodDeclaration;
4677
2250
  }
4678
2251
  // Visit name
4679
- yield this.visit(computedPropMethod.name, otherComputedPropMethod.name);
2252
+ yield this.visit(methodDeclaration.name, otherMethodDeclaration.name);
4680
2253
  if (!this.match)
4681
- return computedPropMethod;
2254
+ return methodDeclaration;
4682
2255
  // Compare parameters
4683
- if (computedPropMethod.parameters.elements.length !== otherComputedPropMethod.parameters.elements.length) {
4684
- this.abort();
4685
- return computedPropMethod;
2256
+ if (methodDeclaration.parameters.elements.length !== otherMethodDeclaration.parameters.elements.length) {
2257
+ return this.abort(methodDeclaration);
4686
2258
  }
4687
- // Visit parameters in lock step
4688
- for (let i = 0; i < computedPropMethod.parameters.elements.length; i++) {
4689
- yield this.visit(computedPropMethod.parameters.elements[i].element, otherComputedPropMethod.parameters.elements[i].element);
2259
+ // Visit each parameter in lock step
2260
+ for (let i = 0; i < methodDeclaration.parameters.elements.length; i++) {
2261
+ yield this.visit(methodDeclaration.parameters.elements[i].element, otherMethodDeclaration.parameters.elements[i].element);
4690
2262
  if (!this.match)
4691
- return computedPropMethod;
2263
+ return methodDeclaration;
4692
2264
  }
4693
- // Compare body
4694
- if (!!computedPropMethod.body !== !!otherComputedPropMethod.body) {
4695
- this.abort();
4696
- return computedPropMethod;
2265
+ // Visit throws if present
2266
+ if (!!methodDeclaration.throws !== !!otherMethodDeclaration.throws) {
2267
+ return this.abort(methodDeclaration);
4697
2268
  }
4698
- if (computedPropMethod.body) {
4699
- yield this.visit(computedPropMethod.body, otherComputedPropMethod.body);
2269
+ if (methodDeclaration.throws && otherMethodDeclaration.throws) {
2270
+ // Visit each throws expression in lock step
2271
+ if (methodDeclaration.throws.elements.length !== otherMethodDeclaration.throws.elements.length) {
2272
+ return this.abort(methodDeclaration);
2273
+ }
2274
+ for (let i = 0; i < methodDeclaration.throws.elements.length; i++) {
2275
+ yield this.visit(methodDeclaration.throws.elements[i].element, otherMethodDeclaration.throws.elements[i].element);
2276
+ if (!this.match)
2277
+ return methodDeclaration;
2278
+ }
2279
+ }
2280
+ // Visit body if present
2281
+ if (!!methodDeclaration.body !== !!otherMethodDeclaration.body) {
2282
+ return this.abort(methodDeclaration);
4700
2283
  }
4701
- return computedPropMethod;
2284
+ if (methodDeclaration.body && otherMethodDeclaration.body) {
2285
+ yield this.visit(methodDeclaration.body, otherMethodDeclaration.body);
2286
+ if (!this.match)
2287
+ return methodDeclaration;
2288
+ }
2289
+ return methodDeclaration;
4702
2290
  });
4703
2291
  }
4704
2292
  }
4705
- exports.JavaScriptComparatorVisitor = JavaScriptComparatorVisitor;
2293
+ exports.JavaScriptSemanticComparatorVisitor = JavaScriptSemanticComparatorVisitor;
4706
2294
  //# sourceMappingURL=comparator.js.map