Skip to content

Commit

Permalink
add FunctionInterfaceLogic
Browse files Browse the repository at this point in the history
  • Loading branch information
ftomassetti committed Nov 13, 2015
1 parent 6755c51 commit a75fd9d
Show file tree
Hide file tree
Showing 3 changed files with 62 additions and 15 deletions.
@@ -0,0 +1,25 @@
package me.tomassetti.symbolsolver.logic;

import me.tomassetti.symbolsolver.model.invokations.MethodUsage;
import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;

import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

public class FunctionalInterfaceLogic {

public static Optional<MethodUsage> getFunctionalMethod(TypeUsage type) {
if (type.isReferenceType() && type.asReferenceTypeUsage().getTypeDeclaration().isInterface()) {
//We need to find all abstract methods
Set<MethodUsage> methods = type.asReferenceTypeUsage().getTypeDeclaration().getAllMethods().stream().filter(m -> m.getDeclaration().isAbstract()).collect(Collectors.toSet());
if (methods.size() == 1) {
return Optional.of(methods.iterator().next());
} else {
return Optional.empty();
}
} else {
return Optional.empty();
}
}
}
Expand Up @@ -4,6 +4,7 @@
import com.github.javaparser.ast.body.*; import com.github.javaparser.ast.body.*;
import com.github.javaparser.ast.expr.*; import com.github.javaparser.ast.expr.*;
import com.github.javaparser.ast.type.*; import com.github.javaparser.ast.type.*;
import me.tomassetti.symbolsolver.logic.FunctionalInterfaceLogic;
import me.tomassetti.symbolsolver.model.declarations.MethodDeclaration; import me.tomassetti.symbolsolver.model.declarations.MethodDeclaration;
import me.tomassetti.symbolsolver.model.declarations.TypeDeclaration; import me.tomassetti.symbolsolver.model.declarations.TypeDeclaration;
import me.tomassetti.symbolsolver.model.declarations.ValueDeclaration; import me.tomassetti.symbolsolver.model.declarations.ValueDeclaration;
Expand Down Expand Up @@ -174,7 +175,7 @@ private TypeUsage getTypeConcrete(Node node, boolean solveLambdas) {
//We should find out which is the functional method (e.g., apply) and replace the params of the //We should find out which is the functional method (e.g., apply) and replace the params of the
//solveLambdas with it, to derive so the values. We should also consider the value returned by the //solveLambdas with it, to derive so the values. We should also consider the value returned by the
//lambdas //lambdas
Optional<MethodUsage> functionalMethod = getFunctionalMethod(result); Optional<MethodUsage> functionalMethod = FunctionalInterfaceLogic.getFunctionalMethod(result);
if (functionalMethod.isPresent()) { if (functionalMethod.isPresent()) {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
Expand Down Expand Up @@ -308,20 +309,6 @@ private TypeUsage getTypeConcrete(Node node, boolean solveLambdas) {
} }
} }


private Optional<MethodUsage> getFunctionalMethod(TypeUsage type) {
if (type.isReferenceType() && type.asReferenceTypeUsage().getTypeDeclaration().isInterface()) {
//We need to find all abstract methods
Set<MethodUsage> methods = type.asReferenceTypeUsage().getTypeDeclaration().getAllMethods().stream().filter(m -> m.getDeclaration().isAbstract()).collect(Collectors.toSet());
if (methods.size() == 1) {
return Optional.of(methods.iterator().next());
} else {
return Optional.empty();
}
} else {
return Optional.empty();
}
}

private com.github.javaparser.ast.body.TypeDeclaration findContainingTypeDecl(Node node) { private com.github.javaparser.ast.body.TypeDeclaration findContainingTypeDecl(Node node) {
if (node instanceof ClassOrInterfaceDeclaration) { if (node instanceof ClassOrInterfaceDeclaration) {
return (ClassOrInterfaceDeclaration) node; return (ClassOrInterfaceDeclaration) node;
Expand Down
@@ -0,0 +1,35 @@
package me.tomassetti.symbolsolver.logic;

import me.tomassetti.symbolsolver.model.resolution.TypeSolver;
import me.tomassetti.symbolsolver.model.typesystem.ReferenceTypeUsageImpl;
import me.tomassetti.symbolsolver.model.typesystem.TypeUsage;
import me.tomassetti.symbolsolver.reflectionmodel.ReflectionClassDeclaration;
import me.tomassetti.symbolsolver.reflectionmodel.ReflectionInterfaceDeclaration;
import me.tomassetti.symbolsolver.resolution.typesolvers.JreTypeSolver;
import org.junit.Test;

import java.util.function.Consumer;
import java.util.function.Function;

import static org.junit.Assert.*;

public class FunctionInterfaceLogicTest {

@Test
public void testGetFunctionalMethodNegativeCaseOnClass() {
TypeSolver typeSolver = new JreTypeSolver();
TypeUsage string = new ReferenceTypeUsageImpl(new ReflectionClassDeclaration(String.class, typeSolver), typeSolver);
assertEquals(false, FunctionalInterfaceLogic.getFunctionalMethod(string).isPresent());
}

@Test
public void testGetFunctionalMethodPositiveCasesOnInterfaces() {
TypeSolver typeSolver = new JreTypeSolver();
TypeUsage function = new ReferenceTypeUsageImpl(new ReflectionInterfaceDeclaration(Function.class, typeSolver), typeSolver);
assertEquals(true, FunctionalInterfaceLogic.getFunctionalMethod(function).isPresent());
assertEquals("apply", FunctionalInterfaceLogic.getFunctionalMethod(function).get().getName());
TypeUsage consumer = new ReferenceTypeUsageImpl(new ReflectionInterfaceDeclaration(Consumer.class, typeSolver), typeSolver);
assertEquals(true, FunctionalInterfaceLogic.getFunctionalMethod(consumer).isPresent());
assertEquals("accept", FunctionalInterfaceLogic.getFunctionalMethod(consumer).get().getName());
}
}

0 comments on commit a75fd9d

Please sign in to comment.