blob: ee77d19880f6dce6b97a912cbfbc79bd91a05cc2 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2015 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
* Fraunhofer FIRST - extended API and implementation
* Technical University Berlin - extended 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;
import org.eclipse.objectteams.otdt.core.compiler.OTNameUtils;
import org.eclipse.objectteams.otdt.internal.core.compiler.ast.AbstractMethodMappingDeclaration;
import org.eclipse.objectteams.otdt.internal.core.compiler.ast.BaseCallMessageSend;
import org.eclipse.objectteams.otdt.internal.core.compiler.ast.CallinMappingDeclaration;
import org.eclipse.objectteams.otdt.internal.core.compiler.ast.CalloutMappingDeclaration;
import org.eclipse.objectteams.otdt.internal.core.compiler.ast.FieldAccessSpec;
import org.eclipse.objectteams.otdt.internal.core.compiler.ast.LiftingTypeReference;
import org.eclipse.objectteams.otdt.internal.core.compiler.ast.MethodSpec;
import org.eclipse.objectteams.otdt.internal.core.compiler.ast.ParameterMapping;
/**
* 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
}
//{ObjectTeams: visit method mappings and method specs
public boolean visit(CalloutMappingDeclaration calloutMappingDeclaration, ClassScope scope)
{
MatchLocatorParser.this.patternLocator.match(calloutMappingDeclaration, MatchLocatorParser.this.nodeSet);
return true;
}
public boolean visit(CallinMappingDeclaration callinMappingDeclaration, ClassScope scope)
{
MatchLocatorParser.this.patternLocator.match(callinMappingDeclaration, MatchLocatorParser.this.nodeSet);
return true;
}
public boolean visit(ParameterMapping paramMapping, BlockScope scope)
{
MatchLocatorParser.this.patternLocator.match(paramMapping, MatchLocatorParser.this.nodeSet);
return true;
}
public boolean visit(MethodSpec methodSpec, BlockScope scope)
{
MatchLocatorParser.this.patternLocator.match(methodSpec, MatchLocatorParser.this.nodeSet);
return true;
}
public boolean visit(FieldAccessSpec fieldSpec, BlockScope scope)
{
MatchLocatorParser.this.patternLocator.match(fieldSpec, MatchLocatorParser.this.nodeSet);
return true;
}
//gbr}
}
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);
}
}
//{ObjectTeams: search in @role tags:
TypeReference[] roleReferences = this.javadoc.roleReferences;
if (roleReferences != null) {
for (int i=0, length=roleReferences.length; i < length; i++) {
this.patternLocator.match(roleReferences[i], this.nodeSet);
}
}
// SH}
// 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);
}
//{ObjectTeams: treat playedBy similar to extends:
protected void consumeClassHeaderPlayedBy() {
this.patternLocator.setFlavors(PatternLocator.SUPERTYPE_REF_FLAVOR);
super.consumeClassHeaderPlayedBy();
if ((this.patternFineGrain & IJavaSearchConstants.SUPERTYPE_TYPE_REFERENCE) != 0) {
TypeDeclaration typeDeclaration = (TypeDeclaration) this.astStack[this.astPtr];
this.patternLocator.match(typeDeclaration.baseclass, this.nodeSet);
}
this.patternLocator.setFlavors(PatternLocator.NO_FLAVOR);
}
// SH}
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);
}
}
//{ObjectTeams: new hook that also creates annotations:
protected void convertTypeAnchor(int annotationKind) {
// consumeMarkerAnnotation, consumeSingleMemberAnnotation, consumeNormalAnnotation:
super.convertTypeAnchor(annotationKind);
final boolean isTypeAnnotation = true;
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);
}
}
// SH}
protected void consumeMemberValuePair() {
super.consumeMemberValuePair();
if ((this.patternFineGrain & ~IJavaSearchConstants.METHOD_REFERENCE_EXPRESSION) != 0) {
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);
}
}
//{ObjectTeams: more kinds of message sends:
@Override
protected void consumeMethodInvocationBase(boolean isSuperAccess)
{
super.consumeMethodInvocationBase(isSuperAccess);
//this is always a BaseCallMessageSend
this.patternLocator.match((BaseCallMessageSend)this.expressionStack[this.expressionPtr], this.nodeSet);
}
@Override
protected void consumeMethodInvocationBaseWithTypeArguments(boolean isSuperAccess) {
super.consumeMethodInvocationBaseWithTypeArguments(isSuperAccess);
BaseCallMessageSend messageSend = (BaseCallMessageSend) this.expressionStack[this.expressionPtr];
if (this.patternFineGrain == 0) {
this.patternLocator.match(messageSend, this.nodeSet);
} else {
// receiver is always implicit this
if ((this.patternFineGrain & IJavaSearchConstants.IMPLICIT_THIS_REFERENCE) != 0) {
this.patternLocator.match(messageSend, this.nodeSet);
}
}
}
@Override
protected void consumeMethodInvocationTSuper(int kind)
{
super.consumeMethodInvocationTSuper(kind);
//this is always a MessageSend
this.patternLocator.match((MessageSend)this.expressionStack[this.expressionPtr], this.nodeSet);
}
@Override
protected void consumeMethodInvocationTSuperWithTypeArguments(int kind) {
super.consumeMethodInvocationTSuperWithTypeArguments(kind);
MessageSend messageSend = (MessageSend) this.expressionStack[this.expressionPtr];
if (this.patternFineGrain == 0) {
this.patternLocator.match(messageSend, this.nodeSet);
} else {
// receiver is always implicit this
if ((this.patternFineGrain & IJavaSearchConstants.IMPLICIT_THIS_REFERENCE) != 0) {
this.patternLocator.match(messageSend, this.nodeSet);
}
}
}
@Override
protected void consumeMethodSpecLong(boolean hasPlus)
{
super.consumeMethodSpecLong(hasPlus);
this.patternLocator.match((MethodSpec)this.astStack[this.astPtr], this.nodeSet);
}
protected void consumeMethodSpecShort()
{
super.consumeMethodSpecShort();
this.patternLocator.match((MethodSpec)this.astStack[this.astPtr], this.nodeSet);
}
protected void consumeFieldSpecLong()
{
super.consumeFieldSpecLong();
this.patternLocator.match((FieldAccessSpec)this.astStack[this.astPtr], this.nodeSet);
}
protected void consumeParameterMappingIn()
{
super.consumeParameterMappingIn();
this.patternLocator.match((ParameterMapping)this.astStack[this.astPtr], this.nodeSet);
}
protected void consumeParameterMappingOut()
{
super.consumeParameterMappingOut();
this.patternLocator.match((ParameterMapping)this.astStack[this.astPtr], this.nodeSet);
}
@Override
protected void consumeCallinBindingLeft(boolean hasSignature) {
super.consumeCallinBindingLeft(hasSignature);
// role args can cause lifting -> interpret as class instance creation:
if (hasSignature && (this.patternFineGrain & IJavaSearchConstants.CLASS_INSTANCE_CREATION_TYPE_REFERENCE) != 0)
{
CallinMappingDeclaration callinDecl = (CallinMappingDeclaration) this.astStack[this.astPtr];
Argument[] roleArgs = callinDecl.roleMethodSpec.arguments;
if (roleArgs != null)
for (Argument arg : roleArgs)
this.patternLocator.match(arg.type, this.nodeSet);
}
}
@Override
protected void consumeCalloutBindingLeft(boolean hasSignature) {
super.consumeCalloutBindingLeft(hasSignature);
// role return can cause lifting -> interpret as class instance creation:
if (hasSignature && (this.patternFineGrain & IJavaSearchConstants.CLASS_INSTANCE_CREATION_TYPE_REFERENCE) != 0)
{
CalloutMappingDeclaration callinDecl = (CalloutMappingDeclaration) this.astStack[this.astPtr];
this.patternLocator.match(callinDecl.roleMethodSpec.returnType, this.nodeSet);
}
}
@Override
protected void liftingTypeReferenceRecognized(LiftingTypeReference ltr) {
// patternFineGrain == 0 already handled in getTypeReference() from super.completeLiftingTypeReference()
if ((this.patternFineGrain & IJavaSearchConstants.CLASS_INSTANCE_CREATION_TYPE_REFERENCE) != 0) {
this.patternLocator.match(ltr.roleReference, this.nodeSet);
}
}
//carp}
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 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) {
//{ObjectTeams: wrap to introduce 2nd parameter
return getTypeReference(dim, false);
}
protected TypeReference getTypeReference(int dim, boolean liftingTypeAllowed) {
/*orig:
TypeReference typeRef = super.getTypeReference(dim);
*/
TypeReference typeRef = super.getTypeReference(dim, liftingTypeAllowed);
// SH}
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];
//{ObjectTeams: after scanner.setSource() we need to restore the Java-OT/J switch:
if (type.isTeam() || type.isRole()) {
this.scanner.enterOTSource();
if (this.javadocParser != null)
this.javadocParser.scanner.enterOTSource();
}
// SH}
this.patternLocator.match(type, this.nodeSet);
this.parseBodies(type, unit);
}
//{ObjectTeams: prevent duplicate parsing:
unit.bits |= ASTNode.HasAllMethodBodies;
// SH}
}
/**
* 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);
}
}
//{ObjectTeams: deal with callins and callouts
AbstractMethodMappingDeclaration[] mappings = type.callinCallouts;
if (mappings != null) {
for (int i = 0; i < mappings.length; i++) {
AbstractMethodMappingDeclaration mapping = mappings[i];
mapping.parseParamMappings(this, unit);
mapping.traverse(this.localDeclarationVisitor, (ClassScope) null);
}
}
//carp}
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
//{ObjectTeams: getMethodBodies() may be called more than once. Prevent Parser from accumulating the methods' statements.
if (OTNameUtils.isPredicate(method.selector)) { // already parsed
((MethodDeclaration)method).traverse(this.localDeclarationVisitor, (ClassScope) null);
continue;
}
method.statements = null; // TODO(SH): is this still needed now that we are flagging HasAllMethodBodies?
//carp}
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);
}
}
}
//TODO(jwl): Do we need to support anonymous inner types in method mapping, i.e. actually
// contained within a block of the parameter mapping?
TypeDeclaration[] memberTypes = type.memberTypes;
if (memberTypes != null) {
for (int i = 0; i < memberTypes.length; i++) {
TypeDeclaration memberType = memberTypes[i];
//{ObjectTeams: don't consider role files:
// MatchLocator.getMethodBodies() calls scanner.setSource() with the original,
// untransformed source of the Compilation_Unit_, which contains no RoleFiles anyway.
// Skipping them prevents an ArrayIndexOutOfBoundsException in the Scanner, later.
// Role files are handled through their own CompilationUnit.
if (memberType.isRoleFile())
continue;
//carp}
//{ObjectTeams:
// I don't get why parseBodies() is invoked recursively, traversing the memberType's fields, methods, etc.
// and right after that, traversing it a second time through memberType.traverse().
// Some hints(SH):
// + parseBodies is needed to do the parsing ;-)
// + memberType.traverse(..) is needed to visit the memberType itself
// which is not part of the recursive parseBodies.
// Also the localDeclarationVisitor might only process a very limited set of ast nodes.
// So, the calls do have different effect, how much redundancy remains, I can't definitely say.
//carp}
this.parseBodies(memberType, unit);
memberType.traverse(this.localDeclarationVisitor, (ClassScope) null);
}
}
}
}