use of spoon.reflect.code.CtLiteral in project spoon by INRIA.
the class ImportScannerImpl method isTypeInCollision.
/**
* Test if the reference can be imported, i.e. test if the importation could lead to a collision.
* @param ref
* @return true if the ref should be imported.
*/
protected boolean isTypeInCollision(CtReference ref, boolean fqnMode) {
if (targetType != null && targetType.getSimpleName().equals(ref.getSimpleName()) && !targetType.equals(ref)) {
return true;
}
try {
CtElement parent;
if (ref instanceof CtTypeReference) {
parent = ref.getParent();
} else {
parent = ref;
}
// i.e. a string, an int, etc.
if (parent instanceof CtLiteral) {
return false;
}
Set<String> localVariablesOfBlock = new HashSet<>();
if (parent instanceof CtField) {
this.fieldAndMethodsNames.add(((CtField) parent).getSimpleName());
} else if (parent instanceof CtMethod) {
this.fieldAndMethodsNames.add(((CtMethod) parent).getSimpleName());
} else {
localVariablesOfBlock = this.lookForLocalVariables(parent);
}
while (!(parent instanceof CtPackage)) {
if ((parent instanceof CtFieldReference) || (parent instanceof CtExecutableReference) || (parent instanceof CtInvocation)) {
CtReference parentType;
if (parent instanceof CtInvocation) {
parentType = ((CtInvocation) parent).getExecutable();
} else {
parentType = (CtReference) parent;
}
LinkedList<String> qualifiedNameTokens = new LinkedList<>();
// we don't want to test the current ref name, as we risk to create field import and make autoreference
if (parentType != parent) {
qualifiedNameTokens.add(parentType.getSimpleName());
}
CtTypeReference typeReference;
if (parent instanceof CtFieldReference) {
typeReference = ((CtFieldReference) parent).getDeclaringType();
} else if (parent instanceof CtExecutableReference) {
typeReference = ((CtExecutableReference) parent).getDeclaringType();
} else {
typeReference = ((CtInvocation) parent).getExecutable().getDeclaringType();
}
if (typeReference != null) {
qualifiedNameTokens.addFirst(typeReference.getSimpleName());
if (typeReference.getPackage() != null) {
StringTokenizer token = new StringTokenizer(typeReference.getPackage().getSimpleName(), CtPackage.PACKAGE_SEPARATOR);
int index = 0;
while (token.hasMoreElements()) {
qualifiedNameTokens.add(index, token.nextToken());
index++;
}
}
}
if (!qualifiedNameTokens.isEmpty()) {
// if the first package name is a variable name somewhere, it could lead to a collision
if (fieldAndMethodsNames.contains(qualifiedNameTokens.getFirst()) || localVariablesOfBlock.contains(qualifiedNameTokens.getFirst())) {
qualifiedNameTokens.removeFirst();
if (fqnMode) {
// for example: spoon.Launcher if a field spoon and another one Launcher exists
if (ref instanceof CtTypeReference) {
if (qualifiedNameTokens.isEmpty()) {
return true;
}
// but if the other package names are not a variable name, it's ok to import
for (int i = 0; i < qualifiedNameTokens.size(); i++) {
String testedToken = qualifiedNameTokens.get(i);
if (!fieldAndMethodsNames.contains(testedToken) && !localVariablesOfBlock.contains(testedToken)) {
return true;
}
}
return false;
// However if it is a static method/field, we always accept to import them in this case
// It is the last possibility for managing import for us
} else {
return true;
}
} else {
// but if the other package names are not a variable name, it's ok to import
for (int i = 0; i < qualifiedNameTokens.size(); i++) {
String testedToken = qualifiedNameTokens.get(i);
if (!fieldAndMethodsNames.contains(testedToken) && !localVariablesOfBlock.contains(testedToken)) {
return false;
}
}
return true;
}
}
}
}
parent = parent.getParent();
}
} catch (ParentNotInitializedException e) {
return false;
}
return false;
}
use of spoon.reflect.code.CtLiteral in project spoon by INRIA.
the class VisitorPartialEvaluator method visitCtIf.
public void visitCtIf(CtIf ifElement) {
CtExpression<Boolean> r = evaluate(ifElement.getCondition());
if (r instanceof CtLiteral) {
CtLiteral<Boolean> l = (CtLiteral<Boolean>) r;
if (l.getValue()) {
setResult(evaluate(ifElement.getThenStatement()));
} else {
if (ifElement.getElseStatement() != null) {
setResult(evaluate(ifElement.getElseStatement()));
} else {
setResult(ifElement.getFactory().Code().createComment("if removed", CtComment.CommentType.INLINE));
}
}
} else {
CtIf ifRes = ifElement.getFactory().Core().createIf();
ifRes.setCondition(r);
boolean thenEnded = false, elseEnded = false;
ifRes.setThenStatement((CtStatement) evaluate(ifElement.getThenStatement()));
if (flowEnded) {
thenEnded = true;
flowEnded = false;
}
if (ifElement.getElseStatement() != null) {
ifRes.setElseStatement((CtStatement) evaluate(ifElement.getElseStatement()));
}
if (flowEnded) {
elseEnded = true;
flowEnded = false;
}
setResult(ifRes);
if (thenEnded && elseEnded) {
flowEnded = true;
}
}
}
use of spoon.reflect.code.CtLiteral in project spoon by INRIA.
the class VisitorPartialEvaluator method visitCtInvocation.
public <T> void visitCtInvocation(CtInvocation<T> invocation) {
CtInvocation<T> i = invocation.getFactory().Core().createInvocation();
i.setExecutable(invocation.getExecutable());
i.setTypeCasts(invocation.getTypeCasts());
boolean constant = true;
i.setTarget(evaluate(invocation.getTarget()));
if ((i.getTarget() != null) && !(i.getTarget() instanceof CtLiteral)) {
constant = false;
}
for (CtExpression<?> e : invocation.getArguments()) {
CtExpression<?> re = evaluate(e);
if (!(re instanceof CtLiteral)) {
constant = false;
}
i.addArgument(re);
}
// do not partially evaluate super(...)
if (i.getExecutable().getSimpleName().equals(CtExecutableReference.CONSTRUCTOR_NAME)) {
setResult(i);
return;
}
if (constant) {
CtExecutable<?> executable = invocation.getExecutable().getDeclaration();
CtType<?> aType = invocation.getParent(CtType.class);
CtTypeReference<?> execDeclaringType = invocation.getExecutable().getDeclaringType();
// (including to superclasses)
if (executable != null && aType != null && invocation.getType() != null && execDeclaringType != null && execDeclaringType.isSubtypeOf(aType.getReference())) {
CtBlock<?> b = evaluate(executable.getBody());
flowEnded = false;
CtStatement last = b.getStatements().get(b.getStatements().size() - 1);
if ((last != null) && (last instanceof CtReturn)) {
if (((CtReturn<?>) last).getReturnedExpression() instanceof CtLiteral) {
setResult(((CtReturn<?>) last).getReturnedExpression());
return;
}
}
} else {
// try to completely evaluate
T r = null;
try {
// System.err.println("invocking "+i);
r = RtHelper.invoke(i);
if (isLiteralType(r)) {
CtLiteral<T> l = invocation.getFactory().Core().createLiteral();
l.setValue(r);
setResult(l);
return;
}
} catch (Exception e) {
}
}
}
setResult(i);
}
use of spoon.reflect.code.CtLiteral in project spoon by INRIA.
the class EqualsChecker method visitCtLiteral.
@Override
public <T> void visitCtLiteral(CtLiteral<T> e) {
final CtLiteral peek = (CtLiteral) this.other;
if (e.getValue() == null) {
if (peek.getValue() != null) {
isNotEqual = true;
return;
}
} else if (peek.getValue() == null) {
isNotEqual = true;
return;
} else if (!e.getValue().equals(peek.getValue())) {
isNotEqual = true;
return;
}
super.visitCtLiteral(e);
}
use of spoon.reflect.code.CtLiteral in project spoon by INRIA.
the class AnnotationTest method testReplaceAnnotationValue.
@Test
public void testReplaceAnnotationValue() throws Exception {
final Launcher launcher = new Launcher();
launcher.addInputResource("./src/test/java/spoon/test/annotation/testclasses/Main.java");
launcher.buildModel();
Factory factory = launcher.getFactory();
CtType<?> type = factory.Type().get("spoon.test.annotation.testclasses.Main");
CtMethod<?> m1 = type.getElements(new NamedElementFilter<>(CtMethod.class, "m1")).get(0);
List<CtAnnotation<? extends Annotation>> annotations = m1.getAnnotations();
assertEquals(1, annotations.size());
CtAnnotation<?> a = annotations.get(0);
AnnotParamTypes annot = (AnnotParamTypes) a.getActualAnnotation();
// contract: test replace of single value
CtExpression integerValue = a.getValue("integer");
assertEquals(42, ((CtLiteral<Integer>) integerValue).getValue().intValue());
assertEquals(42, annot.integer());
integerValue.replace(factory.createLiteral(17));
CtExpression newIntegerValue = a.getValue("integer");
assertEquals(17, ((CtLiteral<Integer>) newIntegerValue).getValue().intValue());
assertEquals(17, annot.integer());
// even if second value is null
try {
a.getValue("integer").replace(Arrays.asList(factory.createLiteral(18), null));
fail();
} catch (SpoonException e) {
// OK
}
// contract: replacing of single value by no value
a.getValue("integer").delete();
assertNull(a.getValue("integer"));
try {
annot.integer();
fail();
} catch (NullPointerException e) {
// OK - fails because int cannot be null
}
// contract: replace with null value means remove
a.getValue("string").replace((CtElement) null);
assertNull(a.getValue("string"));
// contract: check that null value can be returned
assertNull(annot.string());
// contract: replace with null value in collection means remove
a.getValue("clazz").replace(Collections.singletonList(null));
assertNull(a.getValue("clazz"));
// contract: check that null value can be returned
assertNull(annot.clazz());
// contract: test replace of item in collection
assertEquals(1, annot.integers().length);
assertEquals(42, annot.integers()[0]);
CtNewArray<?> integersNewArray = (CtNewArray) a.getValue("integers");
integersNewArray.getElements().get(0).replace(Arrays.asList(null, factory.createLiteral(101), null, factory.createLiteral(102)));
assertEquals(2, annot.integers().length);
assertEquals(101, annot.integers()[0]);
assertEquals(102, annot.integers()[1]);
}
Aggregations