Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
spoon.support.compiler.jdt.JDTTreeBuilder Maven / Gradle / Ivy
/*
* Spoon - http://spoon.gforge.inria.fr/
* Copyright (C) 2006 INRIA Futurs
*
* This software is governed by the CeCILL-C License under French law and
* abiding by the rules of distribution of free software. You can use, modify
* and/or redistribute the software under the terms of the CeCILL-C license as
* circulated by CEA, CNRS and INRIA at http://www.cecill.info.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL-C License for more details.
*
* The fact that you are presently reading this means that you have had
* knowledge of the CeCILL-C license and that you accept its terms.
*/
package spoon.support.compiler.jdt;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Stack;
import java.util.TreeMap;
import java.util.TreeSet;
import org.apache.log4j.Logger;
import org.eclipse.jdt.internal.compiler.ASTVisitor;
import org.eclipse.jdt.internal.compiler.ast.AND_AND_Expression;
import org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.AllocationExpression;
import org.eclipse.jdt.internal.compiler.ast.Annotation;
import org.eclipse.jdt.internal.compiler.ast.AnnotationMethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.Argument;
import org.eclipse.jdt.internal.compiler.ast.ArrayAllocationExpression;
import org.eclipse.jdt.internal.compiler.ast.ArrayInitializer;
import org.eclipse.jdt.internal.compiler.ast.ArrayReference;
import org.eclipse.jdt.internal.compiler.ast.ArrayTypeReference;
import org.eclipse.jdt.internal.compiler.ast.AssertStatement;
import org.eclipse.jdt.internal.compiler.ast.Assignment;
import org.eclipse.jdt.internal.compiler.ast.BinaryExpression;
import org.eclipse.jdt.internal.compiler.ast.Block;
import org.eclipse.jdt.internal.compiler.ast.BreakStatement;
import org.eclipse.jdt.internal.compiler.ast.CaseStatement;
import org.eclipse.jdt.internal.compiler.ast.CastExpression;
import org.eclipse.jdt.internal.compiler.ast.CharLiteral;
import org.eclipse.jdt.internal.compiler.ast.ClassLiteralAccess;
import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
import org.eclipse.jdt.internal.compiler.ast.CompoundAssignment;
import org.eclipse.jdt.internal.compiler.ast.ConditionalExpression;
import org.eclipse.jdt.internal.compiler.ast.ConstructorDeclaration;
import org.eclipse.jdt.internal.compiler.ast.ContinueStatement;
import org.eclipse.jdt.internal.compiler.ast.DoStatement;
import org.eclipse.jdt.internal.compiler.ast.DoubleLiteral;
import org.eclipse.jdt.internal.compiler.ast.EqualExpression;
import org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall;
import org.eclipse.jdt.internal.compiler.ast.Expression;
import org.eclipse.jdt.internal.compiler.ast.ExtendedStringLiteral;
import org.eclipse.jdt.internal.compiler.ast.FalseLiteral;
import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
import org.eclipse.jdt.internal.compiler.ast.FieldReference;
import org.eclipse.jdt.internal.compiler.ast.FloatLiteral;
import org.eclipse.jdt.internal.compiler.ast.ForStatement;
import org.eclipse.jdt.internal.compiler.ast.ForeachStatement;
import org.eclipse.jdt.internal.compiler.ast.IfStatement;
import org.eclipse.jdt.internal.compiler.ast.Initializer;
import org.eclipse.jdt.internal.compiler.ast.InstanceOfExpression;
import org.eclipse.jdt.internal.compiler.ast.IntLiteral;
import org.eclipse.jdt.internal.compiler.ast.Javadoc;
import org.eclipse.jdt.internal.compiler.ast.LabeledStatement;
import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
import org.eclipse.jdt.internal.compiler.ast.LongLiteral;
import org.eclipse.jdt.internal.compiler.ast.MarkerAnnotation;
import org.eclipse.jdt.internal.compiler.ast.MemberValuePair;
import org.eclipse.jdt.internal.compiler.ast.MessageSend;
import org.eclipse.jdt.internal.compiler.ast.MethodDeclaration;
import org.eclipse.jdt.internal.compiler.ast.NormalAnnotation;
import org.eclipse.jdt.internal.compiler.ast.NullLiteral;
import org.eclipse.jdt.internal.compiler.ast.OR_OR_Expression;
import org.eclipse.jdt.internal.compiler.ast.OperatorIds;
import org.eclipse.jdt.internal.compiler.ast.ParameterizedQualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.ParameterizedSingleTypeReference;
import org.eclipse.jdt.internal.compiler.ast.PostfixExpression;
import org.eclipse.jdt.internal.compiler.ast.PrefixExpression;
import org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression;
import org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
import org.eclipse.jdt.internal.compiler.ast.QualifiedSuperReference;
import org.eclipse.jdt.internal.compiler.ast.QualifiedThisReference;
import org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
import org.eclipse.jdt.internal.compiler.ast.ReturnStatement;
import org.eclipse.jdt.internal.compiler.ast.SingleMemberAnnotation;
import org.eclipse.jdt.internal.compiler.ast.SingleNameReference;
import org.eclipse.jdt.internal.compiler.ast.SingleTypeReference;
import org.eclipse.jdt.internal.compiler.ast.Statement;
import org.eclipse.jdt.internal.compiler.ast.StringLiteral;
import org.eclipse.jdt.internal.compiler.ast.StringLiteralConcatenation;
import org.eclipse.jdt.internal.compiler.ast.SuperReference;
import org.eclipse.jdt.internal.compiler.ast.SwitchStatement;
import org.eclipse.jdt.internal.compiler.ast.SynchronizedStatement;
import org.eclipse.jdt.internal.compiler.ast.ThisReference;
import org.eclipse.jdt.internal.compiler.ast.ThrowStatement;
import org.eclipse.jdt.internal.compiler.ast.TrueLiteral;
import org.eclipse.jdt.internal.compiler.ast.TryStatement;
import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
import org.eclipse.jdt.internal.compiler.ast.TypeParameter;
import org.eclipse.jdt.internal.compiler.ast.TypeReference;
import org.eclipse.jdt.internal.compiler.ast.UnaryExpression;
import org.eclipse.jdt.internal.compiler.ast.UnionTypeReference;
import org.eclipse.jdt.internal.compiler.ast.WhileStatement;
import org.eclipse.jdt.internal.compiler.ast.Wildcard;
import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
import org.eclipse.jdt.internal.compiler.lookup.BaseTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.Binding;
import org.eclipse.jdt.internal.compiler.lookup.BlockScope;
import org.eclipse.jdt.internal.compiler.lookup.CaptureBinding;
import org.eclipse.jdt.internal.compiler.lookup.ClassScope;
import org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope;
import org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
import org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
import org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
import org.eclipse.jdt.internal.compiler.lookup.MethodScope;
import org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
import org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding;
import org.eclipse.jdt.internal.compiler.lookup.RawTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.TypeVariableBinding;
import org.eclipse.jdt.internal.compiler.lookup.VariableBinding;
import org.eclipse.jdt.internal.compiler.lookup.WildcardBinding;
import spoon.reflect.code.BinaryOperatorKind;
import spoon.reflect.code.CtAnnotationFieldAccess;
import spoon.reflect.code.CtArrayAccess;
import spoon.reflect.code.CtAssert;
import spoon.reflect.code.CtAssignment;
import spoon.reflect.code.CtBinaryOperator;
import spoon.reflect.code.CtBlock;
import spoon.reflect.code.CtBreak;
import spoon.reflect.code.CtCase;
import spoon.reflect.code.CtCatch;
import spoon.reflect.code.CtConditional;
import spoon.reflect.code.CtContinue;
import spoon.reflect.code.CtDo;
import spoon.reflect.code.CtExpression;
import spoon.reflect.code.CtFieldAccess;
import spoon.reflect.code.CtFor;
import spoon.reflect.code.CtForEach;
import spoon.reflect.code.CtIf;
import spoon.reflect.code.CtInvocation;
import spoon.reflect.code.CtLiteral;
import spoon.reflect.code.CtLocalVariable;
import spoon.reflect.code.CtNewArray;
import spoon.reflect.code.CtNewClass;
import spoon.reflect.code.CtOperatorAssignment;
import spoon.reflect.code.CtReturn;
import spoon.reflect.code.CtStatement;
import spoon.reflect.code.CtSuperAccess;
import spoon.reflect.code.CtSwitch;
import spoon.reflect.code.CtSynchronized;
import spoon.reflect.code.CtTargetedExpression;
import spoon.reflect.code.CtThisAccess;
import spoon.reflect.code.CtThrow;
import spoon.reflect.code.CtTry;
import spoon.reflect.code.CtUnaryOperator;
import spoon.reflect.code.CtVariableAccess;
import spoon.reflect.code.CtWhile;
import spoon.reflect.code.UnaryOperatorKind;
import spoon.reflect.cu.CompilationUnit;
import spoon.reflect.cu.SourcePosition;
import spoon.reflect.declaration.CtAnnotation;
import spoon.reflect.declaration.CtAnonymousExecutable;
import spoon.reflect.declaration.CtClass;
import spoon.reflect.declaration.CtConstructor;
import spoon.reflect.declaration.CtElement;
import spoon.reflect.declaration.CtEnum;
import spoon.reflect.declaration.CtField;
import spoon.reflect.declaration.CtInterface;
import spoon.reflect.declaration.CtMethod;
import spoon.reflect.declaration.CtPackage;
import spoon.reflect.declaration.CtParameter;
import spoon.reflect.declaration.CtSimpleType;
import spoon.reflect.declaration.CtTypedElement;
import spoon.reflect.declaration.ModifierKind;
import spoon.reflect.factory.CoreFactory;
import spoon.reflect.factory.Factory;
import spoon.reflect.reference.CtArrayTypeReference;
import spoon.reflect.reference.CtExecutableReference;
import spoon.reflect.reference.CtFieldReference;
import spoon.reflect.reference.CtLocalVariableReference;
import spoon.reflect.reference.CtPackageReference;
import spoon.reflect.reference.CtParameterReference;
import spoon.reflect.reference.CtTypeParameterReference;
import spoon.reflect.reference.CtTypeReference;
import spoon.reflect.reference.CtVariableReference;
import spoon.reflect.visitor.Query;
import spoon.reflect.visitor.filter.TypeFilter;
/**
* A visitor for iterating through the parse tree.
*/
public class JDTTreeBuilder extends ASTVisitor {
private static final Logger logger = Logger.getLogger(JDTTreeBuilder.class);
public class ASTPair {
public CtElement element;
public ASTNode node;
public ASTPair(CtElement element, ASTNode node) {
super();
this.element = element;
this.node = node;
}
@Override
public String toString() {
return element.getClass().getSimpleName() + "-"
+ node.getClass().getSimpleName();
}
}
public class BuilderContext {
Stack annotationValueName = new Stack();
Stack arguments = new Stack();
List> casts = new ArrayList>();
CompilationUnitDeclaration compilationunitdeclaration;
List> createdTypes = new ArrayList>();
Stack finallyzer = new Stack();
boolean forinit = false;
boolean forupdate = false;
Stack label = new Stack();
boolean selector = false;
/**
* Stack of all parents elements
*/
Stack stack = new Stack();
Stack> target = new Stack>();
public void addCreatedType(CtSimpleType> type) {
createdTypes.add(type);
}
private SourcePosition createSourcePosition(ASTNode node) {
CoreFactory cf = factory.Core();
int sourceStart = node.sourceStart;
int sourceEnd = node.sourceEnd;
CompilationUnit cu = factory.CompilationUnit().create(
new String(compilationunitdeclaration.getFileName()));
return cf
.createSourcePosition(
cu,
sourceStart,
sourceEnd,
compilationunitdeclaration.compilationResult.lineSeparatorPositions);
}
@SuppressWarnings("unchecked")
void enter(CtElement e, ASTNode node) {
stack.push(new ASTPair(e, node));
// aststack.push(node);
if (compilationunitdeclaration != null) {
CoreFactory cf = factory.Core();
int sourceStart = node.sourceStart;
int sourceEnd = node.sourceEnd;
if ((e instanceof CtBlock)
&& (node instanceof MethodDeclaration)) {
sourceStart = ((MethodDeclaration) node).bodyStart;
sourceEnd = ((MethodDeclaration) node).bodyEnd;
}
CompilationUnit cu = factory.CompilationUnit().create(
new String(compilationunitdeclaration.getFileName()));
e.setPosition(cf
.createSourcePosition(
cu,
sourceStart,
sourceEnd,
compilationunitdeclaration.compilationResult.lineSeparatorPositions));
}
ASTPair pair = stack.peek();
CtElement current = pair.element;
if (current instanceof CtExpression) {
while (!casts.isEmpty())
((CtExpression>) current).addTypeCast(casts.remove(0));
}
if (current instanceof CtStatement && !context.label.isEmpty()) {
((CtStatement) current).setLabel(context.label.pop());
}
if (e instanceof CtTypedElement && node instanceof Expression) {
if (((CtTypedElement>) e).getType() == null)
((CtTypedElement) e)
.setType(references
.getTypeReference(((Expression) node).resolvedType));
}
}
void exit(ASTNode node) {
ASTPair pair = stack.pop();
if (pair.node != node)
throw new RuntimeException("Inconsistent Stack " + node+"\n"+pair.node);
CtElement current = pair.element;
if (!stack.isEmpty()) {
current.setParent(stack.peek().element);
exiter.child = current;
exiter.scan(stack.peek().element);
}
}
public List> getCreatedTypes() {
return createdTypes;
}
public boolean isArgument(CtElement e) {
return arguments.size() > 0 && arguments.peek() == e;
}
private void popArgument(CtElement e) {
if (arguments.pop() != e)
throw new RuntimeException("Unconsistant stack");
}
private void pushArgument(CtElement e) {
arguments.push(e);
}
}
public class ReferenceBuilder {
Map> basestypes = new TreeMap>();
Set typevars = new TreeSet();
boolean bounds = false;
public CtTypeReference> getBoundedTypeReference(TypeBinding binding) {
bounds = true;
CtTypeReference> ref = getTypeReference(binding);
bounds = false;
return ref;
}
@SuppressWarnings("unchecked")
public CtExecutableReference getExecutableReference(
MethodBinding exec) {
if (exec == null) {
logger.error("null method binding");
return null;
}
CtExecutableReference ref = factory.Core()
.createExecutableReference();
ref.setDeclaringType(getTypeReference(exec.declaringClass));
ref.setType((CtTypeReference) getTypeReference(exec.returnType));
ref.setSimpleName(new String(exec.selector));
ref.setStatic(exec.isStatic());
if (exec.parameters != null) {
for (TypeBinding b : exec.parameters) {
ref.addParameterType(getTypeReference(b));
}
}
if (exec.typeVariables != null) {
for (TypeVariableBinding b : exec.typeVariables)
ref.addActualTypeArgument(getTypeReference(b));
}
return ref;
}
public CtPackageReference getPackageReference(PackageBinding reference) {
String name = new String(reference.shortReadableName());
if (name.length() == 0)
return null;
CtPackageReference ref = factory.Core().createPackageReference();
ref.setSimpleName(name);
return ref;
}
// Map> bindingCache = new
// HashMap>();
@SuppressWarnings("unchecked")
public CtTypeReference getTypeReference(TypeBinding binding) {
if (binding == null)
return null;
CtTypeReference> ref = null;
if (binding instanceof RawTypeBinding) {
ref = getTypeReference(((ParameterizedTypeBinding) binding)
.genericType());
} else if (binding instanceof ParameterizedTypeBinding) {
ref = factory.Core().createTypeReference();
if (binding.isAnonymousType()) {
ref.setSimpleName("");
} else {
ref.setSimpleName(new String(
((ParameterizedTypeBinding) binding).sourceName));
if (binding.enclosingType() != null) {
ref.setDeclaringType(getTypeReference(binding
.enclosingType()));
} else {
ref.setPackage(getPackageReference(binding.getPackage()));
}
}
// bindingCache.put(binding, ref);
if (((ParameterizedTypeBinding) binding).arguments != null)
for (TypeBinding b : ((ParameterizedTypeBinding) binding).arguments) {
ref.addActualTypeArgument(getTypeReference(b));
}
} else if (binding instanceof BinaryTypeBinding) {
ref = factory.Core().createTypeReference();
if (binding.enclosingType() != null) {
ref.setDeclaringType(getTypeReference(binding
.enclosingType()));
} else {
ref.setPackage(getPackageReference(binding.getPackage()));
}
ref.setSimpleName(new String(binding.sourceName()));
} else if (binding instanceof TypeVariableBinding) {
boolean oldBounds = bounds;
ref = factory.Core().createTypeParameterReference();
if (binding instanceof CaptureBinding) {
ref.setSimpleName("?");
bounds = true;
} else {
ref.setSimpleName(new String(binding.sourceName()));
}
TypeVariableBinding b = (TypeVariableBinding) binding;
if (bounds) {
if (b instanceof CaptureBinding
&& ((CaptureBinding) b).wildcard != null) {
bounds = oldBounds;
return getTypeReference(((CaptureBinding) b).wildcard);
} else if (b.superclass != null
&& b.firstBound == b.superclass) {
bounds = false;
((CtTypeParameterReference) ref)
.addBound(getTypeReference(b.superclass));
bounds = oldBounds;
}
}
if (bounds && b.superInterfaces != null
&& b.superInterfaces != Binding.NO_SUPERINTERFACES) {
bounds = false;
// bindingCache.put(binding, ref);
for (int i = 0, length = b.superInterfaces.length; i < length; i++) {
TypeBinding tb = b.superInterfaces[i];
((CtTypeParameterReference) ref)
.addBound(getTypeReference(tb));
}
}
if (binding instanceof CaptureBinding)
bounds = false;
} else if (binding instanceof BaseTypeBinding) {
String name = new String(binding.sourceName());
ref = basestypes.get(name);
if (ref == null) {
ref = factory.Core().createTypeReference();
ref.setSimpleName(name);
basestypes.put(name, ref);
}
} else if (binding instanceof WildcardBinding) {
CtTypeParameterReference reference = factory.Core()
.createTypeParameterReference();
reference.setSimpleName("?");
if (((WildcardBinding) binding).boundKind == Wildcard.SUPER)
reference.setUpper(false);
if (((WildcardBinding) binding).bound != null)
reference
.addBound(getTypeReference(((WildcardBinding) binding).bound));
ref = reference;
} else if (binding instanceof LocalTypeBinding) {
ref = factory.Core().createTypeReference();
if (binding.isAnonymousType())
ref.setSimpleName("");
else {
ref.setSimpleName(new String(binding.sourceName()));
if (((LocalTypeBinding) binding).enclosingMethod == null
&& binding.enclosingType() != null
&& binding.enclosingType() instanceof LocalTypeBinding)
ref.setDeclaringType(getTypeReference(binding
.enclosingType()));
}
} else if (binding instanceof SourceTypeBinding) {
ref = factory.Core().createTypeReference();
if (binding.isAnonymousType()) {
ref.setSimpleName("");
} else {
ref.setSimpleName(new String(binding.sourceName()));
if (binding.enclosingType() != null)
ref.setDeclaringType(getTypeReference(binding
.enclosingType()));
else
ref.setPackage(getPackageReference(binding.getPackage()));
// if(((SourceTypeBinding) binding).typeVariables!=null &&
// ((SourceTypeBinding) binding).typeVariables.length>0){
// for (TypeBinding b : ((SourceTypeBinding)
// binding).typeVariables) {
// ref.getActualTypeArguments().add(getTypeReference(b));
// }
// }
}
} else if (binding instanceof ArrayBinding) {
CtArrayTypeReference arrayref = factory.Core()
.createArrayTypeReference();
ref = arrayref;
for (int i = 1; i < binding.dimensions(); i++) {
CtArrayTypeReference tmp = factory.Core()
.createArrayTypeReference();
arrayref.setComponentType(tmp);
arrayref = tmp;
}
arrayref.setComponentType(getTypeReference(binding
.leafComponentType()));
} else if (binding instanceof ProblemReferenceBinding) {
// Spoon is able to analyze also without the classpath
ref = factory.Core().createTypeReference();
ref.setSimpleName(new String(binding.readableName()));
} else {
throw new RuntimeException("Unknown TypeBinding: "
+ binding.getClass() + " " + binding);
}
// bindingCache.remove(binding);
return (CtTypeReference) ref;
}
@SuppressWarnings("unchecked")
public CtVariableReference getVariableReference(
MethodBinding methbin) {
CtFieldReference ref = factory.Core().createFieldReference();
ref.setSimpleName(new String(methbin.selector));
ref.setType((CtTypeReference) getTypeReference(methbin.returnType));
if (methbin.declaringClass != null)
ref.setDeclaringType(getTypeReference(methbin.declaringClass));
else {
ref.setDeclaringType(ref.getType());
}
return ref;
}
@SuppressWarnings("unchecked")
public CtVariableReference getVariableReference(
VariableBinding varbin) {
if (varbin instanceof FieldBinding) {
CtFieldReference ref = factory.Core().createFieldReference();
ref.setSimpleName(new String(varbin.name));
ref.setType((CtTypeReference) getTypeReference(varbin.type));
if (((FieldBinding) varbin).declaringClass != null)
ref.setDeclaringType(getTypeReference(((FieldBinding) varbin).declaringClass));
else {
ref.setDeclaringType(ref.getType());
}
ref.setFinal(varbin.isFinal());
ref.setStatic((varbin.modifiers & ClassFileConstants.AccStatic) != 0);
return ref;
} else if (varbin instanceof LocalVariableBinding) {
if (((LocalVariableBinding) varbin).declaration instanceof Argument
&& ((LocalVariableBinding) varbin).declaringScope instanceof MethodScope) {
CtParameterReference ref = factory.Core()
.createParameterReference();
ref.setSimpleName(new String(varbin.name));
ref.setType((CtTypeReference) getTypeReference(varbin.type));
ref.setDeclaringExecutable(getExecutableReference(((AbstractMethodDeclaration) ((MethodScope) ((LocalVariableBinding) varbin).declaringScope)
.referenceContext()).binding));
return ref;
} else {
CtLocalVariableReference ref = factory.Core()
.createLocalVariableReference();
ref.setSimpleName(new String(varbin.name));
CtTypeReference ref2 = getTypeReference(varbin.type);
ref.setType(ref2);
ref.setDeclaration((CtLocalVariable) getLocalVariableDeclaration(ref
.getSimpleName()));
return ref;
}
} else {
logger.error("unknow VariableBinding " + varbin);
return null;
}
}
public List> getBoundedTypesReferences(
TypeBinding[] genericTypeArguments) {
List> res = new ArrayList>();
for (TypeBinding tb : genericTypeArguments) {
res.add(getBoundedTypeReference(tb));
}
return res;
}
}
public static String cleanJavadoc(String doc) {
StringBuffer ret = new StringBuffer();
String[] lines = doc.split("\n");
// limit case
if (lines.length == 1) {
return lines[0].replaceAll("^/\\*+", "").replaceAll("\\*+/$", "");
}
for (String s : lines) {
if (s.startsWith("/**")) {
ret.append(s.replaceAll("/\\*+", ""));
} else if (s.endsWith("*/")) {
ret.append(s.replaceAll("\\*+/$", "").replaceAll("^ *\\*+", ""));
} else {
ret.append(s.replaceAll("^ *\\*+", ""));
}
ret.append("\n");
}
// clean '\r'
StringBuffer ret2 = new StringBuffer();
for (int i = 0; i < ret.length(); i++) {
if (ret.charAt(i) != '\r')
ret2.append(ret.charAt(i));
}
return ret2.toString();
}
public static Set getModifiers(int mod) {
Set ret = new TreeSet();
if ((mod & ClassFileConstants.AccPublic) != 0)
ret.add(ModifierKind.PUBLIC);
if ((mod & ClassFileConstants.AccPrivate) != 0)
ret.add(ModifierKind.PRIVATE);
if ((mod & ClassFileConstants.AccProtected) != 0)
ret.add(ModifierKind.PROTECTED);
if ((mod & ClassFileConstants.AccStatic) != 0)
ret.add(ModifierKind.STATIC);
if ((mod & ClassFileConstants.AccFinal) != 0)
ret.add(ModifierKind.FINAL);
if ((mod & ClassFileConstants.AccSynchronized) != 0)
ret.add(ModifierKind.SYNCHRONIZED);
if ((mod & ClassFileConstants.AccVolatile) != 0)
ret.add(ModifierKind.VOLATILE);
if ((mod & ClassFileConstants.AccTransient) != 0)
ret.add(ModifierKind.TRANSIENT);
if ((mod & ClassFileConstants.AccAbstract) != 0)
ret.add(ModifierKind.ABSTRACT);
if ((mod & ClassFileConstants.AccStrictfp) != 0)
ret.add(ModifierKind.STRICTFP);
if ((mod & ClassFileConstants.AccNative) != 0)
ret.add(ModifierKind.NATIVE);
return ret;
}
/**
* Search the line number corresponding to a specific position
*/
public static final int searchLineNumber(int[] startLineIndexes,
int position) {
if (startLineIndexes == null)
return 1;
int length = startLineIndexes.length;
if (length == 0)
return 1;
int g = 0, d = length - 1;
int m = 0, start;
while (g <= d) {
m = (g + d) / 2;
if (position < (start = startLineIndexes[m])) {
d = m - 1;
} else if (position > start) {
g = m + 1;
} else {
return m + 1;
}
}
if (position < startLineIndexes[m]) {
return m + 1;
}
return m + 2;
}
BuilderContext context = new BuilderContext();
ParentExiter exiter = new ParentExiter(this);
Factory factory;
ReferenceBuilder references = new ReferenceBuilder();
public boolean template = false;
public JDTTreeBuilder(Factory factory) {
super();
this.factory = factory;
}
private void createExpression(StringLiteralConcatenation literal,
BlockScope scope, List rst) {
if (rst.isEmpty())
return;
rst.get(0).traverse(this, scope);
rst.remove(0);
if (rst.size() > 1) {
CtBinaryOperator> op = factory.Core().createBinaryOperator();
op.setKind(BinaryOperatorKind.PLUS);
context.enter(op, literal);
createExpression(literal, scope, rst);
context.exit(literal);
} else {
createExpression(literal, scope, rst);
}
}
CtSimpleType> createType(TypeDeclaration typeDeclaration) {
CtSimpleType> type = null;
if ((typeDeclaration.modifiers & ClassFileConstants.AccAnnotation) != 0) {
CtSimpleType> annotationType = factory.Core()
. createAnnotationType();
type = annotationType;
} else if ((typeDeclaration.modifiers & ClassFileConstants.AccEnum) != 0) {
CtEnum> e = factory.Core().createEnum();
if (typeDeclaration.superInterfaces != null) {
for (TypeReference ref : typeDeclaration.superInterfaces) {
e.addSuperInterface(references
.getTypeReference(ref.resolvedType));
}
}
type = e;
} else if ((typeDeclaration.modifiers & ClassFileConstants.AccInterface) != 0) {
CtInterface> interf = factory.Core().createInterface();
if (typeDeclaration.superInterfaces != null) {
for (TypeReference ref : typeDeclaration.superInterfaces) {
interf.addSuperInterface(references
.getTypeReference(ref.resolvedType));
}
}
if (typeDeclaration.typeParameters != null)
for (TypeParameter p : typeDeclaration.typeParameters) {
interf.addFormalTypeParameter(references
.getBoundedTypeReference(p.binding));
}
type = interf;
} else {
CtClass> cl = factory.Core().createClass();
if (typeDeclaration.superclass != null) {
cl.setSuperclass(references
.getTypeReference(typeDeclaration.superclass.resolvedType));
}
if (typeDeclaration.superInterfaces != null) {
for (TypeReference ref : typeDeclaration.superInterfaces) {
cl.addSuperInterface(references
.getTypeReference(ref.resolvedType));
}
}
if (typeDeclaration.typeParameters != null)
for (TypeParameter p : typeDeclaration.typeParameters) {
cl.addFormalTypeParameter(references
.getBoundedTypeReference(p.binding));
}
type = cl;
}
type.setSimpleName(new String(typeDeclaration.name));
// Setting modifiers
type.setModifiers(getModifiers(typeDeclaration.modifiers));
// type.setDocComment(getJavaDoc(typeDeclaration.javadoc));
return type;
}
@Override
public void endVisit(AllocationExpression allocationExpression,
BlockScope scope) {
context.exit(allocationExpression);
}
@Override
public void endVisit(AND_AND_Expression and_and_Expression, BlockScope scope) {
context.exit(and_and_Expression);
}
@Override
public void endVisit(AnnotationMethodDeclaration annotationTypeDeclaration,
ClassScope classScope) {
context.exit(annotationTypeDeclaration);
}
@Override
public void endVisit(Argument argument, BlockScope scope) {
context.exit(argument);
}
@Override
public void endVisit(ArrayAllocationExpression arrayAllocationExpression,
BlockScope scope) {
context.exit(arrayAllocationExpression);
}
@Override
public void endVisit(ArrayInitializer arrayInitializer, BlockScope scope) {
context.exit(arrayInitializer);
}
@Override
public void endVisit(ArrayReference arrayReference, BlockScope scope) {
context.exit(arrayReference);
}
@Override
public void endVisit(ArrayTypeReference arrayTypeReference, BlockScope scope) {
context.exit(arrayTypeReference);
}
@Override
public void endVisit(AssertStatement assertStatement, BlockScope scope) {
context.exit(assertStatement);
}
@Override
public void endVisit(Assignment assignment, BlockScope scope) {
context.exit(assignment);
}
@Override
public void endVisit(BinaryExpression binaryExpression, BlockScope scope) {
context.exit(binaryExpression);
}
@Override
public void endVisit(Block block, BlockScope scope) {
context.exit(block);
}
@Override
public void endVisit(BreakStatement breakStatement, BlockScope scope) {
context.exit(breakStatement);
}
@Override
public void endVisit(CaseStatement caseStatement, BlockScope scope) {
context.exit(caseStatement);
}
@Override
public void endVisit(CharLiteral charLiteral, BlockScope scope) {
context.exit(charLiteral);
}
@Override
public void endVisit(ClassLiteralAccess classLiteral, BlockScope scope) {
context.exit(classLiteral);
}
@Override
public void endVisit(CompoundAssignment compoundAssignment, BlockScope scope) {
context.exit(compoundAssignment);
}
@Override
public void endVisit(ConditionalExpression conditionalExpression,
BlockScope scope) {
context.exit(conditionalExpression);
}
@Override
public void endVisit(ConstructorDeclaration constructorDeclaration,
ClassScope scope) {
context.exit(constructorDeclaration);
if (context.stack.peek().node == constructorDeclaration)
context.exit(constructorDeclaration);
}
@Override
public void endVisit(ContinueStatement continueStatement, BlockScope scope) {
context.exit(continueStatement);
}
@Override
public void endVisit(DoStatement doStatement, BlockScope scope) {
context.exit(doStatement);
}
@Override
public void endVisit(DoubleLiteral doubleLiteral, BlockScope scope) {
context.exit(doubleLiteral);
}
@Override
public void endVisit(EqualExpression equalExpression, BlockScope scope) {
context.exit(equalExpression);
}
@Override
public void endVisit(ExplicitConstructorCall explicitConstructor,
BlockScope scope) {
context.exit(explicitConstructor);
}
@Override
public void endVisit(ExtendedStringLiteral extendedStringLiteral,
BlockScope scope) {
context.exit(extendedStringLiteral);
}
@Override
public void endVisit(FalseLiteral falseLiteral, BlockScope scope) {
context.exit(falseLiteral);
}
@Override
public void endVisit(FieldDeclaration fieldDeclaration, MethodScope scope) {
context.exit(fieldDeclaration);
}
@Override
public void endVisit(FieldReference fieldReference, BlockScope scope) {
context.exit(fieldReference);
}
@Override
public void endVisit(FloatLiteral floatLiteral, BlockScope scope) {
context.exit(floatLiteral);
}
@Override
public void endVisit(ForeachStatement forStatement, BlockScope scope) {
context.exit(forStatement);
}
@Override
public void endVisit(ForStatement forStatement, BlockScope scope) {
context.exit(forStatement);
}
@Override
public void endVisit(IfStatement ifStatement, BlockScope scope) {
context.exit(ifStatement);
}
@Override
public void endVisit(Initializer initializer, MethodScope scope) {
context.exit(initializer);
}
@Override
public void endVisit(InstanceOfExpression instanceOfExpression,
BlockScope scope) {
context.exit(instanceOfExpression);
}
@Override
public void endVisit(IntLiteral intLiteral, BlockScope scope) {
context.exit(intLiteral);
}
@Override
public void endVisit(LocalDeclaration localDeclaration, BlockScope scope) {
context.exit(localDeclaration);
}
@Override
public void endVisit(LongLiteral longLiteral, BlockScope scope) {
context.exit(longLiteral);
}
@Override
public void endVisit(MarkerAnnotation annotation, BlockScope scope) {
context.exit(annotation);
skipTypeInAnnotation = false;
}
@Override
public void endVisit(MemberValuePair pair, BlockScope scope) {
if (!context.annotationValueName.pop().equals(new String(pair.name))) {
throw new RuntimeException("Unconsistant Stack");
}
}
@Override
public void endVisit(MessageSend messageSend, BlockScope scope) {
context.exit(messageSend);
}
@Override
public void endVisit(MethodDeclaration methodDeclaration, ClassScope scope) {
// Exit from method and Block
context.exit(methodDeclaration);
if (context.stack.peek().node == methodDeclaration)
context.exit(methodDeclaration);
}
@Override
public void endVisit(NormalAnnotation annotation, BlockScope scope) {
context.exit(annotation);
skipTypeInAnnotation = false;
}
@Override
public void endVisit(NullLiteral nullLiteral, BlockScope scope) {
context.exit(nullLiteral);
}
@Override
public void endVisit(OR_OR_Expression or_or_Expression, BlockScope scope) {
context.exit(or_or_Expression);
}
@Override
public void endVisit(
ParameterizedQualifiedTypeReference parameterizedQualifiedTypeReference,
ClassScope scope) {
if (skipTypeInAnnotation) {
skipTypeInAnnotation = false;
return;
}
context.exit(parameterizedQualifiedTypeReference);
}
@Override
public void endVisit(
ParameterizedSingleTypeReference parameterizedSingleTypeReference,
BlockScope scope) {
if (skipTypeInAnnotation) {
skipTypeInAnnotation = false;
return;
}
context.exit(parameterizedSingleTypeReference);
}
@Override
public void endVisit(
ParameterizedSingleTypeReference parameterizedSingleTypeReference,
ClassScope scope) {
if (skipTypeInAnnotation) {
skipTypeInAnnotation = false;
return;
}
context.exit(parameterizedSingleTypeReference);
}
@Override
public void endVisit(PostfixExpression postfixExpression, BlockScope scope) {
context.exit(postfixExpression);
}
@Override
public void endVisit(PrefixExpression prefixExpression, BlockScope scope) {
context.exit(prefixExpression);
}
@Override
public void endVisit(
QualifiedAllocationExpression qualifiedAllocationExpression,
BlockScope scope) {
endVisit((AllocationExpression) qualifiedAllocationExpression, scope);
}
@Override
public void endVisit(QualifiedNameReference qualifiedNameReference,
BlockScope scope) {
if (context.stack.peek().node == qualifiedNameReference) {
context.exit(qualifiedNameReference);
}
}
@Override
public void endVisit(QualifiedThisReference qualifiedThisReference,
BlockScope scope) {
endVisit((ThisReference) qualifiedThisReference, scope);
}
@Override
public void endVisit(QualifiedTypeReference arg0, BlockScope arg1) {
if (skipTypeInAnnotation) {
skipTypeInAnnotation = false;
return;
}
context.exit(arg0);
}
@Override
public void endVisit(ReturnStatement returnStatement, BlockScope scope) {
context.exit(returnStatement);
}
@Override
public void endVisit(SingleMemberAnnotation annotation, BlockScope scope) {
if (!context.annotationValueName.pop().equals("value")) {
throw new RuntimeException("unconsistant Stack");
}
context.exit(annotation);
skipTypeInAnnotation = false;
}
@Override
public void endVisit(SingleNameReference singleNameReference,
BlockScope scope) {
if (context.stack.peek().node == singleNameReference)
context.exit(singleNameReference);
}
@Override
public void endVisit(SingleTypeReference singleTypeReference,
BlockScope scope) {
if (skipTypeInAnnotation) {
skipTypeInAnnotation = false;
return;
}
context.exit(singleTypeReference);
}
@Override
public void endVisit(SingleTypeReference singleTypeReference,
ClassScope scope) {
context.exit(singleTypeReference);
}
@Override
public void endVisit(StringLiteral stringLiteral, BlockScope scope) {
context.exit(stringLiteral);
}
@Override
public void endVisit(StringLiteralConcatenation literal, BlockScope scope) {
context.exit(literal);
}
@Override
public void endVisit(QualifiedSuperReference qualifiedsuperReference,
BlockScope scope) {
context.exit(qualifiedsuperReference);
}
@Override
public void endVisit(SuperReference superReference, BlockScope scope) {
context.exit(superReference);
}
@Override
public void endVisit(SwitchStatement switchStatement, BlockScope scope) {
context.exit(switchStatement);
}
@Override
public void endVisit(SynchronizedStatement synchronizedStatement,
BlockScope scope) {
context.exit(synchronizedStatement);
}
@Override
public void endVisit(ThisReference thisReference, BlockScope scope) {
context.exit(thisReference);
}
@Override
public void endVisit(ThrowStatement throwStatement, BlockScope scope) {
context.exit(throwStatement);
}
@Override
public void endVisit(TrueLiteral trueLiteral, BlockScope scope) {
context.exit(trueLiteral);
}
@Override
public void endVisit(TryStatement tryStatement, BlockScope scope) {
context.exit(tryStatement);
}
@Override
public void endVisit(TypeDeclaration localTypeDeclaration, BlockScope scope) {
context.exit(localTypeDeclaration);
}
@Override
public void endVisit(TypeDeclaration memberTypeDeclaration, ClassScope scope) {
while (!context.stack.isEmpty()
&& context.stack.peek().node == memberTypeDeclaration) {
context.exit(memberTypeDeclaration);
}
}
@Override
public void endVisit(TypeDeclaration typeDeclaration,
CompilationUnitScope scope) {
while (!context.stack.isEmpty()
&& context.stack.peek().node == typeDeclaration) {
context.exit(typeDeclaration);
}
context.compilationunitdeclaration = null;
}
@Override
public void endVisit(UnaryExpression unaryExpression, BlockScope scope) {
context.exit(unaryExpression);
}
@Override
public void endVisit(WhileStatement whileStatement, BlockScope scope) {
context.exit(whileStatement);
}
BinaryOperatorKind getBinaryOperatorKind(int bits) {
// switch ((bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT) {
switch (bits) {
case OperatorIds.EQUAL_EQUAL:
return BinaryOperatorKind.EQ;
case OperatorIds.LESS_EQUAL:
return BinaryOperatorKind.LE;
case OperatorIds.GREATER_EQUAL:
return BinaryOperatorKind.GE;
case OperatorIds.NOT_EQUAL:
return BinaryOperatorKind.NE;
case OperatorIds.LEFT_SHIFT:
return BinaryOperatorKind.SL;
case OperatorIds.RIGHT_SHIFT:
return BinaryOperatorKind.SR;
case OperatorIds.UNSIGNED_RIGHT_SHIFT:
return BinaryOperatorKind.USR;
case OperatorIds.OR_OR:
return BinaryOperatorKind.OR;
case OperatorIds.AND_AND:
return BinaryOperatorKind.AND;
case OperatorIds.PLUS:
return BinaryOperatorKind.PLUS;
case OperatorIds.MINUS:
return BinaryOperatorKind.MINUS;
case OperatorIds.NOT:
return BinaryOperatorKind.NE;
case OperatorIds.REMAINDER:
return BinaryOperatorKind.MOD;
case OperatorIds.XOR:
return BinaryOperatorKind.BITXOR;
case OperatorIds.AND:
return BinaryOperatorKind.BITAND;
case OperatorIds.MULTIPLY:
return BinaryOperatorKind.MUL;
case OperatorIds.OR:
return BinaryOperatorKind.BITOR;
case OperatorIds.DIVIDE:
return BinaryOperatorKind.DIV;
case OperatorIds.GREATER:
return BinaryOperatorKind.GT;
case OperatorIds.LESS:
return BinaryOperatorKind.LT;
case OperatorIds.QUESTIONCOLON:
throw new RuntimeException("Unknow operator");
case OperatorIds.EQUAL:
return BinaryOperatorKind.EQ;
}
return null;
}
public List> getCreatedTypes() {
return context.getCreatedTypes();
}
public String getJavaDoc(Javadoc javadoc,
CompilationUnitDeclaration declaration) {
if (javadoc != null) {
try {
String s = new String(
declaration.compilationResult.compilationUnit
.getContents(),
javadoc.sourceStart, javadoc.sourceEnd
- javadoc.sourceStart + 1);
return cleanJavadoc(s);
} catch (StringIndexOutOfBoundsException e) {// BCUTAG trouver cause
return null;
}
}
return null;
}
protected CtLocalVariable getLocalVariableDeclaration(
final String name) {
List reversedElements = new ArrayList();
for (ASTPair element : context.stack) {
reversedElements.add(0, element.element);
}
for (CtElement element : reversedElements) {
// TODO check if the variable is visible from here
List> var = Query.getElements(element,
new TypeFilter>(CtLocalVariable.class) {
@Override
public boolean matches(CtLocalVariable element) {
return name.equals(element.getSimpleName())
&& super.matches(element);
}
});
if (var.size() > 0) {
return var.get(0);
}
}
// note: this happens when using the new try(vardelc) structure
logger.error("could not find declaration for local variable " + name
+ " at " + context.stack.peek().element.getPosition());
return null;
}
UnaryOperatorKind getUnaryOperator(int op) {
switch (op) {
case OperatorIds.PLUS:
return UnaryOperatorKind.POS;
case OperatorIds.MINUS:
return UnaryOperatorKind.NEG;
case OperatorIds.NOT:
return UnaryOperatorKind.NOT;
case OperatorIds.TWIDDLE:
return UnaryOperatorKind.COMPL;
}
return null;
}
@SuppressWarnings("unchecked")
@Override
public boolean visit(AllocationExpression allocationExpression,
BlockScope scope) {
CtNewClass c = factory.Core().createNewClass();
if (allocationExpression.type != null) {
if (allocationExpression.type.resolvedType instanceof ParameterizedTypeBinding) {
CtTypeReference res = references
.getTypeReference(((ParameterizedTypeBinding) allocationExpression.type.resolvedType)
.genericType());
ParameterizedTypeBinding paramType = ((ParameterizedTypeBinding) allocationExpression.type.resolvedType);
if (paramType.arguments != null
&& paramType.isBoundParameterizedType()
) {
for (TypeBinding b : ((ParameterizedTypeBinding) allocationExpression.type.resolvedType).arguments) {
res.addActualTypeArgument(references
.getTypeReference(b));
}
}
c.setType(res);
} else
c.setType(references
.getTypeReference(allocationExpression.type.resolvedType));
}
c.setExecutable(references
.getExecutableReference(allocationExpression.binding));
if (c.getExecutable() == null) {
logger.error("null executable ref at "
+ context.createSourcePosition(allocationExpression));
} else {
c.getExecutable().setType(
(CtTypeReference) c.getExecutable()
.getDeclaringType());
}
context.enter(c, allocationExpression);
if (allocationExpression.enclosingInstance() != null) {
context.target.push(c);
allocationExpression.enclosingInstance().traverse(this, scope);
context.target.pop();
}
context.pushArgument(c);
if (allocationExpression.arguments != null) {
for (Expression e : allocationExpression.arguments)
e.traverse(this, scope);
}
context.popArgument(c);
return false;
}
@Override
public boolean visit(AND_AND_Expression and_and_Expression, BlockScope scope) {
CtBinaryOperator> op = factory.Core().createBinaryOperator();
op.setKind(getBinaryOperatorKind((and_and_Expression.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT));
context.enter(op, and_and_Expression);
return true; // do nothing by default, keep traversing
}
@Override
public boolean visit(AnnotationMethodDeclaration annotationTypeDeclaration,
ClassScope classScope) {
CtField f = factory.Core().createField();
f.setSimpleName(new String(annotationTypeDeclaration.selector));
f.setType(references
.getTypeReference(annotationTypeDeclaration.binding.returnType));
context.enter(f, annotationTypeDeclaration);
if (annotationTypeDeclaration.annotations != null) {
int annotationsLength = annotationTypeDeclaration.annotations.length;
for (int i = 0; i < annotationsLength; i++)
annotationTypeDeclaration.annotations[i].traverse(this,
annotationTypeDeclaration.scope);
}
if (annotationTypeDeclaration.defaultValue != null) {
annotationTypeDeclaration.defaultValue.traverse(this,
annotationTypeDeclaration.scope);
}
return false;
}
@Override
public boolean visit(Argument argument, BlockScope scope) {
CtParameter p = factory.Core().createParameter();
p.setSimpleName(new String(argument.name));
p.setVarArgs(argument.isVarArgs());
p.setModifiers(getModifiers(argument.modifiers));
if (argument.type != null)
p.setType(references.getTypeReference(argument.type.resolvedType));
context.enter(p, argument);
if (argument.initialization != null)
argument.initialization.traverse(this, scope);
if (argument.annotations != null)
for (Annotation a : argument.annotations)
a.traverse(this, scope);
return false;
}
@Override
public boolean visit(ArrayAllocationExpression arrayAllocationExpression,
BlockScope scope) {
CtNewArray array = factory.Core().createNewArray();
array.setType(references
.getTypeReference(arrayAllocationExpression.resolvedType));
context.enter(array, arrayAllocationExpression);
context.pushArgument(array);
if (arrayAllocationExpression.dimensions != null)
for (Expression e : arrayAllocationExpression.dimensions)
if (e != null)
e.traverse(this, scope);
context.popArgument(array);
if (arrayAllocationExpression.initializer != null
&& arrayAllocationExpression.initializer.expressions != null) {
for (Expression e : arrayAllocationExpression.initializer.expressions)
e.traverse(this, scope);
}
return false;
}
@Override
public boolean visit(ArrayInitializer arrayInitializer, BlockScope scope) {
CtNewArray> array = factory.Core().createNewArray();
context.enter(array, arrayInitializer);
return super.visit(arrayInitializer, scope);
}
@Override
public boolean visit(ArrayReference arrayReference, BlockScope scope) {
CtArrayAccess, ?> a = factory.Core().createArrayAccess();
context.enter(a, arrayReference);
arrayReference.receiver.traverse(this, scope);
context.arguments.push(a);
arrayReference.position.traverse(this, scope);
context.arguments.pop();
return false;
}
@Override
public boolean visit(ArrayTypeReference arrayTypeReference, BlockScope scope) {
CtLiteral> l = factory.Core().createLiteral();
l.setValue(references.getTypeReference(arrayTypeReference.resolvedType));
context.enter(l, arrayTypeReference);
return true;
}
@Override
public boolean visit(AssertStatement assertStatement, BlockScope scope) {
CtAssert> a = factory.Core().createAssert();
context.enter(a, assertStatement);
assertStatement.assertExpression.traverse(this, scope);
context.arguments.push(a);
if (assertStatement.exceptionArgument != null) {
assertStatement.exceptionArgument.traverse(this, scope);
}
context.arguments.pop();
return false;
}
@Override
public boolean visit(Assignment assignment, BlockScope scope) {
CtAssignment assign = factory.Core().createAssignment();
context.enter(assign, assignment);
return true;
}
@Override
public boolean visit(BinaryExpression binaryExpression, BlockScope scope) {
CtBinaryOperator> op = factory.Core().createBinaryOperator();
op.setKind(getBinaryOperatorKind((binaryExpression.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT));
context.enter(op, binaryExpression);
return true;
}
@Override
public boolean visit(Block block, BlockScope scope) {
CtBlock> b = factory.Core().createBlock();
context.enter(b, block);
return true;
}
@Override
public boolean visit(BreakStatement breakStatement, BlockScope scope) {
CtBreak b = factory.Core().createBreak();
if (breakStatement.label != null)
b.setTargetLabel(new String(breakStatement.label));
context.enter(b, breakStatement);
return true;
}
@Override
public boolean visit(CaseStatement caseStatement, BlockScope scope) {
CtCase> c = factory.Core().createCase();
context.enter(c, caseStatement);
if (caseStatement.constantExpression != null) {
context.selector = true;
caseStatement.constantExpression.traverse(this, scope);
context.selector = false;
}
return false;
}
@Override
public boolean visit(CastExpression castExpression, BlockScope scope) {
context.casts.add(references
.getTypeReference(castExpression.resolvedType));
castExpression.expression.traverse(this, scope);
return false;
}
@Override
public boolean visit(CharLiteral charLiteral, BlockScope scope) {
CtLiteral l = factory.Core().createLiteral();
l.setValue(charLiteral.constant.charValue());
context.enter(l, charLiteral);
return true;
}
@Override
public boolean visit(ClassLiteralAccess classLiteral, BlockScope scope) {
CtTypeReference> ref = references
.getTypeReference(classLiteral.targetType);
CtFieldReference> fr = factory.Core()
.createFieldReference();
fr.setSimpleName("class");
fr.setType(ref);
fr.setDeclaringType(ref);
CtFieldAccess> fa = factory.Core().createFieldAccess();
fa.setType(ref);
fa.setVariable(fr);
context.enter(fa, classLiteral);
return true;
}
@Override
public boolean visit(CompoundAssignment compoundAssignment, BlockScope scope) {
CtOperatorAssignment a = factory.Core()
.createOperatorAssignment();
a.setKind(getBinaryOperatorKind(compoundAssignment.operator));
context.enter(a, compoundAssignment);
return super.visit(compoundAssignment, scope);
}
@Override
public boolean visit(ConditionalExpression conditionalExpression,
BlockScope scope) {
CtConditional> c = factory.Core().createConditional();
context.enter(c, conditionalExpression);
return super.visit(conditionalExpression, scope);
}
@Override
public boolean visit(ConstructorDeclaration constructorDeclaration,
ClassScope scope) {
CtConstructor> c = factory.Core().createConstructor();
c.setModifiers(getModifiers(constructorDeclaration.modifiers));
c.setDocComment(getJavaDoc(constructorDeclaration.javadoc,
scope.referenceCompilationUnit()));
context.enter(c, constructorDeclaration);
if (constructorDeclaration.annotations != null) {
int annotationsLength = constructorDeclaration.annotations.length;
for (int i = 0; i < annotationsLength; i++)
constructorDeclaration.annotations[i].traverse(this,
constructorDeclaration.scope);
}
context.pushArgument(c);
if (constructorDeclaration.arguments != null) {
int argumentLength = constructorDeclaration.arguments.length;
for (int i = 0; i < argumentLength; i++)
constructorDeclaration.arguments[i].traverse(this,
constructorDeclaration.scope);
}
context.popArgument(c);
if (constructorDeclaration.thrownExceptions != null) {
for (TypeReference r : constructorDeclaration.thrownExceptions) {
CtTypeReference extends Throwable> tr = references
.getTypeReference(r.resolvedType);
c.addThrownType(tr);
}
}
if (constructorDeclaration.binding != null)
for (TypeBinding b : constructorDeclaration.binding.typeVariables) {
c.addFormalTypeParameter(references.getBoundedTypeReference(b));
}
// Create block
if (!constructorDeclaration.isAbstract()) {
CtBlock> b = factory.Core().createBlock();
context.enter(b, constructorDeclaration);
}
if (constructorDeclaration.constructorCall != null)
constructorDeclaration.constructorCall.traverse(this,
constructorDeclaration.scope);
if (constructorDeclaration.statements != null) {
for (Statement s : constructorDeclaration.statements)
s.traverse(this, constructorDeclaration.scope);
}
return false;
}
@Override
public boolean visit(ContinueStatement continueStatement, BlockScope scope) {
CtContinue c = factory.Core().createContinue();
context.enter(c, continueStatement);
if (continueStatement.label != null) {
c.setTargetLabel(new String(continueStatement.label));
}
return true;
}
@Override
public boolean visit(DoStatement doStatement, BlockScope scope) {
CtDo d = factory.Core().createDo();
context.enter(d, doStatement);
return true;
}
@Override
public boolean visit(DoubleLiteral doubleLiteral, BlockScope scope) {
CtLiteral d = factory.Core().createLiteral();
d.setValue(doubleLiteral.constant.doubleValue());
context.enter(d, doubleLiteral);
return true;
}
@Override
public boolean visit(EqualExpression equalExpression, BlockScope scope) {
CtBinaryOperator> op = factory.Core().createBinaryOperator();
op.setKind(getBinaryOperatorKind((equalExpression.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT));
context.enter(op, equalExpression);
return true; // do nothing by default, keep traversing
}
@SuppressWarnings("unchecked")
@Override
public boolean visit(ExplicitConstructorCall explicitConstructor,
BlockScope scope) {
CtInvocation inv = factory.Core().createInvocation();
if (explicitConstructor.isImplicitSuper()) {
inv.setImplicit(true);
}
CtExecutableReference er = references
.getExecutableReference(explicitConstructor.binding);
inv.setExecutable(er);
inv.getExecutable().setType(
(CtTypeReference) inv.getExecutable()
.getDeclaringType());
inv.setType(inv.getExecutable().getType());
context.enter(inv, explicitConstructor);
if (explicitConstructor.qualification != null) {
explicitConstructor.qualification.traverse(this, scope);
}
if (explicitConstructor.typeArguments != null) {
for (int i = 0, typeArgumentsLength = explicitConstructor.typeArguments.length; i < typeArgumentsLength; i++) {
explicitConstructor.typeArguments[i].traverse(this, scope);
}
}
context.arguments.push(inv);
if (explicitConstructor.arguments != null) {
for (int i = 0, argumentLength = explicitConstructor.arguments.length; i < argumentLength; i++)
explicitConstructor.arguments[i].traverse(this, scope);
}
context.arguments.pop();
return false;
}
@Override
public boolean visit(ExtendedStringLiteral extendedStringLiteral,
BlockScope scope) {
throw new RuntimeException(
"invalid ast node: the parser must be configured with parseLiteralExpressionsAsConstants set to false");
// CtLiteral l = factory.Core().createLiteral();
// l.setValue(new String(extendedStringLiteral.source()));
// context.enter(l, extendedStringLiteral);
// return true;
}
@Override
public boolean visit(FalseLiteral falseLiteral, BlockScope scope) {
CtLiteral l = factory.Core().createLiteral();
l.setValue(false);
context.enter(l, falseLiteral);
return true;
}
@Override
public boolean visit(FieldDeclaration fieldDeclaration, MethodScope scope) {
CtField field = factory.Core().createField();
field.setSimpleName(new String(fieldDeclaration.name));
if (fieldDeclaration.type != null)
field.setType(references
.getTypeReference(fieldDeclaration.type.resolvedType));
field.setModifiers(getModifiers(fieldDeclaration.modifiers));
field.setDocComment(getJavaDoc(fieldDeclaration.javadoc,
scope.referenceCompilationUnit()));
context.enter(field, fieldDeclaration);
if (fieldDeclaration.annotations != null) {
int annotationsLength = fieldDeclaration.annotations.length;
for (int i = 0; i < annotationsLength; i++)
fieldDeclaration.annotations[i].traverse(this, scope);
}
if (fieldDeclaration.initialization != null)
fieldDeclaration.initialization.traverse(this, scope);
return false;
}
@Override
public boolean visit(FieldReference fieldReference, BlockScope scope) {
CtFieldAccess acc = factory.Core().createFieldAccess();
acc.setVariable(references.getVariableReference(fieldReference.binding));
acc.setType(references.getTypeReference(fieldReference.resolvedType));
// Hmmm Maybe this should not be commented, but I cannot see why we need
// it.
// Anyway, the problem is that in jdt-core 3.5+ fieldReferences no
// longer have a receiverType,
// As far as I can tell, this if makes sure that pika.length if pika is
// an array, gets the correct type.
// if anything, I guess that the jdt-core now does not think that length
// is a field... so we wouldn;t need this anymore.
// if (fieldReference.receiverType instanceof ArrayBinding
// && new String(fieldReference.token).equals("length")) {
// acc.getVariable().setDeclaringType(
// references.getTypeReference(fieldReference.receiverType));
// }
context.enter(acc, fieldReference);
context.target.push(acc);
fieldReference.receiver.traverse(this, scope);
context.target.pop();
return false;
}
@Override
public boolean visit(FloatLiteral floatLiteral, BlockScope scope) {
CtLiteral l = factory.Core().createLiteral();
l.setValue(floatLiteral.constant.floatValue());
context.enter(l, floatLiteral);
return true;
}
@Override
public boolean visit(ForeachStatement forStatement, BlockScope scope) {
CtForEach fe = factory.Core().createForEach();
context.enter(fe, forStatement);
return true;
}
@Override
public boolean visit(ForStatement forStatement, BlockScope scope) {
CtFor for1 = factory.Core().createFor();
context.enter(for1, forStatement);
if (forStatement.initializations != null) {
context.forinit = true;
int initializationsLength = forStatement.initializations.length;
for (int i = 0; i < initializationsLength; i++)
forStatement.initializations[i].traverse(this, scope);
context.forinit = false;
}
if (forStatement.condition != null)
forStatement.condition.traverse(this, scope);
if (forStatement.increments != null) {
context.forupdate = true;
int incrementsLength = forStatement.increments.length;
for (int i = 0; i < incrementsLength; i++)
forStatement.increments[i].traverse(this, scope);
context.forupdate = false;
}
if (forStatement.action != null)
forStatement.action.traverse(this, scope);
return false;
}
@Override
public boolean visit(IfStatement ifStatement, BlockScope scope) {
CtIf ifs = factory.Core().createIf();
context.enter(ifs, ifStatement);
return super.visit(ifStatement, scope);
}
@Override
public boolean visit(Initializer initializer, MethodScope scope) {
CtAnonymousExecutable b = factory.Core().createAnonymousExecutable();
if (initializer.isStatic())
b.addModifier(ModifierKind.STATIC);
context.enter(b, initializer);
return true;
}
@Override
public boolean visit(InstanceOfExpression instanceOfExpression,
BlockScope scope) {
CtBinaryOperator> op = factory.Core().createBinaryOperator();
op.setKind(BinaryOperatorKind.INSTANCEOF);
CtLiteral> l = factory.Core().createLiteral();
l.setValue(references
.getBoundedTypeReference(instanceOfExpression.type.resolvedType));
op.setRightHandOperand(l);
l.setParent(op);
context.enter(op, instanceOfExpression);
return true;
}
@Override
public boolean visit(IntLiteral intLiteral, BlockScope scope) {
CtLiteral l = factory.Core().createLiteral();
CtTypeReference r = references
.getTypeReference(intLiteral.resolvedType);
l.setType(r);
l.setValue(intLiteral.constant.intValue());
context.enter(l, intLiteral);
return true;
}
@Override
public boolean visit(LabeledStatement labeledStatement, BlockScope scope) {
context.label.push(new String(labeledStatement.label));
return true;
}
@Override
public boolean visit(LocalDeclaration localDeclaration, BlockScope scope) {
CtLocalVariable v = factory.Core().createLocalVariable();
v.setSimpleName(new String(localDeclaration.name));
v.setType(references
.getTypeReference(localDeclaration.type.resolvedType));
v.setModifiers(getModifiers(localDeclaration.modifiers));
context.enter(v, localDeclaration);
if (localDeclaration.initialization != null) {
context.arguments.push(v);
localDeclaration.initialization.traverse(this, scope);
context.arguments.pop();
}
if (localDeclaration.annotations != null)
for (Annotation a : localDeclaration.annotations)
a.traverse(this, scope);
return false;
}
@Override
public boolean visit(LongLiteral longLiteral, BlockScope scope) {
CtLiteral l = factory.Core().createLiteral();
l.setValue(longLiteral.constant.longValue());
CtTypeReference r = references
.getTypeReference(longLiteral.resolvedType);
l.setType(r);
context.enter(l, longLiteral);
return true;
}
@Override
public boolean visit(MarkerAnnotation annotation, BlockScope scope) {
return visitMarkerAnnoation(annotation, scope);
}
private boolean visitMarkerAnnoation(
MarkerAnnotation annotation, BlockScope scope) {
CtAnnotation a = factory.Core().createAnnotation();
CtTypeReference t = references
.getTypeReference(annotation.resolvedType);
a.setAnnotationType(t);
context.enter(a, annotation);
skipTypeInAnnotation = true;
return true;
}
@Override
public boolean visit(MemberValuePair pair, BlockScope scope) {
context.annotationValueName.push(new String(pair.name));
return true;
}
@Override
public boolean visit(MessageSend messageSend, BlockScope scope) {
if (messageSend.actualReceiverType == null) {
logger.error("unconsistent message send at "
+ context.createSourcePosition(messageSend));
}
if (messageSend.actualReceiverType == null
|| !messageSend.actualReceiverType.isAnnotationType()) {
CtInvocation inv = factory.Core().createInvocation();
if (messageSend.binding != null)
inv.setExecutable(references
.getExecutableReference(messageSend.binding));
// inv
// .setType(references
// .getTypeReference(messageSend.binding.returnType));
context.enter(inv, messageSend);
if (!(messageSend.receiver.getClass().equals(ThisReference.class)))
messageSend.receiver.traverse(this, scope);
context.pushArgument(inv);
if (messageSend.arguments != null)
for (Expression e : messageSend.arguments) {
e.traverse(this, scope);
}
if (messageSend.genericTypeArguments != null)
inv.setGenericTypes(references
.getBoundedTypesReferences(messageSend.genericTypeArguments));
context.popArgument(inv);
return false;
} else {
CtAnnotationFieldAccess acc = factory.Core()
.createAnnotationFieldAccess();
acc.setVariable(references
.getVariableReference(messageSend.binding));
acc.setType(references.getTypeReference(messageSend.resolvedType));
context.enter(acc, messageSend);
context.target.push(acc);
messageSend.receiver.traverse(this, scope);
context.target.pop();
return false;
}
}
@Override
public boolean visit(MethodDeclaration methodDeclaration, ClassScope scope) {
CtMethod m = factory.Core().createMethod();
m.setSimpleName(new String(methodDeclaration.selector));
m.setType(references
.getTypeReference(methodDeclaration.returnType.resolvedType));
m.setModifiers(getModifiers(methodDeclaration.modifiers));
if (methodDeclaration.thrownExceptions != null) {
for (TypeReference r : methodDeclaration.thrownExceptions) {
CtTypeReference extends Throwable> tr = references
.getTypeReference(r.resolvedType);
m.addThrownType(tr);
}
}
if (methodDeclaration.binding != null) {// this may happen when working
// with incomplete classpath
for (TypeBinding b : methodDeclaration.binding.typeVariables) {
m.addFormalTypeParameter(references.getBoundedTypeReference(b));
}
}
if (scope != null) {
m.setDocComment(getJavaDoc(methodDeclaration.javadoc,
scope.referenceCompilationUnit()));
} else if (methodDeclaration.scope != null) {
m.setDocComment(getJavaDoc(methodDeclaration.javadoc,
methodDeclaration.scope.referenceCompilationUnit()));
} else {
logger.error("null scope", new Exception());
}
context.enter(m, methodDeclaration);
if (methodDeclaration.annotations != null)
for (Annotation a : methodDeclaration.annotations)
a.traverse(this, methodDeclaration.scope);
if (methodDeclaration.arguments != null)
for (Argument a : methodDeclaration.arguments)
a.traverse(this, methodDeclaration.scope);
// Create block
if (!methodDeclaration.isAbstract()
&& (methodDeclaration.modifiers & ClassFileConstants.AccNative) == 0) {
CtBlock> b = factory.Core().createBlock();
context.enter(b, methodDeclaration);
}
if (methodDeclaration.statements != null) {
for (Statement s : methodDeclaration.statements)
s.traverse(this, methodDeclaration.scope);
}
return false;
}
@Override
public boolean visit(NormalAnnotation annotation, BlockScope scope) {
return visitNormalAnnotation(annotation, scope);
}
private boolean visitNormalAnnotation(
NormalAnnotation annotation, BlockScope scope) {
CtAnnotation a = factory.Core().createAnnotation();
CtTypeReference r = references
.getTypeReference(annotation.resolvedType);
a.setAnnotationType(r);
context.enter(a, annotation);
skipTypeInAnnotation = true;
return true;
}
@Override
public boolean visit(NullLiteral nullLiteral, BlockScope scope) {
CtLiteral lit = factory.Core().createLiteral();
CtTypeReference ref = factory.Core().createTypeReference();
ref.setSimpleName(CtTypeReference.NULL_TYPE_NAME);
lit.setType(ref);
context.enter(lit, nullLiteral);
return true;
}
@Override
public boolean visit(OR_OR_Expression or_or_Expression, BlockScope scope) {
CtBinaryOperator> op = factory.Core().createBinaryOperator();
op.setKind(getBinaryOperatorKind((or_or_Expression.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT));
context.enter(op, or_or_Expression);
return true;
}
@Override
public boolean visit(
ParameterizedQualifiedTypeReference parameterizedQualifiedTypeReference,
ClassScope scope) {
if (skipTypeInAnnotation) {
return true;
}
CtLiteral> l = factory.Core().createLiteral();
l.setValue(references
.getBoundedTypeReference(parameterizedQualifiedTypeReference.resolvedType));
context.enter(l, parameterizedQualifiedTypeReference);
return true;
}
@Override
public boolean visit(
ParameterizedSingleTypeReference parameterizedSingleTypeReference,
BlockScope scope) {
if (skipTypeInAnnotation) {
return true;
}
CtLiteral> l = factory.Core().createLiteral();
l.setValue(references
.getBoundedTypeReference(parameterizedSingleTypeReference.resolvedType));
context.enter(l, parameterizedSingleTypeReference);
return true;
}
@Override
public boolean visit(
ParameterizedSingleTypeReference parameterizedSingleTypeReference,
ClassScope scope) {
if (skipTypeInAnnotation) {
return true;
}
CtLiteral> l = factory.Core().createLiteral();
l.setValue(references
.getBoundedTypeReference(parameterizedSingleTypeReference.resolvedType));
context.enter(l, parameterizedSingleTypeReference);
return super.visit(parameterizedSingleTypeReference, scope);
}
@Override
public boolean visit(PostfixExpression postfixExpression, BlockScope scope) {
CtUnaryOperator> op = factory.Core().createUnaryOperator();
if (postfixExpression.operator == OperatorIds.PLUS)
op.setKind(UnaryOperatorKind.POSTINC);
if (postfixExpression.operator == OperatorIds.MINUS)
op.setKind(UnaryOperatorKind.POSTDEC);
context.enter(op, postfixExpression);
return true;
}
@Override
public boolean visit(PrefixExpression prefixExpression, BlockScope scope) {
CtUnaryOperator> op = factory.Core().createUnaryOperator();
if (prefixExpression.operator == OperatorIds.PLUS)
op.setKind(UnaryOperatorKind.PREINC);
if (prefixExpression.operator == OperatorIds.MINUS)
op.setKind(UnaryOperatorKind.PREDEC);
context.enter(op, prefixExpression);
return true;
}
@Override
public boolean visit(
QualifiedAllocationExpression qualifiedAllocationExpression,
BlockScope scope) {
boolean ret = visit(
(AllocationExpression) qualifiedAllocationExpression, scope);
if (qualifiedAllocationExpression.enclosingInstance != null)
qualifiedAllocationExpression.enclosingInstance.traverse(this,
scope);
if (qualifiedAllocationExpression.anonymousType != null)
qualifiedAllocationExpression.anonymousType.traverse(this, scope);
return ret;
}
@Override
public boolean visit(QualifiedNameReference qualifiedNameReference,
BlockScope scope) {
if (qualifiedNameReference.binding instanceof FieldBinding) {
CtFieldAccess fa = factory.Core().createFieldAccess();
fa.setVariable(references
.getVariableReference(qualifiedNameReference.fieldBinding()));
if (qualifiedNameReference.otherBindings != null)
for (FieldBinding b : qualifiedNameReference.otherBindings) {
if (b != null) {
CtFieldAccess other = factory.Core()
.createFieldAccess();
other.setVariable(references.getVariableReference(b));
other.setTarget(fa);
fa.setParent(other);
fa = other;
}
}
context.enter(fa, qualifiedNameReference);
return true;
} else if (qualifiedNameReference.binding instanceof VariableBinding) {
CtVariableAccess va = factory.Core().createVariableAccess();
va.setVariable(references
.getVariableReference((VariableBinding) qualifiedNameReference.binding));
va.setType(va.getVariable().getType());
if (qualifiedNameReference.otherBindings != null) {
for (FieldBinding b : qualifiedNameReference.otherBindings) {
CtFieldAccess fa = factory.Core()
.createFieldAccess();
fa.setTarget(va);
CtVariableReference varRef = references
.getVariableReference(b);
if (varRef != null) {
fa.setVariable(varRef);
}
fa.setType(references
.getTypeReference(b.type));
va.setParent(fa);
va = fa;
}
}
context.enter(va, qualifiedNameReference);
return false;
}
return false;
}
@Override
public boolean visit(QualifiedThisReference qualifiedThisReference,
BlockScope scope) {
return visit((ThisReference) qualifiedThisReference, scope);
}
@Override
public boolean visit(QualifiedTypeReference arg0, BlockScope arg1) {
if (skipTypeInAnnotation) {
return true;
}
CtLiteral> l = factory.Core().createLiteral();
l.setValue(references.getTypeReference(arg0.resolvedType));
context.enter(l, arg0);
return true; // do nothing by default, keep traversing
}
@Override
public boolean visit(ReturnStatement returnStatement, BlockScope scope) {
CtReturn> ret = factory.Core().createReturn();
context.enter(ret, returnStatement);
return true;
}
boolean skipTypeInAnnotation = false;
@Override
public boolean visit(SingleMemberAnnotation annotation, BlockScope scope) {
return visitSingleMemberAnnotation(annotation, scope);
}
private boolean visitSingleMemberAnnotation(
SingleMemberAnnotation annotation, BlockScope scope) {
CtAnnotation a = factory.Core().createAnnotation();
CtTypeReference r = references
.getTypeReference(annotation.resolvedType);
a.setAnnotationType(r);
context.enter(a, annotation);
context.annotationValueName.push("value");
skipTypeInAnnotation = true;
return true;
}
@Override
public boolean visit(SingleNameReference singleNameReference,
BlockScope scope) {
CtVariableAccess va = null;
if (singleNameReference.binding instanceof FieldBinding) {
va = factory.Core().createFieldAccess();
va.setVariable(references.getVariableReference(singleNameReference
.fieldBinding()));
} else if (singleNameReference.binding instanceof VariableBinding) {
va = factory.Core().createVariableAccess();
va.setVariable(references
.getVariableReference((VariableBinding) singleNameReference.binding));
}
if (va != null)
context.enter(va, singleNameReference);
return true;
}
@Override
public boolean visit(QualifiedSuperReference qualifiedSuperReference,
BlockScope scope) {
if (skipTypeInAnnotation) {
return true;
}
CtLiteral> l = factory.Core().createLiteral();
CtTypeReference> withoutSuper = references
.getTypeReference(qualifiedSuperReference.qualification.resolvedType);
withoutSuper.setSuperReference(true);
l.setValue(withoutSuper);
context.enter(l, qualifiedSuperReference);
return false;
}
@Override
public boolean visit(SingleTypeReference singleTypeReference,
BlockScope scope) {
if (skipTypeInAnnotation) {
return true;
}
// if(context.annotationValueName.peek().equals("value")) return true;
CtLiteral> l = factory.Core().createLiteral();
l.setValue(references
.getTypeReference(singleTypeReference.resolvedType));
context.enter(l, singleTypeReference);
return true; // do nothing by default, keep traversing
}
@Override
public boolean visit(SingleTypeReference singleTypeReference,
ClassScope scope) {
CtLiteral> l = factory.Core().createLiteral();
l.setValue(references
.getTypeReference(singleTypeReference.resolvedType));
context.enter(l, singleTypeReference);
return true; // do nothing by default, keep traversing
}
@Override
public boolean visit(StringLiteral stringLiteral, BlockScope scope) {
CtLiteral s = factory.Core().createLiteral();
// references.getTypeReference(stringLiteral.resolvedType) can be null
s.setType(factory.Type().createReference(String.class));
// there are two methods in JDT: source() and toString()
// source() seems better but actually does not return the real source
// (for instance \n are not \n but newline)
// toString seems better (see StringLiteralTest)
// here there is a contract between JDTTreeBuilder and
// DefaultJavaPrettyPrinter:
// JDTTreeBuilder si responsible for adding the double quotes
// s.setValue(new String(stringLiteral.toString()));
// RP: this is not a good idea but many other usages of the value can be
// done (appart from the pretty printer). So I moved back the
// responsability of pretty printing the string inside the pretty
// printer (i.e. where it belongs)
s.setValue(new String(stringLiteral.source()));
context.enter(s, stringLiteral);
return true;
}
@Override
public boolean visit(StringLiteralConcatenation literal, BlockScope scope) {
CtBinaryOperator op = factory.Core().createBinaryOperator();
op.setKind(BinaryOperatorKind.PLUS);
context.enter(op, literal);
List exp = new ArrayList();
for (int i = 0; i < literal.counter; i++)
exp.add(literal.literals[i]);
createExpression(literal, scope, exp);
return false;
}
@Override
public boolean visit(SuperReference superReference, BlockScope scope) {
CtFieldReference fr = factory.Core().createFieldReference();
CtTypeReference ref = references
.getTypeReference(superReference.resolvedType);
fr.setSimpleName("super");
fr.setDeclaringType(ref);
fr.setType(ref);
CtSuperAccess fa = factory.Core().createSuperAccess();
fa.setVariable(fr);
context.enter(fa, superReference);
return super.visit(superReference, scope);
}
@Override
public boolean visit(SwitchStatement switchStatement, BlockScope scope) {
CtSwitch> s = factory.Core().createSwitch();
context.enter(s, switchStatement);
switchStatement.expression.traverse(this, switchStatement.scope);
if (switchStatement.statements != null) {
int statementsLength = switchStatement.statements.length;
for (int i = 0; i < statementsLength; i++) {
if (switchStatement.statements[i] instanceof CaseStatement) {
if (context.stack.peek().element instanceof CtCase) {
context.exit(context.stack.peek().node);
}
CaseStatement cas = (CaseStatement) switchStatement.statements[i];
visit(cas, switchStatement.scope);
} else {
switchStatement.statements[i].traverse(this,
switchStatement.scope);
}
}
if (context.stack.peek().element instanceof CtCase) {
context.exit(context.stack.peek().node);
}
}
return false;
}
@Override
public boolean visit(SynchronizedStatement synchronizedStatement,
BlockScope scope) {
CtSynchronized s = factory.Core().createSynchronized();
context.enter(s, synchronizedStatement);
return super.visit(synchronizedStatement, scope);
}
@Override
public boolean visit(ThisReference thisReference, BlockScope scope) {
CtThisAccess fa = factory.Core().createThisAccess();
fa.setImplicit(thisReference.isImplicitThis());
if (thisReference instanceof QualifiedThisReference) {
fa.setQualified(true);
}
CtTypeReference typeref = references
.getTypeReference(thisReference.resolvedType);
fa.setType(typeref);
context.enter(fa, thisReference);
return true;
}
@Override
public boolean visit(ThrowStatement throwStatement, BlockScope scope) {
CtThrow t = factory.Core().createThrow();
context.enter(t, throwStatement);
return true;
}
@Override
public boolean visit(TrueLiteral trueLiteral, BlockScope scope) {
CtLiteral l = factory.Core().createLiteral();
l.setValue(true);
context.enter(l, trueLiteral);
return true;
}
@Override
public boolean visit(TryStatement tryStatement, BlockScope scope) {
CtTry t = factory.Core().createTry();
context.enter(t, tryStatement);
for (LocalDeclaration localDeclaration : tryStatement.resources) {
localDeclaration.traverse(this, scope);
}
tryStatement.tryBlock.traverse(this, scope);
if (tryStatement.catchArguments != null) {
for (int i = 0; i < tryStatement.catchArguments.length; i++) {
// the jdt catch
Argument jdtCatch = tryStatement.catchArguments[i];
// case 1: old catch
if (jdtCatch.type instanceof SingleTypeReference
|| jdtCatch.type instanceof QualifiedTypeReference
) {
CtTypeReference r = references
.getTypeReference(jdtCatch.type.resolvedType);
CtCatch c = createCtCatch(jdtCatch, r);
tryStatement.catchBlocks[i].traverse(this, scope);
context.exit(jdtCatch);
}
// case 2: Java 7 multiple catch blocks
else if (jdtCatch.type instanceof UnionTypeReference) {
UnionTypeReference utr = (UnionTypeReference)jdtCatch.type;
for (TypeReference type : utr.typeReferences) {
CtTypeReference r = references
.getTypeReference(type.resolvedType);
CtCatch c = createCtCatch(jdtCatch, r);
tryStatement.catchBlocks[i].traverse(this, scope);
context.exit(jdtCatch);
}
}
else {
throw new RuntimeException("I don't know how to do this");
}
}
}
if (tryStatement.finallyBlock != null) {
context.finallyzer.push(t);
tryStatement.finallyBlock.traverse(this, scope);
context.finallyzer.pop();
}
return false;
}
private CtCatch createCtCatch(Argument jdtCatch, CtTypeReference r) {
CtCatch c = factory.Core().createCatch();
CtLocalVariable var = factory.Core()
.createLocalVariable();
context.enter(c, jdtCatch);
context.enter(var, jdtCatch);
var.setSimpleName(new String(
jdtCatch.name));
var.setType(r);
for (ModifierKind modifier : getModifiers(jdtCatch.modifiers)) {
var.addModifier(modifier);
}
context.exit(jdtCatch);
return c;
}
@Override
public boolean visit(TypeDeclaration localTypeDeclaration, BlockScope scope) {
CtSimpleType> t = createType(localTypeDeclaration);
t.setDocComment(getJavaDoc(localTypeDeclaration.javadoc,
scope.referenceCompilationUnit()));
context.enter(t, localTypeDeclaration);
// AST bug HACK (see TypeDeclaration.traverse)
if (localTypeDeclaration.fields != null) {
int length = localTypeDeclaration.fields.length;
for (int i = 0; i < length; i++) {
FieldDeclaration field;
if ((field = localTypeDeclaration.fields[i]).isStatic()) {
// local type actually can have static fields
field.traverse(this, localTypeDeclaration.initializerScope);
}
}
}
return true;
}
@Override
public boolean visit(TypeDeclaration memberTypeDeclaration, ClassScope scope) {
CtSimpleType> type = createType(memberTypeDeclaration);
type.setDocComment(getJavaDoc(memberTypeDeclaration.javadoc,
scope.referenceCompilationUnit()));
context.enter(type, memberTypeDeclaration);
// AST bug HACK
if (memberTypeDeclaration.annotations != null)
for (Annotation a : memberTypeDeclaration.annotations) {
a.traverse(this, (BlockScope) null);
}
return true;
}
@Override
public boolean visit(TypeDeclaration typeDeclaration,
CompilationUnitScope scope) {
if (new String(typeDeclaration.name).equals("package-info")) {
CtPackage pack = factory.Package()
.getOrCreate(
new String(typeDeclaration.binding.fPackage
.readableName()));
context.enter(pack, typeDeclaration);
// AST bug HACK
if (typeDeclaration.annotations != null)
for (Annotation a : typeDeclaration.annotations) {
a.traverse(this, (BlockScope) null);
}
return true;
} else {
CtSimpleType> type = createType(typeDeclaration);
type.setDocComment(getJavaDoc(typeDeclaration.javadoc,
scope.referenceContext));
CtPackage pack = null;
if (typeDeclaration.binding.fPackage.shortReadableName() != null
&& typeDeclaration.binding.fPackage.shortReadableName().length > 0) {
pack = factory.Package().getOrCreate(
new String(typeDeclaration.binding.fPackage
.shortReadableName()));
} else {
pack = factory.Package().getOrCreate(
CtPackage.TOP_LEVEL_PACKAGE_NAME);
}
context.enter(pack, typeDeclaration);
context.compilationunitdeclaration = scope.referenceContext;
context.enter(type, typeDeclaration);
// AST bug HACK
if (typeDeclaration.annotations != null)
for (Annotation a : typeDeclaration.annotations) {
a.traverse(this, (BlockScope) null);
}
if (typeDeclaration.memberTypes != null) {
int length = typeDeclaration.memberTypes.length;
for (int i = 0; i < length; i++)
typeDeclaration.memberTypes[i].traverse(this,
typeDeclaration.scope);
}
if (typeDeclaration.fields != null) {
int length = typeDeclaration.fields.length;
for (int i = 0; i < length; i++) {
FieldDeclaration field;
if ((field = typeDeclaration.fields[i]).isStatic()) {
field.traverse(this,
typeDeclaration.staticInitializerScope);
} else {
field.traverse(this, typeDeclaration.initializerScope);
}
}
}
if (typeDeclaration.methods != null) {
int length = typeDeclaration.methods.length;
for (int i = 0; i < length; i++)
typeDeclaration.methods[i].traverse(this,
typeDeclaration.scope);
}
return false;
}
}
@Override
public boolean visit(UnaryExpression unaryExpression, BlockScope scope) {
CtUnaryOperator> op = factory.Core().createUnaryOperator();
op.setKind(getUnaryOperator((unaryExpression.bits & ASTNode.OperatorMASK) >> ASTNode.OperatorSHIFT));
context.enter(op, unaryExpression);
return true;
}
@Override
public boolean visit(WhileStatement whileStatement, BlockScope scope) {
CtWhile w = factory.Core().createWhile();
context.enter(w, whileStatement);
return true;
}
}