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