| /******************************************************************************* |
| * 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.aspectj.org.eclipse.jdt.internal.core.search.matching; |
| |
| import org.aspectj.org.eclipse.jdt.core.search.IJavaSearchConstants; |
| import org.aspectj.org.eclipse.jdt.internal.compiler.ASTVisitor; |
| import org.aspectj.org.eclipse.jdt.internal.compiler.ast.*; |
| import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.*; |
| import org.aspectj.org.eclipse.jdt.internal.compiler.parser.Parser; |
| import org.aspectj.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 (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); |
| } |
| } |
| } |
| |
| } |
| |