0001: /*******************************************************************************
0002: * Copyright (c) 2000, 2007 IBM Corporation and others.
0003: * All rights reserved. This program and the accompanying materials
0004: * are made available under the terms of the Eclipse Public License v1.0
0005: * which accompanies this distribution, and is available at
0006: * http://www.eclipse.org/legal/epl-v10.html
0007: *
0008: * Contributors:
0009: * IBM Corporation - initial API and implementation
0010: *******************************************************************************/package org.eclipse.jdt.core.dom;
0011:
0012: import java.util.Iterator;
0013: import java.util.List;
0014:
0015: /**
0016: * Concrete superclass and default implementation of an AST subtree matcher.
0017: * <p>
0018: * For example, to compute whether two ASTs subtrees are structurally
0019: * isomorphic, use <code>n1.subtreeMatch(new ASTMatcher(), n2)</code> where
0020: * <code>n1</code> and <code>n2</code> are the AST root nodes of the subtrees.
0021: * </p>
0022: * <p>
0023: * For each different concrete AST node type <i>T</i> there is a
0024: * <code>public boolean match(<i>T</i> node, Object other)</code> method
0025: * that matches the given node against another object (typically another
0026: * AST node, although this is not essential). The default implementations
0027: * provided by this class tests whether the other object is a node of the
0028: * same type with structurally isomorphic child subtrees. For nodes with
0029: * list-valued properties, the child nodes within the list are compared in
0030: * order. For nodes with multiple properties, the child nodes are compared
0031: * in the order that most closely corresponds to the lexical reading order
0032: * of the source program. For instance, for a type declaration node, the
0033: * child ordering is: name, superclass, superinterfaces, and body
0034: * declarations.
0035: * </p>
0036: * <p>
0037: * Subclasses may override (extend or reimplement) some or all of the
0038: * <code>match</code> methods in order to define more specialized subtree
0039: * matchers.
0040: * </p>
0041: *
0042: * @see org.eclipse.jdt.core.dom.ASTNode#subtreeMatch(ASTMatcher, Object)
0043: * @since 2.0
0044: */
0045: public class ASTMatcher {
0046:
0047: /**
0048: * Indicates whether doc tags should be matched.
0049: * @since 3.0
0050: */
0051: private boolean matchDocTags;
0052:
0053: /**
0054: * Creates a new AST matcher instance.
0055: * <p>
0056: * For backwards compatibility, the matcher ignores tag
0057: * elements below doc comments by default. Use
0058: * {@link #ASTMatcher(boolean) ASTMatcher(true)}
0059: * for a matcher that compares doc tags by default.
0060: * </p>
0061: */
0062: public ASTMatcher() {
0063: this (false);
0064: }
0065:
0066: /**
0067: * Creates a new AST matcher instance.
0068: *
0069: * @param matchDocTags <code>true</code> if doc comment tags are
0070: * to be compared by default, and <code>false</code> otherwise
0071: * @see #match(Javadoc,Object)
0072: * @since 3.0
0073: */
0074: public ASTMatcher(boolean matchDocTags) {
0075: this .matchDocTags = matchDocTags;
0076: }
0077:
0078: /**
0079: * Returns whether the given lists of AST nodes match pair wise according
0080: * to <code>ASTNode.subtreeMatch</code>.
0081: * <p>
0082: * Note that this is a convenience method, useful for writing recursive
0083: * subtree matchers.
0084: * </p>
0085: *
0086: * @param list1 the first list of AST nodes
0087: * (element type: <code>ASTNode</code>)
0088: * @param list2 the second list of AST nodes
0089: * (element type: <code>ASTNode</code>)
0090: * @return <code>true</code> if the lists have the same number of elements
0091: * and match pair-wise according to <code>ASTNode.subtreeMatch</code>
0092: * @see ASTNode#subtreeMatch(ASTMatcher matcher, Object other)
0093: */
0094: public final boolean safeSubtreeListMatch(List list1, List list2) {
0095: int size1 = list1.size();
0096: int size2 = list2.size();
0097: if (size1 != size2) {
0098: return false;
0099: }
0100: for (Iterator it1 = list1.iterator(), it2 = list2.iterator(); it1
0101: .hasNext();) {
0102: ASTNode n1 = (ASTNode) it1.next();
0103: ASTNode n2 = (ASTNode) it2.next();
0104: if (!n1.subtreeMatch(this , n2)) {
0105: return false;
0106: }
0107: }
0108: return true;
0109: }
0110:
0111: /**
0112: * Returns whether the given nodes match according to
0113: * <code>AST.subtreeMatch</code>. Returns <code>false</code> if one or
0114: * the other of the nodes are <code>null</code>. Returns <code>true</code>
0115: * if both nodes are <code>null</code>.
0116: * <p>
0117: * Note that this is a convenience method, useful for writing recursive
0118: * subtree matchers.
0119: * </p>
0120: *
0121: * @param node1 the first AST node, or <code>null</code>; must be an
0122: * instance of <code>ASTNode</code>
0123: * @param node2 the second AST node, or <code>null</code>; must be an
0124: * instance of <code>ASTNode</code>
0125: * @return <code>true</code> if the nodes match according
0126: * to <code>AST.subtreeMatch</code> or both are <code>null</code>, and
0127: * <code>false</code> otherwise
0128: * @see ASTNode#subtreeMatch(ASTMatcher, Object)
0129: */
0130: public final boolean safeSubtreeMatch(Object node1, Object node2) {
0131: if (node1 == null && node2 == null) {
0132: return true;
0133: }
0134: if (node1 == null || node2 == null) {
0135: return false;
0136: }
0137: // N.B. call subtreeMatch even node1==node2!=null
0138: return ((ASTNode) node1).subtreeMatch(this , node2);
0139: }
0140:
0141: /**
0142: * Returns whether the given objects are equal according to
0143: * <code>equals</code>. Returns <code>false</code> if either
0144: * node is <code>null</code>.
0145: *
0146: * @param o1 the first object, or <code>null</code>
0147: * @param o2 the second object, or <code>null</code>
0148: * @return <code>true</code> if the nodes are equal according to
0149: * <code>equals</code> or both <code>null</code>, and
0150: * <code>false</code> otherwise
0151: */
0152: public static boolean safeEquals(Object o1, Object o2) {
0153: if (o1 == o2) {
0154: return true;
0155: }
0156: if (o1 == null || o2 == null) {
0157: return false;
0158: }
0159: return o1.equals(o2);
0160: }
0161:
0162: /**
0163: * Returns whether the given node and the other object match.
0164: * <p>
0165: * The default implementation provided by this class tests whether the
0166: * other object is a node of the same type with structurally isomorphic
0167: * child subtrees. Subclasses may override this method as needed.
0168: * </p>
0169: *
0170: * @param node the node
0171: * @param other the other object, or <code>null</code>
0172: * @return <code>true</code> if the subtree matches, or
0173: * <code>false</code> if they do not match or the other object has a
0174: * different node type or is <code>null</code>
0175: * @since 3.1
0176: */
0177: public boolean match(AnnotationTypeDeclaration node, Object other) {
0178: if (!(other instanceof AnnotationTypeDeclaration)) {
0179: return false;
0180: }
0181: AnnotationTypeDeclaration o = (AnnotationTypeDeclaration) other;
0182: // node type added in JLS3 - ignore old JLS2-style modifiers
0183: return (safeSubtreeMatch(node.getJavadoc(), o.getJavadoc())
0184: && safeSubtreeListMatch(node.modifiers(), o.modifiers())
0185: && safeSubtreeMatch(node.getName(), o.getName()) && safeSubtreeListMatch(
0186: node.bodyDeclarations(), o.bodyDeclarations()));
0187: }
0188:
0189: /**
0190: * Returns whether the given node and the other object match.
0191: * <p>
0192: * The default implementation provided by this class tests whether the
0193: * other object is a node of the same type with structurally isomorphic
0194: * child subtrees. Subclasses may override this method as needed.
0195: * </p>
0196: *
0197: * @param node the node
0198: * @param other the other object, or <code>null</code>
0199: * @return <code>true</code> if the subtree matches, or
0200: * <code>false</code> if they do not match or the other object has a
0201: * different node type or is <code>null</code>
0202: * @since 3.1
0203: */
0204: public boolean match(AnnotationTypeMemberDeclaration node,
0205: Object other) {
0206: if (!(other instanceof AnnotationTypeMemberDeclaration)) {
0207: return false;
0208: }
0209: AnnotationTypeMemberDeclaration o = (AnnotationTypeMemberDeclaration) other;
0210: // node type added in JLS3 - ignore old JLS2-style modifiers
0211: return (safeSubtreeMatch(node.getJavadoc(), o.getJavadoc())
0212: && safeSubtreeListMatch(node.modifiers(), o.modifiers())
0213: && safeSubtreeMatch(node.getType(), o.getType())
0214: && safeSubtreeMatch(node.getName(), o.getName()) && safeSubtreeMatch(
0215: node.getDefault(), o.getDefault()));
0216: }
0217:
0218: /**
0219: * Returns whether the given node and the other object match.
0220: * <p>
0221: * The default implementation provided by this class tests whether the
0222: * other object is a node of the same type with structurally isomorphic
0223: * child subtrees. Subclasses may override this method as needed.
0224: * </p>
0225: *
0226: * @param node the node
0227: * @param other the other object, or <code>null</code>
0228: * @return <code>true</code> if the subtree matches, or
0229: * <code>false</code> if they do not match or the other object has a
0230: * different node type or is <code>null</code>
0231: */
0232: public boolean match(AnonymousClassDeclaration node, Object other) {
0233: if (!(other instanceof AnonymousClassDeclaration)) {
0234: return false;
0235: }
0236: AnonymousClassDeclaration o = (AnonymousClassDeclaration) other;
0237: return safeSubtreeListMatch(node.bodyDeclarations(), o
0238: .bodyDeclarations());
0239: }
0240:
0241: /**
0242: * Returns whether the given node and the other object match.
0243: * <p>
0244: * The default implementation provided by this class tests whether the
0245: * other object is a node of the same type with structurally isomorphic
0246: * child subtrees. Subclasses may override this method as needed.
0247: * </p>
0248: *
0249: * @param node the node
0250: * @param other the other object, or <code>null</code>
0251: * @return <code>true</code> if the subtree matches, or
0252: * <code>false</code> if they do not match or the other object has a
0253: * different node type or is <code>null</code>
0254: */
0255: public boolean match(ArrayAccess node, Object other) {
0256: if (!(other instanceof ArrayAccess)) {
0257: return false;
0258: }
0259: ArrayAccess o = (ArrayAccess) other;
0260: return (safeSubtreeMatch(node.getArray(), o.getArray()) && safeSubtreeMatch(
0261: node.getIndex(), o.getIndex()));
0262: }
0263:
0264: /**
0265: * Returns whether the given node and the other object object match.
0266: * <p>
0267: * The default implementation provided by this class tests whether the
0268: * other object is a node of the same type with structurally isomorphic
0269: * child subtrees. Subclasses may override this method as needed.
0270: * </p>
0271: *
0272: * @param node the node
0273: * @param other the other object, or <code>null</code>
0274: * @return <code>true</code> if the subtree matches, or
0275: * <code>false</code> if they do not match or the other object has a
0276: * different node type or is <code>null</code>
0277: */
0278: public boolean match(ArrayCreation node, Object other) {
0279: if (!(other instanceof ArrayCreation)) {
0280: return false;
0281: }
0282: ArrayCreation o = (ArrayCreation) other;
0283: return (safeSubtreeMatch(node.getType(), o.getType())
0284: && safeSubtreeListMatch(node.dimensions(), o
0285: .dimensions()) && safeSubtreeMatch(node
0286: .getInitializer(), o.getInitializer()));
0287: }
0288:
0289: /**
0290: * Returns whether the given node and the other object match.
0291: * <p>
0292: * The default implementation provided by this class tests whether the
0293: * other object is a node of the same type with structurally isomorphic
0294: * child subtrees. Subclasses may override this method as needed.
0295: * </p>
0296: *
0297: * @param node the node
0298: * @param other the other object, or <code>null</code>
0299: * @return <code>true</code> if the subtree matches, or
0300: * <code>false</code> if they do not match or the other object has a
0301: * different node type or is <code>null</code>
0302: */
0303: public boolean match(ArrayInitializer node, Object other) {
0304: if (!(other instanceof ArrayInitializer)) {
0305: return false;
0306: }
0307: ArrayInitializer o = (ArrayInitializer) other;
0308: return safeSubtreeListMatch(node.expressions(), o.expressions());
0309: }
0310:
0311: /**
0312: * Returns whether the given node and the other object match.
0313: * <p>
0314: * The default implementation provided by this class tests whether the
0315: * other object is a node of the same type with structurally isomorphic
0316: * child subtrees. Subclasses may override this method as needed.
0317: * </p>
0318: *
0319: * @param node the node
0320: * @param other the other object, or <code>null</code>
0321: * @return <code>true</code> if the subtree matches, or
0322: * <code>false</code> if they do not match or the other object has a
0323: * different node type or is <code>null</code>
0324: */
0325: public boolean match(ArrayType node, Object other) {
0326: if (!(other instanceof ArrayType)) {
0327: return false;
0328: }
0329: ArrayType o = (ArrayType) other;
0330: return safeSubtreeMatch(node.getComponentType(), o
0331: .getComponentType());
0332: }
0333:
0334: /**
0335: * Returns whether the given node and the other object match.
0336: * <p>
0337: * The default implementation provided by this class tests whether the
0338: * other object is a node of the same type with structurally isomorphic
0339: * child subtrees. Subclasses may override this method as needed.
0340: * </p>
0341: *
0342: * @param node the node
0343: * @param other the other object, or <code>null</code>
0344: * @return <code>true</code> if the subtree matches, or
0345: * <code>false</code> if they do not match or the other object has a
0346: * different node type or is <code>null</code>
0347: */
0348: public boolean match(AssertStatement node, Object other) {
0349: if (!(other instanceof AssertStatement)) {
0350: return false;
0351: }
0352: AssertStatement o = (AssertStatement) other;
0353: return (safeSubtreeMatch(node.getExpression(), o
0354: .getExpression()) && safeSubtreeMatch(
0355: node.getMessage(), o.getMessage()));
0356: }
0357:
0358: /**
0359: * Returns whether the given node and the other object match.
0360: * <p>
0361: * The default implementation provided by this class tests whether the
0362: * other object is a node of the same type with structurally isomorphic
0363: * child subtrees. Subclasses may override this method as needed.
0364: * </p>
0365: *
0366: * @param node the node
0367: * @param other the other object, or <code>null</code>
0368: * @return <code>true</code> if the subtree matches, or
0369: * <code>false</code> if they do not match or the other object has a
0370: * different node type or is <code>null</code>
0371: */
0372: public boolean match(Assignment node, Object other) {
0373: if (!(other instanceof Assignment)) {
0374: return false;
0375: }
0376: Assignment o = (Assignment) other;
0377: return (node.getOperator().equals(o.getOperator())
0378: && safeSubtreeMatch(node.getLeftHandSide(), o
0379: .getLeftHandSide()) && safeSubtreeMatch(node
0380: .getRightHandSide(), o.getRightHandSide()));
0381: }
0382:
0383: /**
0384: * Returns whether the given node and the other object match.
0385: * <p>
0386: * The default implementation provided by this class tests whether the
0387: * other object is a node of the same type with structurally isomorphic
0388: * child subtrees. Subclasses may override this method as needed.
0389: * </p>
0390: *
0391: * @param node the node
0392: * @param other the other object, or <code>null</code>
0393: * @return <code>true</code> if the subtree matches, or
0394: * <code>false</code> if they do not match or the other object has a
0395: * different node type or is <code>null</code>
0396: */
0397: public boolean match(Block node, Object other) {
0398: if (!(other instanceof Block)) {
0399: return false;
0400: }
0401: Block o = (Block) other;
0402: return safeSubtreeListMatch(node.statements(), o.statements());
0403: }
0404:
0405: /**
0406: * Returns whether the given node and the other object match.
0407: * <p>
0408: * The default implementation provided by this class tests whether the
0409: * other object is a node of the same type. Subclasses may override
0410: * this method as needed.
0411: * </p>
0412: * <p>Note: {@link LineComment} and {@link BlockComment} nodes are
0413: * not considered part of main structure of the AST. This method will
0414: * only be called if a client goes out of their way to visit this
0415: * kind of node explicitly.
0416: * </p>
0417: *
0418: * @param node the node
0419: * @param other the other object, or <code>null</code>
0420: * @return <code>true</code> if the subtree matches, or
0421: * <code>false</code> if they do not match or the other object has a
0422: * different node type or is <code>null</code>
0423: * @since 3.0
0424: */
0425: public boolean match(BlockComment node, Object other) {
0426: if (!(other instanceof BlockComment)) {
0427: return false;
0428: }
0429: return true;
0430: }
0431:
0432: /**
0433: * Returns whether the given node and the other object match.
0434: * <p>
0435: * The default implementation provided by this class tests whether the
0436: * other object is a node of the same type with structurally isomorphic
0437: * child subtrees. Subclasses may override this method as needed.
0438: * </p>
0439: *
0440: * @param node the node
0441: * @param other the other object, or <code>null</code>
0442: * @return <code>true</code> if the subtree matches, or
0443: * <code>false</code> if they do not match or the other object has a
0444: * different node type or is <code>null</code>
0445: */
0446: public boolean match(BooleanLiteral node, Object other) {
0447: if (!(other instanceof BooleanLiteral)) {
0448: return false;
0449: }
0450: BooleanLiteral o = (BooleanLiteral) other;
0451: return node.booleanValue() == o.booleanValue();
0452: }
0453:
0454: /**
0455: * Returns whether the given node and the other object match.
0456: * <p>
0457: * The default implementation provided by this class tests whether the
0458: * other object is a node of the same type with structurally isomorphic
0459: * child subtrees. Subclasses may override this method as needed.
0460: * </p>
0461: *
0462: * @param node the node
0463: * @param other the other object, or <code>null</code>
0464: * @return <code>true</code> if the subtree matches, or
0465: * <code>false</code> if they do not match or the other object has a
0466: * different node type or is <code>null</code>
0467: */
0468: public boolean match(BreakStatement node, Object other) {
0469: if (!(other instanceof BreakStatement)) {
0470: return false;
0471: }
0472: BreakStatement o = (BreakStatement) other;
0473: return safeSubtreeMatch(node.getLabel(), o.getLabel());
0474: }
0475:
0476: /**
0477: * Returns whether the given node and the other object match.
0478: * <p>
0479: * The default implementation provided by this class tests whether the
0480: * other object is a node of the same type with structurally isomorphic
0481: * child subtrees. Subclasses may override this method as needed.
0482: * </p>
0483: *
0484: * @param node the node
0485: * @param other the other object, or <code>null</code>
0486: * @return <code>true</code> if the subtree matches, or
0487: * <code>false</code> if they do not match or the other object has a
0488: * different node type or is <code>null</code>
0489: */
0490: public boolean match(CastExpression node, Object other) {
0491: if (!(other instanceof CastExpression)) {
0492: return false;
0493: }
0494: CastExpression o = (CastExpression) other;
0495: return (safeSubtreeMatch(node.getType(), o.getType()) && safeSubtreeMatch(
0496: node.getExpression(), o.getExpression()));
0497: }
0498:
0499: /**
0500: * Returns whether the given node and the other object match.
0501: * <p>
0502: * The default implementation provided by this class tests whether the
0503: * other object is a node of the same type with structurally isomorphic
0504: * child subtrees. Subclasses may override this method as needed.
0505: * </p>
0506: *
0507: * @param node the node
0508: * @param other the other object, or <code>null</code>
0509: * @return <code>true</code> if the subtree matches, or
0510: * <code>false</code> if they do not match or the other object has a
0511: * different node type or is <code>null</code>
0512: */
0513: public boolean match(CatchClause node, Object other) {
0514: if (!(other instanceof CatchClause)) {
0515: return false;
0516: }
0517: CatchClause o = (CatchClause) other;
0518: return (safeSubtreeMatch(node.getException(), o.getException()) && safeSubtreeMatch(
0519: node.getBody(), o.getBody()));
0520: }
0521:
0522: /**
0523: * Returns whether the given node and the other object match.
0524: * <p>
0525: * The default implementation provided by this class tests whether the
0526: * other object is a node of the same type with structurally isomorphic
0527: * child subtrees. Subclasses may override this method as needed.
0528: * </p>
0529: *
0530: * @param node the node
0531: * @param other the other object, or <code>null</code>
0532: * @return <code>true</code> if the subtree matches, or
0533: * <code>false</code> if they do not match or the other object has a
0534: * different node type or is <code>null</code>
0535: */
0536: public boolean match(CharacterLiteral node, Object other) {
0537: if (!(other instanceof CharacterLiteral)) {
0538: return false;
0539: }
0540: CharacterLiteral o = (CharacterLiteral) other;
0541: return safeEquals(node.getEscapedValue(), o.getEscapedValue());
0542: }
0543:
0544: /**
0545: * Returns whether the given node and the other object match.
0546: * <p>
0547: * The default implementation provided by this class tests whether the
0548: * other object is a node of the same type with structurally isomorphic
0549: * child subtrees. Subclasses may override this method as needed.
0550: * </p>
0551: *
0552: * @param node the node
0553: * @param other the other object, or <code>null</code>
0554: * @return <code>true</code> if the subtree matches, or
0555: * <code>false</code> if they do not match or the other object has a
0556: * different node type or is <code>null</code>
0557: */
0558: public boolean match(ClassInstanceCreation node, Object other) {
0559: if (!(other instanceof ClassInstanceCreation)) {
0560: return false;
0561: }
0562: ClassInstanceCreation o = (ClassInstanceCreation) other;
0563: int level = node.getAST().apiLevel;
0564: if (level == AST.JLS2_INTERNAL) {
0565: if (!safeSubtreeMatch(node.internalGetName(), o
0566: .internalGetName())) {
0567: return false;
0568: }
0569: }
0570: if (level >= AST.JLS3) {
0571: if (!safeSubtreeListMatch(node.typeArguments(), o
0572: .typeArguments())) {
0573: return false;
0574: }
0575: if (!safeSubtreeMatch(node.getType(), o.getType())) {
0576: return false;
0577: }
0578: }
0579: return safeSubtreeMatch(node.getExpression(), o.getExpression())
0580: && safeSubtreeListMatch(node.arguments(), o.arguments())
0581: && safeSubtreeMatch(
0582: node.getAnonymousClassDeclaration(), o
0583: .getAnonymousClassDeclaration());
0584: }
0585:
0586: /**
0587: * Returns whether the given node and the other object match.
0588: * <p>
0589: * The default implementation provided by this class tests whether the
0590: * other object is a node of the same type with structurally isomorphic
0591: * child subtrees. Subclasses may override this method as needed.
0592: * </p>
0593: *
0594: * @param node the node
0595: * @param other the other object, or <code>null</code>
0596: * @return <code>true</code> if the subtree matches, or
0597: * <code>false</code> if they do not match or the other object has a
0598: * different node type or is <code>null</code>
0599: */
0600: public boolean match(CompilationUnit node, Object other) {
0601: if (!(other instanceof CompilationUnit)) {
0602: return false;
0603: }
0604: CompilationUnit o = (CompilationUnit) other;
0605: return (safeSubtreeMatch(node.getPackage(), o.getPackage())
0606: && safeSubtreeListMatch(node.imports(), o.imports()) && safeSubtreeListMatch(
0607: node.types(), o.types()));
0608: }
0609:
0610: /**
0611: * Returns whether the given node and the other object match.
0612: * <p>
0613: * The default implementation provided by this class tests whether the
0614: * other object is a node of the same type with structurally isomorphic
0615: * child subtrees. Subclasses may override this method as needed.
0616: * </p>
0617: *
0618: * @param node the node
0619: * @param other the other object, or <code>null</code>
0620: * @return <code>true</code> if the subtree matches, or
0621: * <code>false</code> if they do not match or the other object has a
0622: * different node type or is <code>null</code>
0623: */
0624: public boolean match(ConditionalExpression node, Object other) {
0625: if (!(other instanceof ConditionalExpression)) {
0626: return false;
0627: }
0628: ConditionalExpression o = (ConditionalExpression) other;
0629: return (safeSubtreeMatch(node.getExpression(), o
0630: .getExpression())
0631: && safeSubtreeMatch(node.getThenExpression(), o
0632: .getThenExpression()) && safeSubtreeMatch(node
0633: .getElseExpression(), o.getElseExpression()));
0634: }
0635:
0636: /**
0637: * Returns whether the given node and the other object match.
0638: * <p>
0639: * The default implementation provided by this class tests whether the
0640: * other object is a node of the same type with structurally isomorphic
0641: * child subtrees. Subclasses may override this method as needed.
0642: * </p>
0643: *
0644: * @param node the node
0645: * @param other the other object, or <code>null</code>
0646: * @return <code>true</code> if the subtree matches, or
0647: * <code>false</code> if they do not match or the other object has a
0648: * different node type or is <code>null</code>
0649: */
0650: public boolean match(ConstructorInvocation node, Object other) {
0651: if (!(other instanceof ConstructorInvocation)) {
0652: return false;
0653: }
0654: ConstructorInvocation o = (ConstructorInvocation) other;
0655: if (node.getAST().apiLevel >= AST.JLS3) {
0656: if (!safeSubtreeListMatch(node.typeArguments(), o
0657: .typeArguments())) {
0658: return false;
0659: }
0660: }
0661: return safeSubtreeListMatch(node.arguments(), o.arguments());
0662: }
0663:
0664: /**
0665: * Returns whether the given node and the other object match.
0666: * <p>
0667: * The default implementation provided by this class tests whether the
0668: * other object is a node of the same type with structurally isomorphic
0669: * child subtrees. Subclasses may override this method as needed.
0670: * </p>
0671: *
0672: * @param node the node
0673: * @param other the other object, or <code>null</code>
0674: * @return <code>true</code> if the subtree matches, or
0675: * <code>false</code> if they do not match or the other object has a
0676: * different node type or is <code>null</code>
0677: */
0678: public boolean match(ContinueStatement node, Object other) {
0679: if (!(other instanceof ContinueStatement)) {
0680: return false;
0681: }
0682: ContinueStatement o = (ContinueStatement) other;
0683: return safeSubtreeMatch(node.getLabel(), o.getLabel());
0684: }
0685:
0686: /**
0687: * Returns whether the given node and the other object match.
0688: * <p>
0689: * The default implementation provided by this class tests whether the
0690: * other object is a node of the same type with structurally isomorphic
0691: * child subtrees. Subclasses may override this method as needed.
0692: * </p>
0693: *
0694: * @param node the node
0695: * @param other the other object, or <code>null</code>
0696: * @return <code>true</code> if the subtree matches, or
0697: * <code>false</code> if they do not match or the other object has a
0698: * different node type or is <code>null</code>
0699: */
0700: public boolean match(DoStatement node, Object other) {
0701: if (!(other instanceof DoStatement)) {
0702: return false;
0703: }
0704: DoStatement o = (DoStatement) other;
0705: return (safeSubtreeMatch(node.getExpression(), o
0706: .getExpression()) && safeSubtreeMatch(node.getBody(), o
0707: .getBody()));
0708: }
0709:
0710: /**
0711: * Returns whether the given node and the other object match.
0712: * <p>
0713: * The default implementation provided by this class tests whether the
0714: * other object is a node of the same type with structurally isomorphic
0715: * child subtrees. Subclasses may override this method as needed.
0716: * </p>
0717: *
0718: * @param node the node
0719: * @param other the other object, or <code>null</code>
0720: * @return <code>true</code> if the subtree matches, or
0721: * <code>false</code> if they do not match or the other object has a
0722: * different node type or is <code>null</code>
0723: */
0724: public boolean match(EmptyStatement node, Object other) {
0725: if (!(other instanceof EmptyStatement)) {
0726: return false;
0727: }
0728: return true;
0729: }
0730:
0731: /**
0732: * Returns whether the given node and the other object match.
0733: * <p>
0734: * The default implementation provided by this class tests whether the
0735: * other object is a node of the same type with structurally isomorphic
0736: * child subtrees. Subclasses may override this method as needed.
0737: * </p>
0738: *
0739: * @param node the node
0740: * @param other the other object, or <code>null</code>
0741: * @return <code>true</code> if the subtree matches, or
0742: * <code>false</code> if they do not match or the other object has a
0743: * different node type or is <code>null</code>
0744: * @since 3.1
0745: */
0746: public boolean match(EnhancedForStatement node, Object other) {
0747: if (!(other instanceof EnhancedForStatement)) {
0748: return false;
0749: }
0750: EnhancedForStatement o = (EnhancedForStatement) other;
0751: return (safeSubtreeMatch(node.getParameter(), o.getParameter())
0752: && safeSubtreeMatch(node.getExpression(), o
0753: .getExpression()) && safeSubtreeMatch(node
0754: .getBody(), o.getBody()));
0755: }
0756:
0757: /**
0758: * Returns whether the given node and the other object match.
0759: * <p>
0760: * The default implementation provided by this class tests whether the
0761: * other object is a node of the same type with structurally isomorphic
0762: * child subtrees. Subclasses may override this method as needed.
0763: * </p>
0764: *
0765: * @param node the node
0766: * @param other the other object, or <code>null</code>
0767: * @return <code>true</code> if the subtree matches, or
0768: * <code>false</code> if they do not match or the other object has a
0769: * different node type or is <code>null</code>
0770: * @since 3.1
0771: */
0772: public boolean match(EnumConstantDeclaration node, Object other) {
0773: if (!(other instanceof EnumConstantDeclaration)) {
0774: return false;
0775: }
0776: EnumConstantDeclaration o = (EnumConstantDeclaration) other;
0777: return (safeSubtreeMatch(node.getJavadoc(), o.getJavadoc())
0778: && safeSubtreeListMatch(node.modifiers(), o.modifiers())
0779: && safeSubtreeMatch(node.getName(), o.getName())
0780: && safeSubtreeListMatch(node.arguments(), o.arguments()) && safeSubtreeMatch(
0781: node.getAnonymousClassDeclaration(), o
0782: .getAnonymousClassDeclaration()));
0783: }
0784:
0785: /**
0786: * Returns whether the given node and the other object match.
0787: * <p>
0788: * The default implementation provided by this class tests whether the
0789: * other object is a node of the same type with structurally isomorphic
0790: * child subtrees. Subclasses may override this method as needed.
0791: * </p>
0792: *
0793: * @param node the node
0794: * @param other the other object, or <code>null</code>
0795: * @return <code>true</code> if the subtree matches, or
0796: * <code>false</code> if they do not match or the other object has a
0797: * different node type or is <code>null</code>
0798: * @since 3.1
0799: */
0800: public boolean match(EnumDeclaration node, Object other) {
0801: if (!(other instanceof EnumDeclaration)) {
0802: return false;
0803: }
0804: EnumDeclaration o = (EnumDeclaration) other;
0805: return (safeSubtreeMatch(node.getJavadoc(), o.getJavadoc())
0806: && safeSubtreeListMatch(node.modifiers(), o.modifiers())
0807: && safeSubtreeMatch(node.getName(), o.getName())
0808: && safeSubtreeListMatch(node.super InterfaceTypes(), o
0809: .super InterfaceTypes())
0810: && safeSubtreeListMatch(node.enumConstants(), o
0811: .enumConstants()) && safeSubtreeListMatch(node
0812: .bodyDeclarations(), o.bodyDeclarations()));
0813: }
0814:
0815: /**
0816: * Returns whether the given node and the other object match.
0817: * <p>
0818: * The default implementation provided by this class tests whether the
0819: * other object is a node of the same type with structurally isomorphic
0820: * child subtrees. Subclasses may override this method as needed.
0821: * </p>
0822: *
0823: * @param node the node
0824: * @param other the other object, or <code>null</code>
0825: * @return <code>true</code> if the subtree matches, or
0826: * <code>false</code> if they do not match or the other object has a
0827: * different node type or is <code>null</code>
0828: */
0829: public boolean match(ExpressionStatement node, Object other) {
0830: if (!(other instanceof ExpressionStatement)) {
0831: return false;
0832: }
0833: ExpressionStatement o = (ExpressionStatement) other;
0834: return safeSubtreeMatch(node.getExpression(), o.getExpression());
0835: }
0836:
0837: /**
0838: * Returns whether the given node and the other object match.
0839: * <p>
0840: * The default implementation provided by this class tests whether the
0841: * other object is a node of the same type with structurally isomorphic
0842: * child subtrees. Subclasses may override this method as needed.
0843: * </p>
0844: *
0845: * @param node the node
0846: * @param other the other object, or <code>null</code>
0847: * @return <code>true</code> if the subtree matches, or
0848: * <code>false</code> if they do not match or the other object has a
0849: * different node type or is <code>null</code>
0850: */
0851: public boolean match(FieldAccess node, Object other) {
0852: if (!(other instanceof FieldAccess)) {
0853: return false;
0854: }
0855: FieldAccess o = (FieldAccess) other;
0856: return (safeSubtreeMatch(node.getExpression(), o
0857: .getExpression()) && safeSubtreeMatch(node.getName(), o
0858: .getName()));
0859: }
0860:
0861: /**
0862: * Returns whether the given node and the other object match.
0863: * <p>
0864: * The default implementation provided by this class tests whether the
0865: * other object is a node of the same type with structurally isomorphic
0866: * child subtrees. Subclasses may override this method as needed.
0867: * </p>
0868: *
0869: * @param node the node
0870: * @param other the other object, or <code>null</code>
0871: * @return <code>true</code> if the subtree matches, or
0872: * <code>false</code> if they do not match or the other object has a
0873: * different node type or is <code>null</code>
0874: */
0875: public boolean match(FieldDeclaration node, Object other) {
0876: if (!(other instanceof FieldDeclaration)) {
0877: return false;
0878: }
0879: FieldDeclaration o = (FieldDeclaration) other;
0880: int level = node.getAST().apiLevel;
0881: if (level == AST.JLS2_INTERNAL) {
0882: if (node.getModifiers() != o.getModifiers()) {
0883: return false;
0884: }
0885: }
0886: if (level >= AST.JLS3) {
0887: if (!safeSubtreeListMatch(node.modifiers(), o.modifiers())) {
0888: return false;
0889: }
0890: }
0891: return safeSubtreeMatch(node.getJavadoc(), o.getJavadoc())
0892: && safeSubtreeMatch(node.getType(), o.getType())
0893: && safeSubtreeListMatch(node.fragments(), o.fragments());
0894: }
0895:
0896: /**
0897: * Returns whether the given node and the other object match.
0898: * <p>
0899: * The default implementation provided by this class tests whether the
0900: * other object is a node of the same type with structurally isomorphic
0901: * child subtrees. Subclasses may override this method as needed.
0902: * </p>
0903: *
0904: * @param node the node
0905: * @param other the other object, or <code>null</code>
0906: * @return <code>true</code> if the subtree matches, or
0907: * <code>false</code> if they do not match or the other object has a
0908: * different node type or is <code>null</code>
0909: */
0910: public boolean match(ForStatement node, Object other) {
0911: if (!(other instanceof ForStatement)) {
0912: return false;
0913: }
0914: ForStatement o = (ForStatement) other;
0915: return (safeSubtreeListMatch(node.initializers(), o
0916: .initializers())
0917: && safeSubtreeMatch(node.getExpression(), o
0918: .getExpression())
0919: && safeSubtreeListMatch(node.updaters(), o.updaters()) && safeSubtreeMatch(
0920: node.getBody(), o.getBody()));
0921: }
0922:
0923: /**
0924: * Returns whether the given node and the other object match.
0925: * <p>
0926: * The default implementation provided by this class tests whether the
0927: * other object is a node of the same type with structurally isomorphic
0928: * child subtrees. Subclasses may override this method as needed.
0929: * </p>
0930: *
0931: * @param node the node
0932: * @param other the other object, or <code>null</code>
0933: * @return <code>true</code> if the subtree matches, or
0934: * <code>false</code> if they do not match or the other object has a
0935: * different node type or is <code>null</code>
0936: */
0937: public boolean match(IfStatement node, Object other) {
0938: if (!(other instanceof IfStatement)) {
0939: return false;
0940: }
0941: IfStatement o = (IfStatement) other;
0942: return (safeSubtreeMatch(node.getExpression(), o
0943: .getExpression())
0944: && safeSubtreeMatch(node.getThenStatement(), o
0945: .getThenStatement()) && safeSubtreeMatch(node
0946: .getElseStatement(), o.getElseStatement()));
0947: }
0948:
0949: /**
0950: * Returns whether the given node and the other object match.
0951: * <p>
0952: * The default implementation provided by this class tests whether the
0953: * other object is a node of the same type with structurally isomorphic
0954: * child subtrees. Subclasses may override this method as needed.
0955: * </p>
0956: *
0957: * @param node the node
0958: * @param other the other object, or <code>null</code>
0959: * @return <code>true</code> if the subtree matches, or
0960: * <code>false</code> if they do not match or the other object has a
0961: * different node type or is <code>null</code>
0962: */
0963: public boolean match(ImportDeclaration node, Object other) {
0964: if (!(other instanceof ImportDeclaration)) {
0965: return false;
0966: }
0967: ImportDeclaration o = (ImportDeclaration) other;
0968: if (node.getAST().apiLevel >= AST.JLS3) {
0969: if (node.isStatic() != o.isStatic()) {
0970: return false;
0971: }
0972: }
0973: return (safeSubtreeMatch(node.getName(), o.getName()) && node
0974: .isOnDemand() == o.isOnDemand());
0975: }
0976:
0977: /**
0978: * Returns whether the given node and the other object match.
0979: * <p>
0980: * The default implementation provided by this class tests whether the
0981: * other object is a node of the same type with structurally isomorphic
0982: * child subtrees. Subclasses may override this method as needed.
0983: * </p>
0984: *
0985: * @param node the node
0986: * @param other the other object, or <code>null</code>
0987: * @return <code>true</code> if the subtree matches, or
0988: * <code>false</code> if they do not match or the other object has a
0989: * different node type or is <code>null</code>
0990: */
0991: public boolean match(InfixExpression node, Object other) {
0992: if (!(other instanceof InfixExpression)) {
0993: return false;
0994: }
0995: InfixExpression o = (InfixExpression) other;
0996: // be careful not to trigger lazy creation of extended operand lists
0997: if (node.hasExtendedOperands() && o.hasExtendedOperands()) {
0998: if (!safeSubtreeListMatch(node.extendedOperands(), o
0999: .extendedOperands())) {
1000: return false;
1001: }
1002: }
1003: if (node.hasExtendedOperands() != o.hasExtendedOperands()) {
1004: return false;
1005: }
1006: return (node.getOperator().equals(o.getOperator())
1007: && safeSubtreeMatch(node.getLeftOperand(), o
1008: .getLeftOperand()) && safeSubtreeMatch(node
1009: .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 other) {
1027: if (!(other instanceof InstanceofExpression)) {
1028: return false;
1029: }
1030: InstanceofExpression o = (InstanceofExpression) other;
1031: return (safeSubtreeMatch(node.getLeftOperand(), o
1032: .getLeftOperand()) && safeSubtreeMatch(node
1033: .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 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 (safeSubtreeMatch(node.getJavadoc(), o.getJavadoc()) && safeSubtreeMatch(
1067: node.getBody(), o.getBody()));
1068: }
1069:
1070: /**
1071: * Returns whether the given node and the other object match.
1072: * <p>
1073: * Unlike other node types, the behavior of the default
1074: * implementation is controlled by a constructor-supplied
1075: * parameter {@link #ASTMatcher(boolean) ASTMatcher(boolean)}
1076: * which is <code>false</code> if not specified.
1077: * When this parameter is <code>true</code>, the implementation
1078: * tests whether the other object is also a <code>Javadoc</code>
1079: * with structurally isomorphic child subtrees; the comment string
1080: * (<code>Javadoc.getComment()</code>) is ignored.
1081: * Conversely, when the parameter is <code>false</code>, the
1082: * implementation tests whether the other object is also a
1083: * <code>Javadoc</code> with exactly the same comment string;
1084: * the tag elements ({@link Javadoc#tags() Javadoc.tags} are
1085: * ignored. Subclasses may reimplement.
1086: * </p>
1087: *
1088: * @param node the node
1089: * @param other the other object, or <code>null</code>
1090: * @return <code>true</code> if the subtree matches, or
1091: * <code>false</code> if they do not match or the other object has a
1092: * different node type or is <code>null</code>
1093: * @see #ASTMatcher()
1094: * @see #ASTMatcher(boolean)
1095: */
1096: public boolean match(Javadoc node, Object other) {
1097: if (!(other instanceof Javadoc)) {
1098: return false;
1099: }
1100: Javadoc o = (Javadoc) other;
1101: if (this .matchDocTags) {
1102: return safeSubtreeListMatch(node.tags(), o.tags());
1103: } else {
1104: return compareDeprecatedComment(node, o);
1105: }
1106: }
1107:
1108: /**
1109: * Return whether the deprecated comment strings of the given java doc are equals.
1110: * <p>
1111: * Note the only purpose of this method is to hide deprecated warnings.
1112: * @deprecated mark deprecated to hide deprecated usage
1113: */
1114: private boolean compareDeprecatedComment(Javadoc first,
1115: 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 other) {
1138: if (!(other instanceof LabeledStatement)) {
1139: return false;
1140: }
1141: LabeledStatement o = (LabeledStatement) other;
1142: return (safeSubtreeMatch(node.getLabel(), o.getLabel()) && safeSubtreeMatch(
1143: node.getBody(), o.getBody()));
1144: }
1145:
1146: /**
1147: * Returns whether the given node and the other object match.
1148: * <p>
1149: * The default implementation provided by this class tests whether the
1150: * other object is a node of the same type. Subclasses may override
1151: * this method as needed.
1152: * </p>
1153: * <p>Note: {@link LineComment} and {@link BlockComment} nodes are
1154: * not considered part of main structure of the AST. This method will
1155: * only be called if a client goes out of their way to visit this
1156: * kind of node explicitly.
1157: * </p>
1158: *
1159: * @param node the node
1160: * @param other the other object, or <code>null</code>
1161: * @return <code>true</code> if the subtree matches, or
1162: * <code>false</code> if they do not match or the other object has a
1163: * different node type or is <code>null</code>
1164: * @since 3.0
1165: */
1166: public boolean match(LineComment node, Object other) {
1167: if (!(other instanceof LineComment)) {
1168: return false;
1169: }
1170: return true;
1171: }
1172:
1173: /**
1174: * Returns whether the given node and the other object match.
1175: * <p>
1176: * The default implementation provided by this class tests whether the
1177: * other object is a node of the same type with structurally isomorphic
1178: * child subtrees. Subclasses may override this method as needed.
1179: * </p>
1180: *
1181: * @param node the node
1182: * @param other the other object, or <code>null</code>
1183: * @return <code>true</code> if the subtree matches, or
1184: * <code>false</code> if they do not match or the other object has a
1185: * different node type or is <code>null</code>
1186: * @since 3.1
1187: */
1188: public boolean match(MarkerAnnotation node, Object other) {
1189: if (!(other instanceof MarkerAnnotation)) {
1190: return false;
1191: }
1192: MarkerAnnotation o = (MarkerAnnotation) other;
1193: return safeSubtreeMatch(node.getTypeName(), o.getTypeName());
1194: }
1195:
1196: /**
1197: * Returns whether the given node and the other object match.
1198: * <p>
1199: * The default implementation provided by this class tests whether the
1200: * other object is a node of the same type with structurally isomorphic
1201: * child subtrees. Subclasses may override this method as needed.
1202: * </p>
1203: *
1204: * @param node the node
1205: * @param other the other object, or <code>null</code>
1206: * @return <code>true</code> if the subtree matches, or
1207: * <code>false</code> if they do not match or the other object has a
1208: * different node type or is <code>null</code>
1209: * @since 3.0
1210: */
1211: public boolean match(MemberRef node, Object other) {
1212: if (!(other instanceof MemberRef)) {
1213: return false;
1214: }
1215: MemberRef o = (MemberRef) other;
1216: return (safeSubtreeMatch(node.getQualifier(), o.getQualifier()) && safeSubtreeMatch(
1217: node.getName(), o.getName()));
1218: }
1219:
1220: /**
1221: * Returns whether the given node and the other object match.
1222: * <p>
1223: * The default implementation provided by this class tests whether the
1224: * other object is a node of the same type with structurally isomorphic
1225: * child subtrees. Subclasses may override this method as needed.
1226: * </p>
1227: *
1228: * @param node the node
1229: * @param other the other object, or <code>null</code>
1230: * @return <code>true</code> if the subtree matches, or
1231: * <code>false</code> if they do not match or the other object has a
1232: * different node type or is <code>null</code>
1233: * @since 3.1
1234: */
1235: public boolean match(MemberValuePair node, Object other) {
1236: if (!(other instanceof MemberValuePair)) {
1237: return false;
1238: }
1239: MemberValuePair o = (MemberValuePair) other;
1240: return (safeSubtreeMatch(node.getName(), o.getName()) && safeSubtreeMatch(
1241: node.getValue(), o.getValue()));
1242: }
1243:
1244: /**
1245: * Returns whether the given node and the other object match.
1246: * <p>
1247: * The default implementation provided by this class tests whether the
1248: * other object is a node of the same type with structurally isomorphic
1249: * child subtrees. Subclasses may override this method as needed.
1250: * </p>
1251: *
1252: * @param node the node
1253: * @param other the other object, or <code>null</code>
1254: * @return <code>true</code> if the subtree matches, or
1255: * <code>false</code> if they do not match or the other object has a
1256: * different node type or is <code>null</code>
1257: * @since 3.0
1258: */
1259: public boolean match(MethodRef node, Object other) {
1260: if (!(other instanceof MethodRef)) {
1261: return false;
1262: }
1263: MethodRef o = (MethodRef) other;
1264: return (safeSubtreeMatch(node.getQualifier(), o.getQualifier())
1265: && safeSubtreeMatch(node.getName(), o.getName()) && safeSubtreeListMatch(
1266: node.parameters(), o.parameters()));
1267: }
1268:
1269: /**
1270: * Returns whether the given node and the other object match.
1271: * <p>
1272: * The default implementation provided by this class tests whether the
1273: * other object is a node of the same type with structurally isomorphic
1274: * child subtrees. Subclasses may override this method as needed.
1275: * </p>
1276: *
1277: * @param node the node
1278: * @param other the other object, or <code>null</code>
1279: * @return <code>true</code> if the subtree matches, or
1280: * <code>false</code> if they do not match or the other object has a
1281: * different node type or is <code>null</code>
1282: * @since 3.0
1283: */
1284: public boolean match(MethodRefParameter node, Object other) {
1285: if (!(other instanceof MethodRefParameter)) {
1286: return false;
1287: }
1288: MethodRefParameter o = (MethodRefParameter) other;
1289: int level = node.getAST().apiLevel;
1290: if (level >= AST.JLS3) {
1291: if (node.isVarargs() != o.isVarargs()) {
1292: return false;
1293: }
1294: }
1295: return (safeSubtreeMatch(node.getType(), o.getType()) && safeSubtreeMatch(
1296: node.getName(), o.getName()));
1297: }
1298:
1299: /**
1300: * Returns whether the given node and the other object match.
1301: * <p>
1302: * The default implementation provided by this class tests whether the
1303: * other object is a node of the same type with structurally isomorphic
1304: * child subtrees. Subclasses may override this method as needed.
1305: * </p>
1306: * <p>
1307: * Note that extra array dimensions are compared since they are an
1308: * important part of the method declaration.
1309: * </p>
1310: * <p>
1311: * Note that the method return types are compared even for constructor
1312: * declarations.
1313: * </p>
1314: *
1315: * @param node the node
1316: * @param other the other object, or <code>null</code>
1317: * @return <code>true</code> if the subtree matches, or
1318: * <code>false</code> if they do not match or the other object has a
1319: * different node type or is <code>null</code>
1320: */
1321: public boolean match(MethodDeclaration node, Object other) {
1322: if (!(other instanceof MethodDeclaration)) {
1323: return false;
1324: }
1325: MethodDeclaration o = (MethodDeclaration) other;
1326: int level = node.getAST().apiLevel;
1327: if (level == AST.JLS2_INTERNAL) {
1328: if (node.getModifiers() != o.getModifiers()) {
1329: return false;
1330: }
1331: if (!safeSubtreeMatch(node.internalGetReturnType(), o
1332: .internalGetReturnType())) {
1333: return false;
1334: }
1335: }
1336: if (level >= AST.JLS3) {
1337: if (!safeSubtreeListMatch(node.modifiers(), o.modifiers())) {
1338: return false;
1339: }
1340: if (!safeSubtreeMatch(node.getReturnType2(), o
1341: .getReturnType2())) {
1342: return false;
1343: }
1344: // n.b. compare type parameters even for constructors
1345: if (!safeSubtreeListMatch(node.typeParameters(), o
1346: .typeParameters())) {
1347: return false;
1348: }
1349: }
1350: return ((node.isConstructor() == o.isConstructor())
1351: && safeSubtreeMatch(node.getJavadoc(), o.getJavadoc())
1352: && safeSubtreeMatch(node.getName(), o.getName())
1353: // n.b. compare return type even for constructors
1354: && safeSubtreeListMatch(node.parameters(), o
1355: .parameters())
1356: && node.getExtraDimensions() == o.getExtraDimensions()
1357: && safeSubtreeListMatch(node.thrownExceptions(), o
1358: .thrownExceptions()) && safeSubtreeMatch(node
1359: .getBody(), o.getBody()));
1360: }
1361:
1362: /**
1363: * Returns whether the given node and the other object match.
1364: * <p>
1365: * The default implementation provided by this class tests whether the
1366: * other object is a node of the same type with structurally isomorphic
1367: * child subtrees. Subclasses may override this method as needed.
1368: * </p>
1369: *
1370: * @param node the node
1371: * @param other the other object, or <code>null</code>
1372: * @return <code>true</code> if the subtree matches, or
1373: * <code>false</code> if they do not match or the other object has a
1374: * different node type or is <code>null</code>
1375: */
1376: public boolean match(MethodInvocation node, Object other) {
1377: if (!(other instanceof MethodInvocation)) {
1378: return false;
1379: }
1380: MethodInvocation o = (MethodInvocation) other;
1381: if (node.getAST().apiLevel >= AST.JLS3) {
1382: if (!safeSubtreeListMatch(node.typeArguments(), o
1383: .typeArguments())) {
1384: return false;
1385: }
1386: }
1387: return (safeSubtreeMatch(node.getExpression(), o
1388: .getExpression())
1389: && safeSubtreeMatch(node.getName(), o.getName()) && safeSubtreeListMatch(
1390: node.arguments(), o.arguments()));
1391: }
1392:
1393: /**
1394: * Returns whether the given node and the other object match.
1395: * <p>
1396: * The default implementation provided by this class tests whether the
1397: * other object is a node of the same type with structurally isomorphic
1398: * child subtrees. Subclasses may override this method as needed.
1399: * </p>
1400: *
1401: * @param node the node
1402: * @param other the other object, or <code>null</code>
1403: * @return <code>true</code> if the subtree matches, or
1404: * <code>false</code> if they do not match or the other object has a
1405: * different node type or is <code>null</code>
1406: * @since 3.1
1407: */
1408: public boolean match(Modifier node, Object other) {
1409: if (!(other instanceof Modifier)) {
1410: return false;
1411: }
1412: Modifier o = (Modifier) other;
1413: return (node.getKeyword() == o.getKeyword());
1414: }
1415:
1416: /**
1417: * Returns whether the given node and the other object match.
1418: * <p>
1419: * The default implementation provided by this class tests whether the
1420: * other object is a node of the same type with structurally isomorphic
1421: * child subtrees. Subclasses may override this method as needed.
1422: * </p>
1423: *
1424: * @param node the node
1425: * @param other the other object, or <code>null</code>
1426: * @return <code>true</code> if the subtree matches, or
1427: * <code>false</code> if they do not match or the other object has a
1428: * different node type or is <code>null</code>
1429: * @since 3.1
1430: */
1431: public boolean match(NormalAnnotation node, Object other) {
1432: if (!(other instanceof NormalAnnotation)) {
1433: return false;
1434: }
1435: NormalAnnotation o = (NormalAnnotation) other;
1436: return (safeSubtreeMatch(node.getTypeName(), o.getTypeName()) && safeSubtreeListMatch(
1437: node.values(), o.values()));
1438: }
1439:
1440: /**
1441: * Returns whether the given node and the other object match.
1442: * <p>
1443: * The default implementation provided by this class tests whether the
1444: * other object is a node of the same type with structurally isomorphic
1445: * child subtrees. Subclasses may override this method as needed.
1446: * </p>
1447: *
1448: * @param node the node
1449: * @param other the other object, or <code>null</code>
1450: * @return <code>true</code> if the subtree matches, or
1451: * <code>false</code> if they do not match or the other object has a
1452: * different node type or is <code>null</code>
1453: */
1454: public boolean match(NullLiteral node, Object other) {
1455: if (!(other instanceof NullLiteral)) {
1456: return false;
1457: }
1458: return true;
1459: }
1460:
1461: /**
1462: * Returns whether the given node and the other object match.
1463: * <p>
1464: * The default implementation provided by this class tests whether the
1465: * other object is a node of the same type with structurally isomorphic
1466: * child subtrees. Subclasses may override this method as needed.
1467: * </p>
1468: *
1469: * @param node the node
1470: * @param other the other object, or <code>null</code>
1471: * @return <code>true</code> if the subtree matches, or
1472: * <code>false</code> if they do not match or the other object has a
1473: * different node type or is <code>null</code>
1474: */
1475: public boolean match(NumberLiteral node, Object other) {
1476: if (!(other instanceof NumberLiteral)) {
1477: return false;
1478: }
1479: NumberLiteral o = (NumberLiteral) other;
1480: return safeEquals(node.getToken(), o.getToken());
1481: }
1482:
1483: /**
1484: * Returns whether the given node and the other object match.
1485: * <p>
1486: * The default implementation provided by this class tests whether the
1487: * other object is a node of the same type with structurally isomorphic
1488: * child subtrees. Subclasses may override this method as needed.
1489: * </p>
1490: *
1491: * @param node the node
1492: * @param other the other object, or <code>null</code>
1493: * @return <code>true</code> if the subtree matches, or
1494: * <code>false</code> if they do not match or the other object has a
1495: * different node type or is <code>null</code>
1496: */
1497: public boolean match(PackageDeclaration node, Object other) {
1498: if (!(other instanceof PackageDeclaration)) {
1499: return false;
1500: }
1501: PackageDeclaration o = (PackageDeclaration) other;
1502: if (node.getAST().apiLevel >= AST.JLS3) {
1503: if (!safeSubtreeMatch(node.getJavadoc(), o.getJavadoc())) {
1504: return false;
1505: }
1506: if (!safeSubtreeListMatch(node.annotations(), o
1507: .annotations())) {
1508: return false;
1509: }
1510: }
1511: return safeSubtreeMatch(node.getName(), o.getName());
1512: }
1513:
1514: /**
1515: * Returns whether the given node and the other object match.
1516: * <p>
1517: * The default implementation provided by this class tests whether the
1518: * other object is a node of the same type with structurally isomorphic
1519: * child subtrees. Subclasses may override this method as needed.
1520: * </p>
1521: *
1522: * @param node the node
1523: * @param other the other object, or <code>null</code>
1524: * @return <code>true</code> if the subtree matches, or
1525: * <code>false</code> if they do not match or the other object has a
1526: * different node type or is <code>null</code>
1527: * @since 3.1
1528: */
1529: public boolean match(ParameterizedType node, Object other) {
1530: if (!(other instanceof ParameterizedType)) {
1531: return false;
1532: }
1533: ParameterizedType o = (ParameterizedType) other;
1534: return safeSubtreeMatch(node.getType(), o.getType())
1535: && safeSubtreeListMatch(node.typeArguments(), o
1536: .typeArguments());
1537: }
1538:
1539: /**
1540: * Returns whether the given node and the other object match.
1541: * <p>
1542: * The default implementation provided by this class tests whether the
1543: * other object is a node of the same type with structurally isomorphic
1544: * child subtrees. Subclasses may override this method as needed.
1545: * </p>
1546: *
1547: * @param node the node
1548: * @param other the other object, or <code>null</code>
1549: * @return <code>true</code> if the subtree matches, or
1550: * <code>false</code> if they do not match or the other object has a
1551: * different node type or is <code>null</code>
1552: */
1553: public boolean match(ParenthesizedExpression node, Object other) {
1554: if (!(other instanceof ParenthesizedExpression)) {
1555: return false;
1556: }
1557: ParenthesizedExpression o = (ParenthesizedExpression) other;
1558: return safeSubtreeMatch(node.getExpression(), o.getExpression());
1559: }
1560:
1561: /**
1562: * Returns whether the given node and the other object match.
1563: * <p>
1564: * The default implementation provided by this class tests whether the
1565: * other object is a node of the same type with structurally isomorphic
1566: * child subtrees. Subclasses may override this method as needed.
1567: * </p>
1568: *
1569: * @param node the node
1570: * @param other the other object, or <code>null</code>
1571: * @return <code>true</code> if the subtree matches, or
1572: * <code>false</code> if they do not match or the other object has a
1573: * different node type or is <code>null</code>
1574: */
1575: public boolean match(PostfixExpression node, Object other) {
1576: if (!(other instanceof PostfixExpression)) {
1577: return false;
1578: }
1579: PostfixExpression o = (PostfixExpression) other;
1580: return (node.getOperator().equals(o.getOperator()) && safeSubtreeMatch(
1581: node.getOperand(), o.getOperand()));
1582: }
1583:
1584: /**
1585: * Returns whether the given node and the other object match.
1586: * <p>
1587: * The default implementation provided by this class tests whether the
1588: * other object is a node of the same type with structurally isomorphic
1589: * child subtrees. Subclasses may override this method as needed.
1590: * </p>
1591: *
1592: * @param node the node
1593: * @param other the other object, or <code>null</code>
1594: * @return <code>true</code> if the subtree matches, or
1595: * <code>false</code> if they do not match or the other object has a
1596: * different node type or is <code>null</code>
1597: */
1598: public boolean match(PrefixExpression node, Object other) {
1599: if (!(other instanceof PrefixExpression)) {
1600: return false;
1601: }
1602: PrefixExpression o = (PrefixExpression) other;
1603: return (node.getOperator().equals(o.getOperator()) && safeSubtreeMatch(
1604: node.getOperand(), o.getOperand()));
1605: }
1606:
1607: /**
1608: * Returns whether the given node and the other object match.
1609: * <p>
1610: * The default implementation provided by this class tests whether the
1611: * other object is a node of the same type with structurally isomorphic
1612: * child subtrees. Subclasses may override this method as needed.
1613: * </p>
1614: *
1615: * @param node the node
1616: * @param other the other object, or <code>null</code>
1617: * @return <code>true</code> if the subtree matches, or
1618: * <code>false</code> if they do not match or the other object has a
1619: * different node type or is <code>null</code>
1620: */
1621: public boolean match(PrimitiveType node, Object other) {
1622: if (!(other instanceof PrimitiveType)) {
1623: return false;
1624: }
1625: PrimitiveType o = (PrimitiveType) other;
1626: return (node.getPrimitiveTypeCode() == o.getPrimitiveTypeCode());
1627: }
1628:
1629: /**
1630: * Returns whether the given node and the other object match.
1631: * <p>
1632: * The default implementation provided by this class tests whether the
1633: * other object is a node of the same type with structurally isomorphic
1634: * child subtrees. Subclasses may override this method as needed.
1635: * </p>
1636: *
1637: * @param node the node
1638: * @param other the other object, or <code>null</code>
1639: * @return <code>true</code> if the subtree matches, or
1640: * <code>false</code> if they do not match or the other object has a
1641: * different node type or is <code>null</code>
1642: */
1643: public boolean match(QualifiedName node, Object other) {
1644: if (!(other instanceof QualifiedName)) {
1645: return false;
1646: }
1647: QualifiedName o = (QualifiedName) other;
1648: return (safeSubtreeMatch(node.getQualifier(), o.getQualifier()) && safeSubtreeMatch(
1649: node.getName(), o.getName()));
1650: }
1651:
1652: /**
1653: * Returns whether the given node and the other object match.
1654: * <p>
1655: * The default implementation provided by this class tests whether the
1656: * other object is a node of the same type with structurally isomorphic
1657: * child subtrees. Subclasses may override this method as needed.
1658: * </p>
1659: *
1660: * @param node the node
1661: * @param other the other object, or <code>null</code>
1662: * @return <code>true</code> if the subtree matches, or
1663: * <code>false</code> if they do not match or the other object has a
1664: * different node type or is <code>null</code>
1665: * @since 3.1
1666: */
1667: public boolean match(QualifiedType node, Object other) {
1668: if (!(other instanceof QualifiedType)) {
1669: return false;
1670: }
1671: QualifiedType o = (QualifiedType) other;
1672: return (safeSubtreeMatch(node.getQualifier(), o.getQualifier()) && safeSubtreeMatch(
1673: 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 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 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 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 other) {
1758: if (!(other instanceof SingleMemberAnnotation)) {
1759: return false;
1760: }
1761: SingleMemberAnnotation o = (SingleMemberAnnotation) other;
1762: return (safeSubtreeMatch(node.getTypeName(), o.getTypeName()) && safeSubtreeMatch(
1763: 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 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 safeSubtreeMatch(node.getType(), o.getType())
1804: && safeSubtreeMatch(node.getName(), o.getName())
1805: && node.getExtraDimensions() == o.getExtraDimensions()
1806: && safeSubtreeMatch(node.getInitializer(), o
1807: .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 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 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
1853: .typeArguments())) {
1854: return false;
1855: }
1856: }
1857: return (safeSubtreeMatch(node.getExpression(), o
1858: .getExpression()) && safeSubtreeListMatch(node
1859: .arguments(), o.arguments()));
1860: }
1861:
1862: /**
1863: * Returns whether the given node and the other object match.
1864: * <p>
1865: * The default implementation provided by this class tests whether the
1866: * other object is a node of the same type with structurally isomorphic
1867: * child subtrees. Subclasses may override this method as needed.
1868: * </p>
1869: *
1870: * @param node the node
1871: * @param other the other object, or <code>null</code>
1872: * @return <code>true</code> if the subtree matches, or
1873: * <code>false</code> if they do not match or the other object has a
1874: * different node type or is <code>null</code>
1875: */
1876: public boolean match(SuperFieldAccess node, Object other) {
1877: if (!(other instanceof SuperFieldAccess)) {
1878: return false;
1879: }
1880: SuperFieldAccess o = (SuperFieldAccess) other;
1881: return (safeSubtreeMatch(node.getName(), o.getName()) && safeSubtreeMatch(
1882: 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 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
1906: .typeArguments())) {
1907: return false;
1908: }
1909: }
1910: return (safeSubtreeMatch(node.getQualifier(), o.getQualifier())
1911: && safeSubtreeMatch(node.getName(), o.getName()) && safeSubtreeListMatch(
1912: 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 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 other) {
1952: if (!(other instanceof SwitchStatement)) {
1953: return false;
1954: }
1955: SwitchStatement o = (SwitchStatement) other;
1956: return (safeSubtreeMatch(node.getExpression(), o
1957: .getExpression()) && safeSubtreeListMatch(node
1958: .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 other) {
1976: if (!(other instanceof SynchronizedStatement)) {
1977: return false;
1978: }
1979: SynchronizedStatement o = (SynchronizedStatement) other;
1980: return (safeSubtreeMatch(node.getExpression(), o
1981: .getExpression()) && safeSubtreeMatch(node.getBody(), o
1982: .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 other) {
2001: if (!(other instanceof TagElement)) {
2002: return false;
2003: }
2004: TagElement o = (TagElement) other;
2005: return (safeEquals(node.getTagName(), o.getTagName()) && safeSubtreeListMatch(
2006: node.fragments(), o.fragments()));
2007: }
2008:
2009: /**
2010: * Returns whether the given node and the other object match.
2011: * <p>
2012: * The default implementation provided by this class tests whether the
2013: * other object is a node of the same type with structurally isomorphic
2014: * child subtrees. Subclasses may override this method as needed.
2015: * </p>
2016: *
2017: * @param node the node
2018: * @param other the other object, or <code>null</code>
2019: * @return <code>true</code> if the subtree matches, or
2020: * <code>false</code> if they do not match or the other object has a
2021: * different node type or is <code>null</code>
2022: * @since 3.0
2023: */
2024: public boolean match(TextElement node, Object other) {
2025: if (!(other instanceof TextElement)) {
2026: return false;
2027: }
2028: TextElement o = (TextElement) other;
2029: return safeEquals(node.getText(), o.getText());
2030: }
2031:
2032: /**
2033: * Returns whether the given node and the other object match.
2034: * <p>
2035: * The default implementation provided by this class tests whether the
2036: * other object is a node of the same type with structurally isomorphic
2037: * child subtrees. Subclasses may override this method as needed.
2038: * </p>
2039: *
2040: * @param node the node
2041: * @param other the other object, or <code>null</code>
2042: * @return <code>true</code> if the subtree matches, or
2043: * <code>false</code> if they do not match or the other object has a
2044: * different node type or is <code>null</code>
2045: */
2046: public boolean match(ThisExpression node, Object other) {
2047: if (!(other instanceof ThisExpression)) {
2048: return false;
2049: }
2050: ThisExpression o = (ThisExpression) other;
2051: return safeSubtreeMatch(node.getQualifier(), o.getQualifier());
2052: }
2053:
2054: /**
2055: * Returns whether the given node and the other object match.
2056: * <p>
2057: * The default implementation provided by this class tests whether the
2058: * other object is a node of the same type with structurally isomorphic
2059: * child subtrees. Subclasses may override this method as needed.
2060: * </p>
2061: *
2062: * @param node the node
2063: * @param other the other object, or <code>null</code>
2064: * @return <code>true</code> if the subtree matches, or
2065: * <code>false</code> if they do not match or the other object has a
2066: * different node type or is <code>null</code>
2067: */
2068: public boolean match(ThrowStatement node, Object other) {
2069: if (!(other instanceof ThrowStatement)) {
2070: return false;
2071: }
2072: ThrowStatement o = (ThrowStatement) other;
2073: return safeSubtreeMatch(node.getExpression(), o.getExpression());
2074: }
2075:
2076: /**
2077: * Returns whether the given node and the other object match.
2078: * <p>
2079: * The default implementation provided by this class tests whether the
2080: * other object is a node of the same type with structurally isomorphic
2081: * child subtrees. Subclasses may override this method as needed.
2082: * </p>
2083: *
2084: * @param node the node
2085: * @param other the other object, or <code>null</code>
2086: * @return <code>true</code> if the subtree matches, or
2087: * <code>false</code> if they do not match or the other object has a
2088: * different node type or is <code>null</code>
2089: */
2090: public boolean match(TryStatement node, Object other) {
2091: if (!(other instanceof TryStatement)) {
2092: return false;
2093: }
2094: TryStatement o = (TryStatement) other;
2095: return (safeSubtreeMatch(node.getBody(), o.getBody())
2096: && safeSubtreeListMatch(node.catchClauses(), o
2097: .catchClauses()) && safeSubtreeMatch(node
2098: .getFinally(), o.getFinally()));
2099: }
2100:
2101: /**
2102: * Returns whether the given node and the other object match.
2103: * <p>
2104: * The default implementation provided by this class tests whether the
2105: * other object is a node of the same type with structurally isomorphic
2106: * child subtrees. Subclasses may override this method as needed.
2107: * </p>
2108: *
2109: * @param node the node
2110: * @param other the other object, or <code>null</code>
2111: * @return <code>true</code> if the subtree matches, or
2112: * <code>false</code> if they do not match or the other object has a
2113: * different node type or is <code>null</code>
2114: */
2115: public boolean match(TypeDeclaration node, Object other) {
2116: if (!(other instanceof TypeDeclaration)) {
2117: return false;
2118: }
2119: TypeDeclaration o = (TypeDeclaration) other;
2120: int level = node.getAST().apiLevel;
2121: if (level == AST.JLS2_INTERNAL) {
2122: if (node.getModifiers() != o.getModifiers()) {
2123: return false;
2124: }
2125: if (!safeSubtreeMatch(node.internalGetSuperclass(), o
2126: .internalGetSuperclass())) {
2127: return false;
2128: }
2129: if (!safeSubtreeListMatch(node.internalSuperInterfaces(), o
2130: .internalSuperInterfaces())) {
2131: return false;
2132: }
2133: }
2134: if (level >= AST.JLS3) {
2135: if (!safeSubtreeListMatch(node.modifiers(), o.modifiers())) {
2136: return false;
2137: }
2138: if (!safeSubtreeListMatch(node.typeParameters(), o
2139: .typeParameters())) {
2140: return false;
2141: }
2142: if (!safeSubtreeMatch(node.getSuperclassType(), o
2143: .getSuperclassType())) {
2144: return false;
2145: }
2146: if (!safeSubtreeListMatch(node.super InterfaceTypes(), o
2147: .super InterfaceTypes())) {
2148: return false;
2149: }
2150: }
2151: return ((node.isInterface() == o.isInterface())
2152: && safeSubtreeMatch(node.getJavadoc(), o.getJavadoc())
2153: && safeSubtreeMatch(node.getName(), o.getName()) && safeSubtreeListMatch(
2154: node.bodyDeclarations(), o.bodyDeclarations()));
2155: }
2156:
2157: /**
2158: * Returns whether the given node and the other object match.
2159: * <p>
2160: * The default implementation provided by this class tests whether the
2161: * other object is a node of the same type with structurally isomorphic
2162: * child subtrees. Subclasses may override this method as needed.
2163: * </p>
2164: *
2165: * @param node the node
2166: * @param other the other object, or <code>null</code>
2167: * @return <code>true</code> if the subtree matches, or
2168: * <code>false</code> if they do not match or the other object has a
2169: * different node type or is <code>null</code>
2170: */
2171: public boolean match(TypeDeclarationStatement node, Object other) {
2172: if (!(other instanceof TypeDeclarationStatement)) {
2173: return false;
2174: }
2175: TypeDeclarationStatement o = (TypeDeclarationStatement) other;
2176: return safeSubtreeMatch(node.getDeclaration(), o
2177: .getDeclaration());
2178: }
2179:
2180: /**
2181: * Returns whether the given node and the other object match.
2182: * <p>
2183: * The default implementation provided by this class tests whether the
2184: * other object is a node of the same type with structurally isomorphic
2185: * child subtrees. Subclasses may override this method as needed.
2186: * </p>
2187: *
2188: * @param node the node
2189: * @param other the other object, or <code>null</code>
2190: * @return <code>true</code> if the subtree matches, or
2191: * <code>false</code> if they do not match or the other object has a
2192: * different node type or is <code>null</code>
2193: */
2194: public boolean match(TypeLiteral node, Object other) {
2195: if (!(other instanceof TypeLiteral)) {
2196: return false;
2197: }
2198: TypeLiteral o = (TypeLiteral) other;
2199: return safeSubtreeMatch(node.getType(), o.getType());
2200: }
2201:
2202: /**
2203: * Returns whether the given node and the other object match.
2204: * <p>
2205: * The default implementation provided by this class tests whether the
2206: * other object is a node of the same type with structurally isomorphic
2207: * child subtrees. Subclasses may override this method as needed.
2208: * </p>
2209: *
2210: * @param node the node
2211: * @param other the other object, or <code>null</code>
2212: * @return <code>true</code> if the subtree matches, or
2213: * <code>false</code> if they do not match or the other object has a
2214: * different node type or is <code>null</code>
2215: * @since 3.1
2216: */
2217: public boolean match(TypeParameter node, Object other) {
2218: if (!(other instanceof TypeParameter)) {
2219: return false;
2220: }
2221: TypeParameter o = (TypeParameter) other;
2222: return safeSubtreeMatch(node.getName(), o.getName())
2223: && safeSubtreeListMatch(node.typeBounds(), o
2224: .typeBounds());
2225: }
2226:
2227: /**
2228: * Returns whether the given node and the other object match.
2229: * <p>
2230: * The default implementation provided by this class tests whether the
2231: * other object is a node of the same type with structurally isomorphic
2232: * child subtrees. Subclasses may override this method as needed.
2233: * </p>
2234: *
2235: * @param node the node
2236: * @param other the other object, or <code>null</code>
2237: * @return <code>true</code> if the subtree matches, or
2238: * <code>false</code> if they do not match or the other object has a
2239: * different node type or is <code>null</code>
2240: */
2241: public boolean match(VariableDeclarationExpression node,
2242: Object other) {
2243: if (!(other instanceof VariableDeclarationExpression)) {
2244: return false;
2245: }
2246: VariableDeclarationExpression o = (VariableDeclarationExpression) other;
2247: int level = node.getAST().apiLevel;
2248: if (level == AST.JLS2_INTERNAL) {
2249: if (node.getModifiers() != o.getModifiers()) {
2250: return false;
2251: }
2252: }
2253: if (level >= AST.JLS3) {
2254: if (!safeSubtreeListMatch(node.modifiers(), o.modifiers())) {
2255: return false;
2256: }
2257: }
2258: return safeSubtreeMatch(node.getType(), o.getType())
2259: && safeSubtreeListMatch(node.fragments(), o.fragments());
2260: }
2261:
2262: /**
2263: * Returns whether the given node and the other object match.
2264: * <p>
2265: * The default implementation provided by this class tests whether the
2266: * other object is a node of the same type with structurally isomorphic
2267: * child subtrees. Subclasses may override this method as needed.
2268: * </p>
2269: * <p>
2270: * Note that extra array dimensions are compared since they are an
2271: * important part of the type of the variable.
2272: * </p>
2273: *
2274: * @param node the node
2275: * @param other the other object, or <code>null</code>
2276: * @return <code>true</code> if the subtree matches, or
2277: * <code>false</code> if they do not match or the other object has a
2278: * different node type or is <code>null</code>
2279: */
2280: public boolean match(VariableDeclarationFragment node, Object other) {
2281: if (!(other instanceof VariableDeclarationFragment)) {
2282: return false;
2283: }
2284: VariableDeclarationFragment o = (VariableDeclarationFragment) other;
2285: return safeSubtreeMatch(node.getName(), o.getName())
2286: && node.getExtraDimensions() == o.getExtraDimensions()
2287: && safeSubtreeMatch(node.getInitializer(), o
2288: .getInitializer());
2289: }
2290:
2291: /**
2292: * Returns whether the given node and the other object match.
2293: * <p>
2294: * The default implementation provided by this class tests whether the
2295: * other object is a node of the same type with structurally isomorphic
2296: * child subtrees. Subclasses may override this method as needed.
2297: * </p>
2298: *
2299: * @param node the node
2300: * @param other the other object, or <code>null</code>
2301: * @return <code>true</code> if the subtree matches, or
2302: * <code>false</code> if they do not match or the other object has a
2303: * different node type or is <code>null</code>
2304: */
2305: public boolean match(VariableDeclarationStatement node, Object other) {
2306: if (!(other instanceof VariableDeclarationStatement)) {
2307: return false;
2308: }
2309: VariableDeclarationStatement o = (VariableDeclarationStatement) other;
2310: int level = node.getAST().apiLevel;
2311: if (level == AST.JLS2_INTERNAL) {
2312: if (node.getModifiers() != o.getModifiers()) {
2313: return false;
2314: }
2315: }
2316: if (level >= AST.JLS3) {
2317: if (!safeSubtreeListMatch(node.modifiers(), o.modifiers())) {
2318: return false;
2319: }
2320: }
2321: return safeSubtreeMatch(node.getType(), o.getType())
2322: && safeSubtreeListMatch(node.fragments(), o.fragments());
2323: }
2324:
2325: /**
2326: * Returns whether the given node and the other object match.
2327: * <p>
2328: * The default implementation provided by this class tests whether the
2329: * other object is a node of the same type with structurally isomorphic
2330: * child subtrees. Subclasses may override this method as needed.
2331: * </p>
2332: *
2333: * @param node the node
2334: * @param other the other object, or <code>null</code>
2335: * @return <code>true</code> if the subtree matches, or
2336: * <code>false</code> if they do not match or the other object has a
2337: * different node type or is <code>null</code>
2338: */
2339: public boolean match(WhileStatement node, Object other) {
2340: if (!(other instanceof WhileStatement)) {
2341: return false;
2342: }
2343: WhileStatement o = (WhileStatement) other;
2344: return (safeSubtreeMatch(node.getExpression(), o
2345: .getExpression()) && safeSubtreeMatch(node.getBody(), o
2346: .getBody()));
2347: }
2348:
2349: /**
2350: * Returns whether the given node and the other object match.
2351: * <p>
2352: * The default implementation provided by this class tests whether the
2353: * other object is a node of the same type with structurally isomorphic
2354: * child subtrees. Subclasses may override this method as needed.
2355: * </p>
2356: *
2357: * @param node the node
2358: * @param other the other object, or <code>null</code>
2359: * @return <code>true</code> if the subtree matches, or
2360: * <code>false</code> if they do not match or the other object has a
2361: * different node type or is <code>null</code>
2362: * @since 3.1
2363: */
2364: public boolean match(WildcardType node, Object other) {
2365: if (!(other instanceof WildcardType)) {
2366: return false;
2367: }
2368: WildcardType o = (WildcardType) other;
2369: return node.isUpperBound() == o.isUpperBound()
2370: && safeSubtreeMatch(node.getBound(), o.getBound());
2371: }
2372:
2373: }
|