spoon.support.compiler.jdt.ParentExiter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of spoon-core Show documentation
Show all versions of spoon-core Show documentation
Spoon is a tool for meta-programming, analysis and transformation of Java programs.
The newest version!
package spoon.support.compiler.jdt;
import java.util.ArrayList;
import org.eclipse.jdt.internal.compiler.ast.QualifiedAllocationExpression;
import org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding;
import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
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.CtCase;
import spoon.reflect.code.CtCatch;
import spoon.reflect.code.CtCatchVariable;
import spoon.reflect.code.CtConditional;
import spoon.reflect.code.CtConstructorCall;
import spoon.reflect.code.CtDo;
import spoon.reflect.code.CtExecutableReferenceExpression;
import spoon.reflect.code.CtExpression;
import spoon.reflect.code.CtFor;
import spoon.reflect.code.CtForEach;
import spoon.reflect.code.CtIf;
import spoon.reflect.code.CtInvocation;
import spoon.reflect.code.CtLambda;
import spoon.reflect.code.CtLocalVariable;
import spoon.reflect.code.CtLoop;
import spoon.reflect.code.CtNewArray;
import spoon.reflect.code.CtNewClass;
import spoon.reflect.code.CtReturn;
import spoon.reflect.code.CtStatement;
import spoon.reflect.code.CtSwitch;
import spoon.reflect.code.CtSynchronized;
import spoon.reflect.code.CtTargetedExpression;
import spoon.reflect.code.CtThrow;
import spoon.reflect.code.CtTry;
import spoon.reflect.code.CtTryWithResource;
import spoon.reflect.code.CtUnaryOperator;
import spoon.reflect.code.CtVariableAccess;
import spoon.reflect.code.CtWhile;
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.CtExecutable;
import spoon.reflect.declaration.CtField;
import spoon.reflect.declaration.CtGenericElement;
import spoon.reflect.declaration.CtMethod;
import spoon.reflect.declaration.CtPackage;
import spoon.reflect.declaration.CtParameter;
import spoon.reflect.declaration.CtType;
import spoon.reflect.declaration.CtVariable;
import spoon.reflect.reference.CtFieldReference;
import spoon.reflect.visitor.CtInheritanceScanner;
@SuppressWarnings("unchecked")
public class ParentExiter extends CtInheritanceScanner {
private final JDTTreeBuilder jdtTreeBuilder;
/**
* @param jdtTreeBuilder
*/
ParentExiter(JDTTreeBuilder jdtTreeBuilder) {
this.jdtTreeBuilder = jdtTreeBuilder;
}
CtElement child;
@Override
public void scanCtElement(CtElement e) {
if (child instanceof CtAnnotation && this.jdtTreeBuilder.context.annotationValueName.isEmpty()) {
e.addAnnotation((CtAnnotation>) child);
return;
}
}
@Override
public void scanCtExecutable(CtExecutable e) {
if (child instanceof CtParameter) {
e.addParameter((CtParameter>) child);
return;
} else if (child instanceof CtBlock) {
e.setBody((CtBlock) child);
return;
}
super.scanCtExecutable(e);
}
@Override
public void scanCtGenericElement(CtGenericElement e) {
return;
}
@Override
public void scanCtLoop(CtLoop loop) {
if (loop.getBody() == null && child instanceof CtStatement) {
loop.setBody((CtStatement) child);
}
super.scanCtLoop(loop);
}
@Override
public > void scanCtTargetedExpression(CtTargetedExpression targetedExpression) {
if (!this.jdtTreeBuilder.context.target.isEmpty() && this.jdtTreeBuilder.context.target.peek() == targetedExpression) {
targetedExpression.setTarget((E) child);
return;
}
super.scanCtTargetedExpression(targetedExpression);
}
@Override
public void scanCtType(CtType type) {
if (child instanceof CtType) {
if (type.getNestedTypes().contains(child)) {
type.getNestedTypes().remove(child);
}
type.addNestedType((CtType>) child);
return;
} else if (child instanceof CtField) {
type.addField((CtField>) child);
return;
} else if (child instanceof CtConstructor) {
return;
}
if (child instanceof CtMethod) {
type.addMethod((CtMethod>) child);
return;
}
super.scanCtType(type);
}
@Override
public void scanCtVariable(CtVariable v) {
if (child instanceof CtExpression && !this.jdtTreeBuilder.context.arguments.isEmpty() && this.jdtTreeBuilder.context.arguments.peek() == v) {
v.setDefaultExpression((CtExpression) child);
return;
}
super.scanCtVariable(v);
}
@Override
public void visitCtAnnotation(CtAnnotation annotation) {
// //GANYMEDE FIX: JDT now inserts a simpletyperef below annotations
// that points
// //to the type of the annotation. The JDTTreeBuilder supposes that
// this simpletyperef is
// //in fact part of a member/value pair, and will try to construct
// the pair. I think it is safe to
// // ignore this, but we should really migrate to the JDT Binding
// API since this will only get worse
// // Just to be safe I upcall the visitCtAnnotation in the
// inheritance scanner.
// if(context.annotationValueName.isEmpty()){
// super.visitCtAnnotation(annotation);
// return;
// }
String name = this.jdtTreeBuilder.context.annotationValueName.peek();
Object value = child;
if (value instanceof CtVariableAccess) {
value = ((CtVariableAccess>) value).getVariable();
} else if (value instanceof CtFieldReference && ((CtFieldReference>) value).getSimpleName().equals("class")) {
value = ((CtFieldReference>) value).getType();
}
annotation.addValue(name, value);
super.visitCtAnnotation(annotation);
}
@Override
public void visitCtAnonymousExecutable(CtAnonymousExecutable e) {
if (child instanceof CtBlock) {
e.setBody((CtBlock>) child);
return;
}
super.visitCtAnonymousExecutable(e);
}
@Override
public > void visitCtArrayAccess(CtArrayAccess arrayAccess) {
if (this.jdtTreeBuilder.context.arguments.size() > 0 && this.jdtTreeBuilder.context.arguments.peek() == arrayAccess) {
arrayAccess.setIndexExpression((CtExpression) child);
return;
} else if (arrayAccess.getTarget() == null) {
arrayAccess.setTarget((E) child);
return;
}
super.visitCtArrayAccess(arrayAccess);
}
@Override
public void visitCtAssert(CtAssert asserted) {
if (child instanceof CtExpression) {
if (!this.jdtTreeBuilder.context.arguments.isEmpty() && this.jdtTreeBuilder.context.arguments.peek() == asserted) {
asserted.setExpression((CtExpression) child);
return;
} else {
asserted.setAssertExpression((CtExpression) child);
return;
}
}
super.visitCtAssert(asserted);
}
@Override
public void visitCtAssignment(CtAssignment assignement) {
if (assignement.getAssigned() == null) {
assignement.setAssigned((CtExpression) child);
return;
} else if (assignement.getAssignment() == null) {
assignement.setAssignment((CtExpression) child);
return;
}
super.visitCtAssignment(assignement);
}
@Override
public void visitCtBinaryOperator(CtBinaryOperator operator) {
if (child instanceof CtExpression) {
if (operator.getLeftHandOperand() == null) {
operator.setLeftHandOperand((CtExpression>) child);
return;
} else if (operator.getRightHandOperand() == null) {
operator.setRightHandOperand((CtExpression>) child);
return;
}
}
super.visitCtBinaryOperator(operator);
}
@Override
public void visitCtBlock(CtBlock block) {
if (child instanceof CtStatement) {
block.addStatement((CtStatement) child);
return;
}
super.visitCtBlock(block);
}
@Override
public void visitCtCase(CtCase caseStatement) {
if (this.jdtTreeBuilder.context.selector && caseStatement.getCaseExpression() == null && child instanceof CtExpression) {
caseStatement.setCaseExpression((CtExpression) child);
return;
} else if (child instanceof CtStatement) {
caseStatement.addStatement((CtStatement) child);
return;
}
super.visitCtCase(caseStatement);
}
@Override
public void visitCtCatch(CtCatch catchBlock) {
if (child instanceof CtBlock) {
catchBlock.setBody((CtBlock>) child);
return;
} else if (child instanceof CtCatchVariable) {
catchBlock.setParameter((CtCatchVariable extends Throwable>) child);
return;
}
super.visitCtCatch(catchBlock);
}
@Override
public void visitCtClass(CtClass ctClass) {
if (child instanceof CtConstructor) {
CtConstructor c = (CtConstructor) child;
ctClass.addConstructor(c);
if (c.getPosition() != null && c.getPosition().equals(ctClass.getPosition())) {
c.setImplicit(true);
}
}
if (child instanceof CtAnonymousExecutable) {
ctClass.addAnonymousExecutable((CtAnonymousExecutable) child);
}
super.visitCtClass(ctClass);
}
@Override
public void visitCtConditional(CtConditional conditional) {
if (child instanceof CtExpression) {
if (conditional.getCondition() == null) {
conditional.setCondition((CtExpression) child);
} else if (conditional.getThenExpression() == null) {
conditional.setThenExpression((CtExpression) child);
} else if (conditional.getElseExpression() == null) {
conditional.setElseExpression((CtExpression) child);
}
}
super.visitCtConditional(conditional);
}
@Override
public void visitCtDo(CtDo doLoop) {
if (doLoop.getBody() != null && child instanceof CtExpression && doLoop.getLoopingExpression() == null) {
doLoop.setLoopingExpression((CtExpression) child);
return;
}
super.visitCtDo(doLoop);
}
@Override
public void visitCtField(CtField f) {
if ((f.getDefaultExpression() == null && child instanceof CtExpression && !(child instanceof CtAnnotation)) || jdtTreeBuilder.defaultValue) {
f.setDefaultExpression((CtExpression) child);
return;
}
super.visitCtField(f);
}
@Override
public void visitCtFor(CtFor forLoop) {
if (this.jdtTreeBuilder.context.forinit && child instanceof CtStatement) {
forLoop.addForInit((CtStatement) child);
return;
}
if (!this.jdtTreeBuilder.context.forupdate && forLoop.getExpression() == null && child instanceof CtExpression) {
forLoop.setExpression((CtExpression) child);
return;
}
if (this.jdtTreeBuilder.context.forupdate && child instanceof CtStatement) {
forLoop.addForUpdate((CtStatement) child);
return;
}
super.visitCtFor(forLoop);
}
@Override
public void visitCtForEach(CtForEach foreach) {
if (foreach.getVariable() == null && child instanceof CtVariable) {
foreach.setVariable((CtLocalVariable>) child);
return;
} else if (foreach.getExpression() == null && child instanceof CtExpression) {
foreach.setExpression((CtExpression>) child);
return;
} else if (child instanceof CtStatement) {
foreach.setBody((CtStatement) child);
return;
}
super.visitCtForEach(foreach);
}
@Override
public void visitCtIf(CtIf ifElement) {
if (ifElement.getCondition() == null && child instanceof CtExpression) {
ifElement.setCondition((CtExpression) child);
return;
} else if (child instanceof CtStatement) {
if (ifElement.getThenStatement() == null) {
ifElement.setThenStatement((CtStatement) child);
return;
} else if (ifElement.getElseStatement() == null) {
ifElement.setElseStatement((CtStatement) child);
return;
}
}
super.visitCtIf(ifElement);
}
@Override
public void visitCtInvocation(CtInvocation invocation) {
if (this.jdtTreeBuilder.context.isArgument(invocation) && child instanceof CtExpression) {
invocation.addArgument((CtExpression>) child);
return;
} else if (child instanceof CtExpression) {
invocation.setTarget((CtExpression>) child);
return;
}
super.visitCtInvocation(invocation);
}
@Override
public void visitCtNewArray(CtNewArray newArray) {
if (this.jdtTreeBuilder.context.isArgument(newArray)) {
newArray.addDimensionExpression((CtExpression) child);
return;
} else if (child instanceof CtExpression) {
newArray.addElement((CtExpression>) child);
return;
}
}
@Override
public void visitCtConstructorCall(CtConstructorCall ctConstructorCall) {
if (this.jdtTreeBuilder.context.isArgument(ctConstructorCall) && child instanceof CtExpression) {
ctConstructorCall.addArgument((CtExpression>) child);
return;
}
super.visitCtConstructorCall(ctConstructorCall);
}
@Override
public void visitCtNewClass(CtNewClass newClass) {
if (this.jdtTreeBuilder.context.isArgument(newClass) && child instanceof CtExpression) {
newClass.addArgument((CtExpression>) child);
return;
} else if (child instanceof CtClass) {
newClass.setAnonymousClass((CtClass>) child);
final QualifiedAllocationExpression node = (QualifiedAllocationExpression) jdtTreeBuilder.context.stack.peek().node;
final ReferenceBinding[] referenceBindings = ((LocalTypeBinding) node.resolvedType).superInterfaces();
if (referenceBindings != null && referenceBindings.length > 0) {
((CtClass>) child).addSuperInterface(newClass.getType());
} else {
((CtClass>) child).setSuperclass(newClass.getType());
}
return;
}
super.visitCtNewClass(newClass);
}
@Override
public void visitCtLambda(CtLambda lambda) {
if (child instanceof CtParameter) {
lambda.addParameter((CtParameter>) child);
return;
} else if (child instanceof CtBlock) {
lambda.setBody((CtBlock) child);
return;
} else if (child instanceof CtExpression) {
lambda.setExpression((CtExpression) child);
}
super.visitCtLambda(lambda);
}
@Override
public > void visitCtExecutableReferenceExpression(CtExecutableReferenceExpression expression) {
if (child instanceof CtExpression) {
expression.setTarget((E) child);
}
super.visitCtExecutableReferenceExpression(expression);
}
@Override
public void visitCtPackage(CtPackage ctPackage) {
if (child instanceof CtType) {
if (ctPackage.getTypes().contains(child)) {
ctPackage.getTypes().remove(child);
}
ctPackage.getTypes().add((CtType>) child);
this.jdtTreeBuilder.context.addCreatedType((CtType>) child);
if (child.getPosition() != null && child.getPosition().getCompilationUnit() != null) {
child.getPosition().getCompilationUnit().getDeclaredTypes().add((CtType>) child);
}
return;
}
super.visitCtPackage(ctPackage);
}
@Override
public void visitCtReturn(CtReturn returnStatement) {
if (child instanceof CtExpression) {
returnStatement.setReturnedExpression((CtExpression) child);
return;
}
super.visitCtReturn(returnStatement);
}
@Override
public void visitCtSwitch(CtSwitch switchStatement) {
if (switchStatement.getSelector() == null && child instanceof CtExpression) {
switchStatement.setSelector((CtExpression) child);
return;
}
if (child instanceof CtCase) {
switchStatement.addCase((CtCase) child);
return;
}
super.visitCtSwitch(switchStatement);
}
@Override
public void visitCtSynchronized(CtSynchronized synchro) {
if (synchro.getExpression() == null && child instanceof CtExpression) {
synchro.setExpression((CtExpression>) child);
return;
}
if (synchro.getBlock() == null && child instanceof CtBlock) {
synchro.setBlock((CtBlock>) child);
return;
}
super.visitCtSynchronized(synchro);
}
@Override
public void visitCtThrow(CtThrow throwStatement) {
if (throwStatement.getThrownExpression() == null) {
throwStatement.setThrownExpression((CtExpression extends Throwable>) child);
return;
}
super.visitCtThrow(throwStatement);
}
@Override
public void visitCtTry(CtTry tryBlock) {
if (child instanceof CtBlock) {
if (!this.jdtTreeBuilder.context.finallyzer.isEmpty() && this.jdtTreeBuilder.context.finallyzer.peek() == tryBlock) {
tryBlock.setFinalizer((CtBlock>) child);
} else {
tryBlock.setBody((CtBlock>) child);
}
return;
} else if (child instanceof CtCatch) {
tryBlock.addCatcher((CtCatch) child);
return;
}
super.visitCtTry(tryBlock);
}
@Override
public void visitCtTryWithResource(CtTryWithResource tryWithResource) {
if (child instanceof CtBlock) {
if (!this.jdtTreeBuilder.context.finallyzer.isEmpty() && this.jdtTreeBuilder.context.finallyzer.peek() == tryWithResource) {
tryWithResource.setFinalizer((CtBlock>) child);
} else {
tryWithResource.setBody((CtBlock>) child);
}
return;
} else if (child instanceof CtLocalVariable) {
if (tryWithResource.getResources() == null) {
tryWithResource.setResources(new ArrayList>());
}
tryWithResource.addResource((CtLocalVariable>) child);
} else if (child instanceof CtCatch) {
tryWithResource.addCatcher((CtCatch) child);
return;
}
super.visitCtTry(tryWithResource);
}
@Override
public void visitCtUnaryOperator(CtUnaryOperator operator) {
if (operator.getOperand() == null && child instanceof CtExpression) {
operator.setOperand((CtExpression) child);
return;
}
super.visitCtUnaryOperator(operator);
}
@Override
public void visitCtWhile(CtWhile whileLoop) {
if (whileLoop.getLoopingExpression() == null && child instanceof CtExpression) {
whileLoop.setLoopingExpression((CtExpression) child);
return;
}
super.visitCtWhile(whileLoop);
}
}