KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > core > dom > ASTMatcher


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
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jdt.core.dom;
12
13 import java.util.Iterator JavaDoc;
14 import java.util.List JavaDoc;
15
16 /**
17  * Concrete superclass and default implementation of an AST subtree matcher.
18  * <p>
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.
22  * </p>
23  * <p>
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
35  * declarations.
36  * </p>
37  * <p>
38  * Subclasses may override (extend or reimplement) some or all of the
39  * <code>match</code> methods in order to define more specialized subtree
40  * matchers.
41  * </p>
42  *
43  * @see org.eclipse.jdt.core.dom.ASTNode#subtreeMatch(ASTMatcher, Object)
44  * @since 2.0
45  */

46 public class ASTMatcher {
47     
48     /**
49      * Indicates whether doc tags should be matched.
50      * @since 3.0
51      */

52     private boolean matchDocTags;
53     
54     /**
55      * Creates a new AST matcher instance.
56      * <p>
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.
61      * </p>
62      */

63     public ASTMatcher() {
64         this(false);
65     }
66
67     /**
68      * Creates a new AST matcher instance.
69      *
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)
73      * @since 3.0
74      */

75     public ASTMatcher(boolean matchDocTags) {
76         this.matchDocTags = matchDocTags;
77     }
78
79     /**
80      * Returns whether the given lists of AST nodes match pair wise according
81      * to <code>ASTNode.subtreeMatch</code>.
82      * <p>
83      * Note that this is a convenience method, useful for writing recursive
84      * subtree matchers.
85      * </p>
86      *
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)
94      */

95     public final boolean safeSubtreeListMatch(List JavaDoc list1, List JavaDoc list2) {
96         int size1 = list1.size();
97         int size2 = list2.size();
98         if (size1 != size2) {
99             return false;
100         }
101         for (Iterator JavaDoc 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)) {
105                 return false;
106             }
107         }
108         return true;
109     }
110
111     /**
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>.
116      * <p>
117      * Note that this is a convenience method, useful for writing recursive
118      * subtree matchers.
119      * </p>
120      *
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)
129      */

130     public final boolean safeSubtreeMatch(Object JavaDoc node1, Object JavaDoc node2) {
131         if (node1 == null && node2 == null) {
132             return true;
133         }
134         if (node1 == null || node2 == null) {
135             return false;
136         }
137         // N.B. call subtreeMatch even node1==node2!=null
138
return ((ASTNode) node1).subtreeMatch(this, node2);
139     }
140
141     /**
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>.
145      *
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
151      */

152     public static boolean safeEquals(Object JavaDoc o1, Object JavaDoc o2) {
153         if (o1 == o2) {
154             return true;
155         }
156         if (o1 == null || o2 == null) {
157             return false;
158         }
159         return o1.equals(o2);
160     }
161
162     /**
163      * Returns whether the given node and the other object match.
164      * <p>
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.
168      * </p>
169      *
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>
175      * @since 3.1
176      */

177     public boolean match(AnnotationTypeDeclaration node, Object JavaDoc other) {
178         if (!(other instanceof AnnotationTypeDeclaration)) {
179             return false;
180         }
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()));
187     }
188
189     /**
190      * Returns whether the given node and the other object match.
191      * <p>
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.
195      * </p>
196      *
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>
202      * @since 3.1
203      */

204     public boolean match(AnnotationTypeMemberDeclaration node, Object JavaDoc other) {
205         if (!(other instanceof AnnotationTypeMemberDeclaration)) {
206             return false;
207         }
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()));
215     }
216
217     /**
218      * Returns whether the given node and the other object match.
219      * <p>
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.
223      * </p>
224      *
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>
230      */

231     public boolean match(AnonymousClassDeclaration node, Object JavaDoc other) {
232         if (!(other instanceof AnonymousClassDeclaration)) {
233             return false;
234         }
235         AnonymousClassDeclaration o = (AnonymousClassDeclaration) other;
236         return safeSubtreeListMatch(node.bodyDeclarations(), o.bodyDeclarations());
237     }
238
239     /**
240      * Returns whether the given node and the other object match.
241      * <p>
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.
245      * </p>
246      *
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>
252      */

253     public boolean match(ArrayAccess node, Object JavaDoc other) {
254         if (!(other instanceof ArrayAccess)) {
255             return false;
256         }
257         ArrayAccess o = (ArrayAccess) other;
258         return (
259             safeSubtreeMatch(node.getArray(), o.getArray())
260                 && safeSubtreeMatch(node.getIndex(), o.getIndex()));
261     }
262
263     /**
264      * Returns whether the given node and the other object object match.
265      * <p>
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.
269      * </p>
270      *
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>
276      */

277     public boolean match(ArrayCreation node, Object JavaDoc other) {
278         if (!(other instanceof ArrayCreation)) {
279             return false;
280         }
281         ArrayCreation o = (ArrayCreation) other;
282         return (
283             safeSubtreeMatch(node.getType(), o.getType())
284                 && safeSubtreeListMatch(node.dimensions(), o.dimensions())
285                 && safeSubtreeMatch(node.getInitializer(), o.getInitializer()));
286     }
287
288     /**
289      * Returns whether the given node and the other object match.
290      * <p>
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.
294      * </p>
295      *
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>
301      */

302     public boolean match(ArrayInitializer node, Object JavaDoc other) {
303         if (!(other instanceof ArrayInitializer)) {
304             return false;
305         }
306         ArrayInitializer o = (ArrayInitializer) other;
307         return safeSubtreeListMatch(node.expressions(), o.expressions());
308     }
309
310     /**
311      * Returns whether the given node and the other object match.
312      * <p>
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.
316      * </p>
317      *
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>
323      */

324     public boolean match(ArrayType node, Object JavaDoc other) {
325         if (!(other instanceof ArrayType)) {
326             return false;
327         }
328         ArrayType o = (ArrayType) other;
329         return safeSubtreeMatch(node.getComponentType(), o.getComponentType());
330     }
331
332     /**
333      * Returns whether the given node and the other object match.
334      * <p>
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.
338      * </p>
339      *
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>
345      */

346     public boolean match(AssertStatement node, Object JavaDoc other) {
347         if (!(other instanceof AssertStatement)) {
348             return false;
349         }
350         AssertStatement o = (AssertStatement) other;
351         return (
352             safeSubtreeMatch(node.getExpression(), o.getExpression())
353                 && safeSubtreeMatch(node.getMessage(), o.getMessage()));
354     }
355
356     /**
357      * Returns whether the given node and the other object match.
358      * <p>
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.
362      * </p>
363      *
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>
369      */

370     public boolean match(Assignment node, Object JavaDoc other) {
371         if (!(other instanceof Assignment)) {
372             return false;
373         }
374         Assignment o = (Assignment) other;
375         return (
376             node.getOperator().equals(o.getOperator())
377                 && safeSubtreeMatch(node.getLeftHandSide(), o.getLeftHandSide())
378                 && safeSubtreeMatch(node.getRightHandSide(), o.getRightHandSide()));
379     }
380
381     /**
382      * Returns whether the given node and the other object match.
383      * <p>
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.
387      * </p>
388      *
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>
394      */

395     public boolean match(Block node, Object JavaDoc other) {
396         if (!(other instanceof Block)) {
397             return false;
398         }
399         Block o = (Block) other;
400         return safeSubtreeListMatch(node.statements(), o.statements());
401     }
402
403     /**
404      * Returns whether the given node and the other object match.
405      * <p>
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.
409      * </p>
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.
414      * </p>
415      *
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>
421      * @since 3.0
422      */

423     public boolean match(BlockComment node, Object JavaDoc other) {
424         if (!(other instanceof BlockComment)) {
425             return false;
426         }
427         return true;
428     }
429
430     /**
431      * Returns whether the given node and the other object match.
432      * <p>
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.
436      * </p>
437      *
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>
443      */

444     public boolean match(BooleanLiteral node, Object JavaDoc other) {
445         if (!(other instanceof BooleanLiteral)) {
446             return false;
447         }
448         BooleanLiteral o = (BooleanLiteral) other;
449         return node.booleanValue() == o.booleanValue();
450     }
451
452     /**
453      * Returns whether the given node and the other object match.
454      * <p>
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.
458      * </p>
459      *
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>
465      */

466     public boolean match(BreakStatement node, Object JavaDoc other) {
467         if (!(other instanceof BreakStatement)) {
468             return false;
469         }
470         BreakStatement o = (BreakStatement) other;
471         return safeSubtreeMatch(node.getLabel(), o.getLabel());
472     }
473
474     /**
475      * Returns whether the given node and the other object match.
476      * <p>
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.
480      * </p>
481      *
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>
487      */

488     public boolean match(CastExpression node, Object JavaDoc other) {
489         if (!(other instanceof CastExpression)) {
490             return false;
491         }
492         CastExpression o = (CastExpression) other;
493         return (
494             safeSubtreeMatch(node.getType(), o.getType())
495                 && safeSubtreeMatch(node.getExpression(), o.getExpression()));
496     }
497
498     /**
499      * Returns whether the given node and the other object match.
500      * <p>
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.
504      * </p>
505      *
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>
511      */

512     public boolean match(CatchClause node, Object JavaDoc other) {
513         if (!(other instanceof CatchClause)) {
514             return false;
515         }
516         CatchClause o = (CatchClause) other;
517         return (
518             safeSubtreeMatch(node.getException(), o.getException())
519                 && safeSubtreeMatch(node.getBody(), o.getBody()));
520     }
521
522     /**
523      * Returns whether the given node and the other object match.
524      * <p>
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.
528      * </p>
529      *
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>
535      */

536     public boolean match(CharacterLiteral node, Object JavaDoc other) {
537         if (!(other instanceof CharacterLiteral)) {
538             return false;
539         }
540         CharacterLiteral o = (CharacterLiteral) other;
541         return safeEquals(node.getEscapedValue(), o.getEscapedValue());
542     }
543
544     /**
545      * Returns whether the given node and the other object match.
546      * <p>
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.
550      * </p>
551      *
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>
557      */

558     public boolean match(ClassInstanceCreation node, Object JavaDoc other) {
559         if (!(other instanceof ClassInstanceCreation)) {
560             return false;
561         }
562         ClassInstanceCreation o = (ClassInstanceCreation) other;
563         int level = node.getAST().apiLevel;
564         if (level == AST.JLS2_INTERNAL) {
565             if (!safeSubtreeMatch(node.internalGetName(), o.internalGetName())) {
566                 return false;
567             }
568         }
569         if (level >= AST.JLS3) {
570             if (!safeSubtreeListMatch(node.typeArguments(), o.typeArguments())) {
571                 return false;
572             }
573             if (!safeSubtreeMatch(node.getType(), o.getType())) {
574                 return false;
575             }
576         }
577         return
578             safeSubtreeMatch(node.getExpression(), o.getExpression())
579                 && safeSubtreeListMatch(node.arguments(), o.arguments())
580                 && safeSubtreeMatch(
581                     node.getAnonymousClassDeclaration(),
582                     o.getAnonymousClassDeclaration());
583     }
584
585     /**
586      * Returns whether the given node and the other object match.
587      * <p>
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.
591      * </p>
592      *
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>
598      */

599     public boolean match(CompilationUnit node, Object JavaDoc other) {
600         if (!(other instanceof CompilationUnit)) {
601             return false;
602         }
603         CompilationUnit o = (CompilationUnit) other;
604         return (
605             safeSubtreeMatch(node.getPackage(), o.getPackage())
606                 && safeSubtreeListMatch(node.imports(), o.imports())
607                 && safeSubtreeListMatch(node.types(), o.types()));
608     }
609
610     /**
611      * Returns whether the given node and the other object match.
612      * <p>
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.
616      * </p>
617      *
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>
623      */

624     public boolean match(ConditionalExpression node, Object JavaDoc other) {
625         if (!(other instanceof ConditionalExpression)) {
626             return false;
627         }
628         ConditionalExpression o = (ConditionalExpression) other;
629         return (
630             safeSubtreeMatch(node.getExpression(), o.getExpression())
631                 && safeSubtreeMatch(node.getThenExpression(), o.getThenExpression())
632                 && safeSubtreeMatch(node.getElseExpression(), o.getElseExpression()));
633     }
634
635     /**
636      * Returns whether the given node and the other object match.
637      * <p>
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.
641      * </p>
642      *
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>
648      */

649     public boolean match(ConstructorInvocation node, Object JavaDoc other) {
650         if (!(other instanceof ConstructorInvocation)) {
651             return false;
652         }
653         ConstructorInvocation o = (ConstructorInvocation) other;
654         if (node.getAST().apiLevel >= AST.JLS3) {
655             if (!safeSubtreeListMatch(node.typeArguments(), o.typeArguments())) {
656                 return false;
657             }
658         }
659         return safeSubtreeListMatch(node.arguments(), o.arguments());
660     }
661
662     /**
663      * Returns whether the given node and the other object match.
664      * <p>
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.
668      * </p>
669      *
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>
675      */

676     public boolean match(ContinueStatement node, Object JavaDoc other) {
677         if (!(other instanceof ContinueStatement)) {
678             return false;
679         }
680         ContinueStatement o = (ContinueStatement) other;
681         return safeSubtreeMatch(node.getLabel(), o.getLabel());
682     }
683
684     /**
685      * Returns whether the given node and the other object match.
686      * <p>
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.
690      * </p>
691      *
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>
697      */

698     public boolean match(DoStatement node, Object JavaDoc other) {
699         if (!(other instanceof DoStatement)) {
700             return false;
701         }
702         DoStatement o = (DoStatement) other;
703         return (
704             safeSubtreeMatch(node.getExpression(), o.getExpression())
705                 && safeSubtreeMatch(node.getBody(), o.getBody()));
706     }
707     
708     /**
709      * Returns whether the given node and the other object match.
710      * <p>
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.
714      * </p>
715      *
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>
721      */

722     public boolean match(EmptyStatement node, Object JavaDoc other) {
723         if (!(other instanceof EmptyStatement)) {
724             return false;
725         }
726         return true;
727     }
728
729     /**
730      * Returns whether the given node and the other object match.
731      * <p>
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.
735      * </p>
736      *
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>
742      * @since 3.1
743      */

744     public boolean match(EnhancedForStatement node, Object JavaDoc other) {
745         if (!(other instanceof EnhancedForStatement)) {
746             return false;
747         }
748         EnhancedForStatement o = (EnhancedForStatement) other;
749         return (
750             safeSubtreeMatch(node.getParameter(), o.getParameter())
751                 && safeSubtreeMatch(node.getExpression(), o.getExpression())
752                 && safeSubtreeMatch(node.getBody(), o.getBody()));
753     }
754
755     /**
756      * Returns whether the given node and the other object match.
757      * <p>
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.
761      * </p>
762      *
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>
768      * @since 3.1
769      */

770     public boolean match(EnumConstantDeclaration node, Object JavaDoc other) {
771         if (!(other instanceof EnumConstantDeclaration)) {
772             return false;
773         }
774         EnumConstantDeclaration o = (EnumConstantDeclaration) other;
775         return (
776             safeSubtreeMatch(node.getJavadoc(), o.getJavadoc())
777                 && safeSubtreeListMatch(node.modifiers(), o.modifiers())
778                 && safeSubtreeMatch(node.getName(), o.getName())
779                 && safeSubtreeListMatch(node.arguments(), o.arguments())
780                 && safeSubtreeMatch(
781                     node.getAnonymousClassDeclaration(),
782                     o.getAnonymousClassDeclaration()));
783     }
784     
785     /**
786      * Returns whether the given node and the other object match.
787      * <p>
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.
791      * </p>
792      *
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>
798      * @since 3.1
799      */

800     public boolean match(EnumDeclaration node, Object JavaDoc other) {
801         if (!(other instanceof EnumDeclaration)) {
802             return false;
803         }
804         EnumDeclaration o = (EnumDeclaration) other;
805         return (
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()));
814     }
815     
816     /**
817      * Returns whether the given node and the other object match.
818      * <p>
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.
822      * </p>
823      *
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>
829      */

830     public boolean match(ExpressionStatement node, Object JavaDoc other) {
831         if (!(other instanceof ExpressionStatement)) {
832             return false;
833         }
834         ExpressionStatement o = (ExpressionStatement) other;
835         return safeSubtreeMatch(node.getExpression(), o.getExpression());
836     }
837
838     /**
839      * Returns whether the given node and the other object match.
840      * <p>
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.
844      * </p>
845      *
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>
851      */

852     public boolean match(FieldAccess node, Object JavaDoc other) {
853         if (!(other instanceof FieldAccess)) {
854             return false;
855         }
856         FieldAccess o = (FieldAccess) other;
857         return (
858             safeSubtreeMatch(node.getExpression(), o.getExpression())
859                 && safeSubtreeMatch(node.getName(), o.getName()));
860     }
861
862     /**
863      * Returns whether the given node and the other object match.
864      * <p>
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.
868      * </p>
869      *
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>
875      */

876     public boolean match(FieldDeclaration node, Object JavaDoc other) {
877         if (!(other instanceof FieldDeclaration)) {
878             return false;
879         }
880         FieldDeclaration o = (FieldDeclaration) other;
881         int level = node.getAST().apiLevel;
882         if (level == AST.JLS2_INTERNAL) {
883             if (node.getModifiers() != o.getModifiers()) {
884                 return false;
885             }
886         }
887         if (level >= AST.JLS3) {
888             if (!safeSubtreeListMatch(node.modifiers(), o.modifiers())) {
889                 return false;
890             }
891         }
892         return
893             safeSubtreeMatch(node.getJavadoc(), o.getJavadoc())
894             && safeSubtreeMatch(node.getType(), o.getType())
895             && safeSubtreeListMatch(node.fragments(), o.fragments());
896     }
897
898     /**
899      * Returns whether the given node and the other object match.
900      * <p>
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.
904      * </p>
905      *
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>
911      */

912     public boolean match(ForStatement node, Object JavaDoc other) {
913         if (!(other instanceof ForStatement)) {
914             return false;
915         }
916         ForStatement o = (ForStatement) other;
917         return (
918             safeSubtreeListMatch(node.initializers(), o.initializers())
919                 && safeSubtreeMatch(node.getExpression(), o.getExpression())
920                 && safeSubtreeListMatch(node.updaters(), o.updaters())
921                 && safeSubtreeMatch(node.getBody(), o.getBody()));
922     }
923
924     /**
925      * Returns whether the given node and the other object match.
926      * <p>
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.
930      * </p>
931      *
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>
937      */

938     public boolean match(IfStatement node, Object JavaDoc other) {
939         if (!(other instanceof IfStatement)) {
940             return false;
941         }
942         IfStatement o = (IfStatement) other;
943         return (
944             safeSubtreeMatch(node.getExpression(), o.getExpression())
945                 && safeSubtreeMatch(node.getThenStatement(), o.getThenStatement())
946                 && safeSubtreeMatch(node.getElseStatement(), o.getElseStatement()));
947     }
948
949     /**
950      * Returns whether the given node and the other object match.
951      * <p>
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.
955      * </p>
956      *
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>
962      */

963     public boolean match(ImportDeclaration node, Object JavaDoc other) {
964         if (!(other instanceof ImportDeclaration)) {
965             return false;
966         }
967         ImportDeclaration o = (ImportDeclaration) other;
968         if (node.getAST().apiLevel >= AST.JLS3) {
969             if (node.isStatic() != o.isStatic()) {
970                 return false;
971             }
972         }
973         return (
974             safeSubtreeMatch(node.getName(), o.getName())
975                 && node.isOnDemand() == o.isOnDemand());
976     }
977
978     /**
979      * Returns whether the given node and the other object match.
980      * <p>
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.
984      * </p>
985      *
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>
991      */

992     public boolean match(InfixExpression node, Object JavaDoc other) {
993         if (!(other instanceof InfixExpression)) {
994             return false;
995         }
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())) {
1000                return false;
1001            }
1002        }
1003        if (node.hasExtendedOperands() != o.hasExtendedOperands()) {
1004            return false;
1005        }
1006        return (
1007            node.getOperator().equals(o.getOperator())
1008                && safeSubtreeMatch(node.getLeftOperand(), o.getLeftOperand())
1009                && safeSubtreeMatch(node.getRightOperand(), o.getRightOperand()));
1010    }
1011
1012    /**
1013     * Returns whether the given node and the other object match.
1014     * <p>
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.
1018     * </p>
1019     *
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>
1025     */

1026    public boolean match(InstanceofExpression node, Object JavaDoc other) {
1027        if (!(other instanceof InstanceofExpression)) {
1028            return false;
1029        }
1030        InstanceofExpression o = (InstanceofExpression) other;
1031        return (
1032                safeSubtreeMatch(node.getLeftOperand(), o.getLeftOperand())
1033                && safeSubtreeMatch(node.getRightOperand(), o.getRightOperand()));
1034    }
1035
1036    /**
1037     * Returns whether the given node and the other object match.
1038     * <p>
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.
1042     * </p>
1043     *
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>
1049     */

1050    public boolean match(Initializer node, Object JavaDoc other) {
1051        if (!(other instanceof Initializer)) {
1052            return false;
1053        }
1054        Initializer o = (Initializer) other;
1055        int level = node.getAST().apiLevel;
1056        if (level == AST.JLS2_INTERNAL) {
1057            if (node.getModifiers() != o.getModifiers()) {
1058                return false;
1059            }
1060        }
1061        if (level >= AST.JLS3) {
1062            if (!safeSubtreeListMatch(node.modifiers(), o.modifiers())) {
1063                return false;
1064            }
1065        }
1066        return (
1067                safeSubtreeMatch(node.getJavadoc(), o.getJavadoc())
1068                && safeSubtreeMatch(node.getBody(), o.getBody()));
1069    }
1070
1071    /**
1072     * Returns whether the given node and the other object match.
1073     * <p>
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.
1087     * </p>
1088     *
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)
1096     */

1097    public boolean match(Javadoc node, Object JavaDoc other) {
1098        if (!(other instanceof Javadoc)) {
1099            return false;
1100        }
1101        Javadoc o = (Javadoc) other;
1102        if (this.matchDocTags) {
1103            return safeSubtreeListMatch(node.tags(), o.tags());
1104        } else {
1105            return compareDeprecatedComment(node, o);
1106        }
1107    }
1108
1109    /**
1110     * Return whether the deprecated comment strings of the given java doc are equals.
1111     * <p>
1112     * Note the only purpose of this method is to hide deprecated warnings.
1113     * @deprecated mark deprecated to hide deprecated usage
1114     */

1115    private boolean compareDeprecatedComment(Javadoc first, Javadoc second) {
1116        if (first.getAST().apiLevel == AST.JLS2_INTERNAL) {
1117            return safeEquals(first.getComment(), second.getComment());
1118        } else {
1119            return true;
1120        }
1121    }
1122
1123    /**
1124     * Returns whether the given node and the other object match.
1125     * <p>
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.
1129     * </p>
1130     *
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>
1136     */

1137    public boolean match(LabeledStatement node, Object JavaDoc other) {
1138        if (!(other instanceof LabeledStatement)) {
1139            return false;
1140        }
1141        LabeledStatement o = (LabeledStatement) other;
1142        return (
1143            safeSubtreeMatch(node.getLabel(), o.getLabel())
1144                && safeSubtreeMatch(node.getBody(), o.getBody()));
1145    }
1146
1147    /**
1148     * Returns whether the given node and the other object match.
1149     * <p>
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.
1153     * </p>
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.
1158     * </p>
1159     *
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>
1165     * @since 3.0
1166     */

1167    public boolean match(LineComment node, Object JavaDoc other) {
1168        if (!(other instanceof LineComment)) {
1169            return false;
1170        }
1171        return true;
1172    }
1173    
1174    /**
1175     * Returns whether the given node and the other object match.
1176     * <p>
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.
1180     * </p>
1181     *
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>
1187     * @since 3.1
1188     */

1189    public boolean match(MarkerAnnotation node, Object JavaDoc other) {
1190        if (!(other instanceof MarkerAnnotation)) {
1191            return false;
1192        }
1193        MarkerAnnotation o = (MarkerAnnotation) other;
1194        return safeSubtreeMatch(node.getTypeName(), o.getTypeName());
1195    }
1196
1197    /**
1198     * Returns whether the given node and the other object match.
1199     * <p>
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.
1203     * </p>
1204     *
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>
1210     * @since 3.0
1211     */

1212    public boolean match(MemberRef node, Object JavaDoc other) {
1213        if (!(other instanceof MemberRef)) {
1214            return false;
1215        }
1216        MemberRef o = (MemberRef) other;
1217        return (
1218                safeSubtreeMatch(node.getQualifier(), o.getQualifier())
1219                && safeSubtreeMatch(node.getName(), o.getName()));
1220    }
1221    
1222    /**
1223     * Returns whether the given node and the other object match.
1224     * <p>
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.
1228     * </p>
1229     *
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>
1235     * @since 3.1
1236     */

1237    public boolean match(MemberValuePair node, Object JavaDoc other) {
1238        if (!(other instanceof MemberValuePair)) {
1239            return false;
1240        }
1241        MemberValuePair o = (MemberValuePair) other;
1242        return (safeSubtreeMatch(node.getName(), o.getName())
1243                && safeSubtreeMatch(node.getValue(), o.getValue()));
1244    }
1245
1246    /**
1247     * Returns whether the given node and the other object match.
1248     * <p>
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.
1252     * </p>
1253     *
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>
1259     * @since 3.0
1260     */

1261    public boolean match(MethodRef node, Object JavaDoc other) {
1262        if (!(other instanceof MethodRef)) {
1263            return false;
1264        }
1265        MethodRef o = (MethodRef) other;
1266        return (
1267                safeSubtreeMatch(node.getQualifier(), o.getQualifier())
1268                && safeSubtreeMatch(node.getName(), o.getName())
1269                && safeSubtreeListMatch(node.parameters(), o.parameters()));
1270    }
1271
1272    /**
1273     * Returns whether the given node and the other object match.
1274     * <p>
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.
1278     * </p>
1279     *
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>
1285     * @since 3.0
1286     */

1287    public boolean match(MethodRefParameter node, Object JavaDoc other) {
1288        if (!(other instanceof MethodRefParameter)) {
1289            return false;
1290        }
1291        MethodRefParameter o = (MethodRefParameter) other;
1292        int level = node.getAST().apiLevel;
1293        if (level >= AST.JLS3) {
1294            if (node.isVarargs() != o.isVarargs()) {
1295                return false;
1296            }
1297        }
1298        return (
1299                safeSubtreeMatch(node.getType(), o.getType())
1300                && safeSubtreeMatch(node.getName(), o.getName()));
1301    }
1302    
1303    /**
1304     * Returns whether the given node and the other object match.
1305     * <p>
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.
1309     * </p>
1310     * <p>
1311     * Note that extra array dimensions are compared since they are an
1312     * important part of the method declaration.
1313     * </p>
1314     * <p>
1315     * Note that the method return types are compared even for constructor
1316     * declarations.
1317     * </p>
1318     *
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>
1324     */

1325    public boolean match(MethodDeclaration node, Object JavaDoc other) {
1326        if (!(other instanceof MethodDeclaration)) {
1327            return false;
1328        }
1329        MethodDeclaration o = (MethodDeclaration) other;
1330        int level = node.getAST().apiLevel;
1331        if (level == AST.JLS2_INTERNAL) {
1332            if (node.getModifiers() != o.getModifiers()) {
1333                return false;
1334            }
1335            if (!safeSubtreeMatch(node.internalGetReturnType(), o.internalGetReturnType())) {
1336                return false;
1337            }
1338        }
1339        if (level >= AST.JLS3) {
1340            if (!safeSubtreeListMatch(node.modifiers(), o.modifiers())) {
1341                return false;
1342            }
1343            if (!safeSubtreeMatch(node.getReturnType2(), o.getReturnType2())) {
1344                return false;
1345            }
1346            // n.b. compare type parameters even for constructors
1347
if (!safeSubtreeListMatch(node.typeParameters(), o.typeParameters())) {
1348                return false;
1349            }
1350        }
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()));
1359    }
1360
1361    /**
1362     * Returns whether the given node and the other object match.
1363     * <p>
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.
1367     * </p>
1368     *
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>
1374     */

1375    public boolean match(MethodInvocation node, Object JavaDoc other) {
1376        if (!(other instanceof MethodInvocation)) {
1377            return false;
1378        }
1379        MethodInvocation o = (MethodInvocation) other;
1380        if (node.getAST().apiLevel >= AST.JLS3) {
1381            if (!safeSubtreeListMatch(node.typeArguments(), o.typeArguments())) {
1382                return false;
1383            }
1384        }
1385        return (
1386            safeSubtreeMatch(node.getExpression(), o.getExpression())
1387                && safeSubtreeMatch(node.getName(), o.getName())
1388                && safeSubtreeListMatch(node.arguments(), o.arguments()));
1389    }
1390
1391    /**
1392     * Returns whether the given node and the other object match.
1393     * <p>
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.
1397     * </p>
1398     *
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>
1404     * @since 3.1
1405     */

1406    public boolean match(Modifier node, Object JavaDoc other) {
1407        if (!(other instanceof Modifier)) {
1408            return false;
1409        }
1410        Modifier o = (Modifier) other;
1411        return (node.getKeyword() == o.getKeyword());
1412    }
1413
1414    /**
1415     * Returns whether the given node and the other object match.
1416     * <p>
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.
1420     * </p>
1421     *
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>
1427     * @since 3.1
1428     */

1429    public boolean match(NormalAnnotation node, Object JavaDoc other) {
1430        if (!(other instanceof NormalAnnotation)) {
1431            return false;
1432        }
1433        NormalAnnotation o = (NormalAnnotation) other;
1434        return (safeSubtreeMatch(node.getTypeName(), o.getTypeName())
1435                    && safeSubtreeListMatch(node.values(), o.values()));
1436    }
1437
1438    /**
1439     * Returns whether the given node and the other object match.
1440     * <p>
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.
1444     * </p>
1445     *
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>
1451     */

1452    public boolean match(NullLiteral node, Object JavaDoc other) {
1453        if (!(other instanceof NullLiteral)) {
1454            return false;
1455        }
1456        return true;
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     */

1473    public boolean match(NumberLiteral node, Object JavaDoc other) {
1474        if (!(other instanceof NumberLiteral)) {
1475            return false;
1476        }
1477        NumberLiteral o = (NumberLiteral) other;
1478        return safeEquals(node.getToken(), o.getToken());
1479    }
1480
1481    /**
1482     * Returns whether the given node and the other object match.
1483     * <p>
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.
1487     * </p>
1488     *
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>
1494     */

1495    public boolean match(PackageDeclaration node, Object JavaDoc other) {
1496        if (!(other instanceof PackageDeclaration)) {
1497            return false;
1498        }
1499        PackageDeclaration o = (PackageDeclaration) other;
1500        if (node.getAST().apiLevel >= AST.JLS3) {
1501            if (!safeSubtreeMatch(node.getJavadoc(), o.getJavadoc())) {
1502                return false;
1503            }
1504            if (!safeSubtreeListMatch(node.annotations(), o.annotations())) {
1505                return false;
1506            }
1507        }
1508        return safeSubtreeMatch(node.getName(), o.getName());
1509    }
1510
1511    /**
1512     * Returns whether the given node and the other object match.
1513     * <p>
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.
1517     * </p>
1518     *
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>
1524     * @since 3.1
1525     */

1526    public boolean match(ParameterizedType node, Object JavaDoc other) {
1527        if (!(other instanceof ParameterizedType)) {
1528            return false;
1529        }
1530        ParameterizedType o = (ParameterizedType) other;
1531        return safeSubtreeMatch(node.getType(), o.getType())
1532                && safeSubtreeListMatch(node.typeArguments(), o.typeArguments());
1533    }
1534
1535    /**
1536     * Returns whether the given node and the other object match.
1537     * <p>
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.
1541     * </p>
1542     *
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>
1548     */

1549    public boolean match(ParenthesizedExpression node, Object JavaDoc other) {
1550        if (!(other instanceof ParenthesizedExpression)) {
1551            return false;
1552        }
1553        ParenthesizedExpression o = (ParenthesizedExpression) other;
1554        return safeSubtreeMatch(node.getExpression(), o.getExpression());
1555    }
1556
1557    /**
1558     * Returns whether the given node and the other object match.
1559     * <p>
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.
1563     * </p>
1564     *
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>
1570     */

1571    public boolean match(PostfixExpression node, Object JavaDoc other) {
1572        if (!(other instanceof PostfixExpression)) {
1573            return false;
1574        }
1575        PostfixExpression o = (PostfixExpression) other;
1576        return (
1577            node.getOperator().equals(o.getOperator())
1578                && safeSubtreeMatch(node.getOperand(), o.getOperand()));
1579    }
1580
1581    /**
1582     * Returns whether the given node and the other object match.
1583     * <p>
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.
1587     * </p>
1588     *
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>
1594     */

1595    public boolean match(PrefixExpression node, Object JavaDoc other) {
1596        if (!(other instanceof PrefixExpression)) {
1597            return false;
1598        }
1599        PrefixExpression o = (PrefixExpression) other;
1600        return (
1601            node.getOperator().equals(o.getOperator())
1602                && safeSubtreeMatch(node.getOperand(), o.getOperand()));
1603    }
1604
1605    /**
1606     * Returns whether the given node and the other object match.
1607     * <p>
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.
1611     * </p>
1612     *
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>
1618     */

1619    public boolean match(PrimitiveType node, Object JavaDoc other) {
1620        if (!(other instanceof PrimitiveType)) {
1621            return false;
1622        }
1623        PrimitiveType o = (PrimitiveType) other;
1624        return (node.getPrimitiveTypeCode() == o.getPrimitiveTypeCode());
1625    }
1626
1627    /**
1628     * Returns whether the given node and the other object match.
1629     * <p>
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.
1633     * </p>
1634     *
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>
1640     */

1641    public boolean match(QualifiedName node, Object JavaDoc other) {
1642        if (!(other instanceof QualifiedName)) {
1643            return false;
1644        }
1645        QualifiedName o = (QualifiedName) other;
1646        return (
1647            safeSubtreeMatch(node.getQualifier(), o.getQualifier())
1648                && safeSubtreeMatch(node.getName(), o.getName()));
1649    }
1650
1651    /**
1652     * Returns whether the given node and the other object match.
1653     * <p>
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.
1657     * </p>
1658     *
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>
1664     * @since 3.1
1665     */

1666    public boolean match(QualifiedType node, Object JavaDoc other) {
1667        if (!(other instanceof QualifiedType)) {
1668            return false;
1669        }
1670        QualifiedType o = (QualifiedType) other;
1671        return (
1672            safeSubtreeMatch(node.getQualifier(), o.getQualifier())
1673                && safeSubtreeMatch(node.getName(), o.getName()));
1674    }
1675
1676    /**
1677     * Returns whether the given node and the other object match.
1678     * <p>
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.
1682     * </p>
1683     *
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>
1689     */

1690    public boolean match(ReturnStatement node, Object JavaDoc other) {
1691        if (!(other instanceof ReturnStatement)) {
1692            return false;
1693        }
1694        ReturnStatement o = (ReturnStatement) other;
1695        return safeSubtreeMatch(node.getExpression(), o.getExpression());
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     */

1712    public boolean match(SimpleName node, Object JavaDoc other) {
1713        if (!(other instanceof SimpleName)) {
1714            return false;
1715        }
1716        SimpleName o = (SimpleName) other;
1717        return node.getIdentifier().equals(o.getIdentifier());
1718    }
1719
1720    /**
1721     * Returns whether the given node and the other object match.
1722     * <p>
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.
1726     * </p>
1727     *
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>
1733     */

1734    public boolean match(SimpleType node, Object JavaDoc other) {
1735        if (!(other instanceof SimpleType)) {
1736            return false;
1737        }
1738        SimpleType o = (SimpleType) other;
1739        return safeSubtreeMatch(node.getName(), o.getName());
1740    }
1741
1742    /**
1743     * Returns whether the given node and the other object match.
1744     * <p>
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.
1748     * </p>
1749     *
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>
1755     * @since 3.1
1756     */

1757    public boolean match(SingleMemberAnnotation node, Object JavaDoc other) {
1758        if (!(other instanceof SingleMemberAnnotation)) {
1759            return false;
1760        }
1761        SingleMemberAnnotation o = (SingleMemberAnnotation) other;
1762        return (safeSubtreeMatch(node.getTypeName(), o.getTypeName())
1763                && safeSubtreeMatch(node.getValue(), o.getValue()));
1764    }
1765
1766    /**
1767     * Returns whether the given node and the other object match.
1768     * <p>
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.
1772     * </p>
1773     * <p>
1774     * Note that extra array dimensions and the variable arity flag
1775     * are compared since they are both important parts of the declaration.
1776     * </p>
1777     *
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>
1783     */

1784    public boolean match(SingleVariableDeclaration node, Object JavaDoc other) {
1785        if (!(other instanceof SingleVariableDeclaration)) {
1786            return false;
1787        }
1788        SingleVariableDeclaration o = (SingleVariableDeclaration) other;
1789        int level = node.getAST().apiLevel;
1790        if (level == AST.JLS2_INTERNAL) {
1791            if (node.getModifiers() != o.getModifiers()) {
1792                return false;
1793            }
1794        }
1795        if (level >= AST.JLS3) {
1796            if (!safeSubtreeListMatch(node.modifiers(), o.modifiers())) {
1797                return false;
1798            }
1799            if (node.isVarargs() != o.isVarargs()) {
1800                return false;
1801            }
1802        }
1803        return
1804            safeSubtreeMatch(node.getType(), o.getType())
1805                && safeSubtreeMatch(node.getName(), o.getName())
1806                && node.getExtraDimensions() == o.getExtraDimensions()
1807                && safeSubtreeMatch(node.getInitializer(), o.getInitializer());
1808    }
1809
1810    /**
1811     * Returns whether the given node and the other object match.
1812     * <p>
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.
1816     * </p>
1817     *
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>
1823     */

1824    public boolean match(StringLiteral node, Object JavaDoc other) {
1825        if (!(other instanceof StringLiteral)) {
1826            return false;
1827        }
1828        StringLiteral o = (StringLiteral) other;
1829        return safeEquals(node.getEscapedValue(), o.getEscapedValue());
1830    }
1831
1832    /**
1833     * Returns whether the given node and the other object match.
1834     * <p>
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.
1838     * </p>
1839     *
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>
1845     */

1846    public boolean match(SuperConstructorInvocation node, Object JavaDoc other) {
1847        if (!(other instanceof SuperConstructorInvocation)) {
1848            return false;
1849        }
1850        SuperConstructorInvocation o = (SuperConstructorInvocation) other;
1851        if (node.getAST().apiLevel >= AST.JLS3) {
1852            if (!safeSubtreeListMatch(node.typeArguments(), o.typeArguments())) {
1853                return false;
1854            }
1855        }
1856        return (
1857            safeSubtreeMatch(node.getExpression(), o.getExpression())
1858                && safeSubtreeListMatch(node.arguments(), o.arguments()));
1859    }
1860
1861    /**
1862     * Returns whether the given node and the other object match.
1863     * <p>
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.
1867     * </p>
1868     *
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>
1874     */

1875    public boolean match(SuperFieldAccess node, Object JavaDoc other) {
1876        if (!(other instanceof SuperFieldAccess)) {
1877            return false;
1878        }
1879        SuperFieldAccess o = (SuperFieldAccess) other;
1880        return (
1881            safeSubtreeMatch(node.getName(), o.getName())
1882                && safeSubtreeMatch(node.getQualifier(), o.getQualifier()));
1883    }
1884
1885    /**
1886     * Returns whether the given node and the other object match.
1887     * <p>
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.
1891     * </p>
1892     *
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>
1898     */

1899    public boolean match(SuperMethodInvocation node, Object JavaDoc other) {
1900        if (!(other instanceof SuperMethodInvocation)) {
1901            return false;
1902        }
1903        SuperMethodInvocation o = (SuperMethodInvocation) other;
1904        if (node.getAST().apiLevel >= AST.JLS3) {
1905            if (!safeSubtreeListMatch(node.typeArguments(), o.typeArguments())) {
1906                return false;
1907            }
1908        }
1909        return (
1910            safeSubtreeMatch(node.getQualifier(), o.getQualifier())
1911                && safeSubtreeMatch(node.getName(), o.getName())
1912                && safeSubtreeListMatch(node.arguments(), o.arguments()));
1913    }
1914
1915    /**
1916     * Returns whether the given node and the other object match.
1917     * <p>
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.
1921     * </p>
1922     *
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>
1928     */

1929    public boolean match(SwitchCase node, Object JavaDoc other) {
1930        if (!(other instanceof SwitchCase)) {
1931            return false;
1932        }
1933        SwitchCase o = (SwitchCase) other;
1934        return safeSubtreeMatch(node.getExpression(), o.getExpression());
1935    }
1936
1937    /**
1938     * Returns whether the given node and the other object match.
1939     * <p>
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.
1943     * </p>
1944     *
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>
1950     */

1951    public boolean match(SwitchStatement node, Object JavaDoc other) {
1952        if (!(other instanceof SwitchStatement)) {
1953            return false;
1954        }
1955        SwitchStatement o = (SwitchStatement) other;
1956        return (
1957            safeSubtreeMatch(node.getExpression(), o.getExpression())
1958                && safeSubtreeListMatch(node.statements(), o.statements()));
1959    }
1960
1961    /**
1962     * Returns whether the given node and the other object match.
1963     * <p>
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.
1967     * </p>
1968     *
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>
1974     */

1975    public boolean match(SynchronizedStatement node, Object JavaDoc other) {
1976        if (!(other instanceof SynchronizedStatement)) {
1977            return false;
1978        }
1979        SynchronizedStatement o = (SynchronizedStatement) other;
1980        return (
1981            safeSubtreeMatch(node.getExpression(), o.getExpression())
1982                && safeSubtreeMatch(node.getBody(), o.getBody()));
1983    }
1984
1985    /**
1986     * Returns whether the given node and the other object match.
1987     * <p>
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.
1991     * </p>
1992     *
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>
1998     * @since 3.0
1999     */

2000    public boolean match(TagElement node, Object JavaDoc other) {
2001        if (!(other instanceof TagElement)) {
2002            return false;
2003        }
2004        TagElement o = (TagElement) other;
2005        return (
2006                safeEquals(node.getTagName(), o.getTagName())
2007                && safeSubtreeListMatch(node.fragments(), o.fragments()));
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.0
2024     */

2025    public boolean match(TextElement node, Object JavaDoc other) {
2026        if (!(other instanceof TextElement)) {
2027            return false;
2028        }
2029        TextElement o = (TextElement) other;
2030        return safeEquals(node.getText(), o.getText());
2031    }
2032
2033    /**
2034     * Returns whether the given node and the other object match.
2035     * <p>
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.
2039     * </p>
2040     *
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>
2046     */

2047    public boolean match(ThisExpression node, Object JavaDoc other) {
2048        if (!(other instanceof ThisExpression)) {
2049            return false;
2050        }
2051        ThisExpression o = (ThisExpression) other;
2052        return safeSubtreeMatch(node.getQualifier(), o.getQualifier());
2053    }
2054
2055    /**
2056     * Returns whether the given node and the other object match.
2057     * <p>
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.
2061     * </p>
2062     *
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>
2068     */

2069    public boolean match(ThrowStatement node, Object JavaDoc other) {
2070        if (!(other instanceof ThrowStatement)) {
2071            return false;
2072        }
2073        ThrowStatement o = (ThrowStatement) other;
2074        return safeSubtreeMatch(node.getExpression(), o.getExpression());
2075    }
2076
2077    /**
2078     * Returns whether the given node and the other object match.
2079     * <p>
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.
2083     * </p>
2084     *
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>
2090     */

2091    public boolean match(TryStatement node, Object JavaDoc other) {
2092        if (!(other instanceof TryStatement)) {
2093            return false;
2094        }
2095        TryStatement o = (TryStatement) other;
2096        return (
2097            safeSubtreeMatch(node.getBody(), o.getBody())
2098                && safeSubtreeListMatch(node.catchClauses(), o.catchClauses())
2099                && safeSubtreeMatch(node.getFinally(), o.getFinally()));
2100    }
2101
2102    /**
2103     * Returns whether the given node and the other object match.
2104     * <p>
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.
2108     * </p>
2109     *
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>
2115     */

2116    public boolean match(TypeDeclaration node, Object JavaDoc other) {
2117        if (!(other instanceof TypeDeclaration)) {
2118            return false;
2119        }
2120        TypeDeclaration o = (TypeDeclaration) other;
2121        int level = node.getAST().apiLevel;
2122        if (level == AST.JLS2_INTERNAL) {
2123            if (node.getModifiers() != o.getModifiers()) {
2124                return false;
2125            }
2126            if (!safeSubtreeMatch(node.internalGetSuperclass(), o.internalGetSuperclass())) {
2127                return false;
2128            }
2129            if (!safeSubtreeListMatch(node.internalSuperInterfaces(), o.internalSuperInterfaces())) {
2130                return false;
2131            }
2132        }
2133        if (level >= AST.JLS3) {
2134            if (!safeSubtreeListMatch(node.modifiers(), o.modifiers())) {
2135                return false;
2136            }
2137            if (!safeSubtreeListMatch(node.typeParameters(), o.typeParameters())) {
2138                return false;
2139            }
2140            if (!safeSubtreeMatch(node.getSuperclassType(), o.getSuperclassType())) {
2141                return false;
2142            }
2143            if (!safeSubtreeListMatch(node.superInterfaceTypes(), o.superInterfaceTypes())) {
2144                return false;
2145            }
2146        }
2147        return (
2148                (node.isInterface() == o.isInterface())
2149                && safeSubtreeMatch(node.getJavadoc(), o.getJavadoc())
2150                && safeSubtreeMatch(node.getName(), o.getName())
2151                && safeSubtreeListMatch(node.bodyDeclarations(), o.bodyDeclarations()));
2152    }
2153
2154    /**
2155     * Returns whether the given node and the other object match.
2156     * <p>
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.
2160     * </p>
2161     *
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>
2167     */

2168    public boolean match(TypeDeclarationStatement node, Object JavaDoc other) {
2169        if (!(other instanceof TypeDeclarationStatement)) {
2170            return false;
2171        }
2172        TypeDeclarationStatement o = (TypeDeclarationStatement) other;
2173        return safeSubtreeMatch(node.getDeclaration(), o.getDeclaration());
2174    }
2175
2176    /**
2177     * Returns whether the given node and the other object match.
2178     * <p>
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.
2182     * </p>
2183     *
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>
2189     */

2190    public boolean match(TypeLiteral node, Object JavaDoc other) {
2191        if (!(other instanceof TypeLiteral)) {
2192            return false;
2193        }
2194        TypeLiteral o = (TypeLiteral) other;
2195        return safeSubtreeMatch(node.getType(), o.getType());
2196    }
2197
2198    /**
2199     * Returns whether the given node and the other object match.
2200     * <p>
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.
2204     * </p>
2205     *
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>
2211     * @since 3.1
2212     */

2213    public boolean match(TypeParameter node, Object JavaDoc other) {
2214        if (!(other instanceof TypeParameter)) {
2215            return false;
2216        }
2217        TypeParameter o = (TypeParameter) other;
2218        return safeSubtreeMatch(node.getName(), o.getName())
2219                && safeSubtreeListMatch(node.typeBounds(), o.typeBounds());
2220    }
2221
2222    /**
2223     * Returns whether the given node and the other object match.
2224     * <p>
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.
2228     * </p>
2229     *
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>
2235     */

2236    public boolean match(VariableDeclarationExpression node, Object JavaDoc other) {
2237        if (!(other instanceof VariableDeclarationExpression)) {
2238            return false;
2239        }
2240        VariableDeclarationExpression o = (VariableDeclarationExpression) other;
2241        int level = node.getAST().apiLevel;
2242        if (level == AST.JLS2_INTERNAL) {
2243            if (node.getModifiers() != o.getModifiers()) {
2244                return false;
2245            }
2246        }
2247        if (level >= AST.JLS3) {
2248            if (!safeSubtreeListMatch(node.modifiers(), o.modifiers())) {
2249                return false;
2250            }
2251        }
2252        return safeSubtreeMatch(node.getType(), o.getType())
2253            && safeSubtreeListMatch(node.fragments(), o.fragments());
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 are compared since they are an
2265     * important part of the type of the variable.
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(VariableDeclarationFragment node, Object JavaDoc other) {
2275        if (!(other instanceof VariableDeclarationFragment)) {
2276            return false;
2277        }
2278        VariableDeclarationFragment o = (VariableDeclarationFragment) other;
2279        return safeSubtreeMatch(node.getName(), o.getName())
2280            && node.getExtraDimensions() == o.getExtraDimensions()
2281            && safeSubtreeMatch(node.getInitializer(), o.getInitializer());
2282    }
2283
2284    /**
2285     * Returns whether the given node and the other object match.
2286     * <p>
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.
2290     * </p>
2291     *
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>
2297     */

2298    public boolean match(VariableDeclarationStatement node, Object JavaDoc other) {
2299        if (!(other instanceof VariableDeclarationStatement)) {
2300            return false;
2301        }
2302        VariableDeclarationStatement o = (VariableDeclarationStatement) other;
2303        int level = node.getAST().apiLevel;
2304        if (level == AST.JLS2_INTERNAL) {
2305            if (node.getModifiers() != o.getModifiers()) {
2306                return false;
2307            }
2308        }
2309        if (level >= AST.JLS3) {
2310            if (!safeSubtreeListMatch(node.modifiers(), o.modifiers())) {
2311                return false;
2312            }
2313        }
2314        return safeSubtreeMatch(node.getType(), o.getType())
2315            && safeSubtreeListMatch(node.fragments(), o.fragments());
2316    }
2317
2318    /**
2319     * Returns whether the given node and the other object match.
2320     * <p>
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.
2324     * </p>
2325     *
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>
2331     */

2332    public boolean match(WhileStatement node, Object JavaDoc other) {
2333        if (!(other instanceof WhileStatement)) {
2334            return false;
2335        }
2336        WhileStatement o = (WhileStatement) other;
2337        return (
2338            safeSubtreeMatch(node.getExpression(), o.getExpression())
2339                && safeSubtreeMatch(node.getBody(), o.getBody()));
2340    }
2341
2342    /**
2343     * Returns whether the given node and the other object match.
2344     * <p>
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.
2348     * </p>
2349     *
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>
2355     * @since 3.1
2356     */

2357    public boolean match(WildcardType node, Object JavaDoc other) {
2358        if (!(other instanceof WildcardType)) {
2359            return false;
2360        }
2361        WildcardType o = (WildcardType) other;
2362        return node.isUpperBound() == o.isUpperBound()
2363        && safeSubtreeMatch(node.getBound(), o.getBound());
2364    }
2365    
2366}
2367
Popular Tags