1 /*******************************************************************************
2 * Copyright (c) 2000, 2007 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package net.sourceforge.phpdt.core.dom;
13 import java.util.Iterator;
14 import java.util.List;
17 * Concrete superclass and default implementation of an AST subtree matcher.
19 * For example, to compute whether two ASTs subtrees are structurally
20 * isomorphic, use <code>n1.subtreeMatch(new ASTMatcher(), n2)</code> where
21 * <code>n1</code> and <code>n2</code> are the AST root nodes of the subtrees.
24 * For each different concrete AST node type <i>T</i> there is a
25 * <code>public boolean match(<i>T</i> node, Object other)</code> method
26 * that matches the given node against another object (typically another
27 * AST node, although this is not essential). The default implementations
28 * provided by this class tests whether the other object is a node of the
29 * same type with structurally isomorphic child subtrees. For nodes with
30 * list-valued properties, the child nodes within the list are compared in
31 * order. For nodes with multiple properties, the child nodes are compared
32 * in the order that most closely corresponds to the lexical reading order
33 * of the source program. For instance, for a type declaration node, the
34 * child ordering is: name, superclass, superinterfaces, and body
38 * Subclasses may override (extend or reimplement) some or all of the
39 * <code>match</code> methods in order to define more specialized subtree
43 * @see org.eclipse.jdt.core.dom.ASTNode#subtreeMatch(ASTMatcher, Object)
46 public class ASTMatcher {
49 * Indicates whether doc tags should be matched.
52 private boolean matchDocTags;
55 * Creates a new AST matcher instance.
57 * For backwards compatibility, the matcher ignores tag
58 * elements below doc comments by default. Use
59 * {@link #ASTMatcher(boolean) ASTMatcher(true)}
60 * for a matcher that compares doc tags by default.
68 * Creates a new AST matcher instance.
70 * @param matchDocTags <code>true</code> if doc comment tags are
71 * to be compared by default, and <code>false</code> otherwise
72 * @see #match(Javadoc,Object)
75 public ASTMatcher(boolean matchDocTags) {
76 this.matchDocTags = matchDocTags;
80 * Returns whether the given lists of AST nodes match pair wise according
81 * to <code>ASTNode.subtreeMatch</code>.
83 * Note that this is a convenience method, useful for writing recursive
87 * @param list1 the first list of AST nodes
88 * (element type: <code>ASTNode</code>)
89 * @param list2 the second list of AST nodes
90 * (element type: <code>ASTNode</code>)
91 * @return <code>true</code> if the lists have the same number of elements
92 * and match pair-wise according to <code>ASTNode.subtreeMatch</code>
93 * @see ASTNode#subtreeMatch(ASTMatcher matcher, Object other)
95 public final boolean safeSubtreeListMatch(List list1, List list2) {
96 int size1 = list1.size();
97 int size2 = list2.size();
101 for (Iterator it1 = list1.iterator(), it2 = list2.iterator(); it1.hasNext();) {
102 ASTNode n1 = (ASTNode) it1.next();
103 ASTNode n2 = (ASTNode) it2.next();
104 if (!n1.subtreeMatch(this, n2)) {
112 * Returns whether the given nodes match according to
113 * <code>AST.subtreeMatch</code>. Returns <code>false</code> if one or
114 * the other of the nodes are <code>null</code>. Returns <code>true</code>
115 * if both nodes are <code>null</code>.
117 * Note that this is a convenience method, useful for writing recursive
121 * @param node1 the first AST node, or <code>null</code>; must be an
122 * instance of <code>ASTNode</code>
123 * @param node2 the second AST node, or <code>null</code>; must be an
124 * instance of <code>ASTNode</code>
125 * @return <code>true</code> if the nodes match according
126 * to <code>AST.subtreeMatch</code> or both are <code>null</code>, and
127 * <code>false</code> otherwise
128 * @see ASTNode#subtreeMatch(ASTMatcher, Object)
130 public final boolean safeSubtreeMatch(Object node1, Object node2) {
131 if (node1 == null && node2 == null) {
134 if (node1 == null || node2 == null) {
137 // N.B. call subtreeMatch even node1==node2!=null
138 return ((ASTNode) node1).subtreeMatch(this, node2);
142 * Returns whether the given objects are equal according to
143 * <code>equals</code>. Returns <code>false</code> if either
144 * node is <code>null</code>.
146 * @param o1 the first object, or <code>null</code>
147 * @param o2 the second object, or <code>null</code>
148 * @return <code>true</code> if the nodes are equal according to
149 * <code>equals</code> or both <code>null</code>, and
150 * <code>false</code> otherwise
152 public static boolean safeEquals(Object o1, Object o2) {
156 if (o1 == null || o2 == null) {
159 return o1.equals(o2);
163 * Returns whether the given node and the other object match.
165 * The default implementation provided by this class tests whether the
166 * other object is a node of the same type with structurally isomorphic
167 * child subtrees. Subclasses may override this method as needed.
170 * @param node the node
171 * @param other the other object, or <code>null</code>
172 * @return <code>true</code> if the subtree matches, or
173 * <code>false</code> if they do not match or the other object has a
174 * different node type or is <code>null</code>
177 public boolean match(AnnotationTypeDeclaration node, Object other) {
178 if (!(other instanceof AnnotationTypeDeclaration)) {
181 AnnotationTypeDeclaration o = (AnnotationTypeDeclaration) other;
182 // node type added in JLS3 - ignore old JLS2-style modifiers
183 return (safeSubtreeMatch(node.getJavadoc(), o.getJavadoc())
184 && safeSubtreeListMatch(node.modifiers(), o.modifiers())
185 && safeSubtreeMatch(node.getName(), o.getName())
186 && safeSubtreeListMatch(node.bodyDeclarations(), o.bodyDeclarations()));
190 * Returns whether the given node and the other object match.
192 * The default implementation provided by this class tests whether the
193 * other object is a node of the same type with structurally isomorphic
194 * child subtrees. Subclasses may override this method as needed.
197 * @param node the node
198 * @param other the other object, or <code>null</code>
199 * @return <code>true</code> if the subtree matches, or
200 * <code>false</code> if they do not match or the other object has a
201 * different node type or is <code>null</code>
204 public boolean match(AnnotationTypeMemberDeclaration node, Object other) {
205 if (!(other instanceof AnnotationTypeMemberDeclaration)) {
208 AnnotationTypeMemberDeclaration o = (AnnotationTypeMemberDeclaration) other;
209 // node type added in JLS3 - ignore old JLS2-style modifiers
210 return (safeSubtreeMatch(node.getJavadoc(), o.getJavadoc())
211 && safeSubtreeListMatch(node.modifiers(), o.modifiers())
212 && safeSubtreeMatch(node.getType(), o.getType())
213 && safeSubtreeMatch(node.getName(), o.getName())
214 && safeSubtreeMatch(node.getDefault(), o.getDefault()));
218 * Returns whether the given node and the other object match.
220 * The default implementation provided by this class tests whether the
221 * other object is a node of the same type with structurally isomorphic
222 * child subtrees. Subclasses may override this method as needed.
225 * @param node the node
226 * @param other the other object, or <code>null</code>
227 * @return <code>true</code> if the subtree matches, or
228 * <code>false</code> if they do not match or the other object has a
229 * different node type or is <code>null</code>
231 public boolean match(AnonymousClassDeclaration node, Object other) {
232 if (!(other instanceof AnonymousClassDeclaration)) {
235 AnonymousClassDeclaration o = (AnonymousClassDeclaration) other;
236 return safeSubtreeListMatch(node.bodyDeclarations(), o.bodyDeclarations());
240 * Returns whether the given node and the other object match.
242 * The default implementation provided by this class tests whether the
243 * other object is a node of the same type with structurally isomorphic
244 * child subtrees. Subclasses may override this method as needed.
247 * @param node the node
248 * @param other the other object, or <code>null</code>
249 * @return <code>true</code> if the subtree matches, or
250 * <code>false</code> if they do not match or the other object has a
251 * different node type or is <code>null</code>
253 public boolean match(ArrayAccess node, Object other) {
254 if (!(other instanceof ArrayAccess)) {
257 ArrayAccess o = (ArrayAccess) other;
259 safeSubtreeMatch(node.getArray(), o.getArray())
260 && safeSubtreeMatch(node.getIndex(), o.getIndex()));
264 * Returns whether the given node and the other object object match.
266 * The default implementation provided by this class tests whether the
267 * other object is a node of the same type with structurally isomorphic
268 * child subtrees. Subclasses may override this method as needed.
271 * @param node the node
272 * @param other the other object, or <code>null</code>
273 * @return <code>true</code> if the subtree matches, or
274 * <code>false</code> if they do not match or the other object has a
275 * different node type or is <code>null</code>
277 public boolean match(ArrayCreation node, Object other) {
278 if (!(other instanceof ArrayCreation)) {
281 ArrayCreation o = (ArrayCreation) other;
283 safeSubtreeMatch(node.getType(), o.getType())
284 && safeSubtreeListMatch(node.dimensions(), o.dimensions())
285 && safeSubtreeMatch(node.getInitializer(), o.getInitializer()));
289 * Returns whether the given node and the other object match.
291 * The default implementation provided by this class tests whether the
292 * other object is a node of the same type with structurally isomorphic
293 * child subtrees. Subclasses may override this method as needed.
296 * @param node the node
297 * @param other the other object, or <code>null</code>
298 * @return <code>true</code> if the subtree matches, or
299 * <code>false</code> if they do not match or the other object has a
300 * different node type or is <code>null</code>
302 public boolean match(ArrayInitializer node, Object other) {
303 if (!(other instanceof ArrayInitializer)) {
306 ArrayInitializer o = (ArrayInitializer) other;
307 return safeSubtreeListMatch(node.expressions(), o.expressions());
311 * Returns whether the given node and the other object match.
313 * The default implementation provided by this class tests whether the
314 * other object is a node of the same type with structurally isomorphic
315 * child subtrees. Subclasses may override this method as needed.
318 * @param node the node
319 * @param other the other object, or <code>null</code>
320 * @return <code>true</code> if the subtree matches, or
321 * <code>false</code> if they do not match or the other object has a
322 * different node type or is <code>null</code>
324 public boolean match(ArrayType node, Object other) {
325 if (!(other instanceof ArrayType)) {
328 ArrayType o = (ArrayType) other;
329 return safeSubtreeMatch(node.getComponentType(), o.getComponentType());
333 * Returns whether the given node and the other object match.
335 * The default implementation provided by this class tests whether the
336 * other object is a node of the same type with structurally isomorphic
337 * child subtrees. Subclasses may override this method as needed.
340 * @param node the node
341 * @param other the other object, or <code>null</code>
342 * @return <code>true</code> if the subtree matches, or
343 * <code>false</code> if they do not match or the other object has a
344 * different node type or is <code>null</code>
346 public boolean match(AssertStatement node, Object other) {
347 if (!(other instanceof AssertStatement)) {
350 AssertStatement o = (AssertStatement) other;
352 safeSubtreeMatch(node.getExpression(), o.getExpression())
353 && safeSubtreeMatch(node.getMessage(), o.getMessage()));
357 * Returns whether the given node and the other object match.
359 * The default implementation provided by this class tests whether the
360 * other object is a node of the same type with structurally isomorphic
361 * child subtrees. Subclasses may override this method as needed.
364 * @param node the node
365 * @param other the other object, or <code>null</code>
366 * @return <code>true</code> if the subtree matches, or
367 * <code>false</code> if they do not match or the other object has a
368 * different node type or is <code>null</code>
370 public boolean match(Assignment node, Object other) {
371 if (!(other instanceof Assignment)) {
374 Assignment o = (Assignment) other;
376 node.getOperator().equals(o.getOperator())
377 && safeSubtreeMatch(node.getLeftHandSide(), o.getLeftHandSide())
378 && safeSubtreeMatch(node.getRightHandSide(), o.getRightHandSide()));
382 * Returns whether the given node and the other object match.
384 * The default implementation provided by this class tests whether the
385 * other object is a node of the same type with structurally isomorphic
386 * child subtrees. Subclasses may override this method as needed.
389 * @param node the node
390 * @param other the other object, or <code>null</code>
391 * @return <code>true</code> if the subtree matches, or
392 * <code>false</code> if they do not match or the other object has a
393 * different node type or is <code>null</code>
395 public boolean match(Block node, Object other) {
396 if (!(other instanceof Block)) {
399 Block o = (Block) other;
400 return safeSubtreeListMatch(node.statements(), o.statements());
404 * Returns whether the given node and the other object match.
406 * The default implementation provided by this class tests whether the
407 * other object is a node of the same type. Subclasses may override
408 * this method as needed.
410 * <p>Note: {@link LineComment} and {@link BlockComment} nodes are
411 * not considered part of main structure of the AST. This method will
412 * only be called if a client goes out of their way to visit this
413 * kind of node explicitly.
416 * @param node the node
417 * @param other the other object, or <code>null</code>
418 * @return <code>true</code> if the subtree matches, or
419 * <code>false</code> if they do not match or the other object has a
420 * different node type or is <code>null</code>
423 public boolean match(BlockComment node, Object other) {
424 if (!(other instanceof BlockComment)) {
431 * Returns whether the given node and the other object match.
433 * The default implementation provided by this class tests whether the
434 * other object is a node of the same type with structurally isomorphic
435 * child subtrees. Subclasses may override this method as needed.
438 * @param node the node
439 * @param other the other object, or <code>null</code>
440 * @return <code>true</code> if the subtree matches, or
441 * <code>false</code> if they do not match or the other object has a
442 * different node type or is <code>null</code>
444 public boolean match(BooleanLiteral node, Object other) {
445 if (!(other instanceof BooleanLiteral)) {
448 BooleanLiteral o = (BooleanLiteral) other;
449 return node.booleanValue() == o.booleanValue();
453 * Returns whether the given node and the other object match.
455 * The default implementation provided by this class tests whether the
456 * other object is a node of the same type with structurally isomorphic
457 * child subtrees. Subclasses may override this method as needed.
460 * @param node the node
461 * @param other the other object, or <code>null</code>
462 * @return <code>true</code> if the subtree matches, or
463 * <code>false</code> if they do not match or the other object has a
464 * different node type or is <code>null</code>
466 public boolean match(BreakStatement node, Object other) {
467 if (!(other instanceof BreakStatement)) {
470 BreakStatement o = (BreakStatement) other;
471 return safeSubtreeMatch(node.getLabel(), o.getLabel());
475 * Returns whether the given node and the other object match.
477 * The default implementation provided by this class tests whether the
478 * other object is a node of the same type with structurally isomorphic
479 * child subtrees. Subclasses may override this method as needed.
482 * @param node the node
483 * @param other the other object, or <code>null</code>
484 * @return <code>true</code> if the subtree matches, or
485 * <code>false</code> if they do not match or the other object has a
486 * different node type or is <code>null</code>
488 public boolean match(CastExpression node, Object other) {
489 if (!(other instanceof CastExpression)) {
492 CastExpression o = (CastExpression) other;
494 safeSubtreeMatch(node.getType(), o.getType())
495 && safeSubtreeMatch(node.getExpression(), o.getExpression()));
499 * Returns whether the given node and the other object match.
501 * The default implementation provided by this class tests whether the
502 * other object is a node of the same type with structurally isomorphic
503 * child subtrees. Subclasses may override this method as needed.
506 * @param node the node
507 * @param other the other object, or <code>null</code>
508 * @return <code>true</code> if the subtree matches, or
509 * <code>false</code> if they do not match or the other object has a
510 * different node type or is <code>null</code>
512 public boolean match(CatchClause node, Object other) {
513 if (!(other instanceof CatchClause)) {
516 CatchClause o = (CatchClause) other;
518 safeSubtreeMatch(node.getException(), o.getException())
519 && safeSubtreeMatch(node.getBody(), o.getBody()));
523 * Returns whether the given node and the other object match.
525 * The default implementation provided by this class tests whether the
526 * other object is a node of the same type with structurally isomorphic
527 * child subtrees. Subclasses may override this method as needed.
530 * @param node the node
531 * @param other the other object, or <code>null</code>
532 * @return <code>true</code> if the subtree matches, or
533 * <code>false</code> if they do not match or the other object has a
534 * different node type or is <code>null</code>
536 public boolean match(CharacterLiteral node, Object other) {
537 if (!(other instanceof CharacterLiteral)) {
540 CharacterLiteral o = (CharacterLiteral) other;
541 return safeEquals(node.getEscapedValue(), o.getEscapedValue());
545 * Returns whether the given node and the other object match.
547 * The default implementation provided by this class tests whether the
548 * other object is a node of the same type with structurally isomorphic
549 * child subtrees. Subclasses may override this method as needed.
552 * @param node the node
553 * @param other the other object, or <code>null</code>
554 * @return <code>true</code> if the subtree matches, or
555 * <code>false</code> if they do not match or the other object has a
556 * different node type or is <code>null</code>
558 public boolean match(ClassInstanceCreation node, Object other) {
559 if (!(other instanceof ClassInstanceCreation)) {
562 ClassInstanceCreation o = (ClassInstanceCreation) other;
563 int level = node.getAST().apiLevel;
564 if (level == AST.JLS2_INTERNAL) {
565 if (!safeSubtreeMatch(node.internalGetName(), o.internalGetName())) {
569 if (level >= AST.JLS3) {
570 if (!safeSubtreeListMatch(node.typeArguments(), o.typeArguments())) {
573 if (!safeSubtreeMatch(node.getType(), o.getType())) {
578 safeSubtreeMatch(node.getExpression(), o.getExpression())
579 && safeSubtreeListMatch(node.arguments(), o.arguments())
581 node.getAnonymousClassDeclaration(),
582 o.getAnonymousClassDeclaration());
586 * Returns whether the given node and the other object match.
588 * The default implementation provided by this class tests whether the
589 * other object is a node of the same type with structurally isomorphic
590 * child subtrees. Subclasses may override this method as needed.
593 * @param node the node
594 * @param other the other object, or <code>null</code>
595 * @return <code>true</code> if the subtree matches, or
596 * <code>false</code> if they do not match or the other object has a
597 * different node type or is <code>null</code>
599 public boolean match(CompilationUnit node, Object other) {
600 if (!(other instanceof CompilationUnit)) {
603 CompilationUnit o = (CompilationUnit) other;
605 safeSubtreeMatch(node.getPackage(), o.getPackage())
606 && safeSubtreeListMatch(node.imports(), o.imports())
607 && safeSubtreeListMatch(node.types(), o.types()));
611 * Returns whether the given node and the other object match.
613 * The default implementation provided by this class tests whether the
614 * other object is a node of the same type with structurally isomorphic
615 * child subtrees. Subclasses may override this method as needed.
618 * @param node the node
619 * @param other the other object, or <code>null</code>
620 * @return <code>true</code> if the subtree matches, or
621 * <code>false</code> if they do not match or the other object has a
622 * different node type or is <code>null</code>
624 public boolean match(ConditionalExpression node, Object other) {
625 if (!(other instanceof ConditionalExpression)) {
628 ConditionalExpression o = (ConditionalExpression) other;
630 safeSubtreeMatch(node.getExpression(), o.getExpression())
631 && safeSubtreeMatch(node.getThenExpression(), o.getThenExpression())
632 && safeSubtreeMatch(node.getElseExpression(), o.getElseExpression()));
636 * Returns whether the given node and the other object match.
638 * The default implementation provided by this class tests whether the
639 * other object is a node of the same type with structurally isomorphic
640 * child subtrees. Subclasses may override this method as needed.
643 * @param node the node
644 * @param other the other object, or <code>null</code>
645 * @return <code>true</code> if the subtree matches, or
646 * <code>false</code> if they do not match or the other object has a
647 * different node type or is <code>null</code>
649 public boolean match(ConstructorInvocation node, Object other) {
650 if (!(other instanceof ConstructorInvocation)) {
653 ConstructorInvocation o = (ConstructorInvocation) other;
654 if (node.getAST().apiLevel >= AST.JLS3) {
655 if (!safeSubtreeListMatch(node.typeArguments(), o.typeArguments())) {
659 return safeSubtreeListMatch(node.arguments(), o.arguments());
663 * Returns whether the given node and the other object match.
665 * The default implementation provided by this class tests whether the
666 * other object is a node of the same type with structurally isomorphic
667 * child subtrees. Subclasses may override this method as needed.
670 * @param node the node
671 * @param other the other object, or <code>null</code>
672 * @return <code>true</code> if the subtree matches, or
673 * <code>false</code> if they do not match or the other object has a
674 * different node type or is <code>null</code>
676 public boolean match(ContinueStatement node, Object other) {
677 if (!(other instanceof ContinueStatement)) {
680 ContinueStatement o = (ContinueStatement) other;
681 return safeSubtreeMatch(node.getLabel(), o.getLabel());
685 * Returns whether the given node and the other object match.
687 * The default implementation provided by this class tests whether the
688 * other object is a node of the same type with structurally isomorphic
689 * child subtrees. Subclasses may override this method as needed.
692 * @param node the node
693 * @param other the other object, or <code>null</code>
694 * @return <code>true</code> if the subtree matches, or
695 * <code>false</code> if they do not match or the other object has a
696 * different node type or is <code>null</code>
698 public boolean match(DoStatement node, Object other) {
699 if (!(other instanceof DoStatement)) {
702 DoStatement o = (DoStatement) other;
704 safeSubtreeMatch(node.getExpression(), o.getExpression())
705 && safeSubtreeMatch(node.getBody(), o.getBody()));
709 * Returns whether the given node and the other object match.
711 * The default implementation provided by this class tests whether the
712 * other object is a node of the same type with structurally isomorphic
713 * child subtrees. Subclasses may override this method as needed.
716 * @param node the node
717 * @param other the other object, or <code>null</code>
718 * @return <code>true</code> if the subtree matches, or
719 * <code>false</code> if they do not match or the other object has a
720 * different node type or is <code>null</code>
722 public boolean match(EmptyStatement node, Object other) {
723 if (!(other instanceof EmptyStatement)) {
730 * Returns whether the given node and the other object match.
732 * The default implementation provided by this class tests whether the
733 * other object is a node of the same type with structurally isomorphic
734 * child subtrees. Subclasses may override this method as needed.
737 * @param node the node
738 * @param other the other object, or <code>null</code>
739 * @return <code>true</code> if the subtree matches, or
740 * <code>false</code> if they do not match or the other object has a
741 * different node type or is <code>null</code>
744 public boolean match(EnhancedForStatement node, Object other) {
745 if (!(other instanceof EnhancedForStatement)) {
748 EnhancedForStatement o = (EnhancedForStatement) other;
750 safeSubtreeMatch(node.getParameter(), o.getParameter())
751 && safeSubtreeMatch(node.getExpression(), o.getExpression())
752 && safeSubtreeMatch(node.getBody(), o.getBody()));
756 * Returns whether the given node and the other object match.
758 * The default implementation provided by this class tests whether the
759 * other object is a node of the same type with structurally isomorphic
760 * child subtrees. Subclasses may override this method as needed.
763 * @param node the node
764 * @param other the other object, or <code>null</code>
765 * @return <code>true</code> if the subtree matches, or
766 * <code>false</code> if they do not match or the other object has a
767 * different node type or is <code>null</code>
770 public boolean match(EnumConstantDeclaration node, Object other) {
771 if (!(other instanceof EnumConstantDeclaration)) {
774 EnumConstantDeclaration o = (EnumConstantDeclaration) other;
776 safeSubtreeMatch(node.getJavadoc(), o.getJavadoc())
777 && safeSubtreeListMatch(node.modifiers(), o.modifiers())
778 && safeSubtreeMatch(node.getName(), o.getName())
779 && safeSubtreeListMatch(node.arguments(), o.arguments())
781 node.getAnonymousClassDeclaration(),
782 o.getAnonymousClassDeclaration()));
786 * Returns whether the given node and the other object match.
788 * The default implementation provided by this class tests whether the
789 * other object is a node of the same type with structurally isomorphic
790 * child subtrees. Subclasses may override this method as needed.
793 * @param node the node
794 * @param other the other object, or <code>null</code>
795 * @return <code>true</code> if the subtree matches, or
796 * <code>false</code> if they do not match or the other object has a
797 * different node type or is <code>null</code>
800 public boolean match(EnumDeclaration node, Object other) {
801 if (!(other instanceof EnumDeclaration)) {
804 EnumDeclaration o = (EnumDeclaration) other;
806 safeSubtreeMatch(node.getJavadoc(), o.getJavadoc())
807 && safeSubtreeListMatch(node.modifiers(), o.modifiers())
808 && safeSubtreeMatch(node.getName(), o.getName())
809 && safeSubtreeListMatch(node.superInterfaceTypes(), o.superInterfaceTypes())
810 && safeSubtreeListMatch(node.enumConstants(), o.enumConstants())
811 && safeSubtreeListMatch(
812 node.bodyDeclarations(),
813 o.bodyDeclarations()));
817 * Returns whether the given node and the other object match.
819 * The default implementation provided by this class tests whether the
820 * other object is a node of the same type with structurally isomorphic
821 * child subtrees. Subclasses may override this method as needed.
824 * @param node the node
825 * @param other the other object, or <code>null</code>
826 * @return <code>true</code> if the subtree matches, or
827 * <code>false</code> if they do not match or the other object has a
828 * different node type or is <code>null</code>
830 public boolean match(ExpressionStatement node, Object other) {
831 if (!(other instanceof ExpressionStatement)) {
834 ExpressionStatement o = (ExpressionStatement) other;
835 return safeSubtreeMatch(node.getExpression(), o.getExpression());
839 * Returns whether the given node and the other object match.
841 * The default implementation provided by this class tests whether the
842 * other object is a node of the same type with structurally isomorphic
843 * child subtrees. Subclasses may override this method as needed.
846 * @param node the node
847 * @param other the other object, or <code>null</code>
848 * @return <code>true</code> if the subtree matches, or
849 * <code>false</code> if they do not match or the other object has a
850 * different node type or is <code>null</code>
852 public boolean match(FieldAccess node, Object other) {
853 if (!(other instanceof FieldAccess)) {
856 FieldAccess o = (FieldAccess) other;
858 safeSubtreeMatch(node.getExpression(), o.getExpression())
859 && safeSubtreeMatch(node.getName(), o.getName()));
863 * Returns whether the given node and the other object match.
865 * The default implementation provided by this class tests whether the
866 * other object is a node of the same type with structurally isomorphic
867 * child subtrees. Subclasses may override this method as needed.
870 * @param node the node
871 * @param other the other object, or <code>null</code>
872 * @return <code>true</code> if the subtree matches, or
873 * <code>false</code> if they do not match or the other object has a
874 * different node type or is <code>null</code>
876 public boolean match(FieldDeclaration node, Object other) {
877 if (!(other instanceof FieldDeclaration)) {
880 FieldDeclaration o = (FieldDeclaration) other;
881 int level = node.getAST().apiLevel;
882 if (level == AST.JLS2_INTERNAL) {
883 if (node.getModifiers() != o.getModifiers()) {
887 if (level >= AST.JLS3) {
888 if (!safeSubtreeListMatch(node.modifiers(), o.modifiers())) {
893 safeSubtreeMatch(node.getJavadoc(), o.getJavadoc())
894 && safeSubtreeMatch(node.getType(), o.getType())
895 && safeSubtreeListMatch(node.fragments(), o.fragments());
899 * Returns whether the given node and the other object match.
901 * The default implementation provided by this class tests whether the
902 * other object is a node of the same type with structurally isomorphic
903 * child subtrees. Subclasses may override this method as needed.
906 * @param node the node
907 * @param other the other object, or <code>null</code>
908 * @return <code>true</code> if the subtree matches, or
909 * <code>false</code> if they do not match or the other object has a
910 * different node type or is <code>null</code>
912 public boolean match(ForStatement node, Object other) {
913 if (!(other instanceof ForStatement)) {
916 ForStatement o = (ForStatement) other;
918 safeSubtreeListMatch(node.initializers(), o.initializers())
919 && safeSubtreeMatch(node.getExpression(), o.getExpression())
920 && safeSubtreeListMatch(node.updaters(), o.updaters())
921 && safeSubtreeMatch(node.getBody(), o.getBody()));
925 * Returns whether the given node and the other object match.
927 * The default implementation provided by this class tests whether the
928 * other object is a node of the same type with structurally isomorphic
929 * child subtrees. Subclasses may override this method as needed.
932 * @param node the node
933 * @param other the other object, or <code>null</code>
934 * @return <code>true</code> if the subtree matches, or
935 * <code>false</code> if they do not match or the other object has a
936 * different node type or is <code>null</code>
938 public boolean match(IfStatement node, Object other) {
939 if (!(other instanceof IfStatement)) {
942 IfStatement o = (IfStatement) other;
944 safeSubtreeMatch(node.getExpression(), o.getExpression())
945 && safeSubtreeMatch(node.getThenStatement(), o.getThenStatement())
946 && safeSubtreeMatch(node.getElseStatement(), o.getElseStatement()));
950 * Returns whether the given node and the other object match.
952 * The default implementation provided by this class tests whether the
953 * other object is a node of the same type with structurally isomorphic
954 * child subtrees. Subclasses may override this method as needed.
957 * @param node the node
958 * @param other the other object, or <code>null</code>
959 * @return <code>true</code> if the subtree matches, or
960 * <code>false</code> if they do not match or the other object has a
961 * different node type or is <code>null</code>
963 public boolean match(ImportDeclaration node, Object other) {
964 if (!(other instanceof ImportDeclaration)) {
967 ImportDeclaration o = (ImportDeclaration) other;
968 if (node.getAST().apiLevel >= AST.JLS3) {
969 if (node.isStatic() != o.isStatic()) {
974 safeSubtreeMatch(node.getName(), o.getName())
975 && node.isOnDemand() == o.isOnDemand());
979 * Returns whether the given node and the other object match.
981 * The default implementation provided by this class tests whether the
982 * other object is a node of the same type with structurally isomorphic
983 * child subtrees. Subclasses may override this method as needed.
986 * @param node the node
987 * @param other the other object, or <code>null</code>
988 * @return <code>true</code> if the subtree matches, or
989 * <code>false</code> if they do not match or the other object has a
990 * different node type or is <code>null</code>
992 public boolean match(InfixExpression node, Object other) {
993 if (!(other instanceof InfixExpression)) {
996 InfixExpression o = (InfixExpression) other;
997 // be careful not to trigger lazy creation of extended operand lists
998 if (node.hasExtendedOperands() && o.hasExtendedOperands()) {
999 if (!safeSubtreeListMatch(node.extendedOperands(), o.extendedOperands())) {
1003 if (node.hasExtendedOperands() != o.hasExtendedOperands()) {
1007 node.getOperator().equals(o.getOperator())
1008 && safeSubtreeMatch(node.getLeftOperand(), o.getLeftOperand())
1009 && safeSubtreeMatch(node.getRightOperand(), o.getRightOperand()));
1013 * Returns whether the given node and the other object match.
1015 * The default implementation provided by this class tests whether the
1016 * other object is a node of the same type with structurally isomorphic
1017 * child subtrees. Subclasses may override this method as needed.
1020 * @param node the node
1021 * @param other the other object, or <code>null</code>
1022 * @return <code>true</code> if the subtree matches, or
1023 * <code>false</code> if they do not match or the other object has a
1024 * different node type or is <code>null</code>
1026 public boolean match(InstanceofExpression node, Object other) {
1027 if (!(other instanceof InstanceofExpression)) {
1030 InstanceofExpression o = (InstanceofExpression) other;
1032 safeSubtreeMatch(node.getLeftOperand(), o.getLeftOperand())
1033 && safeSubtreeMatch(node.getRightOperand(), o.getRightOperand()));
1037 * Returns whether the given node and the other object match.
1039 * The default implementation provided by this class tests whether the
1040 * other object is a node of the same type with structurally isomorphic
1041 * child subtrees. Subclasses may override this method as needed.
1044 * @param node the node
1045 * @param other the other object, or <code>null</code>
1046 * @return <code>true</code> if the subtree matches, or
1047 * <code>false</code> if they do not match or the other object has a
1048 * different node type or is <code>null</code>
1050 public boolean match(Initializer node, Object other) {
1051 if (!(other instanceof Initializer)) {
1054 Initializer o = (Initializer) other;
1055 int level = node.getAST().apiLevel;
1056 if (level == AST.JLS2_INTERNAL) {
1057 if (node.getModifiers() != o.getModifiers()) {
1061 if (level >= AST.JLS3) {
1062 if (!safeSubtreeListMatch(node.modifiers(), o.modifiers())) {
1067 safeSubtreeMatch(node.getJavadoc(), o.getJavadoc())
1068 && safeSubtreeMatch(node.getBody(), o.getBody()));
1072 * Returns whether the given node and the other object match.
1074 * Unlike other node types, the behavior of the default
1075 * implementation is controlled by a constructor-supplied
1076 * parameter {@link #ASTMatcher(boolean) ASTMatcher(boolean)}
1077 * which is <code>false</code> if not specified.
1078 * When this parameter is <code>true</code>, the implementation
1079 * tests whether the other object is also a <code>Javadoc</code>
1080 * with structurally isomorphic child subtrees; the comment string
1081 * (<code>Javadoc.getComment()</code>) is ignored.
1082 * Conversely, when the parameter is <code>false</code>, the
1083 * implementation tests whether the other object is also a
1084 * <code>Javadoc</code> with exactly the same comment string;
1085 * the tag elements ({@link Javadoc#tags() Javadoc.tags} are
1086 * ignored. Subclasses may reimplement.
1089 * @param node the node
1090 * @param other the other object, or <code>null</code>
1091 * @return <code>true</code> if the subtree matches, or
1092 * <code>false</code> if they do not match or the other object has a
1093 * different node type or is <code>null</code>
1094 * @see #ASTMatcher()
1095 * @see #ASTMatcher(boolean)
1097 public boolean match(Javadoc node, Object other) {
1098 if (!(other instanceof Javadoc)) {
1101 Javadoc o = (Javadoc) other;
1102 if (this.matchDocTags) {
1103 return safeSubtreeListMatch(node.tags(), o.tags());
1105 return compareDeprecatedComment(node, o);
1110 * Return whether the deprecated comment strings of the given java doc are equals.
1112 * Note the only purpose of this method is to hide deprecated warnings.
1113 * @deprecated mark deprecated to hide deprecated usage
1115 private boolean compareDeprecatedComment(Javadoc first, Javadoc second) {
1116 if (first.getAST().apiLevel == AST.JLS2_INTERNAL) {
1117 return safeEquals(first.getComment(), second.getComment());
1124 * Returns whether the given node and the other object match.
1126 * The default implementation provided by this class tests whether the
1127 * other object is a node of the same type with structurally isomorphic
1128 * child subtrees. Subclasses may override this method as needed.
1131 * @param node the node
1132 * @param other the other object, or <code>null</code>
1133 * @return <code>true</code> if the subtree matches, or
1134 * <code>false</code> if they do not match or the other object has a
1135 * different node type or is <code>null</code>
1137 public boolean match(LabeledStatement node, Object other) {
1138 if (!(other instanceof LabeledStatement)) {
1141 LabeledStatement o = (LabeledStatement) other;
1143 safeSubtreeMatch(node.getLabel(), o.getLabel())
1144 && safeSubtreeMatch(node.getBody(), o.getBody()));
1148 * Returns whether the given node and the other object match.
1150 * The default implementation provided by this class tests whether the
1151 * other object is a node of the same type. Subclasses may override
1152 * this method as needed.
1154 * <p>Note: {@link LineComment} and {@link BlockComment} nodes are
1155 * not considered part of main structure of the AST. This method will
1156 * only be called if a client goes out of their way to visit this
1157 * kind of node explicitly.
1160 * @param node the node
1161 * @param other the other object, or <code>null</code>
1162 * @return <code>true</code> if the subtree matches, or
1163 * <code>false</code> if they do not match or the other object has a
1164 * different node type or is <code>null</code>
1167 public boolean match(LineComment node, Object other) {
1168 if (!(other instanceof LineComment)) {
1175 * Returns whether the given node and the other object match.
1177 * The default implementation provided by this class tests whether the
1178 * other object is a node of the same type with structurally isomorphic
1179 * child subtrees. Subclasses may override this method as needed.
1182 * @param node the node
1183 * @param other the other object, or <code>null</code>
1184 * @return <code>true</code> if the subtree matches, or
1185 * <code>false</code> if they do not match or the other object has a
1186 * different node type or is <code>null</code>
1189 public boolean match(MarkerAnnotation node, Object other) {
1190 if (!(other instanceof MarkerAnnotation)) {
1193 MarkerAnnotation o = (MarkerAnnotation) other;
1194 return safeSubtreeMatch(node.getTypeName(), o.getTypeName());
1198 * Returns whether the given node and the other object match.
1200 * The default implementation provided by this class tests whether the
1201 * other object is a node of the same type with structurally isomorphic
1202 * child subtrees. Subclasses may override this method as needed.
1205 * @param node the node
1206 * @param other the other object, or <code>null</code>
1207 * @return <code>true</code> if the subtree matches, or
1208 * <code>false</code> if they do not match or the other object has a
1209 * different node type or is <code>null</code>
1212 public boolean match(MemberRef node, Object other) {
1213 if (!(other instanceof MemberRef)) {
1216 MemberRef o = (MemberRef) other;
1218 safeSubtreeMatch(node.getQualifier(), o.getQualifier())
1219 && safeSubtreeMatch(node.getName(), o.getName()));
1223 * Returns whether the given node and the other object match.
1225 * The default implementation provided by this class tests whether the
1226 * other object is a node of the same type with structurally isomorphic
1227 * child subtrees. Subclasses may override this method as needed.
1230 * @param node the node
1231 * @param other the other object, or <code>null</code>
1232 * @return <code>true</code> if the subtree matches, or
1233 * <code>false</code> if they do not match or the other object has a
1234 * different node type or is <code>null</code>
1237 public boolean match(MemberValuePair node, Object other) {
1238 if (!(other instanceof MemberValuePair)) {
1241 MemberValuePair o = (MemberValuePair) other;
1242 return (safeSubtreeMatch(node.getName(), o.getName())
1243 && safeSubtreeMatch(node.getValue(), o.getValue()));
1247 * Returns whether the given node and the other object match.
1249 * The default implementation provided by this class tests whether the
1250 * other object is a node of the same type with structurally isomorphic
1251 * child subtrees. Subclasses may override this method as needed.
1254 * @param node the node
1255 * @param other the other object, or <code>null</code>
1256 * @return <code>true</code> if the subtree matches, or
1257 * <code>false</code> if they do not match or the other object has a
1258 * different node type or is <code>null</code>
1261 public boolean match(MethodRef node, Object other) {
1262 if (!(other instanceof MethodRef)) {
1265 MethodRef o = (MethodRef) other;
1267 safeSubtreeMatch(node.getQualifier(), o.getQualifier())
1268 && safeSubtreeMatch(node.getName(), o.getName())
1269 && safeSubtreeListMatch(node.parameters(), o.parameters()));
1273 * Returns whether the given node and the other object match.
1275 * The default implementation provided by this class tests whether the
1276 * other object is a node of the same type with structurally isomorphic
1277 * child subtrees. Subclasses may override this method as needed.
1280 * @param node the node
1281 * @param other the other object, or <code>null</code>
1282 * @return <code>true</code> if the subtree matches, or
1283 * <code>false</code> if they do not match or the other object has a
1284 * different node type or is <code>null</code>
1287 public boolean match(MethodRefParameter node, Object other) {
1288 if (!(other instanceof MethodRefParameter)) {
1291 MethodRefParameter o = (MethodRefParameter) other;
1292 int level = node.getAST().apiLevel;
1293 if (level >= AST.JLS3) {
1294 if (node.isVarargs() != o.isVarargs()) {
1299 safeSubtreeMatch(node.getType(), o.getType())
1300 && safeSubtreeMatch(node.getName(), o.getName()));
1304 * Returns whether the given node and the other object match.
1306 * The default implementation provided by this class tests whether the
1307 * other object is a node of the same type with structurally isomorphic
1308 * child subtrees. Subclasses may override this method as needed.
1311 * Note that extra array dimensions are compared since they are an
1312 * important part of the method declaration.
1315 * Note that the method return types are compared even for constructor
1319 * @param node the node
1320 * @param other the other object, or <code>null</code>
1321 * @return <code>true</code> if the subtree matches, or
1322 * <code>false</code> if they do not match or the other object has a
1323 * different node type or is <code>null</code>
1325 public boolean match(MethodDeclaration node, Object other) {
1326 if (!(other instanceof MethodDeclaration)) {
1329 MethodDeclaration o = (MethodDeclaration) other;
1330 int level = node.getAST().apiLevel;
1331 if (level == AST.JLS2_INTERNAL) {
1332 if (node.getModifiers() != o.getModifiers()) {
1335 if (!safeSubtreeMatch(node.internalGetReturnType(), o.internalGetReturnType())) {
1339 if (level >= AST.JLS3) {
1340 if (!safeSubtreeListMatch(node.modifiers(), o.modifiers())) {
1343 if (!safeSubtreeMatch(node.getReturnType2(), o.getReturnType2())) {
1346 // n.b. compare type parameters even for constructors
1347 if (!safeSubtreeListMatch(node.typeParameters(), o.typeParameters())) {
1351 return ((node.isConstructor() == o.isConstructor())
1352 && safeSubtreeMatch(node.getJavadoc(), o.getJavadoc())
1353 && safeSubtreeMatch(node.getName(), o.getName())
1354 // n.b. compare return type even for constructors
1355 && safeSubtreeListMatch(node.parameters(), o.parameters())
1356 && node.getExtraDimensions() == o.getExtraDimensions()
1357 && safeSubtreeListMatch(node.thrownExceptions(), o.thrownExceptions())
1358 && safeSubtreeMatch(node.getBody(), o.getBody()));
1362 * Returns whether the given node and the other object match.
1364 * The default implementation provided by this class tests whether the
1365 * other object is a node of the same type with structurally isomorphic
1366 * child subtrees. Subclasses may override this method as needed.
1369 * @param node the node
1370 * @param other the other object, or <code>null</code>
1371 * @return <code>true</code> if the subtree matches, or
1372 * <code>false</code> if they do not match or the other object has a
1373 * different node type or is <code>null</code>
1375 public boolean match(MethodInvocation node, Object other) {
1376 if (!(other instanceof MethodInvocation)) {
1379 MethodInvocation o = (MethodInvocation) other;
1380 if (node.getAST().apiLevel >= AST.JLS3) {
1381 if (!safeSubtreeListMatch(node.typeArguments(), o.typeArguments())) {
1386 safeSubtreeMatch(node.getExpression(), o.getExpression())
1387 && safeSubtreeMatch(node.getName(), o.getName())
1388 && safeSubtreeListMatch(node.arguments(), o.arguments()));
1392 * Returns whether the given node and the other object match.
1394 * The default implementation provided by this class tests whether the
1395 * other object is a node of the same type with structurally isomorphic
1396 * child subtrees. Subclasses may override this method as needed.
1399 * @param node the node
1400 * @param other the other object, or <code>null</code>
1401 * @return <code>true</code> if the subtree matches, or
1402 * <code>false</code> if they do not match or the other object has a
1403 * different node type or is <code>null</code>
1406 public boolean match(Modifier node, Object other) {
1407 if (!(other instanceof Modifier)) {
1410 Modifier o = (Modifier) other;
1411 return (node.getKeyword() == o.getKeyword());
1415 * Returns whether the given node and the other object match.
1417 * The default implementation provided by this class tests whether the
1418 * other object is a node of the same type with structurally isomorphic
1419 * child subtrees. Subclasses may override this method as needed.
1422 * @param node the node
1423 * @param other the other object, or <code>null</code>
1424 * @return <code>true</code> if the subtree matches, or
1425 * <code>false</code> if they do not match or the other object has a
1426 * different node type or is <code>null</code>
1429 public boolean match(NormalAnnotation node, Object other) {
1430 if (!(other instanceof NormalAnnotation)) {
1433 NormalAnnotation o = (NormalAnnotation) other;
1434 return (safeSubtreeMatch(node.getTypeName(), o.getTypeName())
1435 && safeSubtreeListMatch(node.values(), o.values()));
1439 * Returns whether the given node and the other object match.
1441 * The default implementation provided by this class tests whether the
1442 * other object is a node of the same type with structurally isomorphic
1443 * child subtrees. Subclasses may override this method as needed.
1446 * @param node the node
1447 * @param other the other object, or <code>null</code>
1448 * @return <code>true</code> if the subtree matches, or
1449 * <code>false</code> if they do not match or the other object has a
1450 * different node type or is <code>null</code>
1452 public boolean match(NullLiteral node, Object other) {
1453 if (!(other instanceof NullLiteral)) {
1460 * Returns whether the given node and the other object match.
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.
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>
1473 public boolean match(NumberLiteral node, Object other) {
1474 if (!(other instanceof NumberLiteral)) {
1477 NumberLiteral o = (NumberLiteral) other;
1478 return safeEquals(node.getToken(), o.getToken());
1482 * Returns whether the given node and the other object match.
1484 * The default implementation provided by this class tests whether the
1485 * other object is a node of the same type with structurally isomorphic
1486 * child subtrees. Subclasses may override this method as needed.
1489 * @param node the node
1490 * @param other the other object, or <code>null</code>
1491 * @return <code>true</code> if the subtree matches, or
1492 * <code>false</code> if they do not match or the other object has a
1493 * different node type or is <code>null</code>
1495 public boolean match(PackageDeclaration node, Object other) {
1496 if (!(other instanceof PackageDeclaration)) {
1499 PackageDeclaration o = (PackageDeclaration) other;
1500 if (node.getAST().apiLevel >= AST.JLS3) {
1501 if (!safeSubtreeMatch(node.getJavadoc(), o.getJavadoc())) {
1504 if (!safeSubtreeListMatch(node.annotations(), o.annotations())) {
1508 return safeSubtreeMatch(node.getName(), o.getName());
1512 * Returns whether the given node and the other object match.
1514 * The default implementation provided by this class tests whether the
1515 * other object is a node of the same type with structurally isomorphic
1516 * child subtrees. Subclasses may override this method as needed.
1519 * @param node the node
1520 * @param other the other object, or <code>null</code>
1521 * @return <code>true</code> if the subtree matches, or
1522 * <code>false</code> if they do not match or the other object has a
1523 * different node type or is <code>null</code>
1526 public boolean match(ParameterizedType node, Object other) {
1527 if (!(other instanceof ParameterizedType)) {
1530 ParameterizedType o = (ParameterizedType) other;
1531 return safeSubtreeMatch(node.getType(), o.getType())
1532 && safeSubtreeListMatch(node.typeArguments(), o.typeArguments());
1536 * Returns whether the given node and the other object match.
1538 * The default implementation provided by this class tests whether the
1539 * other object is a node of the same type with structurally isomorphic
1540 * child subtrees. Subclasses may override this method as needed.
1543 * @param node the node
1544 * @param other the other object, or <code>null</code>
1545 * @return <code>true</code> if the subtree matches, or
1546 * <code>false</code> if they do not match or the other object has a
1547 * different node type or is <code>null</code>
1549 public boolean match(ParenthesizedExpression node, Object other) {
1550 if (!(other instanceof ParenthesizedExpression)) {
1553 ParenthesizedExpression o = (ParenthesizedExpression) other;
1554 return safeSubtreeMatch(node.getExpression(), o.getExpression());
1558 * Returns whether the given node and the other object match.
1560 * The default implementation provided by this class tests whether the
1561 * other object is a node of the same type with structurally isomorphic
1562 * child subtrees. Subclasses may override this method as needed.
1565 * @param node the node
1566 * @param other the other object, or <code>null</code>
1567 * @return <code>true</code> if the subtree matches, or
1568 * <code>false</code> if they do not match or the other object has a
1569 * different node type or is <code>null</code>
1571 public boolean match(PostfixExpression node, Object other) {
1572 if (!(other instanceof PostfixExpression)) {
1575 PostfixExpression o = (PostfixExpression) other;
1577 node.getOperator().equals(o.getOperator())
1578 && safeSubtreeMatch(node.getOperand(), o.getOperand()));
1582 * Returns whether the given node and the other object match.
1584 * The default implementation provided by this class tests whether the
1585 * other object is a node of the same type with structurally isomorphic
1586 * child subtrees. Subclasses may override this method as needed.
1589 * @param node the node
1590 * @param other the other object, or <code>null</code>
1591 * @return <code>true</code> if the subtree matches, or
1592 * <code>false</code> if they do not match or the other object has a
1593 * different node type or is <code>null</code>
1595 public boolean match(PrefixExpression node, Object other) {
1596 if (!(other instanceof PrefixExpression)) {
1599 PrefixExpression o = (PrefixExpression) other;
1601 node.getOperator().equals(o.getOperator())
1602 && safeSubtreeMatch(node.getOperand(), o.getOperand()));
1606 * Returns whether the given node and the other object match.
1608 * The default implementation provided by this class tests whether the
1609 * other object is a node of the same type with structurally isomorphic
1610 * child subtrees. Subclasses may override this method as needed.
1613 * @param node the node
1614 * @param other the other object, or <code>null</code>
1615 * @return <code>true</code> if the subtree matches, or
1616 * <code>false</code> if they do not match or the other object has a
1617 * different node type or is <code>null</code>
1619 public boolean match(PrimitiveType node, Object other) {
1620 if (!(other instanceof PrimitiveType)) {
1623 PrimitiveType o = (PrimitiveType) other;
1624 return (node.getPrimitiveTypeCode() == o.getPrimitiveTypeCode());
1628 * Returns whether the given node and the other object match.
1630 * The default implementation provided by this class tests whether the
1631 * other object is a node of the same type with structurally isomorphic
1632 * child subtrees. Subclasses may override this method as needed.
1635 * @param node the node
1636 * @param other the other object, or <code>null</code>
1637 * @return <code>true</code> if the subtree matches, or
1638 * <code>false</code> if they do not match or the other object has a
1639 * different node type or is <code>null</code>
1641 public boolean match(QualifiedName node, Object other) {
1642 if (!(other instanceof QualifiedName)) {
1645 QualifiedName o = (QualifiedName) other;
1647 safeSubtreeMatch(node.getQualifier(), o.getQualifier())
1648 && safeSubtreeMatch(node.getName(), o.getName()));
1652 * Returns whether the given node and the other object match.
1654 * The default implementation provided by this class tests whether the
1655 * other object is a node of the same type with structurally isomorphic
1656 * child subtrees. Subclasses may override this method as needed.
1659 * @param node the node
1660 * @param other the other object, or <code>null</code>
1661 * @return <code>true</code> if the subtree matches, or
1662 * <code>false</code> if they do not match or the other object has a
1663 * different node type or is <code>null</code>
1666 public boolean match(QualifiedType node, Object other) {
1667 if (!(other instanceof QualifiedType)) {
1670 QualifiedType o = (QualifiedType) other;
1672 safeSubtreeMatch(node.getQualifier(), o.getQualifier())
1673 && safeSubtreeMatch(node.getName(), o.getName()));
1677 * Returns whether the given node and the other object match.
1679 * The default implementation provided by this class tests whether the
1680 * other object is a node of the same type with structurally isomorphic
1681 * child subtrees. Subclasses may override this method as needed.
1684 * @param node the node
1685 * @param other the other object, or <code>null</code>
1686 * @return <code>true</code> if the subtree matches, or
1687 * <code>false</code> if they do not match or the other object has a
1688 * different node type or is <code>null</code>
1690 public boolean match(ReturnStatement node, Object other) {
1691 if (!(other instanceof ReturnStatement)) {
1694 ReturnStatement o = (ReturnStatement) other;
1695 return safeSubtreeMatch(node.getExpression(), o.getExpression());
1699 * Returns whether the given node and the other object match.
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.
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>
1712 public boolean match(SimpleName node, Object other) {
1713 if (!(other instanceof SimpleName)) {
1716 SimpleName o = (SimpleName) other;
1717 return node.getIdentifier().equals(o.getIdentifier());
1721 * Returns whether the given node and the other object match.
1723 * The default implementation provided by this class tests whether the
1724 * other object is a node of the same type with structurally isomorphic
1725 * child subtrees. Subclasses may override this method as needed.
1728 * @param node the node
1729 * @param other the other object, or <code>null</code>
1730 * @return <code>true</code> if the subtree matches, or
1731 * <code>false</code> if they do not match or the other object has a
1732 * different node type or is <code>null</code>
1734 public boolean match(SimpleType node, Object other) {
1735 if (!(other instanceof SimpleType)) {
1738 SimpleType o = (SimpleType) other;
1739 return safeSubtreeMatch(node.getName(), o.getName());
1743 * Returns whether the given node and the other object match.
1745 * The default implementation provided by this class tests whether the
1746 * other object is a node of the same type with structurally isomorphic
1747 * child subtrees. Subclasses may override this method as needed.
1750 * @param node the node
1751 * @param other the other object, or <code>null</code>
1752 * @return <code>true</code> if the subtree matches, or
1753 * <code>false</code> if they do not match or the other object has a
1754 * different node type or is <code>null</code>
1757 public boolean match(SingleMemberAnnotation node, Object other) {
1758 if (!(other instanceof SingleMemberAnnotation)) {
1761 SingleMemberAnnotation o = (SingleMemberAnnotation) other;
1762 return (safeSubtreeMatch(node.getTypeName(), o.getTypeName())
1763 && safeSubtreeMatch(node.getValue(), o.getValue()));
1767 * Returns whether the given node and the other object match.
1769 * The default implementation provided by this class tests whether the
1770 * other object is a node of the same type with structurally isomorphic
1771 * child subtrees. Subclasses may override this method as needed.
1774 * Note that extra array dimensions and the variable arity flag
1775 * are compared since they are both important parts of the declaration.
1778 * @param node the node
1779 * @param other the other object, or <code>null</code>
1780 * @return <code>true</code> if the subtree matches, or
1781 * <code>false</code> if they do not match or the other object has a
1782 * different node type or is <code>null</code>
1784 public boolean match(SingleVariableDeclaration node, Object other) {
1785 if (!(other instanceof SingleVariableDeclaration)) {
1788 SingleVariableDeclaration o = (SingleVariableDeclaration) other;
1789 int level = node.getAST().apiLevel;
1790 if (level == AST.JLS2_INTERNAL) {
1791 if (node.getModifiers() != o.getModifiers()) {
1795 if (level >= AST.JLS3) {
1796 if (!safeSubtreeListMatch(node.modifiers(), o.modifiers())) {
1799 if (node.isVarargs() != o.isVarargs()) {
1804 safeSubtreeMatch(node.getType(), o.getType())
1805 && safeSubtreeMatch(node.getName(), o.getName())
1806 && node.getExtraDimensions() == o.getExtraDimensions()
1807 && safeSubtreeMatch(node.getInitializer(), o.getInitializer());
1811 * Returns whether the given node and the other object match.
1813 * The default implementation provided by this class tests whether the
1814 * other object is a node of the same type with structurally isomorphic
1815 * child subtrees. Subclasses may override this method as needed.
1818 * @param node the node
1819 * @param other the other object, or <code>null</code>
1820 * @return <code>true</code> if the subtree matches, or
1821 * <code>false</code> if they do not match or the other object has a
1822 * different node type or is <code>null</code>
1824 public boolean match(StringLiteral node, Object other) {
1825 if (!(other instanceof StringLiteral)) {
1828 StringLiteral o = (StringLiteral) other;
1829 return safeEquals(node.getEscapedValue(), o.getEscapedValue());
1833 * Returns whether the given node and the other object match.
1835 * The default implementation provided by this class tests whether the
1836 * other object is a node of the same type with structurally isomorphic
1837 * child subtrees. Subclasses may override this method as needed.
1840 * @param node the node
1841 * @param other the other object, or <code>null</code>
1842 * @return <code>true</code> if the subtree matches, or
1843 * <code>false</code> if they do not match or the other object has a
1844 * different node type or is <code>null</code>
1846 public boolean match(SuperConstructorInvocation node, Object other) {
1847 if (!(other instanceof SuperConstructorInvocation)) {
1850 SuperConstructorInvocation o = (SuperConstructorInvocation) other;
1851 if (node.getAST().apiLevel >= AST.JLS3) {
1852 if (!safeSubtreeListMatch(node.typeArguments(), o.typeArguments())) {
1857 safeSubtreeMatch(node.getExpression(), o.getExpression())
1858 && safeSubtreeListMatch(node.arguments(), o.arguments()));
1862 * Returns whether the given node and the other object match.
1864 * The default implementation provided by this class tests whether the
1865 * other object is a node of the same type with structurally isomorphic
1866 * child subtrees. Subclasses may override this method as needed.
1869 * @param node the node
1870 * @param other the other object, or <code>null</code>
1871 * @return <code>true</code> if the subtree matches, or
1872 * <code>false</code> if they do not match or the other object has a
1873 * different node type or is <code>null</code>
1875 public boolean match(SuperFieldAccess node, Object other) {
1876 if (!(other instanceof SuperFieldAccess)) {
1879 SuperFieldAccess o = (SuperFieldAccess) other;
1881 safeSubtreeMatch(node.getName(), o.getName())
1882 && safeSubtreeMatch(node.getQualifier(), o.getQualifier()));
1886 * Returns whether the given node and the other object match.
1888 * The default implementation provided by this class tests whether the
1889 * other object is a node of the same type with structurally isomorphic
1890 * child subtrees. Subclasses may override this method as needed.
1893 * @param node the node
1894 * @param other the other object, or <code>null</code>
1895 * @return <code>true</code> if the subtree matches, or
1896 * <code>false</code> if they do not match or the other object has a
1897 * different node type or is <code>null</code>
1899 public boolean match(SuperMethodInvocation node, Object other) {
1900 if (!(other instanceof SuperMethodInvocation)) {
1903 SuperMethodInvocation o = (SuperMethodInvocation) other;
1904 if (node.getAST().apiLevel >= AST.JLS3) {
1905 if (!safeSubtreeListMatch(node.typeArguments(), o.typeArguments())) {
1910 safeSubtreeMatch(node.getQualifier(), o.getQualifier())
1911 && safeSubtreeMatch(node.getName(), o.getName())
1912 && safeSubtreeListMatch(node.arguments(), o.arguments()));
1916 * Returns whether the given node and the other object match.
1918 * The default implementation provided by this class tests whether the
1919 * other object is a node of the same type with structurally isomorphic
1920 * child subtrees. Subclasses may override this method as needed.
1923 * @param node the node
1924 * @param other the other object, or <code>null</code>
1925 * @return <code>true</code> if the subtree matches, or
1926 * <code>false</code> if they do not match or the other object has a
1927 * different node type or is <code>null</code>
1929 public boolean match(SwitchCase node, Object other) {
1930 if (!(other instanceof SwitchCase)) {
1933 SwitchCase o = (SwitchCase) other;
1934 return safeSubtreeMatch(node.getExpression(), o.getExpression());
1938 * Returns whether the given node and the other object match.
1940 * The default implementation provided by this class tests whether the
1941 * other object is a node of the same type with structurally isomorphic
1942 * child subtrees. Subclasses may override this method as needed.
1945 * @param node the node
1946 * @param other the other object, or <code>null</code>
1947 * @return <code>true</code> if the subtree matches, or
1948 * <code>false</code> if they do not match or the other object has a
1949 * different node type or is <code>null</code>
1951 public boolean match(SwitchStatement node, Object other) {
1952 if (!(other instanceof SwitchStatement)) {
1955 SwitchStatement o = (SwitchStatement) other;
1957 safeSubtreeMatch(node.getExpression(), o.getExpression())
1958 && safeSubtreeListMatch(node.statements(), o.statements()));
1962 * Returns whether the given node and the other object match.
1964 * The default implementation provided by this class tests whether the
1965 * other object is a node of the same type with structurally isomorphic
1966 * child subtrees. Subclasses may override this method as needed.
1969 * @param node the node
1970 * @param other the other object, or <code>null</code>
1971 * @return <code>true</code> if the subtree matches, or
1972 * <code>false</code> if they do not match or the other object has a
1973 * different node type or is <code>null</code>
1975 public boolean match(SynchronizedStatement node, Object other) {
1976 if (!(other instanceof SynchronizedStatement)) {
1979 SynchronizedStatement o = (SynchronizedStatement) other;
1981 safeSubtreeMatch(node.getExpression(), o.getExpression())
1982 && safeSubtreeMatch(node.getBody(), o.getBody()));
1986 * Returns whether the given node and the other object match.
1988 * The default implementation provided by this class tests whether the
1989 * other object is a node of the same type with structurally isomorphic
1990 * child subtrees. Subclasses may override this method as needed.
1993 * @param node the node
1994 * @param other the other object, or <code>null</code>
1995 * @return <code>true</code> if the subtree matches, or
1996 * <code>false</code> if they do not match or the other object has a
1997 * different node type or is <code>null</code>
2000 public boolean match(TagElement node, Object other) {
2001 if (!(other instanceof TagElement)) {
2004 TagElement o = (TagElement) other;
2006 safeEquals(node.getTagName(), o.getTagName())
2007 && safeSubtreeListMatch(node.fragments(), o.fragments()));
2011 * Returns whether the given node and the other object match.
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.
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>
2025 public boolean match(TextElement node, Object other) {
2026 if (!(other instanceof TextElement)) {
2029 TextElement o = (TextElement) other;
2030 return safeEquals(node.getText(), o.getText());
2034 * Returns whether the given node and the other object match.
2036 * The default implementation provided by this class tests whether the
2037 * other object is a node of the same type with structurally isomorphic
2038 * child subtrees. Subclasses may override this method as needed.
2041 * @param node the node
2042 * @param other the other object, or <code>null</code>
2043 * @return <code>true</code> if the subtree matches, or
2044 * <code>false</code> if they do not match or the other object has a
2045 * different node type or is <code>null</code>
2047 public boolean match(ThisExpression node, Object other) {
2048 if (!(other instanceof ThisExpression)) {
2051 ThisExpression o = (ThisExpression) other;
2052 return safeSubtreeMatch(node.getQualifier(), o.getQualifier());
2056 * Returns whether the given node and the other object match.
2058 * The default implementation provided by this class tests whether the
2059 * other object is a node of the same type with structurally isomorphic
2060 * child subtrees. Subclasses may override this method as needed.
2063 * @param node the node
2064 * @param other the other object, or <code>null</code>
2065 * @return <code>true</code> if the subtree matches, or
2066 * <code>false</code> if they do not match or the other object has a
2067 * different node type or is <code>null</code>
2069 public boolean match(ThrowStatement node, Object other) {
2070 if (!(other instanceof ThrowStatement)) {
2073 ThrowStatement o = (ThrowStatement) other;
2074 return safeSubtreeMatch(node.getExpression(), o.getExpression());
2078 * Returns whether the given node and the other object match.
2080 * The default implementation provided by this class tests whether the
2081 * other object is a node of the same type with structurally isomorphic
2082 * child subtrees. Subclasses may override this method as needed.
2085 * @param node the node
2086 * @param other the other object, or <code>null</code>
2087 * @return <code>true</code> if the subtree matches, or
2088 * <code>false</code> if they do not match or the other object has a
2089 * different node type or is <code>null</code>
2091 public boolean match(TryStatement node, Object other) {
2092 if (!(other instanceof TryStatement)) {
2095 TryStatement o = (TryStatement) other;
2097 safeSubtreeMatch(node.getBody(), o.getBody())
2098 && safeSubtreeListMatch(node.catchClauses(), o.catchClauses())
2099 && safeSubtreeMatch(node.getFinally(), o.getFinally()));
2103 * Returns whether the given node and the other object match.
2105 * The default implementation provided by this class tests whether the
2106 * other object is a node of the same type with structurally isomorphic
2107 * child subtrees. Subclasses may override this method as needed.
2110 * @param node the node
2111 * @param other the other object, or <code>null</code>
2112 * @return <code>true</code> if the subtree matches, or
2113 * <code>false</code> if they do not match or the other object has a
2114 * different node type or is <code>null</code>
2116 public boolean match(TypeDeclaration node, Object other) {
2117 if (!(other instanceof TypeDeclaration)) {
2120 TypeDeclaration o = (TypeDeclaration) other;
2121 int level = node.getAST().apiLevel;
2122 if (level == AST.JLS2_INTERNAL) {
2123 if (node.getModifiers() != o.getModifiers()) {
2126 if (!safeSubtreeMatch(node.internalGetSuperclass(), o.internalGetSuperclass())) {
2129 if (!safeSubtreeListMatch(node.internalSuperInterfaces(), o.internalSuperInterfaces())) {
2133 if (level >= AST.JLS3) {
2134 if (!safeSubtreeListMatch(node.modifiers(), o.modifiers())) {
2137 if (!safeSubtreeListMatch(node.typeParameters(), o.typeParameters())) {
2140 if (!safeSubtreeMatch(node.getSuperclassType(), o.getSuperclassType())) {
2143 if (!safeSubtreeListMatch(node.superInterfaceTypes(), o.superInterfaceTypes())) {
2148 (node.isInterface() == o.isInterface())
2149 && safeSubtreeMatch(node.getJavadoc(), o.getJavadoc())
2150 && safeSubtreeMatch(node.getName(), o.getName())
2151 && safeSubtreeListMatch(node.bodyDeclarations(), o.bodyDeclarations()));
2155 * Returns whether the given node and the other object match.
2157 * The default implementation provided by this class tests whether the
2158 * other object is a node of the same type with structurally isomorphic
2159 * child subtrees. Subclasses may override this method as needed.
2162 * @param node the node
2163 * @param other the other object, or <code>null</code>
2164 * @return <code>true</code> if the subtree matches, or
2165 * <code>false</code> if they do not match or the other object has a
2166 * different node type or is <code>null</code>
2168 public boolean match(TypeDeclarationStatement node, Object other) {
2169 if (!(other instanceof TypeDeclarationStatement)) {
2172 TypeDeclarationStatement o = (TypeDeclarationStatement) other;
2173 return safeSubtreeMatch(node.getDeclaration(), o.getDeclaration());
2177 * Returns whether the given node and the other object match.
2179 * The default implementation provided by this class tests whether the
2180 * other object is a node of the same type with structurally isomorphic
2181 * child subtrees. Subclasses may override this method as needed.
2184 * @param node the node
2185 * @param other the other object, or <code>null</code>
2186 * @return <code>true</code> if the subtree matches, or
2187 * <code>false</code> if they do not match or the other object has a
2188 * different node type or is <code>null</code>
2190 public boolean match(TypeLiteral node, Object other) {
2191 if (!(other instanceof TypeLiteral)) {
2194 TypeLiteral o = (TypeLiteral) other;
2195 return safeSubtreeMatch(node.getType(), o.getType());
2199 * Returns whether the given node and the other object match.
2201 * The default implementation provided by this class tests whether the
2202 * other object is a node of the same type with structurally isomorphic
2203 * child subtrees. Subclasses may override this method as needed.
2206 * @param node the node
2207 * @param other the other object, or <code>null</code>
2208 * @return <code>true</code> if the subtree matches, or
2209 * <code>false</code> if they do not match or the other object has a
2210 * different node type or is <code>null</code>
2213 public boolean match(TypeParameter node, Object other) {
2214 if (!(other instanceof TypeParameter)) {
2217 TypeParameter o = (TypeParameter) other;
2218 return safeSubtreeMatch(node.getName(), o.getName())
2219 && safeSubtreeListMatch(node.typeBounds(), o.typeBounds());
2223 * Returns whether the given node and the other object match.
2225 * The default implementation provided by this class tests whether the
2226 * other object is a node of the same type with structurally isomorphic
2227 * child subtrees. Subclasses may override this method as needed.
2230 * @param node the node
2231 * @param other the other object, or <code>null</code>
2232 * @return <code>true</code> if the subtree matches, or
2233 * <code>false</code> if they do not match or the other object has a
2234 * different node type or is <code>null</code>
2236 public boolean match(VariableDeclarationExpression node, Object other) {
2237 if (!(other instanceof VariableDeclarationExpression)) {
2240 VariableDeclarationExpression o = (VariableDeclarationExpression) other;
2241 int level = node.getAST().apiLevel;
2242 if (level == AST.JLS2_INTERNAL) {
2243 if (node.getModifiers() != o.getModifiers()) {
2247 if (level >= AST.JLS3) {
2248 if (!safeSubtreeListMatch(node.modifiers(), o.modifiers())) {
2252 return safeSubtreeMatch(node.getType(), o.getType())
2253 && safeSubtreeListMatch(node.fragments(), o.fragments());
2257 * Returns whether the given node and the other object match.
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.
2264 * Note that extra array dimensions are compared since they are an
2265 * important part of the type of the variable.
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>
2274 public boolean match(VariableDeclarationFragment node, Object other) {
2275 if (!(other instanceof VariableDeclarationFragment)) {
2278 VariableDeclarationFragment o = (VariableDeclarationFragment) other;
2279 return safeSubtreeMatch(node.getName(), o.getName())
2280 && node.getExtraDimensions() == o.getExtraDimensions()
2281 && safeSubtreeMatch(node.getInitializer(), o.getInitializer());
2285 * Returns whether the given node and the other object match.
2287 * The default implementation provided by this class tests whether the
2288 * other object is a node of the same type with structurally isomorphic
2289 * child subtrees. Subclasses may override this method as needed.
2292 * @param node the node
2293 * @param other the other object, or <code>null</code>
2294 * @return <code>true</code> if the subtree matches, or
2295 * <code>false</code> if they do not match or the other object has a
2296 * different node type or is <code>null</code>
2298 public boolean match(VariableDeclarationStatement node, Object other) {
2299 if (!(other instanceof VariableDeclarationStatement)) {
2302 VariableDeclarationStatement o = (VariableDeclarationStatement) other;
2303 int level = node.getAST().apiLevel;
2304 if (level == AST.JLS2_INTERNAL) {
2305 if (node.getModifiers() != o.getModifiers()) {
2309 if (level >= AST.JLS3) {
2310 if (!safeSubtreeListMatch(node.modifiers(), o.modifiers())) {
2314 return safeSubtreeMatch(node.getType(), o.getType())
2315 && safeSubtreeListMatch(node.fragments(), o.fragments());
2319 * Returns whether the given node and the other object match.
2321 * The default implementation provided by this class tests whether the
2322 * other object is a node of the same type with structurally isomorphic
2323 * child subtrees. Subclasses may override this method as needed.
2326 * @param node the node
2327 * @param other the other object, or <code>null</code>
2328 * @return <code>true</code> if the subtree matches, or
2329 * <code>false</code> if they do not match or the other object has a
2330 * different node type or is <code>null</code>
2332 public boolean match(WhileStatement node, Object other) {
2333 if (!(other instanceof WhileStatement)) {
2336 WhileStatement o = (WhileStatement) other;
2338 safeSubtreeMatch(node.getExpression(), o.getExpression())
2339 && safeSubtreeMatch(node.getBody(), o.getBody()));
2343 * Returns whether the given node and the other object match.
2345 * The default implementation provided by this class tests whether the
2346 * other object is a node of the same type with structurally isomorphic
2347 * child subtrees. Subclasses may override this method as needed.
2350 * @param node the node
2351 * @param other the other object, or <code>null</code>
2352 * @return <code>true</code> if the subtree matches, or
2353 * <code>false</code> if they do not match or the other object has a
2354 * different node type or is <code>null</code>
2357 public boolean match(WildcardType node, Object other) {
2358 if (!(other instanceof WildcardType)) {
2361 WildcardType o = (WildcardType) other;
2362 return node.isUpperBound() == o.isUpperBound()
2363 && safeSubtreeMatch(node.getBound(), o.getBound());