use of spoon.reflect.code.CtLambda in project spoon by INRIA.
the class ReferenceBuilder method getLambdaExecutableReference.
/**
* In noclasspath, lambda doesn't have always a binding for their variables accesses in their block/expression.
* Here, we make the job of JDT and bind their variables accesses to their parameters.
*
* @param singleNameReference Name of the variable access.
* @return executable reference which corresponds to the lambda.
*/
public CtExecutableReference<?> getLambdaExecutableReference(SingleNameReference singleNameReference) {
ASTPair potentialLambda = null;
for (ASTPair astPair : jdtTreeBuilder.getContextBuilder().stack) {
if (astPair.node instanceof LambdaExpression) {
potentialLambda = astPair;
// stop at innermost lambda, fixes #1100
break;
}
}
if (potentialLambda == null) {
return null;
}
LambdaExpression lambdaJDT = (LambdaExpression) potentialLambda.node;
for (Argument argument : lambdaJDT.arguments()) {
if (CharOperation.equals(argument.name, singleNameReference.token)) {
CtTypeReference<?> declaringType = null;
if (lambdaJDT.enclosingScope instanceof MethodScope) {
declaringType = jdtTreeBuilder.getReferencesBuilder().getTypeReference(((MethodScope) lambdaJDT.enclosingScope).parent.enclosingSourceType());
}
CtLambda<?> ctLambda = (CtLambda<?>) potentialLambda.element;
List<CtTypeReference<?>> parametersType = new ArrayList<>();
List<CtParameter<?>> parameters = ctLambda.getParameters();
for (CtParameter<?> parameter : parameters) {
parametersType.add(parameter.getType() != null ? parameter.getType().clone() : // it's the best match :(
jdtTreeBuilder.getFactory().Type().OBJECT.clone());
}
return jdtTreeBuilder.getFactory().Executable().createReference(declaringType, ctLambda.getType(), ctLambda.getSimpleName(), parametersType);
}
}
return null;
}
use of spoon.reflect.code.CtLambda in project spoon by INRIA.
the class MethodsRefactoringTest method testExecutableReferenceFilter.
@Test
public void testExecutableReferenceFilter() {
Factory factory = ModelUtils.build(new File("./src/test/java/spoon/test/refactoring/parameter/testclasses"));
List<CtExecutable<?>> executables = factory.getModel().filterChildren((CtExecutable<?> e) -> true).list();
int nrExecRefsTotal = 0;
// contract check that ExecutableReferenceFilter found CtExecutableReferences of each executable individually
for (CtExecutable<?> executable : executables) {
nrExecRefsTotal += checkExecutableReferenceFilter(factory, Collections.singletonList(executable));
}
// contract check that ExecutableReferenceFilter found CtExecutableReferences of all executables together
int nrExecRefsTotal2 = checkExecutableReferenceFilter(factory, executables);
assertSame(nrExecRefsTotal, nrExecRefsTotal2);
// contract check that it found lambdas too
CtLambda lambda = factory.getModel().filterChildren((CtLambda<?> e) -> true).first();
assertNotNull(lambda);
// this test case is quite wild, because there is normally lambda reference in spoon model. So make one lambda reference here:
CtExecutableReference<?> lambdaRef = lambda.getReference();
List<CtExecutableReference<?>> refs = lambdaRef.filterChildren(null).select(new ExecutableReferenceFilter(lambda)).list();
assertEquals(1, refs.size());
assertSame(lambdaRef, refs.get(0));
}
use of spoon.reflect.code.CtLambda in project spoon by INRIA.
the class TypeTest method testIntersectionTypeReferenceInGenericsAndCasts.
@Test
public void testIntersectionTypeReferenceInGenericsAndCasts() throws Exception {
final String target = "./target/type";
final Launcher launcher = new Launcher();
launcher.addInputResource("./src/test/java/spoon/test/type/testclasses");
launcher.setSourceOutputDirectory(target);
launcher.getEnvironment().setNoClasspath(true);
launcher.run();
final CtClass<Pozole> aPozole = launcher.getFactory().Class().get(Pozole.class);
final CtMethod<?> prepare = aPozole.getMethodsByName("prepare").get(0);
// Intersection type in generic types.
final List<CtClass> localTypes = prepare.getElements(new TypeFilter<>(CtClass.class));
assertEquals(1, localTypes.size());
// New type parameter declaration.
final CtTypeParameter typeParameter = localTypes.get(0).getFormalCtTypeParameters().get(0);
assertNotNull(typeParameter);
assertEquals("T", typeParameter.getSimpleName());
assertIntersectionTypeForPozolePrepareMethod(aPozole, typeParameter.getSuperclass());
// Intersection type in casts.
final List<CtLambda<?>> lambdas = prepare.getElements(new TypeFilter<CtLambda<?>>(CtLambda.class));
assertEquals(1, lambdas.size());
assertEquals(1, lambdas.get(0).getTypeCasts().size());
assertTrue(lambdas.get(0).getTypeCasts().get(0) instanceof CtIntersectionTypeReference);
final CtIntersectionTypeReference<?> intersectionType = lambdas.get(0).getTypeCasts().get(0).asCtIntersectionTypeReference();
assertEquals("java.lang.Runnable & java.io.Serializable", intersectionType.toString());
assertEquals(aPozole.getFactory().Type().createReference(Runnable.class), intersectionType.getBounds().stream().collect(Collectors.toList()).get(0));
assertEquals(aPozole.getFactory().Type().createReference(Serializable.class), intersectionType.getBounds().stream().collect(Collectors.toList()).get(1));
canBeBuilt(target, 8, true);
}
use of spoon.reflect.code.CtLambda in project spoon by INRIA.
the class MethodsRefactoringTest method checkMethodHierarchy.
private void checkMethodHierarchy(List<CtExecutable<?>> expectedExecutables, CtExecutable startExecutable) {
// contract: check that by default it does not includes self
// contract: check that by default it returns lambdas
{
final List<CtExecutable<?>> executables = startExecutable.map(new AllMethodsSameSignatureFunction()).list();
assertFalse("Unexpected start executable " + startExecutable, containsSame(executables, startExecutable));
// check that some method was found
assertTrue(executables.size() > 0);
// check that expected methods were found and remove them
expectedExecutables.forEach(m -> {
boolean found = removeSame(executables, m);
if (startExecutable == m) {
// it is start method. It should not be there
assertFalse("The signature " + getQSignature(m) + " was returned too", found);
} else {
assertTrue("The signature " + getQSignature(m) + " not found", found);
}
});
// check that there is no unexpected executable
assertTrue("Unexpected executables: " + executables, executables.isEmpty());
}
// contract: check that includingSelf(true) returns startMethod too
// contract: check that by default it still returns lambdas
{
final List<CtExecutable<?>> executables = startExecutable.map(new AllMethodsSameSignatureFunction().includingSelf(true)).list();
assertTrue("Missing start executable " + startExecutable, containsSame(executables, startExecutable));
// check that some method was found
assertTrue(executables.size() > 0);
// check that expected methods were found and remove them
expectedExecutables.forEach(m -> {
assertTrue("The signature " + getQSignature(m) + " not found", removeSame(executables, m));
});
// check that there is no unexpected executable
assertTrue("Unexpected executables: " + executables, executables.isEmpty());
}
// contract: check that includingLambdas(false) returns no lambda expressions
{
final List<CtExecutable<?>> executables = startExecutable.map(new AllMethodsSameSignatureFunction().includingSelf(true).includingLambdas(false)).list();
if (startExecutable instanceof CtLambda) {
// lambda must not be returned even if it is first
assertFalse("Unexpected start executable " + startExecutable, containsSame(executables, startExecutable));
} else {
assertTrue("Missing start executable " + startExecutable, containsSame(executables, startExecutable));
}
// check that some method was found
assertTrue(executables.size() > 0);
// check that expected methods were found and remove them
expectedExecutables.forEach(m -> {
if (m instanceof CtLambda) {
// the lambdas are not expected. Do not ask for them
return;
}
assertTrue("The signature " + getQSignature(m) + " not found", removeSame(executables, m));
});
// check that there is no unexpected executable or lambda
assertTrue("Unexepcted executables " + executables, executables.isEmpty());
}
// contract: check early termination
// contract: check that first returned element is the startExecutable itself if includingSelf == true
CtExecutable<?> exec = startExecutable.map(new AllMethodsSameSignatureFunction().includingSelf(true)).first();
assertSame(startExecutable, exec);
// contract: check that first returned element is not the startExecutable itself if includingSelf == false, but some other executable from the expected
exec = startExecutable.map(new AllMethodsSameSignatureFunction().includingSelf(false)).first();
assertNotSame(startExecutable, exec);
assertTrue(containsSame(expectedExecutables, exec));
}
use of spoon.reflect.code.CtLambda in project spoon by INRIA.
the class VariableReferencesTest method getLiteralValue.
private Integer getLiteralValue(CtVariable<?> var) {
CtExpression<?> exp = var.getDefaultExpression();
if (exp != null) {
try {
return getLiteralValue(exp);
} catch (ClassCastException e) {
}
}
if (var instanceof CtParameter) {
CtParameter param = (CtParameter) var;
CtExecutable<?> l_exec = param.getParent(CtExecutable.class);
int l_argIdx = l_exec.getParameters().indexOf(param);
assertTrue(l_argIdx >= 0);
if (l_exec instanceof CtLambda) {
CtLambda<?> lambda = (CtLambda<?>) l_exec;
CtLocalVariable<?> lamVar = (CtLocalVariable) lambda.getParent();
CtLocalVariableReference<?> lamVarRef = lamVar.getParent().filterChildren((CtLocalVariableReference ref) -> ref.getSimpleName().equals(lamVar.getSimpleName())).first();
CtAbstractInvocation inv = lamVarRef.getParent(CtAbstractInvocation.class);
return getLiteralValue((CtExpression<?>) inv.getArguments().get(l_argIdx));
} else {
CtExecutableReference<?> l_execRef = l_exec.getReference();
List<CtAbstractInvocation<?>> list = l_exec.getFactory().Package().getRootPackage().filterChildren((CtAbstractInvocation inv) -> {
// return inv.getExecutable().equals(l_execRef);
return inv.getExecutable().getExecutableDeclaration() == l_exec;
}).list();
CtAbstractInvocation inv = list.get(0);
Integer firstValue = getLiteralValue((CtExpression<?>) inv.getArguments().get(l_argIdx));
// check that all found method invocations are using same key
list.forEach(inv2 -> {
assertEquals(firstValue, getLiteralValue((CtExpression<?>) inv2.getArguments().get(l_argIdx)));
});
return firstValue;
}
}
return getCommentValue(var);
}
Aggregations