package spoon.reflect.ast;
import spoon.reflect.code.CtConstructorCall;
import spoon.reflect.code.CtThrow;
import spoon.reflect.declaration.CtElement;
import spoon.reflect.declaration.CtMethod;
import spoon.reflect.factory.Factory;
import spoon.reflect.reference.CtTypeReference;
import spoon.reflect.visitor.CtScanner;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Set;
public abstract class IntercessionScanner extends CtScanner {
protected final Factory factory;
protected final List<CtTypeReference<?>> COLLECTIONS;
protected final CtTypeReference<CtElement> CTELEMENT_REFERENCE;
protected final CtTypeReference<Collection> COLLECTION_REFERENCE;
protected final CtTypeReference<List> LIST_REFERENCE;
protected final CtTypeReference<Set> SET_REFERENCE;
public IntercessionScanner(Factory factory) {
this.factory = factory;
COLLECTION_REFERENCE = factory.Type().createReference(Collection.class);
LIST_REFERENCE = factory.Type().createReference(List.class);
SET_REFERENCE = factory.Type().createReference(Set.class);
COLLECTIONS = Arrays.asList(COLLECTION_REFERENCE, LIST_REFERENCE, SET_REFERENCE);
CTELEMENT_REFERENCE = factory.Type().createReference(CtElement.class);
}
protected abstract boolean isToBeProcessed(CtMethod<?> candidate);
protected abstract void process(CtMethod<?> element);
@Override
public <T> void visitCtMethod(CtMethod<T> m) {
if (isToBeProcessed(m)) {
process(m);
}
super.visitCtMethod(m);
}
protected boolean avoidThrowUnsupportedOperationException(CtMethod<?> candidate) {
if (candidate.getBody().getStatements().size() != 1) {
return true;
}
if (!(candidate.getBody().getStatement(0) instanceof CtThrow)) {
return true;
}
CtThrow ctThrow = candidate.getBody().getStatement(0);
if (!(ctThrow.getThrownExpression() instanceof CtConstructorCall)) {
return true;
}
final CtConstructorCall<? extends Throwable> thrownExpression = (CtConstructorCall<? extends Throwable>) ctThrow.getThrownExpression();
if (!thrownExpression.getType().equals(factory.Type().createReference(UnsupportedOperationException.class))) {
return true;
}
return false;
}
protected boolean takeSetterForCtElement(CtMethod<?> candidate) {
return candidate.getParameters().get(0).getType().isSubtypeOf(CTELEMENT_REFERENCE);
}
protected boolean avoidInterfaces(CtMethod<?> candidate) {
return candidate.getBody() != null;
}
}