/** * Copyright (C) 2006-2017 INRIA and contributors * Spoon - http://spoon.gforge.inria.fr/ * * 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 static spoon.support.compiler.jdt.JDTTreeBuilderQuery.getBinaryOperatorKind; import static spoon.support.compiler.jdt.JDTTreeBuilderQuery.getModifiers; import static spoon.support.compiler.jdt.JDTTreeBuilderQuery.getUnaryOperator; import static spoon.support.compiler.jdt.JDTTreeBuilderQuery.isLhsAssignment; import java.util.Collections; import org.apache.log4j.Logger; import org.eclipse.jdt.core.compiler.CharOperation; 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.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.ArrayQualifiedTypeReference; 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.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.LambdaExpression; 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.ReferenceExpression; 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.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.classfmt.ClassFileConstants; import org.eclipse.jdt.internal.compiler.lookup.BlockScope; 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.MethodBinding; import org.eclipse.jdt.internal.compiler.lookup.MethodScope; import org.eclipse.jdt.internal.compiler.lookup.ProblemBinding; import org.eclipse.jdt.internal.compiler.lookup.ProblemMethodBinding; import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; import org.eclipse.jdt.internal.compiler.lookup.Scope; import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; import org.eclipse.jdt.internal.compiler.lookup.VariableBinding; import spoon.SpoonException; import spoon.reflect.code.BinaryOperatorKind; import spoon.reflect.code.CtArrayAccess; import spoon.reflect.code.CtBinaryOperator; import spoon.reflect.code.CtBreak; import spoon.reflect.code.CtCatch; import spoon.reflect.code.CtConstructorCall; import spoon.reflect.code.CtContinue; import spoon.reflect.code.CtExpression; import spoon.reflect.code.CtInvocation; import spoon.reflect.code.CtLambda; import spoon.reflect.code.CtLiteral; import spoon.reflect.code.CtLocalVariable; import spoon.reflect.code.CtOperatorAssignment; import spoon.reflect.code.CtTry; import spoon.reflect.code.CtTypeAccess; import spoon.reflect.code.CtUnaryOperator; import spoon.reflect.code.UnaryOperatorKind; import spoon.reflect.declaration.CtAnnotationMethod; import spoon.reflect.declaration.CtAnonymousExecutable; import spoon.reflect.declaration.CtClass; import spoon.reflect.declaration.CtConstructor; import spoon.reflect.declaration.CtField; import spoon.reflect.declaration.CtMethod; import spoon.reflect.declaration.CtPackage; import spoon.reflect.declaration.CtType; import spoon.reflect.declaration.CtTypeParameter; import spoon.reflect.declaration.ModifierKind; import spoon.reflect.factory.Factory; import spoon.reflect.reference.CtArrayTypeReference; import spoon.reflect.reference.CtTypeReference; import spoon.reflect.reference.CtUnboundVariableReference; import spoon.support.comparator.CtLineElementComparator; /** * A visitor for iterating through the parse tree. */ public class JDTTreeBuilder extends ASTVisitor { private final PositionBuilder position; private final ContextBuilder context; private final ParentExiter exiter; final ReferenceBuilder references; private final JDTTreeBuilderHelper helper; private final Factory factory; boolean skipTypeInAnnotation = false; public static Logger getLogger() { return LOGGER; } private static final Logger LOGGER = Logger.getLogger(JDTTreeBuilder.class); public PositionBuilder getPositionBuilder() { return position; } public ContextBuilder getContextBuilder() { return context; } public ReferenceBuilder getReferencesBuilder() { return references; } public JDTTreeBuilderHelper getHelper() { return helper; } public ParentExiter getExiter() { return exiter; } public Factory getFactory() { return factory; } public JDTTreeBuilder(Factory factory) { super(); this.factory = factory; this.position = new PositionBuilder(this); this.context = new ContextBuilder(this); this.exiter = new ParentExiter(this); this.references = new ReferenceBuilder(this); this.helper = new JDTTreeBuilderHelper(this); LOGGER.setLevel(factory.getEnvironment().getLevel()); } interface OnAccessListener { boolean onAccess(char[][] tokens, int index); } class SpoonReferenceBinding extends ReferenceBinding { private ReferenceBinding enclosingType; SpoonReferenceBinding(char[] sourceName, ReferenceBinding enclosingType) { this.sourceName = sourceName; this.enclosingType = enclosingType; } @Override public ReferenceBinding enclosingType() { return enclosingType; } } @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(ArrayTypeReference arrayTypeReference, ClassScope scope) { context.exit(arrayTypeReference); } @Override public void endVisit(ArrayQualifiedTypeReference arrayQualifiedTypeReference, BlockScope scope) { context.exit(arrayQualifiedTypeReference); } @Override public void endVisit(ArrayQualifiedTypeReference arrayQualifiedTypeReference, ClassScope scope) { context.exit(arrayQualifiedTypeReference); } @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) { } @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); } @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(NormalAnnotation annotation, ClassScope scope) { context.exit(annotation); skipTypeInAnnotation = false; } @Override public void endVisit(MarkerAnnotation annotation, ClassScope scope) { context.exit(annotation); skipTypeInAnnotation = false; } @Override public void endVisit(MarkerAnnotation annotation, BlockScope scope) { context.exit(annotation); skipTypeInAnnotation = false; } @Override public void endVisit(MemberValuePair pair, ClassScope scope) { if (!context.annotationValueName.pop().equals(new String(pair.name))) { throw new RuntimeException("Unconsistant Stack"); } } @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); } @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(ParameterizedQualifiedTypeReference parameterizedQualifiedTypeReference, BlockScope 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 qualifiedTypeReference, BlockScope scope) { if (skipTypeInAnnotation) { skipTypeInAnnotation = false; return; } context.exit(qualifiedTypeReference); } @Override public void endVisit(QualifiedTypeReference qualifiedTypeReference, ClassScope scope) { endVisit(qualifiedTypeReference, (BlockScope) null); } @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) { if (skipTypeInAnnotation) { skipTypeInAnnotation = false; return; } 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(QualifiedThisReference qualifiedThisReference, ClassScope scope) { super.endVisit(qualifiedThisReference, scope); context.exit(qualifiedThisReference); } @Override public void endVisit(ThisReference thisReference, BlockScope scope) { context.exit(thisReference); } @Override public void endVisit(SwitchStatement switchStatement, BlockScope scope) { if (context.stack.peek().node instanceof CaseStatement) { context.exit(context.stack.peek().node); } context.exit(switchStatement); } @Override public void endVisit(SynchronizedStatement synchronizedStatement, BlockScope scope) { context.exit(synchronizedStatement); } @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(TypeParameter typeParameter, BlockScope scope) { context.exit(typeParameter); } @Override public void endVisit(TypeParameter typeParameter, ClassScope scope) { context.exit(typeParameter); } @Override public void endVisit(TypeDeclaration localTypeDeclaration, BlockScope scope) { Collections.sort(((CtType) context.stack.peek().element).getTypeMembers(), new CtLineElementComparator()); context.exit(localTypeDeclaration); } @Override public void endVisit(TypeDeclaration memberTypeDeclaration, ClassScope scope) { while (!context.stack.isEmpty() && context.stack.peek().node == memberTypeDeclaration) { Collections.sort(((CtType) context.stack.peek().element).getTypeMembers(), new CtLineElementComparator()); context.exit(memberTypeDeclaration); } } @Override public void endVisit(TypeDeclaration typeDeclaration, CompilationUnitScope scope) { while (!context.stack.isEmpty() && context.stack.peek().node == typeDeclaration) { if (context.stack.peek().element instanceof CtType) { Collections.sort(((CtType) context.stack.peek().element).getTypeMembers(), new CtLineElementComparator()); } context.exit(typeDeclaration); } } @Override public void endVisit(UnaryExpression unaryExpression, BlockScope scope) { context.exit(unaryExpression); } @Override public void endVisit(WhileStatement whileStatement, BlockScope scope) { context.exit(whileStatement); } @Override public void endVisit(CompilationUnitDeclaration compilationUnitDeclaration, CompilationUnitScope scope) { context.compilationunitdeclaration = null; context.compilationUnitSpoon = null; } @Override public boolean visit(Javadoc javadoc, BlockScope scope) { // Use a custom compiler. return false; } @Override public boolean visit(Javadoc javadoc, ClassScope scope) { // Use a custom compiler. return false; } @Override public boolean visit(CompilationUnitDeclaration compilationUnitDeclaration, CompilationUnitScope scope) { context.compilationunitdeclaration = scope.referenceContext; context.compilationUnitSpoon = getFactory().CompilationUnit().create(new String(context.compilationunitdeclaration.getFileName())); context.compilationUnitSpoon.setDeclaredPackage(getFactory().Package().getOrCreate(CharOperation.toString(scope.currentPackageName))); return true; } @Override public boolean visit(ReferenceExpression referenceExpression, BlockScope blockScope) { context.enter(helper.createExecutableReferenceExpression(referenceExpression), referenceExpression); return true; } @Override public void endVisit(ReferenceExpression referenceExpression, BlockScope blockScope) { context.exit(referenceExpression); } @Override public boolean visit(LambdaExpression lambdaExpression, BlockScope blockScope) { CtLambda<?> lambda = factory.Core().createLambda(); final MethodBinding methodBinding = lambdaExpression.getMethodBinding(); if (methodBinding != null) { lambda.setSimpleName(CharOperation.charToString(methodBinding.constantPoolName())); } context.isBuildLambda = true; context.enter(lambda, lambdaExpression); return true; } @Override public void endVisit(LambdaExpression lambdaExpression, BlockScope blockScope) { context.isBuildLambda = false; context.exit(lambdaExpression); } @Override public boolean visit(AllocationExpression allocationExpression, BlockScope scope) { CtConstructorCall constructorCall = factory.Core().createConstructorCall(); constructorCall.setExecutable(references.getExecutableReference(allocationExpression)); context.enter(constructorCall, allocationExpression); return true; } @Override public boolean visit(QualifiedAllocationExpression qualifiedAllocationExpression, BlockScope scope) { CtConstructorCall constructorCall; if (qualifiedAllocationExpression.anonymousType != null) { constructorCall = factory.Core().createNewClass(); } else { constructorCall = factory.Core().createConstructorCall(); } constructorCall.setExecutable(references.getExecutableReference(qualifiedAllocationExpression)); context.enter(constructorCall, qualifiedAllocationExpression); return true; } @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; } @Override public boolean visit(AnnotationMethodDeclaration annotationTypeDeclaration, ClassScope classScope) { CtAnnotationMethod<Object> ctAnnotationMethod = factory.Core().createAnnotationMethod(); ctAnnotationMethod.setSimpleName(CharOperation.charToString(annotationTypeDeclaration.selector)); context.enter(ctAnnotationMethod, annotationTypeDeclaration); return true; } @Override public boolean visit(Argument argument, BlockScope scope) { if (this.getContextBuilder().stack.peekFirst().element instanceof CtTry) { context.enter(factory.Core().createCatch(), argument); return true; } context.enter(helper.createParameter(argument), argument); return true; } @Override public boolean visit(ArrayAllocationExpression arrayAllocationExpression, BlockScope scope) { context.enter(factory.Core().createNewArray(), arrayAllocationExpression); return true; } @Override public boolean visit(ArrayInitializer arrayInitializer, BlockScope scope) { context.enter(factory.Core().createNewArray(), arrayInitializer); return true; } @Override public boolean visit(ArrayReference arrayReference, BlockScope scope) { CtArrayAccess<?, ?> a; if (isLhsAssignment(context, arrayReference)) { a = factory.Core().createArrayWrite(); } else { a = factory.Core().createArrayRead(); } context.enter(a, arrayReference); return true; } @Override public boolean visit(ArrayTypeReference arrayTypeReference, BlockScope scope) { final CtTypeAccess<Object> typeAccess = factory.Code().createTypeAccess(references.buildTypeReference(arrayTypeReference, scope)); if (typeAccess.getAccessedType() instanceof CtArrayTypeReference) { ((CtArrayTypeReference) typeAccess.getAccessedType()).getArrayType().setAnnotations(this.references.buildTypeReference(arrayTypeReference, scope).getAnnotations()); } context.enter(typeAccess, arrayTypeReference); return true; } @Override public boolean visit(ArrayTypeReference arrayTypeReference, ClassScope scope) { return visit(arrayTypeReference, (BlockScope) null); } @Override public boolean visit(ArrayQualifiedTypeReference arrayQualifiedTypeReference, BlockScope scope) { final CtTypeAccess<Object> typeAccess = factory.Core().createTypeAccess(); context.enter(typeAccess, arrayQualifiedTypeReference); final CtArrayTypeReference<Object> arrayType = (CtArrayTypeReference<Object>) references.getTypeReference(arrayQualifiedTypeReference.resolvedType); arrayType.getArrayType().setAnnotations(this.references.buildTypeReference(arrayQualifiedTypeReference, scope).getAnnotations()); typeAccess.setAccessedType(arrayType); return true; } @Override public boolean visit(ArrayQualifiedTypeReference arrayQualifiedTypeReference, ClassScope scope) { return visit(arrayQualifiedTypeReference, (BlockScope) null); } @Override public boolean visit(AssertStatement assertStatement, BlockScope scope) { context.enter(factory.Core().createAssert(), assertStatement); return true; } @Override public boolean visit(Assignment assignment, BlockScope scope) { context.enter(factory.Core().createAssignment(), assignment); return true; } @Override public boolean visit(CompoundAssignment compoundAssignment, BlockScope scope) { CtOperatorAssignment<Object, Object> a = factory.Core().createOperatorAssignment(); a.setKind(getBinaryOperatorKind(compoundAssignment.operator)); context.enter(a, compoundAssignment); 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) { context.enter(factory.Core().createBlock(), 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(CastExpression castExpression, BlockScope scope) { context.casts.add(this.references.buildTypeReference(castExpression.type, scope)); castExpression.expression.traverse(this, scope); return false; } @Override public boolean visit(CharLiteral charLiteral, BlockScope scope) { charLiteral.computeConstant(); context.enter(factory.Code().createLiteral(charLiteral.constant.charValue()), charLiteral); return true; } @Override public boolean visit(ClassLiteralAccess classLiteral, BlockScope scope) { context.enter(factory.Code().createClassAccess(references.getTypeReference(classLiteral.targetType)), classLiteral); return false; } @Override public boolean visit(ConditionalExpression conditionalExpression, BlockScope scope) { context.enter(factory.Core().createConditional(), conditionalExpression); return true; } @Override public boolean visit(MethodDeclaration methodDeclaration, ClassScope scope) { CtMethod<Object> m = factory.Core().createMethod(); m.setSimpleName(CharOperation.charToString(methodDeclaration.selector)); m.setModifiers(getModifiers(methodDeclaration.modifiers)); m.setDefaultMethod(methodDeclaration.isDefaultMethod()); context.enter(m, methodDeclaration); // Create block if (!methodDeclaration.isAbstract() && (methodDeclaration.modifiers & ClassFileConstants.AccNative) == 0) { context.enter(getFactory().Core().createBlock(), methodDeclaration); context.exit(methodDeclaration); } return true; } @Override public boolean visit(ConstructorDeclaration constructorDeclaration, ClassScope scope) { CtConstructor<Object> c = factory.Core().createConstructor(); c.setModifiers(getModifiers(constructorDeclaration.modifiers)); context.enter(c, constructorDeclaration); // Create block context.enter(factory.Core().createBlock(), constructorDeclaration); context.exit(constructorDeclaration); return true; } @Override public boolean visit(TypeParameter typeParameter, ClassScope scope) { return visitTypeParameter(typeParameter, scope); } @Override public boolean visit(TypeParameter typeParameter, BlockScope scope) { return visitTypeParameter(typeParameter, scope); } private boolean visitTypeParameter(TypeParameter typeParameter, Scope scope) { final CtTypeParameter typeParameterRef = factory.Core().createTypeParameter(); typeParameterRef.setSimpleName(CharOperation.charToString(typeParameter.name)); context.enter(typeParameterRef, typeParameter); return true; } @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) { context.enter(factory.Core().createDo(), doStatement); return true; } @Override public boolean visit(DoubleLiteral doubleLiteral, BlockScope scope) { doubleLiteral.computeConstant(); context.enter(factory.Code().createLiteral(doubleLiteral.constant.doubleValue()), 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 } @Override public boolean visit(ExplicitConstructorCall explicitConstructor, BlockScope scope) { CtInvocation<Object> inv = factory.Core().createInvocation(); inv.setImplicit(explicitConstructor.isImplicitSuper()); inv.setExecutable(references.getExecutableReference(explicitConstructor.binding)); inv.getExecutable().setType((CtTypeReference<Object>) inv.getExecutable().getDeclaringType()); context.enter(inv, explicitConstructor); return true; } @Override public boolean visit(ExtendedStringLiteral extendedStringLiteral, BlockScope scope) { context.enter(factory.Code().createLiteral(CharOperation.charToString(extendedStringLiteral.source())), extendedStringLiteral); return true; } @Override public boolean visit(FalseLiteral falseLiteral, BlockScope scope) { context.enter(factory.Code().createLiteral(false), falseLiteral); return true; } @Override public boolean visit(FieldDeclaration fieldDeclaration, MethodScope scope) { CtField<Object> field; if (fieldDeclaration.type != null) { field = factory.Core().createField(); } else { field = factory.Core().createEnumValue(); if (fieldDeclaration.binding != null) { field.setType(references.getTypeReference(fieldDeclaration.binding.type)); } } field.setSimpleName(CharOperation.charToString(fieldDeclaration.name)); field.setModifiers(getModifiers(fieldDeclaration.modifiers)); context.enter(field, fieldDeclaration); return true; } @Override public boolean visit(FieldReference fieldReference, BlockScope scope) { context.enter(helper.createFieldAccess(fieldReference), fieldReference); return true; } @Override public boolean visit(FloatLiteral floatLiteral, BlockScope scope) { floatLiteral.computeConstant(); context.enter(factory.Code().createLiteral(floatLiteral.constant.floatValue()), floatLiteral); return true; } @Override public boolean visit(ForeachStatement forStatement, BlockScope scope) { context.enter(factory.Core().createForEach(), forStatement); return true; } @Override public boolean visit(ForStatement forStatement, BlockScope scope) { context.enter(factory.Core().createFor(), forStatement); return true; } @Override public boolean visit(IfStatement ifStatement, BlockScope scope) { context.enter(factory.Core().createIf(), ifStatement); return true; } @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); context.enter(op, instanceOfExpression); return true; } @Override public boolean visit(IntLiteral intLiteral, BlockScope scope) { intLiteral.computeConstant(); CtLiteral<Integer> l = factory.Code().createLiteral(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<Object> v = factory.Core().createLocalVariable(); v.setSimpleName(CharOperation.charToString(localDeclaration.name)); v.setModifiers(getModifiers(localDeclaration.modifiers)); context.enter(v, localDeclaration); return true; } @Override public boolean visit(LongLiteral longLiteral, BlockScope scope) { longLiteral.computeConstant(); context.enter(factory.Code().createLiteral(longLiteral.constant.longValue()), longLiteral); return true; } @Override public boolean visit(NormalAnnotation annotation, ClassScope scope) { return visitNormalAnnotation(annotation, scope); } @Override public boolean visit(NormalAnnotation annotation, BlockScope scope) { return visitNormalAnnotation(annotation, scope); } @Override public boolean visit(MarkerAnnotation annotation, ClassScope scope) { return visitMarkerAnnotation(annotation, scope); } @Override public boolean visit(MarkerAnnotation annotation, BlockScope scope) { return visitMarkerAnnotation(annotation, scope); } @Override public boolean visit(SingleMemberAnnotation annotation, BlockScope scope) { visitMarkerAnnotation(annotation, scope); context.annotationValueName.push("value"); return true; } private <A extends java.lang.annotation.Annotation> boolean visitNormalAnnotation(NormalAnnotation annotation, Scope scope) { context.enter(factory.Code().createAnnotation(references.<A>getTypeReference(annotation.resolvedType)), annotation); skipTypeInAnnotation = true; return true; } private <A extends java.lang.annotation.Annotation> boolean visitMarkerAnnotation(Annotation annotation, Scope scope) { context.enter(factory.Code().createAnnotation(references.<A>getTypeReference(annotation.resolvedType, annotation.type)), annotation); skipTypeInAnnotation = true; return true; } @Override public boolean visit(MemberValuePair pair, ClassScope scope) { context.annotationValueName.push(new String(pair.name)); 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) { CtInvocation<Object> inv = factory.Core().createInvocation(); inv.setExecutable(references.getExecutableReference(messageSend)); if (messageSend.binding instanceof ProblemMethodBinding) { // We are in a static complex in noclasspath mode. if (inv.getExecutable() != null && inv.getExecutable().getDeclaringType() != null) { inv.setTarget(factory.Code().createTypeAccess(inv.getExecutable().getDeclaringType(), inv.getExecutable().getDeclaringType().isAnonymous())); } if (messageSend.expectedType() != null) { inv.getExecutable().setType(references.getTypeReference(messageSend.expectedType())); } } context.enter(inv, messageSend); return true; } @Override public boolean visit(NullLiteral nullLiteral, BlockScope scope) { context.enter(factory.Code().createLiteral(null), 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, BlockScope scope) { return createParameterizedType(parameterizedQualifiedTypeReference); } @Override public boolean visit(ParameterizedQualifiedTypeReference parameterizedQualifiedTypeReference, ClassScope scope) { return createParameterizedType(parameterizedQualifiedTypeReference); } @Override public boolean visit(ParameterizedSingleTypeReference parameterizedSingleTypeReference, BlockScope scope) { return createParameterizedType(parameterizedSingleTypeReference); } @Override public boolean visit(ParameterizedSingleTypeReference parameterizedSingleTypeReference, ClassScope scope) { return createParameterizedType(parameterizedSingleTypeReference); } private boolean createParameterizedType(TypeReference parameterizedTypeReference) { if (skipTypeInAnnotation) { return true; } context.enter(factory.Code().createTypeAccessWithoutCloningReference(references.buildTypeReference(parameterizedTypeReference, null)), parameterizedTypeReference); return true; } @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(QualifiedNameReference qualifiedNameRef, BlockScope scope) { if (qualifiedNameRef.binding instanceof FieldBinding || qualifiedNameRef.binding instanceof VariableBinding) { context.enter(helper.createVariableAccess(qualifiedNameRef), qualifiedNameRef); return true; } else if (qualifiedNameRef.binding instanceof TypeBinding) { context.enter(factory.Code().createTypeAccessWithoutCloningReference(references.getTypeReference((TypeBinding) qualifiedNameRef.binding)), qualifiedNameRef); return true; } else if (qualifiedNameRef.binding instanceof ProblemBinding) { if (context.stack.peek().element instanceof CtInvocation) { context.enter(helper.createTypeAccessNoClasspath(qualifiedNameRef), qualifiedNameRef); return true; } context.enter(helper.createFieldAccessNoClasspath(qualifiedNameRef), qualifiedNameRef); return true; } else { context.enter( helper.createVariableAccess( factory.Core().createUnboundVariableReference().<CtUnboundVariableReference>setSimpleName(qualifiedNameRef.toString()), isLhsAssignment(context, qualifiedNameRef)), qualifiedNameRef ); return true; } } @Override public boolean visit(QualifiedTypeReference qualifiedTypeReference, BlockScope scope) { if (skipTypeInAnnotation) { return true; } if (context.stack.peekFirst().node instanceof UnionTypeReference) { context.enter(references.<Throwable>getTypeReference(qualifiedTypeReference.resolvedType), qualifiedTypeReference); return true; } else if (context.stack.peekFirst().element instanceof CtCatch) { context.enter(helper.createCatchVariable(qualifiedTypeReference), qualifiedTypeReference); return true; } context.enter(factory.Code().createTypeAccessWithoutCloningReference(references.buildTypeReference(qualifiedTypeReference, scope)), qualifiedTypeReference); return true; } @Override public boolean visit(QualifiedTypeReference qualifiedTypeReference, ClassScope scope) { return visit(qualifiedTypeReference, (BlockScope) null); } @Override public boolean visit(ReturnStatement returnStatement, BlockScope scope) { context.enter(factory.Core().createReturn(), returnStatement); return true; } @Override public boolean visit(SingleNameReference singleNameReference, BlockScope scope) { if (singleNameReference.binding instanceof FieldBinding) { context.enter(helper.createFieldAccess(singleNameReference), singleNameReference); } else if (singleNameReference.binding instanceof VariableBinding) { context.enter(helper.createVariableAccess(singleNameReference), singleNameReference); } else if (singleNameReference.binding instanceof TypeBinding) { context.enter(factory.Code().createTypeAccessWithoutCloningReference(references.getTypeReference((TypeBinding) singleNameReference.binding)), singleNameReference); } else if (singleNameReference.binding instanceof ProblemBinding) { if (context.stack.peek().element instanceof CtInvocation && Character.isUpperCase(CharOperation.charToString(singleNameReference.token).charAt(0))) { context.enter(helper.createTypeAccessNoClasspath(singleNameReference), singleNameReference); } else { context.enter(helper.createFieldAccessNoClasspath(singleNameReference), singleNameReference); } } else if (singleNameReference.binding == null) { CtExpression access = helper.createVariableAccessNoClasspath(singleNameReference); if (access == null) { access = helper.createTypeAccessNoClasspath(singleNameReference); } context.enter(access, singleNameReference); } return true; } @Override public boolean visit(QualifiedSuperReference qualifiedSuperReference, BlockScope scope) { if (skipTypeInAnnotation) { return true; } context.enter(factory.Core().createSuperAccess(), qualifiedSuperReference); return true; } @Override public boolean visit(SuperReference superReference, BlockScope scope) { context.enter(factory.Core().createSuperAccess(), superReference); return true; } @Override public boolean visit(QualifiedThisReference qualifiedThisRef, BlockScope scope) { context.enter(factory.Code().createThisAccess(references.getTypeReference(qualifiedThisRef.qualification.resolvedType), qualifiedThisRef.isImplicitThis()), qualifiedThisRef); return true; } @Override public boolean visit(ThisReference thisReference, BlockScope scope) { context.enter(factory.Code().createThisAccess(references.getTypeReference(thisReference.resolvedType), thisReference.isImplicitThis()), thisReference); return true; } @Override public void endVisit(UnionTypeReference unionTypeReference, BlockScope scope) { context.exit(unionTypeReference); } @Override public void endVisit(UnionTypeReference unionTypeReference, ClassScope scope) { endVisit(unionTypeReference, (BlockScope) null); } @Override public boolean visit(UnionTypeReference unionTypeReference, BlockScope scope) { if (!(context.stack.peekFirst().node instanceof Argument)) { throw new SpoonException("UnionType is only supported for CtCatch."); } context.enter(helper.createCatchVariable(unionTypeReference), unionTypeReference); return true; } @Override public boolean visit(UnionTypeReference unionTypeReference, ClassScope scope) { return visit(unionTypeReference, (BlockScope) null); } @Override public boolean visit(SingleTypeReference singleTypeReference, BlockScope scope) { if (skipTypeInAnnotation) { return true; } if (context.stack.peekFirst().node instanceof UnionTypeReference) { context.enter(references.<Throwable>getTypeReference(singleTypeReference.resolvedType), singleTypeReference); return true; } else if (context.stack.peekFirst().element instanceof CtCatch) { context.enter(helper.createCatchVariable(singleTypeReference), singleTypeReference); return true; } context.enter(factory.Code().createTypeAccessWithoutCloningReference(references.buildTypeReference(singleTypeReference, scope)), singleTypeReference); return true; } @Override public boolean visit(SingleTypeReference singleTypeReference, ClassScope scope) { return visit(singleTypeReference, (BlockScope) null); } @Override public boolean visit(StringLiteral stringLiteral, BlockScope scope) { context.enter(factory.Code().createLiteral(CharOperation.charToString(stringLiteral.source())), stringLiteral); return true; } @Override public boolean visit(StringLiteralConcatenation literal, BlockScope scope) { context.enter(factory.Core().createBinaryOperator().<CtBinaryOperator>setKind(BinaryOperatorKind.PLUS), literal); return true; } @Override public boolean visit(CaseStatement caseStatement, BlockScope scope) { if (context.stack.peek().node instanceof CaseStatement) { context.exit(context.stack.peek().node); } context.enter(factory.Core().createCase(), caseStatement); return true; } @Override public boolean visit(SwitchStatement switchStatement, BlockScope scope) { context.enter(factory.Core().createSwitch(), switchStatement); return true; } @Override public boolean visit(SynchronizedStatement synchronizedStatement, BlockScope scope) { context.enter(factory.Core().createSynchronized(), synchronizedStatement); return true; } @Override public boolean visit(ThrowStatement throwStatement, BlockScope scope) { context.enter(factory.Core().createThrow(), throwStatement); return true; } @Override public boolean visit(TrueLiteral trueLiteral, BlockScope scope) { context.enter(factory.Code().createLiteral(true), trueLiteral); return true; } @Override public boolean visit(TryStatement tryStatement, BlockScope scope) { CtTry t; if (tryStatement.resources.length > 0) { t = factory.Core().createTryWithResource(); } else { t = factory.Core().createTry(); } context.enter(t, tryStatement); return true; } @Override public boolean visit(TypeDeclaration localTypeDeclaration, BlockScope scope) { CtType<?> t; if (localTypeDeclaration.binding == null) { // no classpath mode but JDT returns nothing. We create an empty class. t = factory.Core().createClass(); t.setSimpleName(CtType.NAME_UNKNOWN); ((CtClass) t).setSuperclass(references.getTypeReference(null, localTypeDeclaration.allocation.type)); context.enter(t, localTypeDeclaration); } else { helper.createType(localTypeDeclaration); } return true; } @Override public boolean visit(TypeDeclaration memberTypeDeclaration, ClassScope scope) { helper.createType(memberTypeDeclaration); return true; } @Override public boolean visit(TypeDeclaration typeDeclaration, CompilationUnitScope scope) { if (new String(typeDeclaration.name).equals("package-info")) { context.enter(factory.Package().getOrCreate(new String(typeDeclaration.binding.fPackage.readableName())), typeDeclaration); return true; } else { CtPackage pack; 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().getRootPackage(); } context.enter(pack, typeDeclaration); pack.addType(helper.createType(typeDeclaration)); return true; } } @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) { context.enter(factory.Core().createWhile(), whileStatement); return true; } }