/******************************************************************************* * Copyright (c) 2000, 2014 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; 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) { if ((locator.matchContainer & PatternLocator.COMPILATION_UNIT_CONTAINER) != 0) { return new ImportMatchLocatorParser(problemReporter, locator); } return new MatchLocatorParser(problemReporter, locator); } /** * 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; } } protected 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 consumeCastExpressionLL1WithBounds() { super.consumeCastExpressionLL1WithBounds(); if ((this.patternFineGrain & IJavaSearchConstants.CAST_TYPE_REFERENCE) != 0) { CastExpression castExpression = (CastExpression) this.expressionStack[this.expressionPtr]; TypeReference[] typeReferences = ((IntersectionCastTypeReference) castExpression.type).typeReferences; for (int i = 0, length = typeReferences.length; i < length; i++) this.patternLocator.match(typeReferences[i], 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); } @Override protected void consumeLambdaExpression() { super.consumeLambdaExpression(); this.patternLocator.match((LambdaExpression) this.expressionStack[this.expressionPtr], this.nodeSet); } protected void consumeLocalVariableDeclaration() { super.consumeLocalVariableDeclaration(); this.patternLocator.match((LocalDeclaration) this.astStack[this.astPtr], this.nodeSet); } protected void consumeMarkerAnnotation(boolean isTypeAnnotation) { super.consumeMarkerAnnotation(isTypeAnnotation); if (this.patternFineGrain == 0 || (this.patternFineGrain & IJavaSearchConstants.ANNOTATION_TYPE_REFERENCE) != 0) { Annotation annotation = (Annotation) (isTypeAnnotation ? this.typeAnnotationStack[this.typeAnnotationPtr] : 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(boolean isTypeAnnotation) { super.consumeNormalAnnotation(isTypeAnnotation); if (this.patternFineGrain == 0 || (this.patternFineGrain & IJavaSearchConstants.ANNOTATION_TYPE_REFERENCE) != 0) { // this is always an Annotation Annotation annotation = (Annotation) (isTypeAnnotation ? this.typeAnnotationStack[this.typeAnnotationPtr] : 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--; } @Override protected void consumeReferenceExpression(ReferenceExpression referenceExpression) { super.consumeReferenceExpression(referenceExpression); if (this.patternFineGrain == 0) { this.patternLocator.match(referenceExpression, this.nodeSet); } else if ((this.patternFineGrain & IJavaSearchConstants.METHOD_REFERENCE_EXPRESSION) != 0) { this.patternLocator.match(referenceExpression, this.nodeSet); } else if (referenceExpression.lhs.isThis()) { if ((this.patternFineGrain & IJavaSearchConstants.THIS_REFERENCE) != 0) { this.patternLocator.match(referenceExpression, this.nodeSet); } } else if (referenceExpression.lhs.isSuper()) { if ((this.patternFineGrain & IJavaSearchConstants.SUPER_REFERENCE) != 0) { this.patternLocator.match(referenceExpression, this.nodeSet); } } else if (referenceExpression.lhs instanceof QualifiedNameReference || referenceExpression.lhs instanceof QualifiedTypeReference) { if ((this.patternFineGrain & IJavaSearchConstants.QUALIFIED_REFERENCE) != 0) { this.patternLocator.match(referenceExpression, this.nodeSet); } } } protected void consumeSingleMemberAnnotation(boolean isTypeAnnotation) { super.consumeSingleMemberAnnotation(isTypeAnnotation); if (this.patternFineGrain == 0 || (this.patternFineGrain & IJavaSearchConstants.ANNOTATION_TYPE_REFERENCE) != 0) { // this is always an Annotation Annotation annotation = (Annotation) (isTypeAnnotation ? this.typeAnnotationStack[this.typeAnnotationPtr] : 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 consumeTypeElidedLambdaParameter(boolean parenthesized) { super.consumeTypeElidedLambdaParameter(parenthesized); this.patternLocator.match((LocalDeclaration) this.astStack[this.astPtr], 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 augmentTypeWithAdditionalDimensions(TypeReference typeRef, int additionalDimensions, Annotation [][] additionalAnnotations, boolean isVarargs) { TypeReference result = super.augmentTypeWithAdditionalDimensions(typeRef, additionalDimensions, additionalAnnotations, isVarargs); 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(boolean rejectTypeAnnotations) { NameReference nameRef = super.getUnspecifiedReference(rejectTypeAnnotations); 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); } } } }