org.eclipse.jdt.internal.core.search.matching.MatchLocatorParser.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipse.jdt.internal.core.search.matching.MatchLocatorParser.java

Source

/*******************************************************************************
 * Copyright (c) 2000, 2011 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.core.search.matching; // GROOVY PATCHED

import org.codehaus.jdt.groovy.integration.LanguageSupportFactory;
import org.eclipse.jdt.core.search.IJavaSearchConstants;
import org.eclipse.jdt.internal.compiler.ASTVisitor;
import org.eclipse.jdt.internal.compiler.ast.*;
import org.eclipse.jdt.internal.compiler.lookup.*;
import org.eclipse.jdt.internal.compiler.parser.Parser;
import org.eclipse.jdt.internal.compiler.problem.ProblemReporter;

/**
 * A parser that locates ast nodes that match a given search pattern.
 */
public class MatchLocatorParser extends Parser {

    MatchingNodeSet nodeSet;
    PatternLocator patternLocator;
    private ASTVisitor localDeclarationVisitor;
    final int patternFineGrain;

    public static MatchLocatorParser createParser(ProblemReporter problemReporter, MatchLocator locator) {
        // GROOVY Start
        /* old {
        if ((locator.matchContainer & PatternLocator.COMPILATION_UNIT_CONTAINER) != 0) {
           return new ImportMatchLocatorParser(problemReporter, locator);
        }
        return new MatchLocatorParser(problemReporter, locator);
        } new */
        // use multiplexing parsers instead
        if ((locator.matchContainer & PatternLocator.COMPILATION_UNIT_CONTAINER) != 0) {
            return LanguageSupportFactory.getImportMatchLocatorParser(problemReporter, locator);
        }
        return LanguageSupportFactory.getMatchLocatorParser(problemReporter, locator);
        // GROOVY End
    }

    /**
     * An ast visitor that visits local type declarations.
     */
    public class NoClassNoMethodDeclarationVisitor extends ASTVisitor {
        public boolean visit(ConstructorDeclaration constructorDeclaration, ClassScope scope) {
            return (constructorDeclaration.bits & ASTNode.HasLocalType) != 0; // continue only if it has local type
        }

        public boolean visit(FieldDeclaration fieldDeclaration, MethodScope scope) {
            return (fieldDeclaration.bits & ASTNode.HasLocalType) != 0; // continue only if it has local type;
        }

        public boolean visit(Initializer initializer, MethodScope scope) {
            return (initializer.bits & ASTNode.HasLocalType) != 0; // continue only if it has local type
        }

        public boolean visit(MethodDeclaration methodDeclaration, ClassScope scope) {
            return (methodDeclaration.bits & ASTNode.HasLocalType) != 0; // continue only if it has local type
        }
    }

    public class MethodButNoClassDeclarationVisitor extends NoClassNoMethodDeclarationVisitor {
        public boolean visit(TypeDeclaration localTypeDeclaration, BlockScope scope) {
            MatchLocatorParser.this.patternLocator.match(localTypeDeclaration, MatchLocatorParser.this.nodeSet);
            return true;
        }
    }

    public class ClassButNoMethodDeclarationVisitor extends ASTVisitor {
        public boolean visit(ConstructorDeclaration constructorDeclaration, ClassScope scope) {
            MatchLocatorParser.this.patternLocator.match(constructorDeclaration, MatchLocatorParser.this.nodeSet);
            return (constructorDeclaration.bits & ASTNode.HasLocalType) != 0; // continue only if it has local type
        }

        public boolean visit(FieldDeclaration fieldDeclaration, MethodScope scope) {
            MatchLocatorParser.this.patternLocator.match(fieldDeclaration, MatchLocatorParser.this.nodeSet);
            return (fieldDeclaration.bits & ASTNode.HasLocalType) != 0; // continue only if it has local type;
        }

        public boolean visit(Initializer initializer, MethodScope scope) {
            MatchLocatorParser.this.patternLocator.match(initializer, MatchLocatorParser.this.nodeSet);
            return (initializer.bits & ASTNode.HasLocalType) != 0; // continue only if it has local type
        }

        public boolean visit(TypeDeclaration memberTypeDeclaration, ClassScope scope) {
            MatchLocatorParser.this.patternLocator.match(memberTypeDeclaration, MatchLocatorParser.this.nodeSet);
            return true;
        }

        public boolean visit(MethodDeclaration methodDeclaration, ClassScope scope) {
            MatchLocatorParser.this.patternLocator.match(methodDeclaration, MatchLocatorParser.this.nodeSet);
            return (methodDeclaration.bits & ASTNode.HasLocalType) != 0; // continue only if it has local type
        }

        public boolean visit(AnnotationMethodDeclaration methodDeclaration, ClassScope scope) {
            MatchLocatorParser.this.patternLocator.match(methodDeclaration, MatchLocatorParser.this.nodeSet);
            return false; // no local type for annotation type members
        }
    }

    public class ClassAndMethodDeclarationVisitor extends ClassButNoMethodDeclarationVisitor {
        public boolean visit(TypeDeclaration localTypeDeclaration, BlockScope scope) {
            MatchLocatorParser.this.patternLocator.match(localTypeDeclaration, MatchLocatorParser.this.nodeSet);
            return true;
        }
    }

    //GROOVY Start
    //make public
    //Original code
    //protected 
    public
    //GROOVY End
    MatchLocatorParser(ProblemReporter problemReporter, MatchLocator locator) {
        super(problemReporter, true);
        this.reportOnlyOneSyntaxError = true;
        this.patternLocator = locator.patternLocator;
        if ((locator.matchContainer & PatternLocator.CLASS_CONTAINER) != 0) {
            this.localDeclarationVisitor = (locator.matchContainer & PatternLocator.METHOD_CONTAINER) != 0
                    ? new ClassAndMethodDeclarationVisitor()
                    : new ClassButNoMethodDeclarationVisitor();
        } else {
            this.localDeclarationVisitor = (locator.matchContainer & PatternLocator.METHOD_CONTAINER) != 0
                    ? new MethodButNoClassDeclarationVisitor()
                    : new NoClassNoMethodDeclarationVisitor();
        }
        this.patternFineGrain = this.patternLocator.fineGrain();
    }

    public void checkComment() {
        super.checkComment();
        if (this.javadocParser.checkDocComment && this.javadoc != null
                && this.patternFineGrain == 0 /* there's no fine grain concerning Javadoc*/) {

            // Search for pattern locator matches in javadoc comment parameters @param tags
            JavadocSingleNameReference[] paramReferences = this.javadoc.paramReferences;
            if (paramReferences != null) {
                for (int i = 0, length = paramReferences.length; i < length; i++) {
                    this.patternLocator.match(paramReferences[i], this.nodeSet);
                }
            }

            // Search for pattern locator matches in javadoc comment type parameters @param tags
            JavadocSingleTypeReference[] paramTypeParameters = this.javadoc.paramTypeParameters;
            if (paramTypeParameters != null) {
                for (int i = 0, length = paramTypeParameters.length; i < length; i++) {
                    this.patternLocator.match(paramTypeParameters[i], this.nodeSet);
                }
            }

            // Search for pattern locator matches in javadoc comment @throws/@exception tags
            TypeReference[] thrownExceptions = this.javadoc.exceptionReferences;
            if (thrownExceptions != null) {
                for (int i = 0, length = thrownExceptions.length; i < length; i++) {
                    this.patternLocator.match(thrownExceptions[i], this.nodeSet);
                }
            }

            // Search for pattern locator matches in javadoc comment @see tags
            Expression[] references = this.javadoc.seeReferences;
            if (references != null) {
                for (int i = 0, length = references.length; i < length; i++) {
                    Expression reference = references[i];
                    if (reference instanceof TypeReference) {
                        TypeReference typeRef = (TypeReference) reference;
                        this.patternLocator.match(typeRef, this.nodeSet);
                    } else if (reference instanceof JavadocFieldReference) {
                        JavadocFieldReference fieldRef = (JavadocFieldReference) reference;
                        this.patternLocator.match(fieldRef, this.nodeSet);
                        if (fieldRef.receiver instanceof TypeReference && !fieldRef.receiver.isThis()) {
                            TypeReference typeRef = (TypeReference) fieldRef.receiver;
                            this.patternLocator.match(typeRef, this.nodeSet);
                        }
                    } else if (reference instanceof JavadocMessageSend) {
                        JavadocMessageSend messageSend = (JavadocMessageSend) reference;
                        this.patternLocator.match(messageSend, this.nodeSet);
                        if (messageSend.receiver instanceof TypeReference && !messageSend.receiver.isThis()) {
                            TypeReference typeRef = (TypeReference) messageSend.receiver;
                            this.patternLocator.match(typeRef, this.nodeSet);
                        }
                        if (messageSend.arguments != null) {
                            for (int a = 0, al = messageSend.arguments.length; a < al; a++) {
                                JavadocArgumentExpression argument = (JavadocArgumentExpression) messageSend.arguments[a];
                                if (argument.argument != null && argument.argument.type != null) {
                                    this.patternLocator.match(argument.argument.type, this.nodeSet);
                                }
                            }
                        }
                    } else if (reference instanceof JavadocAllocationExpression) {
                        JavadocAllocationExpression constructor = (JavadocAllocationExpression) reference;
                        this.patternLocator.match(constructor, this.nodeSet);
                        if (constructor.type != null && !constructor.type.isThis()) {
                            this.patternLocator.match(constructor.type, this.nodeSet);
                        }
                        if (constructor.arguments != null) {
                            for (int a = 0, al = constructor.arguments.length; a < al; a++) {
                                this.patternLocator.match(constructor.arguments[a], this.nodeSet);
                                JavadocArgumentExpression argument = (JavadocArgumentExpression) constructor.arguments[a];
                                if (argument.argument != null && argument.argument.type != null) {
                                    this.patternLocator.match(argument.argument.type, this.nodeSet);
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    protected void classInstanceCreation(boolean alwaysQualified) {
        super.classInstanceCreation(alwaysQualified);
        if (this.patternFineGrain == 0) {
            this.patternLocator.match(this.expressionStack[this.expressionPtr], this.nodeSet);
        } else if ((this.patternFineGrain & IJavaSearchConstants.CLASS_INSTANCE_CREATION_TYPE_REFERENCE) != 0) {
            AllocationExpression allocation = (AllocationExpression) this.expressionStack[this.expressionPtr];
            this.patternLocator.match(allocation.type, this.nodeSet);
        }
    }

    protected void consumeAdditionalBound() {
        super.consumeAdditionalBound();
        if ((this.patternFineGrain & IJavaSearchConstants.TYPE_VARIABLE_BOUND_TYPE_REFERENCE) != 0) {
            TypeReference typeReference = (TypeReference) this.genericsStack[this.genericsPtr];
            this.patternLocator.match(typeReference, this.nodeSet);
        }
    }

    protected void consumeAssignment() {
        super.consumeAssignment();
        if (this.patternFineGrain == 0) {
            this.patternLocator.match(this.expressionStack[this.expressionPtr], this.nodeSet);
        }
    }

    protected void consumeCastExpressionLL1() {
        super.consumeCastExpressionLL1();
        if ((this.patternFineGrain & IJavaSearchConstants.CAST_TYPE_REFERENCE) != 0) {
            CastExpression castExpression = (CastExpression) this.expressionStack[this.expressionPtr];
            this.patternLocator.match(castExpression.type, this.nodeSet);
        }
    }

    protected void consumeCastExpressionWithGenericsArray() {
        super.consumeCastExpressionWithGenericsArray();
        if ((this.patternFineGrain & IJavaSearchConstants.CAST_TYPE_REFERENCE) != 0) {
            CastExpression castExpression = (CastExpression) this.expressionStack[this.expressionPtr];
            this.patternLocator.match(castExpression.type, this.nodeSet);
        }
    }

    protected void consumeCastExpressionWithNameArray() {
        super.consumeCastExpressionWithNameArray();
        if ((this.patternFineGrain & IJavaSearchConstants.CAST_TYPE_REFERENCE) != 0) {
            CastExpression castExpression = (CastExpression) this.expressionStack[this.expressionPtr];
            this.patternLocator.match(castExpression.type, this.nodeSet);
        }
    }

    protected void consumeCastExpressionWithPrimitiveType() {
        super.consumeCastExpressionWithPrimitiveType();
        if ((this.patternFineGrain & IJavaSearchConstants.CAST_TYPE_REFERENCE) != 0) {
            CastExpression castExpression = (CastExpression) this.expressionStack[this.expressionPtr];
            this.patternLocator.match(castExpression.type, this.nodeSet);
        }
    }

    protected void consumeCastExpressionWithQualifiedGenericsArray() {
        super.consumeCastExpressionWithQualifiedGenericsArray();
        if ((this.patternFineGrain & IJavaSearchConstants.CAST_TYPE_REFERENCE) != 0) {
            CastExpression castExpression = (CastExpression) this.expressionStack[this.expressionPtr];
            this.patternLocator.match(castExpression.type, this.nodeSet);
        }
    }

    protected void consumeCatchFormalParameter() {
        super.consumeCatchFormalParameter();
        this.patternLocator.match((LocalDeclaration) this.astStack[this.astPtr], this.nodeSet);
    }

    protected void consumeClassHeaderExtends() {
        this.patternLocator.setFlavors(PatternLocator.SUPERTYPE_REF_FLAVOR);
        super.consumeClassHeaderExtends();
        if ((this.patternFineGrain & IJavaSearchConstants.SUPERTYPE_TYPE_REFERENCE) != 0) {
            TypeDeclaration typeDeclaration = (TypeDeclaration) this.astStack[this.astPtr];
            this.patternLocator.match(typeDeclaration.superclass, this.nodeSet);
        }
        this.patternLocator.setFlavors(PatternLocator.NO_FLAVOR);
    }

    protected void consumeClassInstanceCreationExpressionQualifiedWithTypeArguments() {
        super.consumeClassInstanceCreationExpressionWithTypeArguments();
        if (this.patternFineGrain == 0) {
            this.patternLocator.match(this.expressionStack[this.expressionPtr], this.nodeSet);
        } else if ((this.patternFineGrain & IJavaSearchConstants.CLASS_INSTANCE_CREATION_TYPE_REFERENCE) != 0) {
            AllocationExpression allocation = (AllocationExpression) this.expressionStack[this.expressionPtr];
            this.patternLocator.match(allocation.type, this.nodeSet);
        }
    }

    protected void consumeClassInstanceCreationExpressionWithTypeArguments() {
        super.consumeClassInstanceCreationExpressionWithTypeArguments();
        if (this.patternFineGrain == 0) {
            this.patternLocator.match(this.expressionStack[this.expressionPtr], this.nodeSet);
        } else if ((this.patternFineGrain & IJavaSearchConstants.CLASS_INSTANCE_CREATION_TYPE_REFERENCE) != 0) {
            AllocationExpression allocation = (AllocationExpression) this.expressionStack[this.expressionPtr];
            this.patternLocator.match(allocation.type, this.nodeSet);
        }
    }

    protected void consumeEnterAnonymousClassBody(boolean qualified) {
        this.patternLocator.setFlavors(PatternLocator.SUPERTYPE_REF_FLAVOR);
        super.consumeEnterAnonymousClassBody(qualified);
        this.patternLocator.setFlavors(PatternLocator.NO_FLAVOR);
    }

    protected void consumeEnterVariable() {
        boolean isLocalDeclaration = this.nestedMethod[this.nestedType] != 0;
        super.consumeEnterVariable();
        if (isLocalDeclaration) {
            if ((this.patternFineGrain & IJavaSearchConstants.LOCAL_VARIABLE_DECLARATION_TYPE_REFERENCE) != 0) {
                LocalDeclaration localDeclaration = (LocalDeclaration) this.astStack[this.astPtr];
                this.patternLocator.match(localDeclaration.type, this.nodeSet);
            }
        } else {
            if ((this.patternFineGrain & IJavaSearchConstants.FIELD_DECLARATION_TYPE_REFERENCE) != 0) {
                FieldDeclaration fieldDeclaration = (FieldDeclaration) this.astStack[this.astPtr];
                this.patternLocator.match(fieldDeclaration.type, this.nodeSet);
            }
        }
    }

    protected void consumeExplicitConstructorInvocation(int flag, int recFlag) {
        super.consumeExplicitConstructorInvocation(flag, recFlag);
        this.patternLocator.match(this.astStack[this.astPtr], this.nodeSet);
    }

    protected void consumeExplicitConstructorInvocationWithTypeArguments(int flag, int recFlag) {
        super.consumeExplicitConstructorInvocationWithTypeArguments(flag, recFlag);
        this.patternLocator.match(this.astStack[this.astPtr], this.nodeSet);
    }

    protected void consumeFieldAccess(boolean isSuperAccess) {
        super.consumeFieldAccess(isSuperAccess);

        int fineGrain = isSuperAccess ? IJavaSearchConstants.SUPER_REFERENCE : IJavaSearchConstants.THIS_REFERENCE;
        if (this.patternFineGrain == 0 || (this.patternFineGrain & fineGrain) != 0) {
            // this is always a Reference
            this.patternLocator.match((Reference) this.expressionStack[this.expressionPtr], this.nodeSet);
        }
    }

    protected void consumeFormalParameter(boolean isVarArgs) {
        super.consumeFormalParameter(isVarArgs);
        this.patternLocator.match((LocalDeclaration) this.astStack[this.astPtr], this.nodeSet);
    }

    protected void consumeInstanceOfExpression() {
        super.consumeInstanceOfExpression();
        if ((this.patternFineGrain & IJavaSearchConstants.INSTANCEOF_TYPE_REFERENCE) != 0) {
            InstanceOfExpression expression = (InstanceOfExpression) this.expressionStack[this.expressionPtr];
            this.patternLocator.match(expression.type, this.nodeSet);
        }
    }

    protected void consumeInstanceOfExpressionWithName() {
        super.consumeInstanceOfExpressionWithName();
        if ((this.patternFineGrain & IJavaSearchConstants.INSTANCEOF_TYPE_REFERENCE) != 0) {
            InstanceOfExpression expression = (InstanceOfExpression) this.expressionStack[this.expressionPtr];
            this.patternLocator.match(expression.type, this.nodeSet);
        }
    }

    protected void consumeInterfaceType() {
        this.patternLocator.setFlavors(PatternLocator.SUPERTYPE_REF_FLAVOR);
        super.consumeInterfaceType();
        if ((this.patternFineGrain & IJavaSearchConstants.SUPERTYPE_TYPE_REFERENCE) != 0) {
            TypeReference typeReference = (TypeReference) this.astStack[this.astPtr];
            this.patternLocator.match(typeReference, this.nodeSet);
        }
        this.patternLocator.setFlavors(PatternLocator.NO_FLAVOR);
    }

    protected void consumeLocalVariableDeclaration() {
        super.consumeLocalVariableDeclaration();
        this.patternLocator.match((LocalDeclaration) this.astStack[this.astPtr], this.nodeSet);
    }

    protected void consumeMarkerAnnotation() {
        super.consumeMarkerAnnotation();
        if (this.patternFineGrain == 0
                || (this.patternFineGrain & IJavaSearchConstants.ANNOTATION_TYPE_REFERENCE) != 0) {
            Annotation annotation = (Annotation) this.expressionStack[this.expressionPtr];
            this.patternLocator.match(annotation, this.nodeSet);
        }
    }

    protected void consumeMemberValuePair() {
        super.consumeMemberValuePair();
        this.patternLocator.match((MemberValuePair) this.astStack[this.astPtr], this.nodeSet);
    }

    protected void consumeMethodHeaderName(boolean isAnnotationMethod) {
        super.consumeMethodHeaderName(isAnnotationMethod);
        if ((this.patternFineGrain & IJavaSearchConstants.RETURN_TYPE_REFERENCE) != 0) {
            // when no fine grain flag is set, type reference match is evaluated in getTypeReference(int) method
            MethodDeclaration methodDeclaration = (MethodDeclaration) this.astStack[this.astPtr];
            this.patternLocator.match(methodDeclaration.returnType, this.nodeSet);
        }
    }

    protected void consumeMethodHeaderRightParen() {
        super.consumeMethodHeaderRightParen();
        if ((this.patternFineGrain & IJavaSearchConstants.PARAMETER_DECLARATION_TYPE_REFERENCE) != 0) {
            // when no fine grain flag is set, type reference match is evaluated in getTypeReference(int) method
            AbstractMethodDeclaration methodDeclaration = (AbstractMethodDeclaration) this.astStack[this.astPtr];
            Argument[] arguments = methodDeclaration.arguments;
            if (arguments != null) {
                int argLength = arguments.length;
                for (int i = 0; i < argLength; i++) {
                    this.patternLocator.match(arguments[i].type, this.nodeSet);
                }
            }
        }
    }

    protected void consumeMethodHeaderThrowsClause() {
        super.consumeMethodHeaderThrowsClause();
        if ((this.patternFineGrain & IJavaSearchConstants.THROWS_CLAUSE_TYPE_REFERENCE) != 0) {
            // when no fine grain flag is set, type reference match is evaluated in getTypeReference(int) method
            AbstractMethodDeclaration methodDeclaration = (AbstractMethodDeclaration) this.astStack[this.astPtr];
            TypeReference[] thrownExceptions = methodDeclaration.thrownExceptions;
            if (thrownExceptions != null) {
                int thrownLength = thrownExceptions.length;
                for (int i = 0; i < thrownLength; i++) {
                    this.patternLocator.match(thrownExceptions[i], this.nodeSet);
                }
            }
        }
    }

    protected void consumeMethodInvocationName() {
        super.consumeMethodInvocationName();
        MessageSend messageSend = (MessageSend) this.expressionStack[this.expressionPtr];
        if (this.patternFineGrain == 0) {
            this.patternLocator.match(messageSend, this.nodeSet);
        } else {
            if (messageSend.receiver.isThis()) {
                if ((this.patternFineGrain & IJavaSearchConstants.IMPLICIT_THIS_REFERENCE) != 0) {
                    this.patternLocator.match(messageSend, this.nodeSet);
                }
            } else {
                if ((this.patternFineGrain & IJavaSearchConstants.QUALIFIED_REFERENCE) != 0) {
                    this.patternLocator.match(messageSend, this.nodeSet);
                }
            }
        }
    }

    protected void consumeMethodInvocationNameWithTypeArguments() {
        super.consumeMethodInvocationNameWithTypeArguments();
        MessageSend messageSend = (MessageSend) this.expressionStack[this.expressionPtr];
        if (this.patternFineGrain == 0) {
            this.patternLocator.match(messageSend, this.nodeSet);
        } else {
            if (messageSend.receiver.isThis()) {
                if ((this.patternFineGrain & IJavaSearchConstants.IMPLICIT_THIS_REFERENCE) != 0) {
                    this.patternLocator.match(messageSend, this.nodeSet);
                }
            } else {
                if ((this.patternFineGrain & IJavaSearchConstants.QUALIFIED_REFERENCE) != 0) {
                    this.patternLocator.match(messageSend, this.nodeSet);
                }
            }
        }
    }

    protected void consumeMethodInvocationPrimary() {
        super.consumeMethodInvocationPrimary();
        if (this.patternFineGrain == 0 || (this.patternFineGrain & IJavaSearchConstants.THIS_REFERENCE) != 0) {
            this.patternLocator.match((MessageSend) this.expressionStack[this.expressionPtr], this.nodeSet);
        }
    }

    protected void consumeMethodInvocationPrimaryWithTypeArguments() {
        super.consumeMethodInvocationPrimaryWithTypeArguments();
        if (this.patternFineGrain == 0 || (this.patternFineGrain & IJavaSearchConstants.THIS_REFERENCE) != 0) {
            this.patternLocator.match((MessageSend) this.expressionStack[this.expressionPtr], this.nodeSet);
        }
    }

    protected void consumeMethodInvocationSuper() {
        super.consumeMethodInvocationSuper();
        if (this.patternFineGrain == 0 || (this.patternFineGrain & IJavaSearchConstants.SUPER_REFERENCE) != 0) {
            this.patternLocator.match((MessageSend) this.expressionStack[this.expressionPtr], this.nodeSet);
        }
    }

    protected void consumeMethodInvocationSuperWithTypeArguments() {
        super.consumeMethodInvocationSuperWithTypeArguments();
        if (this.patternFineGrain == 0 || (this.patternFineGrain & IJavaSearchConstants.SUPER_REFERENCE) != 0) {
            this.patternLocator.match((MessageSend) this.expressionStack[this.expressionPtr], this.nodeSet);
        }
    }

    protected void consumeNormalAnnotation() {
        super.consumeNormalAnnotation();
        if (this.patternFineGrain == 0
                || (this.patternFineGrain & IJavaSearchConstants.ANNOTATION_TYPE_REFERENCE) != 0) {
            // this is always an Annotation
            Annotation annotation = (Annotation) this.expressionStack[this.expressionPtr];
            this.patternLocator.match(annotation, this.nodeSet);
        }
    }

    protected void consumeOnlyTypeArguments() {
        super.consumeOnlyTypeArguments();
        if ((this.patternFineGrain & IJavaSearchConstants.TYPE_ARGUMENT_TYPE_REFERENCE) != 0) {
            int length = this.genericsLengthStack[this.genericsLengthPtr];
            if (length == 1) {
                TypeReference typeReference = (TypeReference) this.genericsStack[this.genericsPtr];
                if (!(typeReference instanceof Wildcard)) {
                    this.patternLocator.match(typeReference, this.nodeSet);
                }
            }
        }
    }

    protected void consumePrimaryNoNewArray() {
        // pop parenthesis positions (and don't update expression positions
        // (see http://bugs.eclipse.org/bugs/show_bug.cgi?id=23329)
        this.intPtr--;
        this.intPtr--;
    }

    protected void consumePrimaryNoNewArrayWithName() {
        // PrimaryNoNewArray ::=  PushLPAREN Expression PushRPAREN
        pushOnExpressionStack(getUnspecifiedReferenceOptimized());
        // pop parenthesis positions (and don't update expression positions
        // (see http://bugs.eclipse.org/bugs/show_bug.cgi?id=23329)
        this.intPtr--;
        this.intPtr--;
    }

    protected void consumeSingleMemberAnnotation() {
        super.consumeSingleMemberAnnotation();
        if (this.patternFineGrain == 0
                || (this.patternFineGrain & IJavaSearchConstants.ANNOTATION_TYPE_REFERENCE) != 0) {
            // this is always an Annotation
            Annotation annotation = (Annotation) this.expressionStack[this.expressionPtr];
            this.patternLocator.match(annotation, this.nodeSet);
        }
    }

    protected void consumeStatementCatch() {
        super.consumeStatementCatch();
        if ((this.patternFineGrain & IJavaSearchConstants.CATCH_TYPE_REFERENCE) != 0) {
            // when no fine grain flag is set, type reference match is evaluated in getTypeReference(int) method
            LocalDeclaration localDeclaration = (LocalDeclaration) this.astStack[this.astPtr - 1];
            if (localDeclaration.type instanceof UnionTypeReference) {
                TypeReference[] refs = ((UnionTypeReference) localDeclaration.type).typeReferences;
                for (int i = 0, len = refs.length; i < len; i++) {
                    this.patternLocator.match(refs[i], this.nodeSet);
                }
            } else {
                this.patternLocator.match(localDeclaration.type, this.nodeSet);
            }
        }
    }

    protected void consumeTypeArgumentList1() {
        super.consumeTypeArgumentList1();
        if ((this.patternFineGrain & IJavaSearchConstants.TYPE_ARGUMENT_TYPE_REFERENCE) != 0) {
            for (int i = this.genericsPtr - this.genericsLengthStack[this.genericsLengthPtr]
                    + 1; i <= this.genericsPtr; i++) {
                TypeReference typeReference = (TypeReference) this.genericsStack[i];
                if (!(typeReference instanceof Wildcard)) {
                    this.patternLocator.match(typeReference, this.nodeSet);
                }
            }
        }
    }

    protected void consumeTypeArgumentList2() {
        super.consumeTypeArgumentList2();
        if ((this.patternFineGrain & IJavaSearchConstants.TYPE_ARGUMENT_TYPE_REFERENCE) != 0) {
            for (int i = this.genericsPtr - this.genericsLengthStack[this.genericsLengthPtr]
                    + 1; i <= this.genericsPtr; i++) {
                TypeReference typeReference = (TypeReference) this.genericsStack[i];
                if (!(typeReference instanceof Wildcard)) {
                    this.patternLocator.match(typeReference, this.nodeSet);
                }
            }
        }
    }

    protected void consumeTypeArgumentList3() {
        super.consumeTypeArgumentList3();
        if ((this.patternFineGrain & IJavaSearchConstants.TYPE_ARGUMENT_TYPE_REFERENCE) != 0) {
            for (int i = this.genericsPtr - this.genericsLengthStack[this.genericsLengthPtr]
                    + 1; i <= this.genericsPtr; i++) {
                TypeReference typeReference = (TypeReference) this.genericsStack[i];
                if (!(typeReference instanceof Wildcard)) {
                    this.patternLocator.match(typeReference, this.nodeSet);
                }
            }
        }
    }

    protected void consumeTypeArgumentReferenceType1() {
        super.consumeTypeArgumentReferenceType1();
        if ((this.patternFineGrain & IJavaSearchConstants.TYPE_ARGUMENT_TYPE_REFERENCE) != 0) {
            int length = this.genericsLengthStack[this.genericsLengthPtr];
            if (length == 1) {
                TypeReference typeReference = (TypeReference) this.genericsStack[this.genericsPtr];
                TypeReference[] typeArguments = null;
                if (typeReference instanceof ParameterizedSingleTypeReference) {
                    typeArguments = ((ParameterizedSingleTypeReference) typeReference).typeArguments;
                } else if (typeReference instanceof ParameterizedQualifiedTypeReference) {
                    TypeReference[][] allTypeArguments = ((ParameterizedQualifiedTypeReference) typeReference).typeArguments;
                    typeArguments = allTypeArguments[allTypeArguments.length - 1];
                }
                if (typeArguments != null) {
                    for (int i = 0, ln = typeArguments.length; i < ln; i++) {
                        if (!(typeArguments[i] instanceof Wildcard)) {
                            this.patternLocator.match(typeArguments[i], this.nodeSet);
                        }
                    }
                }
            }
        }
    }

    protected void consumeTypeArgumentReferenceType2() {
        super.consumeTypeArgumentReferenceType2();
        if ((this.patternFineGrain & IJavaSearchConstants.TYPE_ARGUMENT_TYPE_REFERENCE) != 0) {
            int length = this.genericsLengthStack[this.genericsLengthPtr];
            if (length == 1) {
                TypeReference typeReference = (TypeReference) this.genericsStack[this.genericsPtr];
                TypeReference[] typeArguments = null;
                if (typeReference instanceof ParameterizedSingleTypeReference) {
                    typeArguments = ((ParameterizedSingleTypeReference) typeReference).typeArguments;
                } else if (typeReference instanceof ParameterizedQualifiedTypeReference) {
                    TypeReference[][] allTypeArguments = ((ParameterizedQualifiedTypeReference) typeReference).typeArguments;
                    typeArguments = allTypeArguments[allTypeArguments.length - 1];
                }
                if (typeArguments != null) {
                    for (int i = 0, ln = typeArguments.length; i < ln; i++) {
                        if (!(typeArguments[i] instanceof Wildcard)) {
                            this.patternLocator.match(typeArguments[i], this.nodeSet);
                        }
                    }
                }
            }
        }
    }

    protected void consumeTypeArguments() {
        super.consumeTypeArguments();
        if ((this.patternFineGrain & IJavaSearchConstants.TYPE_ARGUMENT_TYPE_REFERENCE) != 0) {
            int length = this.genericsLengthStack[this.genericsLengthPtr];
            if (length == 1) {
                TypeReference typeReference = (TypeReference) this.genericsStack[this.genericsPtr];
                if (!(typeReference instanceof Wildcard)) {
                    this.patternLocator.match(typeReference, this.nodeSet);
                }
            }
        }
    }

    protected void consumeTypeParameter1WithExtends() {
        super.consumeTypeParameter1WithExtends();
        if ((this.patternFineGrain & IJavaSearchConstants.TYPE_VARIABLE_BOUND_TYPE_REFERENCE) != 0) {
            TypeParameter typeParameter = (TypeParameter) this.genericsStack[this.genericsPtr];
            this.patternLocator.match(typeParameter.type, this.nodeSet);
        }
    }

    protected void consumeTypeParameter1WithExtendsAndBounds() {
        super.consumeTypeParameter1WithExtendsAndBounds();
        if ((this.patternFineGrain & IJavaSearchConstants.TYPE_VARIABLE_BOUND_TYPE_REFERENCE) != 0) {
            TypeParameter typeParameter = (TypeParameter) this.genericsStack[this.genericsPtr];
            this.patternLocator.match(typeParameter.type, this.nodeSet);
        }
    }

    protected void consumeTypeParameterHeader() {
        super.consumeTypeParameterHeader();
        this.patternLocator.match((TypeParameter) this.genericsStack[this.genericsPtr], this.nodeSet);
    }

    protected void consumeTypeParameterWithExtends() {
        super.consumeTypeParameterWithExtends();
        if ((this.patternFineGrain & IJavaSearchConstants.TYPE_VARIABLE_BOUND_TYPE_REFERENCE) != 0) {
            TypeParameter typeParameter = (TypeParameter) this.genericsStack[this.genericsPtr];
            this.patternLocator.match(typeParameter.type, this.nodeSet);
        }
    }

    protected void consumeTypeParameterWithExtendsAndBounds() {
        super.consumeTypeParameterWithExtendsAndBounds();
        if ((this.patternFineGrain & IJavaSearchConstants.TYPE_VARIABLE_BOUND_TYPE_REFERENCE) != 0) {
            TypeParameter typeParameter = (TypeParameter) this.genericsStack[this.genericsPtr];
            this.patternLocator.match(typeParameter.type, this.nodeSet);
        }
    }

    protected void consumeUnaryExpression(int op, boolean post) {
        super.consumeUnaryExpression(op, post);
        this.patternLocator.match(this.expressionStack[this.expressionPtr], this.nodeSet);
    }

    protected void consumeWildcardBounds1Extends() {
        super.consumeWildcardBounds1Extends();
        if ((this.patternFineGrain & IJavaSearchConstants.WILDCARD_BOUND_TYPE_REFERENCE) != 0) {
            Wildcard wildcard = (Wildcard) this.genericsStack[this.genericsPtr];
            this.patternLocator.match(wildcard.bound, this.nodeSet);
        }
    }

    protected void consumeWildcardBounds1Super() {
        super.consumeWildcardBounds1Super();
        if ((this.patternFineGrain & IJavaSearchConstants.WILDCARD_BOUND_TYPE_REFERENCE) != 0) {
            Wildcard wildcard = (Wildcard) this.genericsStack[this.genericsPtr];
            this.patternLocator.match(wildcard.bound, this.nodeSet);
        }
    }

    protected void consumeWildcardBounds2Extends() {
        super.consumeWildcardBounds2Extends();
        if ((this.patternFineGrain & IJavaSearchConstants.WILDCARD_BOUND_TYPE_REFERENCE) != 0) {
            Wildcard wildcard = (Wildcard) this.genericsStack[this.genericsPtr];
            this.patternLocator.match(wildcard.bound, this.nodeSet);
        }
    }

    protected void consumeWildcardBounds2Super() {
        super.consumeWildcardBounds2Super();
        if ((this.patternFineGrain & IJavaSearchConstants.WILDCARD_BOUND_TYPE_REFERENCE) != 0) {
            Wildcard wildcard = (Wildcard) this.genericsStack[this.genericsPtr];
            this.patternLocator.match(wildcard.bound, this.nodeSet);
        }
    }

    protected void consumeWildcardBounds3Extends() {
        super.consumeWildcardBounds3Extends();
        if ((this.patternFineGrain & IJavaSearchConstants.WILDCARD_BOUND_TYPE_REFERENCE) != 0) {
            Wildcard wildcard = (Wildcard) this.genericsStack[this.genericsPtr];
            this.patternLocator.match(wildcard.bound, this.nodeSet);
        }
    }

    protected void consumeWildcardBounds3Super() {
        super.consumeWildcardBounds3Super();
        if ((this.patternFineGrain & IJavaSearchConstants.WILDCARD_BOUND_TYPE_REFERENCE) != 0) {
            Wildcard wildcard = (Wildcard) this.genericsStack[this.genericsPtr];
            this.patternLocator.match(wildcard.bound, this.nodeSet);
        }
    }

    protected void consumeWildcardBoundsExtends() {
        super.consumeWildcardBoundsExtends();
        if ((this.patternFineGrain & IJavaSearchConstants.WILDCARD_BOUND_TYPE_REFERENCE) != 0) {
            Wildcard wildcard = (Wildcard) this.genericsStack[this.genericsPtr];
            this.patternLocator.match(wildcard.bound, this.nodeSet);
        }
    }

    protected void consumeWildcardBoundsSuper() {
        super.consumeWildcardBoundsSuper();
        if ((this.patternFineGrain & IJavaSearchConstants.WILDCARD_BOUND_TYPE_REFERENCE) != 0) {
            Wildcard wildcard = (Wildcard) this.genericsStack[this.genericsPtr];
            this.patternLocator.match(wildcard.bound, this.nodeSet);
        }
    }

    protected TypeReference copyDims(TypeReference typeRef, int dim) {
        TypeReference result = super.copyDims(typeRef, dim);
        if (this.nodeSet.removePossibleMatch(typeRef) != null)
            this.nodeSet.addPossibleMatch(result);
        else if (this.nodeSet.removeTrustedMatch(typeRef) != null)
            this.nodeSet.addTrustedMatch(result, true);
        return result;
    }

    protected TypeReference getTypeReference(int dim) {
        TypeReference typeRef = super.getTypeReference(dim);
        if (this.patternFineGrain == 0) {
            this.patternLocator.match(typeRef, this.nodeSet); // NB: Don't check container since type reference can happen anywhere
        }
        return typeRef;
    }

    protected NameReference getUnspecifiedReference() {
        NameReference nameRef = super.getUnspecifiedReference();
        if (this.patternFineGrain == 0) {
            this.patternLocator.match(nameRef, this.nodeSet); // NB: Don't check container since unspecified reference can happen anywhere
        } else if ((this.patternFineGrain & IJavaSearchConstants.QUALIFIED_REFERENCE) != 0) {
            if (nameRef instanceof QualifiedNameReference) {
                this.patternLocator.match(nameRef, this.nodeSet);
            }
        } else if ((this.patternFineGrain & IJavaSearchConstants.IMPLICIT_THIS_REFERENCE) != 0) {
            if (nameRef instanceof SingleNameReference) {
                this.patternLocator.match(nameRef, this.nodeSet);
            }
        }
        return nameRef;
    }

    protected NameReference getUnspecifiedReferenceOptimized() {
        NameReference nameRef = super.getUnspecifiedReferenceOptimized();
        if (this.patternFineGrain == 0) {
            this.patternLocator.match(nameRef, this.nodeSet); // NB: Don't check container since unspecified reference can happen anywhere
        } else {
            boolean flagQualifiedRef = (this.patternFineGrain & IJavaSearchConstants.QUALIFIED_REFERENCE) != 0;
            boolean flagImplicitThis = (this.patternFineGrain & IJavaSearchConstants.IMPLICIT_THIS_REFERENCE) != 0;
            if (flagQualifiedRef && flagImplicitThis) {
                this.patternLocator.match(nameRef, this.nodeSet);
            } else if (flagQualifiedRef) {
                if (nameRef instanceof QualifiedNameReference) {
                    this.patternLocator.match(nameRef, this.nodeSet);
                }
            } else if (flagImplicitThis) {
                if (nameRef instanceof SingleNameReference) {
                    this.patternLocator.match(nameRef, this.nodeSet);
                }
            }
        }
        return nameRef;
    }

    /**
     * Parses the method bodies in the given compilation unit
     * @param unit CompilationUnitDeclaration
     */
    public void parseBodies(CompilationUnitDeclaration unit) {
        TypeDeclaration[] types = unit.types;
        if (types == null)
            return;

        for (int i = 0; i < types.length; i++) {
            TypeDeclaration type = types[i];
            this.patternLocator.match(type, this.nodeSet);
            this.parseBodies(type, unit);
        }
    }

    /**
     * Parses the member bodies in the given type.
     * @param type TypeDeclaration
     * @param unit CompilationUnitDeclaration
     */
    protected void parseBodies(TypeDeclaration type, CompilationUnitDeclaration unit) {
        FieldDeclaration[] fields = type.fields;
        if (fields != null) {
            for (int i = 0; i < fields.length; i++) {
                FieldDeclaration field = fields[i];
                if (field instanceof Initializer)
                    this.parse((Initializer) field, type, unit);
                field.traverse(this.localDeclarationVisitor, null);
            }
        }

        AbstractMethodDeclaration[] methods = type.methods;
        if (methods != null) {
            for (int i = 0; i < methods.length; i++) {
                AbstractMethodDeclaration method = methods[i];
                if (method.sourceStart >= type.bodyStart) { // if not synthetic
                    if (method instanceof MethodDeclaration) {
                        MethodDeclaration methodDeclaration = (MethodDeclaration) method;
                        this.parse(methodDeclaration, unit);
                        methodDeclaration.traverse(this.localDeclarationVisitor, (ClassScope) null);
                    } else if (method instanceof ConstructorDeclaration) {
                        ConstructorDeclaration constructorDeclaration = (ConstructorDeclaration) method;
                        this.parse(constructorDeclaration, unit, false);
                        constructorDeclaration.traverse(this.localDeclarationVisitor, (ClassScope) null);
                    }
                } else if (method.isDefaultConstructor()) {
                    method.parseStatements(this, unit);
                }
            }
        }

        TypeDeclaration[] memberTypes = type.memberTypes;
        if (memberTypes != null) {
            for (int i = 0; i < memberTypes.length; i++) {
                TypeDeclaration memberType = memberTypes[i];
                this.parseBodies(memberType, unit);
                memberType.traverse(this.localDeclarationVisitor, (ClassScope) null);
            }
        }
    }

}