EclipseJDT Source Viewer

Home|eclipse_jdt/src/org/eclipse/jdt/core/dom/ASTMatcher.java
1/*******************************************************************************
2 * Copyright (c) 2000, 2022 IBM Corporation and others.
3 *
4 * This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License 2.0
6 * which accompanies this distribution, and is available at
7 * https://www.eclipse.org/legal/epl-2.0/
8 *
9 * SPDX-License-Identifier: EPL-2.0
10 * Contributors:
11 *     IBM Corporation - initial API and implementation
12 *******************************************************************************/
13package org.eclipse.jdt.core.dom;
14
15import java.util.Iterator;
16import java.util.List;
17
18import org.eclipse.jdt.internal.core.dom.util.DOMASTUtil;
19
20/**
21 * Concrete superclass and default implementation of an AST subtree matcher.
22 * <p>
23 * For example, to compute whether two ASTs subtrees are structurally
24 * isomorphic, use <code>n1.subtreeMatch(new ASTMatcher(), n2)</code> where
25 * <code>n1</code> and <code>n2</code> are the AST root nodes of the subtrees.
26 * </p>
27 * <p>
28 * For each different concrete AST node type <i>T</i> there is a
29 * <code>public boolean match(<i>T</i> node, Object other)</code> method
30 * that matches the given node against another object (typically another
31 * AST node, although this is not essential). The default implementations
32 * provided by this class tests whether the other object is a node of the
33 * same type with structurally isomorphic child subtrees. For nodes with
34 * list-valued properties, the child nodes within the list are compared in
35 * order. For nodes with multiple properties, the child nodes are compared
36 * in the order that most closely corresponds to the lexical reading order
37 * of the source program. For instance, for a type declaration node, the
38 * child ordering is: name, superclass, superinterfaces, and body
39 * declarations.
40 * </p>
41 * <p>
42 * Subclasses may override (extend or reimplement) some or all of the
43 * <code>match</code> methods in order to define more specialized subtree
44 * matchers.
45 * </p>
46 *
47 * @see org.eclipse.jdt.core.dom.ASTNode#subtreeMatch(ASTMatcher, Object)
48 * @since 2.0
49 */
50@SuppressWarnings("rawtypes")
51public class ASTMatcher {
52
53    /**
54     * Indicates whether doc tags should be matched.
55     * @since 3.0
56     */
57    private boolean matchDocTags;
58
59    /**
60     * Creates a new AST matcher instance.
61     * <p>
62     * For backwards compatibility, the matcher ignores tag
63     * elements below doc comments by default. Use
64     * {@link #ASTMatcher(boolean) ASTMatcher(true)}
65     * for a matcher that compares doc tags by default.
66     * </p>
67     */
68    public ASTMatcher() {
69        this(false);
70    }
71
72    /**
73     * Creates a new AST matcher instance.
74     *
75     * @param matchDocTags <code>true</code> if doc comment tags are
76     * to be compared by default, and <code>false</code> otherwise
77     * @see #match(Javadoc,Object)
78     * @since 3.0
79     */
80    public ASTMatcher(boolean matchDocTags) {
81        this.matchDocTags = matchDocTags;
82    }
83
84    /**
85     * Returns whether the given lists of AST nodes match pair wise according
86     * to <code>ASTNode.subtreeMatch</code>.
87     * <p>
88     * Note that this is a convenience method, useful for writing recursive
89     * subtree matchers.
90     * </p>
91     *
92     * @param list1 the first list of AST nodes
93     *    (element type: {@link ASTNode})
94     * @param list2 the second list of AST nodes
95     *    (element type: {@link ASTNode})
96     * @return <code>true</code> if the lists have the same number of elements
97     *    and match pair-wise according to {@link ASTNode#subtreeMatch(ASTMatcher, Object) ASTNode.subtreeMatch}
98     * @see ASTNode#subtreeMatch(ASTMatcher matcher, Object other)
99     */
100    public final boolean safeSubtreeListMatch(List list1List list2) {
101        int size1 = list1.size();
102        int size2 = list2.size();
103        if (size1 != size2) {
104            return false;
105        }
106        for (Iterator it1 = list1.iterator(), it2 = list2.iterator(); it1.hasNext();) {
107            ASTNode n1 = (ASTNodeit1.next();
108            ASTNode n2 = (ASTNodeit2.next();
109            if (!n1.subtreeMatch(this, n2)) {
110                return false;
111            }
112        }
113        return true;
114    }
115
116    /**
117     * Returns whether the given nodes match according to
118     * <code>AST.subtreeMatch</code>. Returns <code>false</code> if one or
119     * the other of the nodes are <code>null</code>. Returns <code>true</code>
120     * if both nodes are <code>null</code>.
121     * <p>
122     * Note that this is a convenience method, useful for writing recursive
123     * subtree matchers.
124     * </p>
125     *
126     * @param node1 the first AST node, or <code>null</code>; must be an
127     *    instance of <code>ASTNode</code>
128     * @param node2 the second AST node, or <code>null</code>; must be an
129     *    instance of <code>ASTNode</code>
130     * @return <code>true</code> if the nodes match according
131     *    to <code>AST.subtreeMatch</code> or both are <code>null</code>, and
132     *    <code>false</code> otherwise
133     * @see ASTNode#subtreeMatch(ASTMatcher, Object)
134     */
135    public final boolean safeSubtreeMatch(Object node1Object node2) {
136        if (node1 == null && node2 == null) {
137            return true;
138        }
139        if (node1 == null || node2 == null) {
140            return false;
141        }
142        // N.B. call subtreeMatch even node1==node2!=null
143        return ((ASTNodenode1).subtreeMatch(this, node2);
144    }
145
146    /**
147     * Returns whether the given objects are equal according to
148     * <code>equals</code>. Returns <code>false</code> if either
149     * node is <code>null</code>.
150     *
151     * @param o1 the first object, or <code>null</code>
152     * @param o2 the second object, or <code>null</code>
153     * @return <code>true</code> if the nodes are equal according to
154     *    <code>equals</code> or both <code>null</code>, and
155     *    <code>false</code> otherwise
156     */
157    public static boolean safeEquals(Object o1Object o2) {
158        if (o1 == o2) {
159            return true;
160        }
161        if (o1 == null || o2 == null) {
162            return false;
163        }
164        return o1.equals(o2);
165    }
166
167    /**
168     * @deprecated
169     */
170    private Type componentType(ArrayType array) {
171        return array.getComponentType();
172    }
173
174    /**
175     * Returns whether the given node and the other object match.
176     * <p>
177     * The default implementation provided by this class tests whether the
178     * other object is a node of the same type with structurally isomorphic
179     * child subtrees. Subclasses may override this method as needed.
180     * </p>
181     *
182     * @param node the node
183     * @param other the other object, or <code>null</code>
184     * @return <code>true</code> if the subtree matches, or
185     *   <code>false</code> if they do not match or the other object has a
186     *   different node type or is <code>null</code>
187     * @since 3.1
188     */
189    public boolean match(AnnotationTypeDeclaration nodeObject other) {
190        if (!(other instanceof AnnotationTypeDeclaration)) {
191            return false;
192        }
193        AnnotationTypeDeclaration o = (AnnotationTypeDeclarationother;
194        // node type added in JLS3 - ignore old JLS2-style modifiers
195        return (safeSubtreeMatch(node.getJavadoc(), o.getJavadoc())
196                && safeSubtreeListMatch(node.modifiers(), o.modifiers())
197                && safeSubtreeMatch(node.getName(), o.getName())
198                && safeSubtreeListMatch(node.bodyDeclarations(), o.bodyDeclarations()));
199    }
200
201    /**
202     * Returns whether the given node and the other object match.
203     * <p>
204     * The default implementation provided by this class tests whether the
205     * other object is a node of the same type with structurally isomorphic
206     * child subtrees. Subclasses may override this method as needed.
207     * </p>
208     *
209     * @param node the node
210     * @param other the other object, or <code>null</code>
211     * @return <code>true</code> if the subtree matches, or
212     *   <code>false</code> if they do not match or the other object has a
213     *   different node type or is <code>null</code>
214     * @since 3.1
215     */
216    public boolean match(AnnotationTypeMemberDeclaration nodeObject other) {
217        if (!(other instanceof AnnotationTypeMemberDeclaration)) {
218            return false;
219        }
220        AnnotationTypeMemberDeclaration o = (AnnotationTypeMemberDeclarationother;
221        // node type added in JLS3 - ignore old JLS2-style modifiers
222        return (safeSubtreeMatch(node.getJavadoc(), o.getJavadoc())
223                && safeSubtreeListMatch(node.modifiers(), o.modifiers())
224                && safeSubtreeMatch(node.getType(), o.getType())
225                && safeSubtreeMatch(node.getName(), o.getName())
226                && safeSubtreeMatch(node.getDefault(), o.getDefault()));
227    }
228
229    /**
230     * Returns whether the given node and the other object match.
231     * <p>
232     * The default implementation provided by this class tests whether the
233     * other object is a node of the same type with structurally isomorphic
234     * child subtrees. Subclasses may override this method as needed.
235     * </p>
236     *
237     * @param node the node
238     * @param other the other object, or <code>null</code>
239     * @return <code>true</code> if the subtree matches, or
240     *   <code>false</code> if they do not match or the other object has a
241     *   different node type or is <code>null</code>
242     */
243    public boolean match(AnonymousClassDeclaration nodeObject other) {
244        if (!(other instanceof AnonymousClassDeclaration)) {
245            return false;
246        }
247        AnonymousClassDeclaration o = (AnonymousClassDeclarationother;
248        return safeSubtreeListMatch(node.bodyDeclarations(), o.bodyDeclarations());
249    }
250
251    /**
252     * Returns whether the given node and the other object match.
253     * <p>
254     * The default implementation provided by this class tests whether the
255     * other object is a node of the same type with structurally isomorphic
256     * child subtrees. Subclasses may override this method as needed.
257     * </p>
258     *
259     * @param node the node
260     * @param other the other object, or <code>null</code>
261     * @return <code>true</code> if the subtree matches, or
262     *   <code>false</code> if they do not match or the other object has a
263     *   different node type or is <code>null</code>
264     */
265    public boolean match(ArrayAccess nodeObject other) {
266        if (!(other instanceof ArrayAccess)) {
267            return false;
268        }
269        ArrayAccess o = (ArrayAccessother;
270        return (
271            safeSubtreeMatch(node.getArray(), o.getArray())
272                && safeSubtreeMatch(node.getIndex(), o.getIndex()));
273    }
274
275    /**
276     * Returns whether the given node and the other object object match.
277     * <p>
278     * The default implementation provided by this class tests whether the
279     * other object is a node of the same type with structurally isomorphic
280     * child subtrees. Subclasses may override this method as needed.
281     * </p>
282     *
283     * @param node the node
284     * @param other the other object, or <code>null</code>
285     * @return <code>true</code> if the subtree matches, or
286     *   <code>false</code> if they do not match or the other object has a
287     *   different node type or is <code>null</code>
288     */
289    public boolean match(ArrayCreation nodeObject other) {
290        if (!(other instanceof ArrayCreation)) {
291            return false;
292        }
293        ArrayCreation o = (ArrayCreationother;
294        return (
295            safeSubtreeMatch(node.getType(), o.getType())
296                && safeSubtreeListMatch(node.dimensions(), o.dimensions())
297                && safeSubtreeMatch(node.getInitializer(), o.getInitializer()));
298    }
299
300    /**
301     * Returns whether the given node and the other object match.
302     * <p>
303     * The default implementation provided by this class tests whether the
304     * other object is a node of the same type with structurally isomorphic
305     * child subtrees. Subclasses may override this method as needed.
306     * </p>
307     *
308     * @param node the node
309     * @param other the other object, or <code>null</code>
310     * @return <code>true</code> if the subtree matches, or
311     *   <code>false</code> if they do not match or the other object has a
312     *   different node type or is <code>null</code>
313     */
314    public boolean match(ArrayInitializer nodeObject other) {
315        if (!(other instanceof ArrayInitializer)) {
316            return false;
317        }
318        ArrayInitializer o = (ArrayInitializerother;
319        return safeSubtreeListMatch(node.expressions(), o.expressions());
320    }
321
322    /**
323     * Returns whether the given node and the other object match.
324     * <p>
325     * The default implementation provided by this class tests whether the
326     * other object is a node of the same type with structurally isomorphic
327     * child subtrees. Subclasses may override this method as needed.
328     * </p>
329     *
330     * @param node the node
331     * @param other the other object, or <code>null</code>
332     * @return <code>true</code> if the subtree matches, or
333     *   <code>false</code> if they do not match or the other object has a
334     *   different node type or is <code>null</code>
335     */
336    public boolean match(ArrayType nodeObject other) {
337        if (!(other instanceof ArrayType)) {
338            return false;
339        }
340        ArrayType o = (ArrayTypeother;
341        int level = node.getAST().apiLevel;
342        if (level < AST.JLS8_INTERNAL) {
343            return safeSubtreeMatch(componentType(node), componentType(o));
344        }
345        return safeSubtreeMatch(node.getElementType(), o.getElementType())
346                && safeSubtreeListMatch(node.dimensions(), o.dimensions());
347    }
348
349    /**
350     * Returns whether the given node and the other object match.
351     * <p>
352     * The default implementation provided by this class tests whether the
353     * other object is a node of the same type with structurally isomorphic
354     * child subtrees. Subclasses may override this method as needed.
355     * </p>
356     *
357     * @param node the node
358     * @param other the other object, or <code>null</code>
359     * @return <code>true</code> if the subtree matches, or
360     *   <code>false</code> if they do not match or the other object has a
361     *   different node type or is <code>null</code>
362     */
363    public boolean match(AssertStatement nodeObject other) {
364        if (!(other instanceof AssertStatement)) {
365            return false;
366        }
367        AssertStatement o = (AssertStatementother;
368        return (
369            safeSubtreeMatch(node.getExpression(), o.getExpression())
370                && safeSubtreeMatch(node.getMessage(), o.getMessage()));
371    }
372
373    /**
374     * Returns whether the given node and the other object match.
375     * <p>
376     * The default implementation provided by this class tests whether the
377     * other object is a node of the same type with structurally isomorphic
378     * child subtrees. Subclasses may override this method as needed.
379     * </p>
380     *
381     * @param node the node
382     * @param other the other object, or <code>null</code>
383     * @return <code>true</code> if the subtree matches, or
384     *   <code>false</code> if they do not match or the other object has a
385     *   different node type or is <code>null</code>
386     */
387    public boolean match(Assignment nodeObject other) {
388        if (!(other instanceof Assignment)) {
389            return false;
390        }
391        Assignment o = (Assignmentother;
392        return (
393            node.getOperator().equals(o.getOperator())
394                && safeSubtreeMatch(node.getLeftHandSide(), o.getLeftHandSide())
395                && safeSubtreeMatch(node.getRightHandSide(), o.getRightHandSide()));
396    }
397
398    /**
399     * Returns whether the given node and the other object match.
400     * <p>
401     * The default implementation provided by this class tests whether the
402     * other object is a node of the same type with structurally isomorphic
403     * child subtrees. Subclasses may override this method as needed.
404     * </p>
405     *
406     * @param node the node
407     * @param other the other object, or <code>null</code>
408     * @return <code>true</code> if the subtree matches, or
409     *   <code>false</code> if they do not match or the other object has a
410     *   different node type or is <code>null</code>
411     */
412    public boolean match(Block nodeObject other) {
413        if (!(other instanceof Block)) {
414            return false;
415        }
416        Block o = (Blockother;
417        return safeSubtreeListMatch(node.statements(), o.statements());
418    }
419
420    /**
421     * Returns whether the given node and the other object match.
422     * <p>
423     * The default implementation provided by this class tests whether the
424     * other object is a node of the same type. Subclasses may override
425     * this method as needed.
426     * </p>
427     * <p>Note: {@link LineComment} and {@link BlockComment} nodes are
428     * not considered part of main structure of the AST. This method will
429     * only be called if a client goes out of their way to visit this
430     * kind of node explicitly.
431     * </p>
432     *
433     * @param node the node
434     * @param other the other object, or <code>null</code>
435     * @return <code>true</code> if the subtree matches, or
436     *   <code>false</code> if they do not match or the other object has a
437     *   different node type or is <code>null</code>
438     * @since 3.0
439     */
440    public boolean match(BlockComment nodeObject other) {
441        if (!(other instanceof BlockComment)) {
442            return false;
443        }
444        return true;
445    }
446
447    /**
448     * Returns whether the given node and the other object match.
449     * <p>
450     * The default implementation provided by this class tests whether the
451     * other object is a node of the same type with structurally isomorphic
452     * child subtrees. Subclasses may override this method as needed.
453     * </p>
454     *
455     * @param node the node
456     * @param other the other object, or <code>null</code>
457     * @return <code>true</code> if the subtree matches, or
458     *   <code>false</code> if they do not match or the other object has a
459     *   different node type or is <code>null</code>
460     */
461    public boolean match(BooleanLiteral nodeObject other) {
462        if (!(other instanceof BooleanLiteral)) {
463            return false;
464        }
465        BooleanLiteral o = (BooleanLiteralother;
466        return node.booleanValue() == o.booleanValue();
467    }
468
469    /**
470     * Returns whether the given node and the other object match.
471     * <p>
472     * The default implementation provided by this class tests whether the
473     * other object is a node of the same type with structurally isomorphic
474     * child subtrees. Subclasses may override this method as needed.
475     * </p>
476     *
477     * @param node the node
478     * @param other the other object, or <code>null</code>
479     * @return <code>true</code> if the subtree matches, or
480     *   <code>false</code> if they do not match or the other object has a
481     *   different node type or is <code>null</code>
482     */
483    public boolean match(BreakStatement nodeObject other) {
484        if (!(other instanceof BreakStatement)) {
485            return false;
486        }
487        BreakStatement o = (BreakStatementother;
488        return (safeSubtreeMatch(node.getLabel(), o.getLabel()));
489    }
490
491    /**
492     * Returns whether the given node and the other object match.
493     * <p>
494     * The default implementation provided by this class tests whether the
495     * other object is a node of the same type with structurally isomorphic
496     * child subtrees. Subclasses may override this method as needed.
497     * </p>
498     *
499     * @param node the node
500     * @param other the other object, or <code>null</code>
501     * @return <code>true</code> if the subtree matches, or
502     *   <code>false</code> if they do not match or the other object has a
503     *   different node type or is <code>null</code>
504     *  @since 3.28
505     */
506    public boolean match(CaseDefaultExpression nodeObject other) {
507        if (!(other instanceof CaseDefaultExpression)) {
508            return false;
509        }
510        return true;
511    }
512
513    /**
514     * Returns whether the given node and the other object match.
515     * <p>
516     * The default implementation provided by this class tests whether the
517     * other object is a node of the same type with structurally isomorphic
518     * child subtrees. Subclasses may override this method as needed.
519     * </p>
520     *
521     * @param node the node
522     * @param other the other object, or <code>null</code>
523     * @return <code>true</code> if the subtree matches, or
524     *   <code>false</code> if they do not match or the other object has a
525     *   different node type or is <code>null</code>
526     */
527    public boolean match(CastExpression nodeObject other) {
528        if (!(other instanceof CastExpression)) {
529            return false;
530        }
531        CastExpression o = (CastExpressionother;
532        return (
533            safeSubtreeMatch(node.getType(), o.getType())
534                && safeSubtreeMatch(node.getExpression(), o.getExpression()));
535    }
536
537    /**
538     * Returns whether the given node and the other object match.
539     * <p>
540     * The default implementation provided by this class tests whether the
541     * other object is a node of the same type with structurally isomorphic
542     * child subtrees. Subclasses may override this method as needed.
543     * </p>
544     *
545     * @param node the node
546     * @param other the other object, or <code>null</code>
547     * @return <code>true</code> if the subtree matches, or
548     *   <code>false</code> if they do not match or the other object has a
549     *   different node type or is <code>null</code>
550     */
551    public boolean match(CatchClause nodeObject other) {
552        if (!(other instanceof CatchClause)) {
553            return false;
554        }
555        CatchClause o = (CatchClauseother;
556        return (
557            safeSubtreeMatch(node.getException(), o.getException())
558                && safeSubtreeMatch(node.getBody(), o.getBody()));
559    }
560
561    /**
562     * Returns whether the given node and the other object match.
563     * <p>
564     * The default implementation provided by this class tests whether the
565     * other object is a node of the same type with structurally isomorphic
566     * child subtrees. Subclasses may override this method as needed.
567     * </p>
568     *
569     * @param node the node
570     * @param other the other object, or <code>null</code>
571     * @return <code>true</code> if the subtree matches, or
572     *   <code>false</code> if they do not match or the other object has a
573     *   different node type or is <code>null</code>
574     */
575    public boolean match(CharacterLiteral nodeObject other) {
576        if (!(other instanceof CharacterLiteral)) {
577            return false;
578        }
579        CharacterLiteral o = (CharacterLiteralother;
580        return safeEquals(node.getEscapedValue(), o.getEscapedValue());
581    }
582
583    /**
584     * Returns whether the given node and the other object match.
585     * <p>
586     * The default implementation provided by this class tests whether the
587     * other object is a node of the same type with structurally isomorphic
588     * child subtrees. Subclasses may override this method as needed.
589     * </p>
590     *
591     * @param node the node
592     * @param other the other object, or <code>null</code>
593     * @return <code>true</code> if the subtree matches, or
594     *   <code>false</code> if they do not match or the other object has a
595     *   different node type or is <code>null</code>
596     */
597    public boolean match(ClassInstanceCreation nodeObject other) {
598        if (!(other instanceof ClassInstanceCreation)) {
599            return false;
600        }
601        ClassInstanceCreation o = (ClassInstanceCreationother;
602        int level = node.getAST().apiLevel;
603        if (level == AST.JLS2_INTERNAL) {
604            if (!safeSubtreeMatch(node.internalGetName(), o.internalGetName())) {
605                return false;
606            }
607        }
608        if (level >= AST.JLS3_INTERNAL) {
609            if (!safeSubtreeListMatch(node.typeArguments(), o.typeArguments())) {
610                return false;
611            }
612            if (!safeSubtreeMatch(node.getType(), o.getType())) {
613                return false;
614            }
615        }
616        return
617            safeSubtreeMatch(node.getExpression(), o.getExpression())
618                && safeSubtreeListMatch(node.arguments(), o.arguments())
619                && safeSubtreeMatch(
620                    node.getAnonymousClassDeclaration(),
621                    o.getAnonymousClassDeclaration());
622    }
623
624    /**
625     * Returns whether the given node and the other object match.
626     * <p>
627     * The default implementation provided by this class tests whether the
628     * other object is a node of the same type with structurally isomorphic
629     * child subtrees. Subclasses may override this method as needed.
630     * </p>
631     *
632     * @param node the node
633     * @param other the other object, or <code>null</code>
634     * @return <code>true</code> if the subtree matches, or
635     *   <code>false</code> if they do not match or the other object has a
636     *   different node type or is <code>null</code>
637     */
638    public boolean match(CompilationUnit nodeObject other) {
639        if (!(other instanceof CompilationUnit)) {
640            return false;
641        }
642        CompilationUnit o = (CompilationUnitother;
643        return (
644            (node.getAST().apiLevel >= AST.JLS9_INTERNAL ? safeSubtreeMatch(node.getModule(), o.getModule()) : true)
645                && safeSubtreeMatch(node.getPackage(), o.getPackage())
646                && safeSubtreeListMatch(node.imports(), o.imports())
647                && safeSubtreeListMatch(node.types(), o.types()));
648    }
649
650    /**
651     * Returns whether the given node and the other object match.
652     * <p>
653     * The default implementation provided by this class tests whether the
654     * other object is a node of the same type with structurally isomorphic
655     * child subtrees. Subclasses may override this method as needed.
656     * </p>
657     *
658     * @param node the node
659     * @param other the other object, or <code>null</code>
660     * @return <code>true</code> if the subtree matches, or
661     *   <code>false</code> if they do not match or the other object has a
662     *   different node type or is <code>null</code>
663     */
664    public boolean match(ConditionalExpression nodeObject other) {
665        if (!(other instanceof ConditionalExpression)) {
666            return false;
667        }
668        ConditionalExpression o = (ConditionalExpressionother;
669        return (
670            safeSubtreeMatch(node.getExpression(), o.getExpression())
671                && safeSubtreeMatch(node.getThenExpression(), o.getThenExpression())
672                && safeSubtreeMatch(node.getElseExpression(), o.getElseExpression()));
673    }
674
675    /**
676     * Returns whether the given node and the other object match.
677     * <p>
678     * The default implementation provided by this class tests whether the
679     * other object is a node of the same type with structurally isomorphic
680     * child subtrees. Subclasses may override this method as needed.
681     * </p>
682     *
683     * @param node the node
684     * @param other the other object, or <code>null</code>
685     * @return <code>true</code> if the subtree matches, or
686     *   <code>false</code> if they do not match or the other object has a
687     *   different node type or is <code>null</code>
688     */
689    public boolean match(ConstructorInvocation nodeObject other) {
690        if (!(other instanceof ConstructorInvocation)) {
691            return false;
692        }
693        ConstructorInvocation o = (ConstructorInvocationother;
694        if (node.getAST().apiLevel >= AST.JLS3_INTERNAL) {
695            if (!safeSubtreeListMatch(node.typeArguments(), o.typeArguments())) {
696                return false;
697            }
698        }
699        return safeSubtreeListMatch(node.arguments(), o.arguments());
700    }
701
702    /**
703     * Returns whether the given node and the other object match.
704     * <p>
705     * The default implementation provided by this class tests whether the
706     * other object is a node of the same type with structurally isomorphic
707     * child subtrees. Subclasses may override this method as needed.
708     * </p>
709     *
710     * @param node the node
711     * @param other the other object, or <code>null</code>
712     * @return <code>true</code> if the subtree matches, or
713     *   <code>false</code> if they do not match or the other object has a
714     *   different node type or is <code>null</code>
715     */
716    public boolean match(ContinueStatement nodeObject other) {
717        if (!(other instanceof ContinueStatement)) {
718            return false;
719        }
720        ContinueStatement o = (ContinueStatementother;
721        return safeSubtreeMatch(node.getLabel(), o.getLabel());
722    }
723
724    /**
725     * Returns whether the given node and the other object match.
726     * <p>
727     * The default implementation provided by this class tests whether the
728     * other object is a node of the same type with structurally isomorphic
729     * child subtrees. Subclasses may override this method as needed.
730     * </p>
731     *
732     * @param node the node
733     * @param other the other object, or <code>null</code>
734     * @return <code>true</code> if the subtree matches, or
735     *   <code>false</code> if they do not match or the other object has a
736     *   different node type or is <code>null</code>
737     * @since 3.10
738     */
739    public boolean match(CreationReference nodeObject other) {
740        if (!(other instanceof CreationReference)) {
741            return false;
742        }
743        CreationReference o = (CreationReferenceother;
744        return (
745            safeSubtreeMatch(node.getType(), o.getType())
746                && safeSubtreeListMatch(node.typeArguments(), o.typeArguments()));
747    }
748
749    /**
750     * Returns whether the given node and the other object match.
751     * <p>
752     * The default implementation provided by this class tests whether the
753     * other object is a node of the same type with structurally isomorphic
754     * child subtrees. Subclasses may override this method as needed.
755     * </p>
756     *
757     * @param node the node
758     * @param other the other object, or <code>null</code>
759     * @return <code>true</code> if the subtree matches, or
760     *   <code>false</code> if they do not match or the other object has a
761     *   different node type or is <code>null</code>
762     * @since 3.10
763     */
764    public boolean match(Dimension nodeObject other) {
765        if (!(other instanceof Dimension)) {
766            return false;
767        }
768        Dimension o = (Dimensionother;
769        return safeSubtreeListMatch(node.annotations(), o.annotations());
770    }
771
772    /**
773     * Returns whether the given node and the other object match.
774     * <p>
775     * The default implementation provided by this class tests whether the
776     * other object is a node of the same type with structurally isomorphic
777     * child subtrees. Subclasses may override this method as needed.
778     * </p>
779     *
780     * @param node the node
781     * @param other the other object, or <code>null</code>
782     * @return <code>true</code> if the subtree matches, or
783     *   <code>false</code> if they do not match or the other object has a
784     *   different node type or is <code>null</code>
785     */
786    public boolean match(DoStatement nodeObject other) {
787        if (!(other instanceof DoStatement)) {
788            return false;
789        }
790        DoStatement o = (DoStatementother;
791        return (
792            safeSubtreeMatch(node.getExpression(), o.getExpression())
793                && safeSubtreeMatch(node.getBody(), o.getBody()));
794    }
795
796    /**
797     * Returns whether the given node and the other object match.
798     * <p>
799     * The default implementation provided by this class tests whether the
800     * other object is a node of the same type with structurally isomorphic
801     * child subtrees. Subclasses may override this method as needed.
802     * </p>
803     *
804     * @param node the node
805     * @param other the other object, or <code>null</code>
806     * @return <code>true</code> if the subtree matches, or
807     *   <code>false</code> if they do not match or the other object has a
808     *   different node type or is <code>null</code>
809     */
810    public boolean match(EmptyStatement nodeObject other) {
811        if (!(other instanceof EmptyStatement)) {
812            return false;
813        }
814        return true;
815    }
816
817    /**
818     * Returns whether the given node and the other object match.
819     * <p>
820     * The default implementation provided by this class tests whether the
821     * other object is a node of the same type with structurally isomorphic
822     * child subtrees. Subclasses may override this method as needed.
823     * </p>
824     *
825     * @param node the node
826     * @param other the other object, or <code>null</code>
827     * @return <code>true</code> if the subtree matches, or
828     *   <code>false</code> if they do not match or the other object has a
829     *   different node type or is <code>null</code>
830     * @since 3.1
831     */
832    public boolean match(EnhancedForStatement nodeObject other) {
833        if (!(other instanceof EnhancedForStatement)) {
834            return false;
835        }
836        EnhancedForStatement o = (EnhancedForStatementother;
837        return (
838            safeSubtreeMatch(node.getParameter(), o.getParameter())
839                && safeSubtreeMatch(node.getExpression(), o.getExpression())
840                && safeSubtreeMatch(node.getBody(), o.getBody()));
841    }
842
843    /**
844     * Returns whether the given node and the other object match.
845     * <p>
846     * The default implementation provided by this class tests whether the
847     * other object is a node of the same type with structurally isomorphic
848     * child subtrees. Subclasses may override this method as needed.
849     * </p>
850     *
851     * @param node the node
852     * @param other the other object, or <code>null</code>
853     * @return <code>true</code> if the subtree matches, or
854     *   <code>false</code> if they do not match or the other object has a
855     *   different node type or is <code>null</code>
856     * @since 3.1
857     */
858    public boolean match(EnumConstantDeclaration nodeObject other) {
859        if (!(other instanceof EnumConstantDeclaration)) {
860            return false;
861        }
862        EnumConstantDeclaration o = (EnumConstantDeclarationother;
863        return (
864            safeSubtreeMatch(node.getJavadoc(), o.getJavadoc())
865                && safeSubtreeListMatch(node.modifiers(), o.modifiers())
866                && safeSubtreeMatch(node.getName(), o.getName())
867                && safeSubtreeListMatch(node.arguments(), o.arguments())
868                && safeSubtreeMatch(
869                    node.getAnonymousClassDeclaration(),
870                    o.getAnonymousClassDeclaration()));
871    }
872
873    /**
874     * Returns whether the given node and the other object match.
875     * <p>
876     * The default implementation provided by this class tests whether the
877     * other object is a node of the same type with structurally isomorphic
878     * child subtrees. Subclasses may override this method as needed.
879     * </p>
880     *
881     * @param node the node
882     * @param other the other object, or <code>null</code>
883     * @return <code>true</code> if the subtree matches, or
884     *   <code>false</code> if they do not match or the other object has a
885     *   different node type or is <code>null</code>
886     * @since 3.1
887     */
888    public boolean match(EnumDeclaration nodeObject other) {
889        if (!(other instanceof EnumDeclaration)) {
890            return false;
891        }
892        EnumDeclaration o = (EnumDeclarationother;
893        return (
894            safeSubtreeMatch(node.getJavadoc(), o.getJavadoc())
895                && safeSubtreeListMatch(node.modifiers(), o.modifiers())
896                && safeSubtreeMatch(node.getName(), o.getName())
897                && safeSubtreeListMatch(node.superInterfaceTypes(), o.superInterfaceTypes())
898                && safeSubtreeListMatch(node.enumConstants(), o.enumConstants())
899                && safeSubtreeListMatch(
900                    node.bodyDeclarations(),
901                    o.bodyDeclarations()));
902    }
903
904    /**
905     * Returns whether the given node and the other object match.
906     * <p>
907     * The default implementation provided by this class tests whether the
908     * other object is a node of the same type with structurally isomorphic
909     * child subtrees. Subclasses may override this method as needed.
910     * </p>
911     *
912     * @param node the node
913     * @param other the other object, or <code>null</code>
914     * @return <code>true</code> if the subtree matches, or
915     *   <code>false</code> if they do not match or the other object has a
916     *   different node type or is <code>null</code>
917     * @since 3.14
918     */
919    public boolean match(ExportsDirective nodeObject other) {
920        if (!(other instanceof ExportsDirective)) {
921            return false;
922        }
923        ExportsDirective o = (ExportsDirectiveother;
924        return (
925            safeSubtreeMatch(node.getName(), o.getName())
926                && safeSubtreeListMatch(node.modules(), o.modules()));
927    }
928
929    /**
930     * Returns whether the given node and the other object match.
931     * <p>
932     * The default implementation provided by this class tests whether the
933     * other object is a node of the same type with structurally isomorphic
934     * child subtrees. Subclasses may override this method as needed.
935     * </p>
936     *
937     * @param node the node
938     * @param other the other object, or <code>null</code>
939     * @return <code>true</code> if the subtree matches, or
940     *   <code>false</code> if they do not match or the other object has a
941     *   different node type or is <code>null</code>
942     * @since 3.10
943     */
944    public boolean match(ExpressionMethodReference nodeObject other) {
945        if (!(other instanceof ExpressionMethodReference)) {
946            return false;
947        }
948        ExpressionMethodReference o = (ExpressionMethodReferenceother;
949        return (
950            safeSubtreeMatch(node.getExpression(), o.getExpression())
951                && safeSubtreeListMatch(node.typeArguments(), o.typeArguments())
952                && safeSubtreeMatch(node.getName(), o.getName()));
953    }
954
955    /**
956     * Returns whether the given node and the other object match.
957     * <p>
958     * The default implementation provided by this class tests whether the
959     * other object is a node of the same type with structurally isomorphic
960     * child subtrees. Subclasses may override this method as needed.
961     * </p>
962     *
963     * @param node the node
964     * @param other the other object, or <code>null</code>
965     * @return <code>true</code> if the subtree matches, or
966     *   <code>false</code> if they do not match or the other object has a
967     *   different node type or is <code>null</code>
968     */
969    public boolean match(ExpressionStatement nodeObject other) {
970        if (!(other instanceof ExpressionStatement)) {
971            return false;
972        }
973        ExpressionStatement o = (ExpressionStatementother;
974        return safeSubtreeMatch(node.getExpression(), o.getExpression());
975    }
976
977    /**
978     * Returns whether the given node and the other object match.
979     * <p>
980     * The default implementation provided by this class tests whether the
981     * other object is a node of the same type with structurally isomorphic
982     * child subtrees. Subclasses may override this method as needed.
983     * </p>
984     *
985     * @param node the node
986     * @param other the other object, or <code>null</code>
987     * @return <code>true</code> if the subtree matches, or
988     *   <code>false</code> if they do not match or the other object has a
989     *   different node type or is <code>null</code>
990     */
991    public boolean match(FieldAccess nodeObject other) {
992        if (!(other instanceof FieldAccess)) {
993            return false;
994        }
995        FieldAccess o = (FieldAccessother;
996        return (
997            safeSubtreeMatch(node.getExpression(), o.getExpression())
998                && safeSubtreeMatch(node.getName(), o.getName()));
999    }
1000
1001    /**
1002     * Returns whether the given node and the other object match.
1003     * <p>
1004     * The default implementation provided by this class tests whether the
1005     * other object is a node of the same type with structurally isomorphic
1006     * child subtrees. Subclasses may override this method as needed.
1007     * </p>
1008     *
1009     * @param node the node
1010     * @param other the other object, or <code>null</code>
1011     * @return <code>true</code> if the subtree matches, or
1012     *   <code>false</code> if they do not match or the other object has a
1013     *   different node type or is <code>null</code>
1014     */
1015    public boolean match(FieldDeclaration nodeObject other) {
1016        if (!(other instanceof FieldDeclaration)) {
1017            return false;
1018        }
1019        FieldDeclaration o = (FieldDeclarationother;
1020        int level = node.getAST().apiLevel;
1021        if (level == AST.JLS2_INTERNAL) {
1022            if (node.getModifiers() != o.getModifiers()) {
1023                return false;
1024            }
1025        }
1026        if (level >= AST.JLS3_INTERNAL) {
1027            if (!safeSubtreeListMatch(node.modifiers(), o.modifiers())) {
1028                return false;
1029            }
1030        }
1031        return
1032            safeSubtreeMatch(node.getJavadoc(), o.getJavadoc())
1033            && safeSubtreeMatch(node.getType(), o.getType())
1034            && safeSubtreeListMatch(node.fragments(), o.fragments());
1035    }
1036
1037    /**
1038     * Returns whether the given node and the other object match.
1039     * <p>
1040     * The default implementation provided by this class tests whether the
1041     * other object is a node of the same type with structurally isomorphic
1042     * child subtrees. Subclasses may override this method as needed.
1043     * </p>
1044     *
1045     * @param node the node
1046     * @param other the other object, or <code>null</code>
1047     * @return <code>true</code> if the subtree matches, or
1048     *   <code>false</code> if they do not match or the other object has a
1049     *   different node type or is <code>null</code>
1050     */
1051    public boolean match(ForStatement nodeObject other) {
1052        if (!(other instanceof ForStatement)) {
1053            return false;
1054        }
1055        ForStatement o = (ForStatementother;
1056        return (
1057            safeSubtreeListMatch(node.initializers(), o.initializers())
1058                && safeSubtreeMatch(node.getExpression(), o.getExpression())
1059                && safeSubtreeListMatch(node.updaters(), o.updaters())
1060                && safeSubtreeMatch(node.getBody(), o.getBody()));
1061    }
1062
1063    /**
1064     * Returns whether the given node and the other object match.
1065     * <p>
1066     * The default implementation provided by this class tests whether the
1067     * other object is a node of the same type with structurally isomorphic
1068     * child subtrees. Subclasses may override this method as needed.
1069     * </p>
1070     *
1071     * @param node the node
1072     * @param other the other object, or <code>null</code>
1073     * @return <code>true</code> if the subtree matches, or
1074     *   <code>false</code> if they do not match or the other object has a
1075     *   different node type or is <code>null</code>
1076     * @since 3.28
1077     */
1078    public boolean match(GuardedPattern nodeObject other) {
1079        if (!(other instanceof GuardedPattern)) {
1080            return false;
1081        }
1082        GuardedPattern o = (GuardedPatternother;
1083        return  safeSubtreeMatch(node.getPattern(), o.getPattern())
1084                && safeSubtreeMatch(node.getExpression(), o.getExpression());
1085    }
1086
1087    /**
1088     * Returns whether the given node and the other object match.
1089     * <p>
1090     * The default implementation provided by this class tests whether the
1091     * other object is a node of the same type with structurally isomorphic
1092     * child subtrees. Subclasses may override this method as needed.
1093     * </p>
1094     *
1095     * @param node the node
1096     * @param other the other object, or <code>null</code>
1097     * @return <code>true</code> if the subtree matches, or
1098     *   <code>false</code> if they do not match or the other object has a
1099     *   different node type or is <code>null</code>
1100     */
1101    public boolean match(IfStatement nodeObject other) {
1102        if (!(other instanceof IfStatement)) {
1103            return false;
1104        }
1105        IfStatement o = (IfStatementother;
1106        return (
1107            safeSubtreeMatch(node.getExpression(), o.getExpression())
1108                && safeSubtreeMatch(node.getThenStatement(), o.getThenStatement())
1109                && safeSubtreeMatch(node.getElseStatement(), o.getElseStatement()));
1110    }
1111
1112    /**
1113     * Returns whether the given node and the other object match.
1114     * <p>
1115     * The default implementation provided by this class tests whether the
1116     * other object is a node of the same type with structurally isomorphic
1117     * child subtrees. Subclasses may override this method as needed.
1118     * </p>
1119     *
1120     * @param node the node
1121     * @param other the other object, or <code>null</code>
1122     * @return <code>true</code> if the subtree matches, or
1123     *   <code>false</code> if they do not match or the other object has a
1124     *   different node type or is <code>null</code>
1125     */
1126    public boolean match(ImportDeclaration nodeObject other) {
1127        if (!(other instanceof ImportDeclaration)) {
1128            return false;
1129        }
1130        ImportDeclaration o = (ImportDeclarationother;
1131        if (node.getAST().apiLevel >= AST.JLS3_INTERNAL) {
1132            if (node.isStatic() != o.isStatic()) {
1133                return false;
1134            }
1135        }
1136        return (
1137            safeSubtreeMatch(node.getName(), o.getName())
1138                && node.isOnDemand() == o.isOnDemand());
1139    }
1140
1141    /**
1142     * Returns whether the given node and the other object match.
1143     * <p>
1144     * The default implementation provided by this class tests whether the
1145     * other object is a node of the same type with structurally isomorphic
1146     * child subtrees. Subclasses may override this method as needed.
1147     * </p>
1148     *
1149     * @param node the node
1150     * @param other the other object, or <code>null</code>
1151     * @return <code>true</code> if the subtree matches, or
1152     *   <code>false</code> if they do not match or the other object has a
1153     *   different node type or is <code>null</code>
1154     */
1155    public boolean match(InfixExpression nodeObject other) {
1156        if (!(other instanceof InfixExpression)) {
1157            return false;
1158        }
1159        InfixExpression o = (InfixExpressionother;
1160        // be careful not to trigger lazy creation of extended operand lists
1161        if (node.hasExtendedOperands() && o.hasExtendedOperands()) {
1162            if (!safeSubtreeListMatch(node.extendedOperands(), o.extendedOperands())) {
1163                return false;
1164            }
1165        }
1166        if (node.hasExtendedOperands() != o.hasExtendedOperands()) {
1167            return false;
1168        }
1169        return (
1170            node.getOperator().equals(o.getOperator())
1171                && safeSubtreeMatch(node.getLeftOperand(), o.getLeftOperand())
1172                && safeSubtreeMatch(node.getRightOperand(), o.getRightOperand()));
1173    }
1174
1175    /**
1176     * Returns whether the given node and the other object match.
1177     * <p>
1178     * The default implementation provided by this class tests whether the
1179     * other object is a node of the same type with structurally isomorphic
1180     * child subtrees. Subclasses may override this method as needed.
1181     * </p>
1182     *
1183     * @param node the node
1184     * @param other the other object, or <code>null</code>
1185     * @return <code>true</code> if the subtree matches, or
1186     *   <code>false</code> if they do not match or the other object has a
1187     *   different node type or is <code>null</code>
1188     */
1189    public boolean match(Initializer nodeObject other) {
1190        if (!(other instanceof Initializer)) {
1191            return false;
1192        }
1193        Initializer o = (Initializerother;
1194        int level = node.getAST().apiLevel;
1195        if (level == AST.JLS2_INTERNAL) {
1196            if (node.getModifiers() != o.getModifiers()) {
1197                return false;
1198            }
1199        }
1200        if (level >= AST.JLS3_INTERNAL) {
1201            if (!safeSubtreeListMatch(node.modifiers(), o.modifiers())) {
1202                return false;
1203            }
1204        }
1205        return (
1206                safeSubtreeMatch(node.getJavadoc(), o.getJavadoc())
1207                && safeSubtreeMatch(node.getBody(), o.getBody()));
1208    }
1209
1210    /**
1211     * Returns whether the given node and the other object match.
1212     * <p>
1213     * The default implementation provided by this class tests whether the
1214     * other object is a node of the same type with structurally isomorphic
1215     * child subtrees. Subclasses may override this method as needed.
1216     * </p>
1217     *
1218     * @param node the node
1219     * @param other the other object, or <code>null</code>
1220     * @return <code>true</code> if the subtree matches, or
1221     *   <code>false</code> if they do not match or the other object has a
1222     *   different node type or is <code>null</code>
1223     */
1224    public boolean match(InstanceofExpression nodeObject other) {
1225        if (!(other instanceof InstanceofExpression)) {
1226            return false;
1227        }
1228        InstanceofExpression o = (InstanceofExpressionother;
1229        return
1230            safeSubtreeMatch(node.getLeftOperand(), o.getLeftOperand())
1231            && safeSubtreeMatch(node.getRightOperand(), o.getRightOperand());
1232    }
1233
1234    /**
1235     * Returns whether the given node and the other object match.
1236     * <p>
1237     * The default implementation provided by this class tests whether the
1238     * other object is a node of the same type with structurally isomorphic
1239     * child subtrees. Subclasses may override this method as needed.
1240     * </p>
1241     *
1242     * @param node the node
1243     * @param other the other object, or <code>null</code>
1244     * @return <code>true</code> if the subtree matches, or
1245     *   <code>false</code> if they do not match or the other object has a
1246     *   different node type or is <code>null</code>
1247     * @since 3.10
1248     */
1249    public boolean match(IntersectionType nodeObject other) {
1250        if (!(other instanceof IntersectionType)) {
1251            return false;
1252        }
1253        IntersectionType o = (IntersectionTypeother;
1254        return safeSubtreeListMatch(node.types(), o.types());
1255    }
1256
1257    /**
1258     * Returns whether the given node and the other object match.
1259     * <p>
1260     * Unlike other node types, the behavior of the default
1261     * implementation is controlled by a constructor-supplied
1262     * parameter  {@link #ASTMatcher(boolean) ASTMatcher(boolean)}
1263     * which is <code>false</code> if not specified.
1264     * When this parameter is <code>true</code>, the implementation
1265     * tests whether the other object is also a <code>Javadoc</code>
1266     * with structurally isomorphic child subtrees; the comment string
1267     * (<code>Javadoc.getComment()</code>) is ignored.
1268     * Conversely, when the parameter is <code>false</code>, the
1269     * implementation tests whether the other object is also a
1270     * <code>Javadoc</code> with exactly the same comment string;
1271     * the tag elements ({@link Javadoc#tags() Javadoc.tags} are
1272     * ignored. Subclasses may reimplement.
1273     * </p>
1274     *
1275     * @param node the node
1276     * @param other the other object, or <code>null</code>
1277     * @return <code>true</code> if the subtree matches, or
1278     *   <code>false</code> if they do not match or the other object has a
1279     *   different node type or is <code>null</code>
1280     * @see #ASTMatcher()
1281     * @see #ASTMatcher(boolean)
1282     */
1283    public boolean match(Javadoc nodeObject other) {
1284        if (!(other instanceof Javadoc)) {
1285            return false;
1286        }
1287        Javadoc o = (Javadocother;
1288        if (this.matchDocTags) {
1289            return safeSubtreeListMatch(node.tags(), o.tags());
1290        } else {
1291            return compareDeprecatedComment(nodeo);
1292        }
1293    }
1294
1295    /**
1296     * Returns whether the given node and the other object match.
1297     * <p>
1298     * The default implementation provided by this class tests whether the
1299     * other object is a node of the same type with structurally isomorphic
1300     * child subtrees. Subclasses may override this method as needed.
1301     * </p>
1302     *
1303     * @param node the node
1304     * @param other the other object, or <code>null</code>
1305     * @return <code>true</code> if the subtree matches, or
1306     *   <code>false</code> if they do not match or the other object has a
1307     *   different node type or is <code>null</code>
1308     * @see #ASTMatcher()
1309     * @see #ASTMatcher(boolean)
1310     * @since 3.30
1311     */
1312    public boolean match(JavaDocRegion nodeObject other) {
1313        if (!(other instanceof JavaDocRegion)) {
1314            return false;
1315        }
1316        JavaDocRegion o = (JavaDocRegionother;
1317        return safeEquals(node.getTagName(), o.getTagName()) && safeSubtreeListMatch(node.tags(), o.tags()) && safeSubtreeListMatch(node.fragments(), o.fragments())
1318                && safeEquals(node.isDummyRegion(), o.isDummyRegion() && safeEquals(node.isValidSnippet(), o.isValidSnippet()));
1319    }
1320
1321    /**
1322     * Return whether the deprecated comment strings of the given java doc are equals.
1323     * <p>
1324     * Note the only purpose of this method is to hide deprecated warnings.
1325     * @deprecated mark deprecated to hide deprecated usage
1326     */
1327    private boolean compareDeprecatedComment(Javadoc firstJavadoc second) {
1328        if (first.getAST().apiLevel == AST.JLS2_INTERNAL) {
1329            return safeEquals(first.getComment(), second.getComment());
1330        } else {
1331            return true;
1332        }
1333    }
1334
1335    /**
1336     * Returns whether the given node and the other object match.
1337     * <p>
1338     * The default implementation provided by this class tests whether the
1339     * other object is a node of the same type with structurally isomorphic
1340     * child subtrees. Subclasses may override this method as needed.
1341     * </p>
1342     *
1343     * @param node the node
1344     * @param other the other object, or <code>null</code>
1345     * @return <code>true</code> if the subtree matches, or
1346     *   <code>false</code> if they do not match or the other object has a
1347     *   different node type or is <code>null</code>
1348     */
1349    public boolean match(LabeledStatement nodeObject other) {
1350        if (!(other instanceof LabeledStatement)) {
1351            return false;
1352        }
1353        LabeledStatement o = (LabeledStatementother;
1354        return (
1355            safeSubtreeMatch(node.getLabel(), o.getLabel())
1356                && safeSubtreeMatch(node.getBody(), o.getBody()));
1357    }
1358
1359    /**
1360     * Returns whether the given node and the other object match.
1361     * <p>
1362     * The default implementation provided by this class tests whether the
1363     * other object is a node of the same type with structurally isomorphic
1364     * child subtrees. Subclasses may override this method as needed.
1365     * </p>
1366     *
1367     * @param node the node
1368     * @param other the other object, or <code>null</code>
1369     * @return <code>true</code> if the subtree matches, or
1370     *   <code>false</code> if they do not match or the other object has a
1371     *   different node type or is <code>null</code>
1372     * @since 3.10
1373     */
1374    public boolean match(LambdaExpression nodeObject other) {
1375        if (!(other instanceof LambdaExpression)) {
1376            return false;
1377        }
1378        LambdaExpression o = (LambdaExpressionother;
1379        return    (node.hasParentheses() == o.hasParentheses())
1380                && safeSubtreeListMatch(node.parameters(), o.parameters())
1381                && safeSubtreeMatch(node.getBody(), o.getBody());
1382    }
1383
1384    /**
1385     * Returns whether the given node and the other object match.
1386     * <p>
1387     * The default implementation provided by this class tests whether the
1388     * other object is a node of the same type. Subclasses may override
1389     * this method as needed.
1390     * </p>
1391     * <p>Note: {@link LineComment} and {@link BlockComment} nodes are
1392     * not considered part of main structure of the AST. This method will
1393     * only be called if a client goes out of their way to visit this
1394     * kind of node explicitly.
1395     * </p>
1396     *
1397     * @param node the node
1398     * @param other the other object, or <code>null</code>
1399     * @return <code>true</code> if the subtree matches, or
1400     *   <code>false</code> if they do not match or the other object has a
1401     *   different node type or is <code>null</code>
1402     * @since 3.0
1403     */
1404    public boolean match(LineComment nodeObject other) {
1405        if (!(other instanceof LineComment)) {
1406            return false;
1407        }
1408        return true;
1409    }
1410
1411    /**
1412     * Returns whether the given node and the other object match.
1413     * <p>
1414     * The default implementation provided by this class tests whether the
1415     * other object is a node of the same type with structurally isomorphic
1416     * child subtrees. Subclasses may override this method as needed.
1417     * </p>
1418     *
1419     * @param node the node
1420     * @param other the other object, or <code>null</code>
1421     * @return <code>true</code> if the subtree matches, or
1422     *   <code>false</code> if they do not match or the other object has a
1423     *   different node type or is <code>null</code>
1424     * @since 3.1
1425     */
1426    public boolean match(MarkerAnnotation nodeObject other) {
1427        if (!(other instanceof MarkerAnnotation)) {
1428            return false;
1429        }
1430        MarkerAnnotation o = (MarkerAnnotationother;
1431        return safeSubtreeMatch(node.getTypeName(), o.getTypeName());
1432    }
1433
1434    /**
1435     * Returns whether the given node and the other object match.
1436     * <p>
1437     * The default implementation provided by this class tests whether the
1438     * other object is a node of the same type with structurally isomorphic
1439     * child subtrees. Subclasses may override this method as needed.
1440     * </p>
1441     *
1442     * @param node the node
1443     * @param other the other object, or <code>null</code>
1444     * @return <code>true</code> if the subtree matches, or
1445     *   <code>false</code> if they do not match or the other object has a
1446     *   different node type or is <code>null</code>
1447     * @since 3.0
1448     */
1449    public boolean match(MemberRef nodeObject other) {
1450        if (!(other instanceof MemberRef)) {
1451            return false;
1452        }
1453        MemberRef o = (MemberRefother;
1454        return (
1455                safeSubtreeMatch(node.getQualifier(), o.getQualifier())
1456                && safeSubtreeMatch(node.getName(), o.getName()));
1457    }
1458
1459    /**
1460     * Returns whether the given node and the other object match.
1461     * <p>
1462     * The default implementation provided by this class tests whether the
1463     * other object is a node of the same type with structurally isomorphic
1464     * child subtrees. Subclasses may override this method as needed.
1465     * </p>
1466     *
1467     * @param node the node
1468     * @param other the other object, or <code>null</code>
1469     * @return <code>true</code> if the subtree matches, or
1470     *   <code>false</code> if they do not match or the other object has a
1471     *   different node type or is <code>null</code>
1472     * @since 3.1
1473     */
1474    public boolean match(MemberValuePair nodeObject other) {
1475        if (!(other instanceof MemberValuePair)) {
1476            return false;
1477        }
1478        MemberValuePair o = (MemberValuePairother;
1479        return (safeSubtreeMatch(node.getName(), o.getName())
1480                && safeSubtreeMatch(node.getValue(), o.getValue()));
1481    }
1482
1483    /**
1484     * Returns whether the given node and the other object match.
1485     * <p>
1486     * The default implementation provided by this class tests whether the
1487     * other object is a node of the same type with structurally isomorphic
1488     * child subtrees. Subclasses may override this method as needed.
1489     * </p>
1490     *
1491     * @param node the node
1492     * @param other the other object, or <code>null</code>
1493     * @return <code>true</code> if the subtree matches, or
1494     *   <code>false</code> if they do not match or the other object has a
1495     *   different node type or is <code>null</code>
1496     * @since 3.0
1497     */
1498    public boolean match(MethodRef nodeObject other) {
1499        if (!(other instanceof MethodRef)) {
1500            return false;
1501        }
1502        MethodRef o = (MethodRefother;
1503        return (
1504                safeSubtreeMatch(node.getQualifier(), o.getQualifier())
1505                && safeSubtreeMatch(node.getName(), o.getName())
1506                && safeSubtreeListMatch(node.parameters(), o.parameters()));
1507    }
1508
1509    /**
1510     * Returns whether the given node and the other object match.
1511     * <p>
1512     * The default implementation provided by this class tests whether the
1513     * other object is a node of the same type with structurally isomorphic
1514     * child subtrees. Subclasses may override this method as needed.
1515     * </p>
1516     *
1517     * @param node the node
1518     * @param other the other object, or <code>null</code>
1519     * @return <code>true</code> if the subtree matches, or
1520     *   <code>false</code> if they do not match or the other object has a
1521     *   different node type or is <code>null</code>
1522     * @since 3.0
1523     */
1524    public boolean match(MethodRefParameter nodeObject other) {
1525        if (!(other instanceof MethodRefParameter)) {
1526            return false;
1527        }
1528        MethodRefParameter o = (MethodRefParameterother;
1529        int level = node.getAST().apiLevel;
1530        if (level >= AST.JLS3_INTERNAL) {
1531            if (node.isVarargs() != o.isVarargs()) {
1532                return false;
1533            }
1534        }
1535        return (
1536                safeSubtreeMatch(node.getType(), o.getType())
1537                && safeSubtreeMatch(node.getName(), o.getName()));
1538    }
1539
1540    /**
1541     * Returns whether the given node and the other object match.
1542     * <p>
1543     * The default implementation provided by this class tests whether the
1544     * other object is a node of the same type with structurally isomorphic
1545     * child subtrees. Subclasses may override this method as needed.
1546     * </p>
1547     * <p>
1548     * Note that extra array dimensions are compared since they are an
1549     * important part of the method declaration.
1550     * </p>
1551     * <p>
1552     * Note that the method return types are compared even for constructor
1553     * declarations.
1554     * </p>
1555     *
1556     * @param node the node
1557     * @param other the other object, or <code>null</code>
1558     * @return <code>true</code> if the subtree matches, or
1559     *   <code>false</code> if they do not match or the other object has a
1560     *   different node type or is <code>null</code>
1561     */
1562    public boolean match(MethodDeclaration nodeObject other) {
1563        if (!(other instanceof MethodDeclaration)) {
1564            return false;
1565        }
1566        MethodDeclaration o = (MethodDeclarationother;
1567        int level = node.getAST().apiLevel;
1568        return node.isConstructor() == o.isConstructor()
1569                && safeSubtreeMatch(node.getJavadoc(), o.getJavadoc())
1570                && (level >= AST.JLS3_INTERNAL
1571                        ? safeSubtreeListMatch(node.modifiers(), o.modifiers())
1572                                && safeSubtreeListMatch(node.typeParameters(), o.typeParameters())
1573                                // n.b. compare return type even for constructors
1574                                && safeSubtreeMatch(node.getReturnType2(), o.getReturnType2())
1575                        : node.getModifiers() == o.getModifiers()
1576                                // n.b. compare return type even for constructors
1577                                && safeSubtreeMatch(node.internalGetReturnType(), o.internalGetReturnType()))
1578                && safeSubtreeMatch(node.getName(), o.getName())
1579                && (level >= AST.JLS8_INTERNAL
1580                        ? safeSubtreeMatch(node.getReceiverType(), o.getReceiverType())
1581                                && safeSubtreeMatch(node.getReceiverQualifier(), o.getReceiverQualifier())
1582                        : true)
1583                && safeSubtreeListMatch(node.parameters(), o.parameters())
1584                && (level >= AST.JLS8_INTERNAL
1585                        ? safeSubtreeListMatch(node.extraDimensions(), o.extraDimensions())
1586                                && safeSubtreeListMatch(node.thrownExceptionTypes(), o.thrownExceptionTypes())
1587                        : node.getExtraDimensions() == o.getExtraDimensions()
1588                                && safeSubtreeListMatch(node.internalThrownExceptions(), o.internalThrownExceptions()))
1589                && safeSubtreeMatch(node.getBody(), o.getBody())
1590                && (DOMASTUtil.isRecordDeclarationSupported(node.getAST())
1591                        ? node.isCompactConstructor() == o.isCompactConstructor()
1592                        : true);
1593    }
1594
1595    /**
1596     * Returns whether the given node and the other object match.
1597     * <p>
1598     * The default implementation provided by this class tests whether the
1599     * other object is a node of the same type with structurally isomorphic
1600     * child subtrees. Subclasses may override this method as needed.
1601     * </p>
1602     *
1603     * @param node the node
1604     * @param other the other object, or <code>null</code>
1605     * @return <code>true</code> if the subtree matches, or
1606     *   <code>false</code> if they do not match or the other object has a
1607     *   different node type or is <code>null</code>
1608     */
1609    public boolean match(MethodInvocation nodeObject other) {
1610        if (!(other instanceof MethodInvocation)) {
1611            return false;
1612        }
1613        MethodInvocation o = (MethodInvocationother;
1614        if (node.getAST().apiLevel >= AST.JLS3_INTERNAL) {
1615            if (!safeSubtreeListMatch(node.typeArguments(), o.typeArguments())) {
1616                return false;
1617            }
1618        }
1619        return (
1620            safeSubtreeMatch(node.getExpression(), o.getExpression())
1621                && safeSubtreeMatch(node.getName(), o.getName())
1622                && safeSubtreeListMatch(node.arguments(), o.arguments()));
1623    }
1624
1625    /**
1626     * Returns whether the given node and the other object match.
1627     * <p>
1628     * The default implementation provided by this class tests whether the
1629     * other object is a node of the same type with structurally isomorphic
1630     * child subtrees. Subclasses may override this method as needed.
1631     * </p>
1632     *
1633     * @param node the node
1634     * @param other the other object, or <code>null</code>
1635     * @return <code>true</code> if the subtree matches, or
1636     *   <code>false</code> if they do not match or the other object has a
1637     *   different node type or is <code>null</code>
1638     * @since 3.1
1639     */
1640    public boolean match(Modifier nodeObject other) {
1641        if (!(other instanceof Modifier)) {
1642            return false;
1643        }
1644        Modifier o = (Modifierother;
1645        return (node.getKeyword() == o.getKeyword());
1646    }
1647
1648    /**
1649     * Returns whether the given node and the other object match.
1650     * <p>
1651     * The default implementation provided by this class tests whether the
1652     * other object is a node of the same type with structurally isomorphic
1653     * child subtrees. Subclasses may override this method as needed.
1654     * </p>
1655     *
1656     * @param node the node
1657     * @param other the other object, or <code>null</code>
1658     * @return <code>true</code> if the subtree matches, or
1659     *   <code>false</code> if they do not match or the other object has a
1660     *   different node type or is <code>null</code>
1661     * @since 3.14
1662     */
1663    public boolean match(ModuleDeclaration nodeObject other) {
1664        if (!(other instanceof ModuleDeclaration)) {
1665            return false;
1666        }
1667        ModuleDeclaration o = (ModuleDeclarationother;
1668        return (safeSubtreeMatch(node.getJavadoc(), o.getJavadoc())
1669                && safeSubtreeListMatch(node.annotations(), o.annotations())
1670                && node.isOpen() == o.isOpen()
1671                && safeSubtreeMatch(node.getName(), o.getName())
1672                && safeSubtreeListMatch(node.moduleStatements(), o.moduleStatements()));
1673    }
1674
1675    /**
1676     * Returns whether the given node and the other object match.
1677     * <p>
1678     * The default implementation provided by this class tests whether the
1679     * other object is a node of the same type with structurally isomorphic
1680     * child subtrees. Subclasses may override this method as needed.
1681     * </p>
1682     *
1683     * @param node the node
1684     * @param other the other object, or <code>null</code>
1685     * @return <code>true</code> if the subtree matches, or
1686     *   <code>false</code> if they do not match or the other object has a
1687     *   different node type or is <code>null</code>
1688     * @since 3.14
1689     */
1690    public boolean match(ModuleModifier nodeObject other) {
1691        if (!(other instanceof ModuleModifier)) {
1692            return false;
1693        }
1694        ModuleModifier o = (ModuleModifierother;
1695        return (node.getKeyword() == o.getKeyword());
1696    }
1697
1698    /**
1699     * Returns whether the given node and the other object match.
1700     * <p>
1701     * The default implementation provided by this class tests whether the
1702     * other object is a node of the same type with structurally isomorphic
1703     * child subtrees. Subclasses may override this method as needed.
1704     * </p>
1705     *
1706     * @param node the node
1707     * @param other the other object, or <code>null</code>
1708     * @return <code>true</code> if the subtree matches, or
1709     *   <code>false</code> if they do not match or the other object has a
1710     *   different node type or is <code>null</code>
1711     * @since 3.10
1712     */
1713    public boolean match(NameQualifiedType nodeObject other) {
1714        if (!(other instanceof NameQualifiedType)) {
1715            return false;
1716        }
1717        NameQualifiedType o = (NameQualifiedTypeother;
1718        return safeSubtreeMatch(node.getQualifier(), o.getQualifier())
1719                && safeSubtreeListMatch(node.annotations(), o.annotations())
1720                && safeSubtreeMatch(node.getName(), o.getName());
1721    }
1722
1723    /**
1724     * Returns whether the given node and the other object match.
1725     * <p>
1726     * The default implementation provided by this class tests whether the
1727     * other object is a node of the same type with structurally isomorphic
1728     * child subtrees. Subclasses may override this method as needed.
1729     * </p>
1730     *
1731     * @param node the node
1732     * @param other the other object, or <code>null</code>
1733     * @return <code>true</code> if the subtree matches, or
1734     *   <code>false</code> if they do not match or the other object has a
1735     *   different node type or is <code>null</code>
1736     * @since 3.1
1737     */
1738    public boolean match(NormalAnnotation nodeObject other) {
1739        if (!(other instanceof NormalAnnotation)) {
1740            return false;
1741        }
1742        NormalAnnotation o = (NormalAnnotationother;
1743        return (safeSubtreeMatch(node.getTypeName(), o.getTypeName())
1744                    && safeSubtreeListMatch(node.values(), o.values()));
1745    }
1746
1747    /**
1748     * Returns whether the given node and the other object match.
1749     * <p>
1750     * The default implementation provided by this class tests whether the
1751     * other object is a node of the same type with structurally isomorphic
1752     * child subtrees. Subclasses may override this method as needed.
1753     * </p>
1754     *
1755     * @param node the node
1756     * @param other the other object, or <code>null</code>
1757     * @return <code>true</code> if the subtree matches, or
1758     *   <code>false</code> if they do not match or the other object has a
1759     *   different node type or is <code>null</code>
1760     */
1761    public boolean match(NullLiteral nodeObject other) {
1762        if (!(other instanceof NullLiteral)) {
1763            return false;
1764        }
1765        return true;
1766    }
1767
1768    /**
1769     * Returns whether the given node and the other object match.
1770     * <p>
1771     * The default implementation provided by this class tests whether the
1772     * other object is a node of the same type with structurally isomorphic
1773     * child subtrees. Subclasses may override this method as needed.
1774     * </p>
1775     *
1776     * @param node the node
1777     * @param other the other object, or <code>null</code>
1778     * @return <code>true</code> if the subtree matches, or
1779     *   <code>false</code> if they do not match or the other object has a
1780     *   different node type or is <code>null</code>
1781     *  @since 3.28
1782     */
1783    public boolean match(NullPattern nodeObject other) {
1784        if (!(other instanceof NullPattern)) {
1785            return false;
1786        }
1787        return true;
1788    }
1789
1790    /**
1791     * Returns whether the given node and the other object match.
1792     * <p>
1793     * The default implementation provided by this class tests whether the
1794     * other object is a node of the same type with structurally isomorphic
1795     * child subtrees. Subclasses may override this method as needed.
1796     * </p>
1797     *
1798     * @param node the node
1799     * @param other the other object, or <code>null</code>
1800     * @return <code>true</code> if the subtree matches, or
1801     *   <code>false</code> if they do not match or the other object has a
1802     *   different node type or is <code>null</code>
1803     */
1804    public boolean match(NumberLiteral nodeObject other) {
1805        if (!(other instanceof NumberLiteral)) {
1806            return false;
1807        }
1808        NumberLiteral o = (NumberLiteralother;
1809        return safeEquals(node.getToken(), o.getToken());
1810    }
1811
1812    /**
1813     * Returns whether the given node and the other object match.
1814     * <p>
1815     * The default implementation provided by this class tests whether the
1816     * other object is a node of the same type with structurally isomorphic
1817     * child subtrees. Subclasses may override this method as needed.
1818     * </p>
1819     *
1820     * @param node the node
1821     * @param other the other object, or <code>null</code>
1822     * @return <code>true</code> if the subtree matches, or
1823     *   <code>false</code> if they do not match or the other object has a
1824     *   different node type or is <code>null</code>
1825     * @since 3.14
1826     */
1827    public boolean match(OpensDirective nodeObject other) {
1828        if (!(other instanceof OpensDirective)) {
1829            return false;
1830        }
1831        OpensDirective o = (OpensDirectiveother;
1832        return (
1833            safeSubtreeMatch(node.getName(), o.getName())
1834                && safeSubtreeListMatch(node.modules(), o.modules()));
1835    }
1836
1837    /**
1838     * Returns whether the given node and the other object match.
1839     * <p>
1840     * The default implementation provided by this class tests whether the
1841     * other object is a node of the same type with structurally isomorphic
1842     * child subtrees. Subclasses may override this method as needed.
1843     * </p>
1844     *
1845     * @param node the node
1846     * @param other the other object, or <code>null</code>
1847     * @return <code>true</code> if the subtree matches, or
1848     *   <code>false</code> if they do not match or the other object has a
1849     *   different node type or is <code>null</code>
1850     */
1851    public boolean match(PackageDeclaration nodeObject other) {
1852        if (!(other instanceof PackageDeclaration)) {
1853            return false;
1854        }
1855        PackageDeclaration o = (PackageDeclarationother;
1856        if (node.getAST().apiLevel >= AST.JLS3_INTERNAL) {
1857            if (!safeSubtreeMatch(node.getJavadoc(), o.getJavadoc())) {
1858                return false;
1859            }
1860            if (!safeSubtreeListMatch(node.annotations(), o.annotations())) {
1861                return false;
1862            }
1863        }
1864        return safeSubtreeMatch(node.getName(), o.getName());
1865    }
1866
1867    /**
1868     * Returns whether the given node and the other object match.
1869     * <p>
1870     * The default implementation provided by this class tests whether the
1871     * other object is a node of the same type with structurally isomorphic
1872     * child subtrees. Subclasses may override this method as needed.
1873     * </p>
1874     *
1875     * @param node the node
1876     * @param other the other object, or <code>null</code>
1877     * @return <code>true</code> if the subtree matches, or
1878     *   <code>false</code> if they do not match or the other object has a
1879     *   different node type or is <code>null</code>
1880     * @since 3.1
1881     */
1882    public boolean match(ParameterizedType nodeObject other) {
1883        if (!(other instanceof ParameterizedType)) {
1884            return false;
1885        }
1886        ParameterizedType o = (ParameterizedTypeother;
1887        return safeSubtreeMatch(node.getType(), o.getType())
1888                && safeSubtreeListMatch(node.typeArguments(), o.typeArguments());
1889    }
1890
1891    /**
1892     * Returns whether the given node and the other object match.
1893     * <p>
1894     * The default implementation provided by this class tests whether the
1895     * other object is a node of the same type with structurally isomorphic
1896     * child subtrees. Subclasses may override this method as needed.
1897     * </p>
1898     *
1899     * @param node the node
1900     * @param other the other object, or <code>null</code>
1901     * @return <code>true</code> if the subtree matches, or
1902     *   <code>false</code> if they do not match or the other object has a
1903     *   different node type or is <code>null</code>
1904     */
1905    public boolean match(ParenthesizedExpression nodeObject other) {
1906        if (!(other instanceof ParenthesizedExpression)) {
1907            return false;
1908        }
1909        ParenthesizedExpression o = (ParenthesizedExpressionother;
1910        return safeSubtreeMatch(node.getExpression(), o.getExpression());
1911    }
1912
1913    /**
1914     * Returns whether the given node and the other object match.
1915     * <p>
1916     * The default implementation provided by this class tests whether the
1917     * other object is a node of the same type with structurally isomorphic
1918     * child subtrees. Subclasses may override this method as needed.
1919     * </p>
1920     *
1921     * @param node the node
1922     * @param other the other object, or <code>null</code>
1923     * @return <code>true</code> if the subtree matches, or
1924     *   <code>false</code> if they do not match or the other object has a
1925     *   different node type or is <code>null</code>
1926     * @since 3.26
1927     */
1928    public boolean match(PatternInstanceofExpression nodeObject other) {
1929        if (!(other instanceof PatternInstanceofExpression)) {
1930            return false;
1931        }
1932        PatternInstanceofExpression o = (PatternInstanceofExpressionother;
1933        return
1934            safeSubtreeMatch(node.getLeftOperand(), o.getLeftOperand())
1935            && safeSubtreeMatch(node.getRightOperand(), o.getRightOperand());
1936    }
1937
1938    /**
1939     * Returns whether the given node and the other object match.
1940     * <p>
1941     * The default implementation provided by this class tests whether the
1942     * other object is a node of the same type with structurally isomorphic
1943     * child subtrees. Subclasses may override this method as needed.
1944     * </p>
1945     *
1946     * @param node the node
1947     * @param other the other object, or <code>null</code>
1948     * @return <code>true</code> if the subtree matches, or
1949     *   <code>false</code> if they do not match or the other object has a
1950     *   different node type or is <code>null</code>
1951     */
1952    public boolean match(PostfixExpression nodeObject other) {
1953        if (!(other instanceof PostfixExpression)) {
1954            return false;
1955        }
1956        PostfixExpression o = (PostfixExpressionother;
1957        return (
1958            node.getOperator().equals(o.getOperator())
1959                && safeSubtreeMatch(node.getOperand(), o.getOperand()));
1960    }
1961
1962    /**
1963     * Returns whether the given node and the other object match.
1964     * <p>
1965     * The default implementation provided by this class tests whether the
1966     * other object is a node of the same type with structurally isomorphic
1967     * child subtrees. Subclasses may override this method as needed.
1968     * </p>
1969     *
1970     * @param node the node
1971     * @param other the other object, or <code>null</code>
1972     * @return <code>true</code> if the subtree matches, or
1973     *   <code>false</code> if they do not match or the other object has a
1974     *   different node type or is <code>null</code>
1975     */
1976    public boolean match(PrefixExpression nodeObject other) {
1977        if (!(other instanceof PrefixExpression)) {
1978            return false;
1979        }
1980        PrefixExpression o = (PrefixExpressionother;
1981        return (
1982            node.getOperator().equals(o.getOperator())
1983                && safeSubtreeMatch(node.getOperand(), o.getOperand()));
1984    }
1985
1986    /**
1987     * Returns whether the given node and the other object match.
1988     * <p>
1989     * The default implementation provided by this class tests whether the
1990     * other object is a node of the same type with structurally isomorphic
1991     * child subtrees. Subclasses may override this method as needed.
1992     * </p>
1993     *
1994     * @param node the node
1995     * @param other the other object, or <code>null</code>
1996     * @return <code>true</code> if the subtree matches, or
1997     *   <code>false</code> if they do not match or the other object has a
1998     *   different node type or is <code>null</code>
1999     */
2000    public boolean match(PrimitiveType nodeObject other) {
2001        if (!(other instanceof PrimitiveType)) {
2002            return false;
2003        }
2004        PrimitiveType o = (PrimitiveTypeother;
2005        int level = node.getAST().apiLevel;
2006        return (level >= AST.JLS8_INTERNAL ? safeSubtreeListMatch(node.annotations(), o.annotations()) : true)
2007                && node.getPrimitiveTypeCode() == o.getPrimitiveTypeCode();
2008    }
2009
2010    /**
2011     * Returns whether the given node and the other object match.
2012     * <p>
2013     * The default implementation provided by this class tests whether the
2014     * other object is a node of the same type with structurally isomorphic
2015     * child subtrees. Subclasses may override this method as needed.
2016     * </p>
2017     *
2018     * @param node the node
2019     * @param other the other object, or <code>null</code>
2020     * @return <code>true</code> if the subtree matches, or
2021     *   <code>false</code> if they do not match or the other object has a
2022     *   different node type or is <code>null</code>
2023     * @since 3.14
2024
2025     */
2026    public boolean match(ProvidesDirective nodeObject other) {
2027        if (!(other instanceof ProvidesDirective)) {
2028            return false;
2029        }
2030        ProvidesDirective o = (ProvidesDirectiveother;
2031        return (
2032                safeSubtreeMatch(node.getName(), o.getName())
2033                && safeSubtreeListMatch(node.implementations(), o.implementations()));
2034    }
2035
2036    /**
2037     * Returns whether the given node and the other object match.
2038     * <p>
2039     * The default implementation provided by this class tests whether the
2040     * other object is a node of the same type with structurally isomorphic
2041     * child subtrees. Subclasses may override this method as needed.
2042     * </p>
2043     *
2044     * @param node the node
2045     * @param other the other object, or <code>null</code>
2046     * @return <code>true</code> if the subtree matches, or
2047     *   <code>false</code> if they do not match or the other object has a
2048     *   different node type or is <code>null</code>
2049     */
2050    public boolean match(QualifiedName nodeObject other) {
2051        if (!(other instanceof QualifiedName)) {
2052            return false;
2053        }
2054        QualifiedName o = (QualifiedNameother;
2055        return safeSubtreeMatch(node.getQualifier(), o.getQualifier())
2056                && safeSubtreeMatch(node.getName(), o.getName());
2057    }
2058
2059    /**
2060     * Returns whether the given node and the other object match.
2061     * <p>
2062     * The default implementation provided by this class tests whether the
2063     * other object is a node of the same type with structurally isomorphic
2064     * child subtrees. Subclasses may override this method as needed.
2065     * </p>
2066     *
2067     * @param node the node
2068     * @param other the other object, or <code>null</code>
2069     * @return <code>true</code> if the subtree matches, or
2070     *   <code>false</code> if they do not match or the other object has a
2071     *   different node type or is <code>null</code>
2072     * @noreference
2073     */
2074    public boolean match(ModuleQualifiedName nodeObject other) {
2075        if (!(other instanceof ModuleQualifiedName)) {
2076            return false;
2077        }
2078        ModuleQualifiedName o = (ModuleQualifiedNameother;
2079        return safeSubtreeMatch(node.getModuleQualifier(), o.getModuleQualifier())
2080                && safeSubtreeMatch(node.getName(), o.getName());
2081    }
2082
2083    /**
2084     * Returns whether the given node and the other object match.
2085     * <p>
2086     * The default implementation provided by this class tests whether the
2087     * other object is a node of the same type with structurally isomorphic
2088     * child subtrees. Subclasses may override this method as needed.
2089     * </p>
2090     *
2091     * @param node the node
2092     * @param other the other object, or <code>null</code>
2093     * @return <code>true</code> if the subtree matches, or
2094     *   <code>false</code> if they do not match or the other object has a
2095     *   different node type or is <code>null</code>
2096     * @since 3.1
2097     */
2098    public boolean match(QualifiedType nodeObject other) {
2099        if (!(other instanceof QualifiedType)) {
2100            return false;
2101        }
2102        QualifiedType o = (QualifiedTypeother;
2103        int level = node.getAST().apiLevel;
2104        return safeSubtreeMatch(node.getQualifier(), o.getQualifier())
2105                && (level >= AST.JLS8_INTERNAL ? safeSubtreeListMatch(node.annotations(), o.annotations()) : true)
2106                && safeSubtreeMatch(node.getName(), o.getName());
2107    }
2108
2109    /**
2110     * Returns whether the given node and the other object match.
2111     * <p>
2112     * The default implementation provided by this class tests whether the
2113     * other object is a node of the same type with structurally isomorphic
2114     * child subtrees. Subclasses may override this method as needed.
2115     * </p>
2116     *
2117     * @param node the node
2118     * @param other the other object, or <code>null</code>
2119     * @return <code>true</code> if the subtree matches, or
2120     *   <code>false</code> if they do not match or the other object has a
2121     *   different node type or is <code>null</code>
2122     * @since 3.22
2123     */
2124    public boolean match(RecordDeclaration nodeObject other) {
2125        if (!(other instanceof RecordDeclaration)) {
2126            return false;
2127        }
2128        RecordDeclaration o = (RecordDeclarationother;
2129        return (
2130            safeSubtreeMatch(node.getJavadoc(), o.getJavadoc())
2131                && safeSubtreeListMatch(node.modifiers(), o.modifiers())
2132                && safeSubtreeMatch(node.getName(), o.getName())
2133                && safeSubtreeListMatch(node.superInterfaceTypes(), o.superInterfaceTypes())
2134                && safeSubtreeMatch(node.typeParameters(), o.typeParameters())
2135                && safeSubtreeListMatch(node.bodyDeclarations(), o.bodyDeclarations())
2136                && safeSubtreeMatch(node.recordComponents(), o.recordComponents()));
2137    }
2138
2139    /**
2140     * Returns whether the given node and the other object match.
2141     * <p>
2142     * The default implementation provided by this class tests whether the
2143     * other object is a node of the same type with structurally isomorphic
2144     * child subtrees. Subclasses may override this method as needed.
2145     * </p>
2146     *
2147     * @param node the node
2148     * @param other the other object, or <code>null</code>
2149     * @return <code>true</code> if the subtree matches, or
2150     *   <code>false</code> if they do not match or the other object has a
2151     *   different node type or is <code>null</code>
2152     *
2153     *   @since 3.14
2154     */
2155    public boolean match(RequiresDirective nodeObject other) {
2156        if (!(other instanceof RequiresDirective)) {
2157            return false;
2158        }
2159        RequiresDirective o = (RequiresDirectiveother;
2160        return safeSubtreeListMatch(node.modifiers(), o.modifiers())
2161                && safeSubtreeMatch(node.getName(), o.getName());
2162    }
2163
2164    /**
2165     * Returns whether the given node and the other object match.
2166     * <p>
2167     * The default implementation provided by this class tests whether the
2168     * other object is a node of the same type with structurally isomorphic
2169     * child subtrees. Subclasses may override this method as needed.
2170     * </p>
2171     *
2172     * @param node the node
2173     * @param other the other object, or <code>null</code>
2174     * @return <code>true</code> if the subtree matches, or
2175     *   <code>false</code> if they do not match or the other object has a
2176     *   different node type or is <code>null</code>
2177     */
2178    public boolean match(ReturnStatement nodeObject other) {
2179        if (!(other instanceof ReturnStatement)) {
2180            return false;
2181        }
2182        ReturnStatement o = (ReturnStatementother;
2183        return safeSubtreeMatch(node.getExpression(), o.getExpression());
2184    }
2185
2186    /**
2187     * Returns whether the given node and the other object match.
2188     * <p>
2189     * The default implementation provided by this class tests whether the
2190     * other object is a node of the same type with structurally isomorphic
2191     * child subtrees. Subclasses may override this method as needed.
2192     * </p>
2193     *
2194     * @param node the node
2195     * @param other the other object, or <code>null</code>
2196     * @return <code>true</code> if the subtree matches, or
2197     *   <code>false</code> if they do not match or the other object has a
2198     *   different node type or is <code>null</code>
2199     */
2200    public boolean match(SimpleName nodeObject other) {
2201        if (!(other instanceof SimpleName)) {
2202            return false;
2203        }
2204        SimpleName o = (SimpleNameother;
2205        return node.getIdentifier().equals(o.getIdentifier());
2206    }
2207
2208    /**
2209     * Returns whether the given node and the other object match.
2210     * <p>
2211     * The default implementation provided by this class tests whether the
2212     * other object is a node of the same type with structurally isomorphic
2213     * child subtrees. Subclasses may override this method as needed.
2214     * </p>
2215     *
2216     * @param node the node
2217     * @param other the other object, or <code>null</code>
2218     * @return <code>true</code> if the subtree matches, or
2219     *   <code>false</code> if they do not match or the other object has a
2220     *   different node type or is <code>null</code>
2221     */
2222    public boolean match(SimpleType nodeObject other) {
2223        if (!(other instanceof SimpleType)) {
2224            return false;
2225        }
2226        SimpleType o = (SimpleTypeother;
2227        int level = node.getAST().apiLevel;
2228        return (level >= AST.JLS8_INTERNAL ? safeSubtreeListMatch(node.annotations(), o.annotations()) : true)
2229                && safeSubtreeMatch(node.getName(), o.getName());
2230    }
2231
2232    /**
2233     * Returns whether the given node and the other object match.
2234     * <p>
2235     * The default implementation provided by this class tests whether the
2236     * other object is a node of the same type with structurally isomorphic
2237     * child subtrees. Subclasses may override this method as needed.
2238     * </p>
2239     *
2240     * @param node the node
2241     * @param other the other object, or <code>null</code>
2242     * @return <code>true</code> if the subtree matches, or
2243     *   <code>false</code> if they do not match or the other object has a
2244     *   different node type or is <code>null</code>
2245     * @since 3.1
2246     */
2247    public boolean match(SingleMemberAnnotation nodeObject other) {
2248        if (!(other instanceof SingleMemberAnnotation)) {
2249            return false;
2250        }
2251        SingleMemberAnnotation o = (SingleMemberAnnotationother;
2252        return (safeSubtreeMatch(node.getTypeName(), o.getTypeName())
2253                && safeSubtreeMatch(node.getValue(), o.getValue()));
2254    }
2255
2256    /**
2257     * Returns whether the given node and the other object match.
2258     * <p>
2259     * The default implementation provided by this class tests whether the
2260     * other object is a node of the same type with structurally isomorphic
2261     * child subtrees. Subclasses may override this method as needed.
2262     * </p>
2263     * <p>
2264     * Note that extra array dimensions and the variable arity flag
2265     * are compared since they are both important parts of the declaration.
2266     * </p>
2267     *
2268     * @param node the node
2269     * @param other the other object, or <code>null</code>
2270     * @return <code>true</code> if the subtree matches, or
2271     *   <code>false</code> if they do not match or the other object has a
2272     *   different node type or is <code>null</code>
2273     */
2274    public boolean match(SingleVariableDeclaration nodeObject other) {
2275        if (!(other instanceof SingleVariableDeclaration)) {
2276            return false;
2277        }
2278        SingleVariableDeclaration o = (SingleVariableDeclarationother;
2279        int level = node.getAST().apiLevel;
2280        return (level >= AST.JLS3_INTERNAL
2281                        ? safeSubtreeListMatch(node.modifiers(), o.modifiers())
2282                        : node.getModifiers() == o.getModifiers())
2283                && safeSubtreeMatch(node.getType(), o.getType())
2284                && (level >= AST.JLS8_INTERNAL && node.isVarargs()
2285                        ? safeSubtreeListMatch(node.varargsAnnotations(), o.varargsAnnotations())
2286                        : true)
2287                && (level >= AST.JLS3_INTERNAL
2288                        ? node.isVarargs() == o.isVarargs()
2289                        : true)
2290                && safeSubtreeMatch(node.getName(), o.getName())
2291                && ((level >= AST.JLS8_INTERNAL)
2292                        ? safeSubtreeListMatch(node.extraDimensions(), o.extraDimensions())
2293                        : node.getExtraDimensions() == o.getExtraDimensions())
2294                && safeSubtreeMatch(node.getInitializer(), o.getInitializer());
2295    }
2296
2297    /**
2298     * Returns whether the given node and the other object match.
2299     * <p>
2300     * The default implementation provided by this class tests whether the
2301     * other object is a node of the same type with structurally isomorphic
2302     * child subtrees. Subclasses may override this method as needed.
2303     * </p>
2304     *
2305     * @param node the node
2306     * @param other the other object, or <code>null</code>
2307     * @return <code>true</code> if the subtree matches, or
2308     *   <code>false</code> if they do not match or the other object has a
2309     *   different node type or is <code>null</code>
2310     */
2311    public boolean match(StringLiteral nodeObject other) {
2312        if (!(other instanceof StringLiteral)) {
2313            return false;
2314        }
2315        StringLiteral o = (StringLiteralother;
2316        return safeEquals(node.getEscapedValue(), o.getEscapedValue());
2317    }
2318
2319    /**
2320     * Returns whether the given node and the other object match.
2321     * <p>
2322     * The default implementation provided by this class tests whether the
2323     * other object is a node of the same type with structurally isomorphic
2324     * child subtrees. Subclasses may override this method as needed.
2325     * </p>
2326     *
2327     * @param node the node
2328     * @param other the other object, or <code>null</code>
2329     * @return <code>true</code> if the subtree matches, or
2330     *   <code>false</code> if they do not match or the other object has a
2331     *   different node type or is <code>null</code>
2332     */
2333    public boolean match(SuperConstructorInvocation nodeObject other) {
2334        if (!(other instanceof SuperConstructorInvocation)) {
2335            return false;
2336        }
2337        SuperConstructorInvocation o = (SuperConstructorInvocationother;
2338        if (node.getAST().apiLevel >= AST.JLS3_INTERNAL) {
2339            if (!safeSubtreeListMatch(node.typeArguments(), o.typeArguments())) {
2340                return false;
2341            }
2342        }
2343        return (
2344            safeSubtreeMatch(node.getExpression(), o.getExpression())
2345                && safeSubtreeListMatch(node.arguments(), o.arguments()));
2346    }
2347
2348    /**
2349     * Returns whether the given node and the other object match.
2350     * <p>
2351     * The default implementation provided by this class tests whether the
2352     * other object is a node of the same type with structurally isomorphic
2353     * child subtrees. Subclasses may override this method as needed.
2354     * </p>
2355     *
2356     * @param node the node
2357     * @param other the other object, or <code>null</code>
2358     * @return <code>true</code> if the subtree matches, or
2359     *   <code>false</code> if they do not match or the other object has a
2360     *   different node type or is <code>null</code>
2361     */
2362    public boolean match(SuperFieldAccess nodeObject other) {
2363        if (!(other instanceof SuperFieldAccess)) {
2364            return false;
2365        }
2366        SuperFieldAccess o = (SuperFieldAccessother;
2367        return (
2368            safeSubtreeMatch(node.getName(), o.getName())
2369                && safeSubtreeMatch(node.getQualifier(), o.getQualifier()));
2370    }
2371
2372    /**
2373     * Returns whether the given node and the other object match.
2374     * <p>
2375     * The default implementation provided by this class tests whether the
2376     * other object is a node of the same type with structurally isomorphic
2377     * child subtrees. Subclasses may override this method as needed.
2378     * </p>
2379     *
2380     * @param node the node
2381     * @param other the other object, or <code>null</code>
2382     * @return <code>true</code> if the subtree matches, or
2383     *   <code>false</code> if they do not match or the other object has a
2384     *   different node type or is <code>null</code>
2385     */
2386    public boolean match(SuperMethodInvocation nodeObject other) {
2387        if (!(other instanceof SuperMethodInvocation)) {
2388            return false;
2389        }
2390        SuperMethodInvocation o = (SuperMethodInvocationother;
2391        if (node.getAST().apiLevel >= AST.JLS3_INTERNAL) {
2392            if (!safeSubtreeListMatch(node.typeArguments(), o.typeArguments())) {
2393                return false;
2394            }
2395        }
2396        return (
2397            safeSubtreeMatch(node.getQualifier(), o.getQualifier())
2398                && safeSubtreeMatch(node.getName(), o.getName())
2399                && safeSubtreeListMatch(node.arguments(), o.arguments()));
2400    }
2401
2402    /**
2403     * Returns whether the given node and the other object match.
2404     * <p>
2405     * The default implementation provided by this class tests whether the
2406     * other object is a node of the same type with structurally isomorphic
2407     * child subtrees. Subclasses may override this method as needed.
2408     * </p>
2409     *
2410     * @param node the node
2411     * @param other the other object, or <code>null</code>
2412     * @return <code>true</code> if the subtree matches, or
2413     *   <code>false</code> if they do not match or the other object has a
2414     *   different node type or is <code>null</code>
2415     *
2416     *   @since 3.10
2417     */
2418    public boolean match(SuperMethodReference nodeObject other) {
2419        if (!(other instanceof SuperMethodReference)) {
2420            return false;
2421        }
2422        SuperMethodReference o = (SuperMethodReferenceother;
2423        return (safeSubtreeMatch(node.getQualifier(), o.getQualifier())
2424                && safeSubtreeListMatch(node.typeArguments(), o.typeArguments())
2425                && safeSubtreeMatch(node.getName(), o.getName()));
2426    }
2427
2428    /**
2429     * Returns whether the given node and the other object match.
2430     * <p>
2431     * The default implementation provided by this class tests whether the
2432     * other object is a node of the same type with structurally isomorphic
2433     * child subtrees. Subclasses may override this method as needed.
2434     * </p>
2435     *
2436     * @param node the node
2437     * @param other the other object, or <code>null</code>
2438     * @return <code>true</code> if the subtree matches, or
2439     *   <code>false</code> if they do not match or the other object has a
2440     *   different node type or is <code>null</code>
2441     */
2442    public boolean match(SwitchCase nodeObject other) {
2443        if (!(other instanceof SwitchCase)) {
2444            return false;
2445        }
2446        SwitchCase o = (SwitchCaseother;
2447        return ( node.getAST().apiLevel >= AST.JLS14_INTERNAL
2448                ? safeSubtreeListMatch(node.expressions(), o.expressions())
2449                        : compareDeprecatedSwitchExpression(nodeo));
2450    }
2451
2452    /**
2453     * Return whether the deprecated comment strings of the given java doc are equals.
2454     * <p>
2455     * Note the only purpose of this method is to hide deprecated warnings.
2456     * @deprecated mark deprecated to hide deprecated usage
2457     */
2458    private boolean compareDeprecatedSwitchExpression(SwitchCase firstSwitchCase second) {
2459        return safeSubtreeMatch(first.getExpression(), second.getExpression());
2460    }
2461
2462    /**
2463     * Returns whether the given node and the other object match.
2464     * <p>
2465     * The default implementation provided by this class tests whether the
2466     * other object is a node of the same type with structurally isomorphic
2467     * child subtrees. Subclasses may override this method as needed.
2468     * </p>
2469     *
2470     * @param node the node
2471     * @param other the other object, or <code>null</code>
2472     * @return <code>true</code> if the subtree matches, or
2473     *   <code>false</code> if they do not match or the other object has a
2474     *   different node type or is <code>null</code>
2475     * @since 3.18
2476     */
2477    public boolean match(SwitchExpression nodeObject other) {
2478        if (!(other instanceof SwitchExpression)) {
2479            return false;
2480        }
2481        SwitchExpression o = (SwitchExpressionother;
2482        return    safeSubtreeMatch(node.getExpression(), o.getExpression())
2483                && safeSubtreeListMatch(node.statements(), o.statements());
2484    }
2485
2486    /**
2487     * Returns whether the given node and the other object match.
2488     * <p>
2489     * The default implementation provided by this class tests whether the
2490     * other object is a node of the same type with structurally isomorphic
2491     * child subtrees. Subclasses may override this method as needed.
2492     * </p>
2493     *
2494     * @param node the node
2495     * @param other the other object, or <code>null</code>
2496     * @return <code>true</code> if the subtree matches, or
2497     *   <code>false</code> if they do not match or the other object has a
2498     *   different node type or is <code>null</code>
2499     */
2500    public boolean match(SwitchStatement nodeObject other) {
2501        if (!(other instanceof SwitchStatement)) {
2502            return false;
2503        }
2504        SwitchStatement o = (SwitchStatementother;
2505        return (
2506            safeSubtreeMatch(node.getExpression(), o.getExpression())
2507                && safeSubtreeListMatch(node.statements(), o.statements()));
2508    }
2509
2510    /**
2511     * Returns whether the given node and the other object match.
2512     * <p>
2513     * The default implementation provided by this class tests whether the
2514     * other object is a node of the same type with structurally isomorphic
2515     * child subtrees. Subclasses may override this method as needed.
2516     * </p>
2517     *
2518     * @param node the node
2519     * @param other the other object, or <code>null</code>
2520     * @return <code>true</code> if the subtree matches, or
2521     *   <code>false</code> if they do not match or the other object has a
2522     *   different node type or is <code>null</code>
2523     */
2524    public boolean match(SynchronizedStatement nodeObject other) {
2525        if (!(other instanceof SynchronizedStatement)) {
2526            return false;
2527        }
2528        SynchronizedStatement o = (SynchronizedStatementother;
2529        return (
2530            safeSubtreeMatch(node.getExpression(), o.getExpression())
2531                && safeSubtreeMatch(node.getBody(), o.getBody()));
2532    }
2533
2534    /**
2535     * Returns whether the given node and the other object match.
2536     * <p>
2537     * The default implementation provided by this class tests whether the
2538     * other object is a node of the same type with structurally isomorphic
2539     * child subtrees. Subclasses may override this method as needed.
2540     * </p>
2541     *
2542     * @param node the node
2543     * @param other the other object, or <code>null</code>
2544     * @return <code>true</code> if the subtree matches, or
2545     *   <code>false</code> if they do not match or the other object has a
2546     *   different node type or is <code>null</code>
2547     * @since 3.0
2548     */
2549    public boolean match(TagElement nodeObject other) {
2550        if (!(other instanceof TagElement)) {
2551            return false;
2552        }
2553        TagElement o = (TagElementother;
2554        return (
2555                safeEquals(node.getTagName(), o.getTagName())
2556                && safeSubtreeListMatch(node.fragments(), o.fragments())
2557                && (DOMASTUtil.isJavaDocCodeSnippetSupported(node.getAST().apiLevel)? safeSubtreeListMatch(node.tagProperties(), o.tagProperties()) : true));
2558    }
2559
2560    /**
2561     * Returns whether the given node and the other object match.
2562     * <p>
2563     * The default implementation provided by this class tests whether the
2564     * other object is a node of the same type with structurally isomorphic
2565     * child subtrees. Subclasses may override this method as needed.
2566     * </p>
2567     *
2568     * @param node the node
2569     * @param other the other object, or <code>null</code>
2570     * @return <code>true</code> if the subtree matches, or
2571     *   <code>false</code> if they do not match or the other object has a
2572     *   different node type or is <code>null</code>
2573     * @since 3.30
2574     */
2575    public boolean match(TagProperty nodeObject other) {
2576        if (!(other instanceof TagProperty)) {
2577            return false;
2578        }
2579        TagProperty o = (TagPropertyother;
2580        return (
2581                safeEquals(node.getName(), o.getName())
2582                && safeEquals(node.getStringValue(), o.getStringValue()))
2583                && safeSubtreeMatch(node.getNodeValue(), o.getNodeValue());
2584    }
2585
2586    /**
2587     * Returns whether the given node and the other object match.
2588     * <p>
2589     * The default implementation provided by this class tests whether the
2590     * other object is a node of the same type with structurally isomorphic
2591     * child subtrees. Subclasses may override this method as needed.
2592     * </p>
2593     *
2594     * @param node the node
2595     * @param other the other object, or <code>null</code>
2596     * @return <code>true</code> if the subtree matches, or
2597     *   <code>false</code> if they do not match or the other object has a
2598     *   different node type or is <code>null</code>
2599     * @noreference This method is not intended to be referenced by clients as it is a part of Java preview feature.
2600     * @nooverride This method is not intended to be re-implemented or extended by clients as it is a part of Java preview feature.
2601     * @since 3.20
2602     */
2603    public boolean match(TextBlock nodeObject other) {
2604        if (!(other instanceof TextBlock)) {
2605            return false;
2606        }
2607        TextBlock o = (TextBlockother;
2608        return safeEquals(node.getEscapedValue(), o.getEscapedValue());
2609    }
2610
2611    /**
2612     * Returns whether the given node and the other object match.
2613     * <p>
2614     * The default implementation provided by this class tests whether the
2615     * other object is a node of the same type with structurally isomorphic
2616     * child subtrees. Subclasses may override this method as needed.
2617     * </p>
2618     *
2619     * @param node the node
2620     * @param other the other object, or <code>null</code>
2621     * @return <code>true</code> if the subtree matches, or
2622     *   <code>false</code> if they do not match or the other object has a
2623     *   different node type or is <code>null</code>
2624     * @since 3.0
2625     */
2626    public boolean match(TextElement nodeObject other) {
2627        if (!(other instanceof TextElement)) {
2628            return false;
2629        }
2630        TextElement o = (TextElementother;
2631        return safeEquals(node.getText(), o.getText());
2632    }
2633
2634    /**
2635     * Returns whether the given node and the other object match.
2636     * <p>
2637     * The default implementation provided by this class tests whether the
2638     * other object is a node of the same type with structurally isomorphic
2639     * child subtrees. Subclasses may override this method as needed.
2640     * </p>
2641     *
2642     * @param node the node
2643     * @param other the other object, or <code>null</code>
2644     * @return <code>true</code> if the subtree matches, or
2645     *   <code>false</code> if they do not match or the other object has a
2646     *   different node type or is <code>null</code>
2647     */
2648    public boolean match(ThisExpression nodeObject other) {
2649        if (!(other instanceof ThisExpression)) {
2650            return false;
2651        }
2652        ThisExpression o = (ThisExpressionother;
2653        return safeSubtreeMatch(node.getQualifier(), o.getQualifier());
2654    }
2655
2656    /**
2657     * Returns whether the given node and the other object match.
2658     * <p>
2659     * The default implementation provided by this class tests whether the
2660     * other object is a node of the same type with structurally isomorphic
2661     * child subtrees. Subclasses may override this method as needed.
2662     * </p>
2663     *
2664     * @param node the node
2665     * @param other the other object, or <code>null</code>
2666     * @return <code>true</code> if the subtree matches, or
2667     *   <code>false</code> if they do not match or the other object has a
2668     *   different node type or is <code>null</code>
2669     */
2670    public boolean match(ThrowStatement nodeObject other) {
2671        if (!(other instanceof ThrowStatement)) {
2672            return false;
2673        }
2674        ThrowStatement o = (ThrowStatementother;
2675        return safeSubtreeMatch(node.getExpression(), o.getExpression());
2676    }
2677
2678    /**
2679     * Returns whether the given node and the other object match.
2680     * <p>
2681     * The default implementation provided by this class tests whether the
2682     * other object is a node of the same type with structurally isomorphic
2683     * child subtrees. Subclasses may override this method as needed.
2684     * </p>
2685     *
2686     * @param node the node
2687     * @param other the other object, or <code>null</code>
2688     * @return <code>true</code> if the subtree matches, or
2689     *   <code>false</code> if they do not match or the other object has a
2690     *   different node type or is <code>null</code>
2691     */
2692    public boolean match(TryStatement nodeObject other) {
2693        if (!(other instanceof TryStatement)) {
2694            return false;
2695        }
2696        TryStatement o = (TryStatementother;
2697        int level = node.getAST().apiLevel;
2698        return (level >= AST.JLS4_INTERNAL ? safeSubtreeListMatch(node.resources(), o.resources()) : true)
2699                && safeSubtreeMatch(node.getBody(), o.getBody())
2700                && safeSubtreeListMatch(node.catchClauses(), o.catchClauses())
2701                && safeSubtreeMatch(node.getFinally(), o.getFinally());
2702    }
2703
2704    /**
2705     * Returns whether the given node and the other object match.
2706     * <p>
2707     * The default implementation provided by this class tests whether the
2708     * other object is a node of the same type with structurally isomorphic
2709     * child subtrees. Subclasses may override this method as needed.
2710     * </p>
2711     *
2712     * @param node the node
2713     * @param other the other object, or <code>null</code>
2714     * @return <code>true</code> if the subtree matches, or
2715     *   <code>false</code> if they do not match or the other object has a
2716     *   different node type or is <code>null</code>
2717     */
2718    public boolean match(TypeDeclaration nodeObject other) {
2719        if (!(other instanceof TypeDeclaration)) {
2720            return false;
2721        }
2722        TypeDeclaration o = (TypeDeclarationother;
2723        int level = node.getAST().apiLevel;
2724        if (level == AST.JLS2_INTERNAL) {
2725            if (node.getModifiers() != o.getModifiers()) {
2726                return false;
2727            }
2728            if (!safeSubtreeMatch(node.internalGetSuperclass(), o.internalGetSuperclass())) {
2729                return false;
2730            }
2731            if (!safeSubtreeListMatch(node.internalSuperInterfaces(), o.internalSuperInterfaces())) {
2732                return false;
2733            }
2734        }
2735        if (level >= AST.JLS3_INTERNAL) {
2736            if (!safeSubtreeListMatch(node.modifiers(), o.modifiers())) {
2737                return false;
2738            }
2739            if (!safeSubtreeListMatch(node.typeParameters(), o.typeParameters())) {
2740                return false;
2741            }
2742            if (!safeSubtreeMatch(node.getSuperclassType(), o.getSuperclassType())) {
2743                return false;
2744            }
2745            if (!safeSubtreeListMatch(node.superInterfaceTypes(), o.superInterfaceTypes())) {
2746                return false;
2747            }
2748        }
2749        if (DOMASTUtil.isFeatureSupportedinAST(node.getAST(), Modifier.SEALED)) {
2750            if (!safeSubtreeListMatch(node.permittedTypes(), o.permittedTypes())) {
2751                return false;
2752            }
2753        }
2754        return (
2755                (node.isInterface() == o.isInterface())
2756                && safeSubtreeMatch(node.getJavadoc(), o.getJavadoc())
2757                && safeSubtreeMatch(node.getName(), o.getName())
2758                && safeSubtreeListMatch(node.bodyDeclarations(), o.bodyDeclarations()));
2759    }
2760
2761    /**
2762     * Returns whether the given node and the other object match.
2763     * <p>
2764     * The default implementation provided by this class tests whether the
2765     * other object is a node of the same type with structurally isomorphic
2766     * child subtrees. Subclasses may override this method as needed.
2767     * </p>
2768     *
2769     * @param node the node
2770     * @param other the other object, or <code>null</code>
2771     * @return <code>true</code> if the subtree matches, or
2772     *   <code>false</code> if they do not match or the other object has a
2773     *   different node type or is <code>null</code>
2774     */
2775    public boolean match(TypeDeclarationStatement nodeObject other) {
2776        if (!(other instanceof TypeDeclarationStatement)) {
2777            return false;
2778        }
2779        TypeDeclarationStatement o = (TypeDeclarationStatementother;
2780        return safeSubtreeMatch(node.getDeclaration(), o.getDeclaration());
2781    }
2782
2783    /**
2784     * Returns whether the given node and the other object match.
2785     * <p>
2786     * The default implementation provided by this class tests whether the
2787     * other object is a node of the same type with structurally isomorphic
2788     * child subtrees. Subclasses may override this method as needed.
2789     * </p>
2790     *
2791     * @param node the node
2792     * @param other the other object, or <code>null</code>
2793     * @return <code>true</code> if the subtree matches, or
2794     *   <code>false</code> if they do not match or the other object has a
2795     *   different node type or is <code>null</code>
2796     */
2797    public boolean match(TypeLiteral nodeObject other) {
2798        if (!(other instanceof TypeLiteral)) {
2799            return false;
2800        }
2801        TypeLiteral o = (TypeLiteralother;
2802        return safeSubtreeMatch(node.getType(), o.getType());
2803    }
2804
2805    /**
2806     * Returns whether the given node and the other object match.
2807     * <p>
2808     * The default implementation provided by this class tests whether the
2809     * other object is a node of the same type with structurally isomorphic
2810     * child subtrees. Subclasses may override this method as needed.
2811     * </p>
2812     *
2813     * @param node the node
2814     * @param other the other object, or <code>null</code>
2815     * @return <code>true</code> if the subtree matches, or
2816     *   <code>false</code> if they do not match or the other object has a
2817     *   different node type or is <code>null</code>
2818     * @since 3.10
2819     */
2820    public boolean match(TypeMethodReference nodeObject other) {
2821        if (!(other instanceof TypeMethodReference)) {
2822            return false;
2823        }
2824        TypeMethodReference o = (TypeMethodReferenceother;
2825        return (
2826            safeSubtreeMatch(node.getType(), o.getType())
2827                && safeSubtreeListMatch(node.typeArguments(), o.typeArguments())
2828                && safeSubtreeMatch(node.getName(), o.getName()));
2829    }
2830
2831    /**
2832     * Returns whether the given node and the other object match.
2833     * <p>
2834     * The default implementation provided by this class tests whether the
2835     * other object is a node of the same type with structurally isomorphic
2836     * child subtrees. Subclasses may override this method as needed.
2837     * </p>
2838     *
2839     * @param node the node
2840     * @param other the other object, or <code>null</code>
2841     * @return <code>true</code> if the subtree matches, or
2842     *   <code>false</code> if they do not match or the other object has a
2843     *   different node type or is <code>null</code>
2844     * @since 3.1
2845     */
2846    public boolean match(TypeParameter nodeObject other) {
2847        if (!(other instanceof TypeParameter)) {
2848            return false;
2849        }
2850        TypeParameter o = (TypeParameterother;
2851        int level = node.getAST().apiLevel;
2852        return (level >= AST.JLS8_INTERNAL ? safeSubtreeListMatch(node.modifiers(), o.modifiers()) : true)
2853                && safeSubtreeMatch(node.getName(), o.getName())
2854                && safeSubtreeListMatch(node.typeBounds(), o.typeBounds());
2855    }
2856
2857    /**
2858     * Returns whether the given node and the other object match.
2859     * <p>
2860     * The default implementation provided by this class tests whether the
2861     * other object is a node of the same type with structurally isomorphic
2862     * child subtrees. Subclasses may override this method as needed.
2863     * </p>
2864     *
2865     * @param node the node
2866     * @param other the other object, or <code>null</code>
2867     * @return <code>true</code> if the subtree matches, or
2868     *   <code>false</code> if they do not match or the other object has a
2869     *   different node type or is <code>null</code>
2870     * @since 3.28
2871     */
2872    public boolean match(TypePattern nodeObject other) {
2873        if (!(other instanceof TypePattern)) {
2874            return false;
2875        }
2876        TypePattern o = (TypePatternother;
2877        return safeSubtreeMatch(node.getPatternVariable(), o.getPatternVariable());
2878    }
2879
2880    /**
2881     * Returns whether the given node and the other object match.
2882     * <p>
2883     * The default implementation provided by this class tests whether the
2884     * other object is a node of the same type with structurally isomorphic
2885     * child subtrees. Subclasses may override this method as needed.
2886     * </p>
2887     *
2888     * @param node the node
2889     * @param other the other object, or <code>null</code>
2890     * @return <code>true</code> if the subtree matches, or
2891     *   <code>false</code> if they do not match or the other object has a
2892     *   different node type or is <code>null</code>
2893     * @since 3.7.1
2894     */
2895    public boolean match(UnionType nodeObject other) {
2896        if (!(other instanceof UnionType)) {
2897            return false;
2898        }
2899        UnionType o = (UnionTypeother;
2900        return safeSubtreeListMatch(node.types(),    o.types());
2901    }
2902
2903    /**
2904     * Returns whether the given node and the other object match.
2905     * <p>
2906     * The default implementation provided by this class tests whether the
2907     * other object is a node of the same type with structurally isomorphic
2908     * child subtrees. Subclasses may override this method as needed.
2909     * </p>
2910     *
2911     * @param node the node
2912     * @param other the other object, or <code>null</code>
2913     * @return <code>true</code> if the subtree matches, or
2914     *   <code>false</code> if they do not match or the other object has a
2915     *   different node type or is <code>null</code>
2916     * @since 3.14
2917     */
2918    public boolean match(UsesDirective nodeObject other) {
2919        if (!(other instanceof UsesDirective)) {
2920            return false;
2921        }
2922        UsesDirective o = (UsesDirectiveother;
2923        return safeSubtreeMatch(node.getName(), o.getName());
2924    }
2925
2926    /**
2927     * Returns whether the given node and the other object match.
2928     * <p>
2929     * The default implementation provided by this class tests whether the
2930     * other object is a node of the same type with structurally isomorphic
2931     * child subtrees. Subclasses may override this method as needed.
2932     * </p>
2933     *
2934     * @param node the node
2935     * @param other the other object, or <code>null</code>
2936     * @return <code>true</code> if the subtree matches, or
2937     *   <code>false</code> if they do not match or the other object has a
2938     *   different node type or is <code>null</code>
2939     */
2940    public boolean match(VariableDeclarationExpression nodeObject other) {
2941        if (!(other instanceof VariableDeclarationExpression)) {
2942            return false;
2943        }
2944        VariableDeclarationExpression o = (VariableDeclarationExpressionother;
2945        int level = node.getAST().apiLevel;
2946        if (level == AST.JLS2_INTERNAL) {
2947            if (node.getModifiers() != o.getModifiers()) {
2948                return false;
2949            }
2950        }
2951        if (level >= AST.JLS3_INTERNAL) {
2952            if (!safeSubtreeListMatch(node.modifiers(), o.modifiers())) {
2953                return false;
2954            }
2955        }
2956        return safeSubtreeMatch(node.getType(), o.getType())
2957            && safeSubtreeListMatch(node.fragments(), o.fragments());
2958    }
2959
2960    /**
2961     * Returns whether the given node and the other object match.
2962     * <p>
2963     * The default implementation provided by this class tests whether the
2964     * other object is a node of the same type with structurally isomorphic
2965     * child subtrees. Subclasses may override this method as needed.
2966     * </p>
2967     * <p>
2968     * Note that extra array dimensions are compared since they are an
2969     * important part of the type of the variable.
2970     * </p>
2971     *
2972     * @param node the node
2973     * @param other the other object, or <code>null</code>
2974     * @return <code>true</code> if the subtree matches, or
2975     *   <code>false</code> if they do not match or the other object has a
2976     *   different node type or is <code>null</code>
2977     */
2978    public boolean match(VariableDeclarationFragment nodeObject other) {
2979        if (!(other instanceof VariableDeclarationFragment)) {
2980            return false;
2981        }
2982        VariableDeclarationFragment o = (VariableDeclarationFragmentother;
2983        int level = node.getAST().apiLevel;
2984        return safeSubtreeMatch(node.getName(), o.getName())
2985                && (level >= AST.JLS8_INTERNAL
2986                        ? safeSubtreeListMatch(node.extraDimensions(), o.extraDimensions())
2987                        : node.getExtraDimensions() == o.getExtraDimensions())
2988                && safeSubtreeMatch(node.getInitializer(), o.getInitializer());
2989    }
2990
2991    /**
2992     * Returns whether the given node and the other object match.
2993     * <p>
2994     * The default implementation provided by this class tests whether the
2995     * other object is a node of the same type with structurally isomorphic
2996     * child subtrees. Subclasses may override this method as needed.
2997     * </p>
2998     *
2999     * @param node the node
3000     * @param other the other object, or <code>null</code>
3001     * @return <code>true</code> if the subtree matches, or
3002     *   <code>false</code> if they do not match or the other object has a
3003     *   different node type or is <code>null</code>
3004     */
3005    public boolean match(VariableDeclarationStatement nodeObject other) {
3006        if (!(other instanceof VariableDeclarationStatement)) {
3007            return false;
3008        }
3009        VariableDeclarationStatement o = (VariableDeclarationStatementother;
3010        int level = node.getAST().apiLevel;
3011        if (level == AST.JLS2_INTERNAL) {
3012            if (node.getModifiers() != o.getModifiers()) {
3013                return false;
3014            }
3015        }
3016        if (level >= AST.JLS3_INTERNAL) {
3017            if (!safeSubtreeListMatch(node.modifiers(), o.modifiers())) {
3018                return false;
3019            }
3020        }
3021        return safeSubtreeMatch(node.getType(), o.getType())
3022            && safeSubtreeListMatch(node.fragments(), o.fragments());
3023    }
3024
3025    /**
3026     * Returns whether the given node and the other object match.
3027     * <p>
3028     * The default implementation provided by this class tests whether the
3029     * other object is a node of the same type with structurally isomorphic
3030     * child subtrees. Subclasses may override this method as needed.
3031     * </p>
3032     *
3033     * @param node the node
3034     * @param other the other object, or <code>null</code>
3035     * @return <code>true</code> if the subtree matches, or
3036     *   <code>false</code> if they do not match or the other object has a
3037     *   different node type or is <code>null</code>
3038     */
3039    public boolean match(WhileStatement nodeObject other) {
3040        if (!(other instanceof WhileStatement)) {
3041            return false;
3042        }
3043        WhileStatement o = (WhileStatementother;
3044        return (
3045            safeSubtreeMatch(node.getExpression(), o.getExpression())
3046                && safeSubtreeMatch(node.getBody(), o.getBody()));
3047    }
3048
3049    /**
3050     * Returns whether the given node and the other object match.
3051     * <p>
3052     * The default implementation provided by this class tests whether the
3053     * other object is a node of the same type with structurally isomorphic
3054     * child subtrees. Subclasses may override this method as needed.
3055     * </p>
3056     *
3057     * @param node the node
3058     * @param other the other object, or <code>null</code>
3059     * @return <code>true</code> if the subtree matches, or
3060     *   <code>false</code> if they do not match or the other object has a
3061     *   different node type or is <code>null</code>
3062     * @since 3.1
3063     */
3064    public boolean match(WildcardType nodeObject other) {
3065        if (!(other instanceof WildcardType)) {
3066            return false;
3067        }
3068        WildcardType o = (WildcardTypeother;
3069        int level = node.getAST().apiLevel;
3070        return (level >= AST.JLS8_INTERNAL ? safeSubtreeListMatch(node.annotations(), o.annotations()) : true)
3071                && node.isUpperBound() == o.isUpperBound()
3072                && safeSubtreeMatch(node.getBound(), o.getBound());
3073    }
3074
3075    /**
3076     * Returns whether the given node and the other object match.
3077     * <p>
3078     * The default implementation provided by this class tests whether the
3079     * other object is a node of the same type with structurally isomorphic
3080     * child subtrees. Subclasses may override this method as needed.
3081     * </p>
3082     *
3083     * @param node the node
3084     * @param other the other object, or <code>null</code>
3085     * @return <code>true</code> if the subtree matches, or
3086     *   <code>false</code> if they do not match or the other object has a
3087     *   different node type or is <code>null</code>
3088     * @noreference This method is not intended to be referenced by clients as it is a part of Java preview feature.
3089     * @nooverride This method is not intended to be re-implemented or extended by clients as it is a part of Java preview feature.
3090     * @since 3.20
3091     */
3092    public boolean match(YieldStatement nodeObject other) {
3093        if (!(other instanceof YieldStatement)) {
3094            return false;
3095        }
3096        YieldStatement o = (YieldStatementother;
3097        return    safeSubtreeMatch(node.getExpression(), o.getExpression());
3098    }
3099
3100}
3101
MembersX
ASTMatcher:matchDocTags
ASTMatcher:ASTMatcher
ASTMatcher:safeSubtreeListMatch
ASTMatcher:safeSubtreeListMatch:Block:size2
ASTMatcher:compareDeprecatedSwitchExpression
ASTMatcher:safeSubtreeListMatch:Block:size1
ASTMatcher:safeSubtreeListMatch:Block:Block:n2
ASTMatcher:safeSubtreeMatch
ASTMatcher:safeSubtreeListMatch:Block:Block:n1
ASTMatcher:componentType
ASTMatcher:compareDeprecatedComment
ASTMatcher:safeEquals
ASTMatcher:match:Block:o
ASTMatcher:match:Block:level
ASTMatcher:match
Members
X