Skip to content

Commit

Permalink
Issue 322: Implement symbol solving in JavassistEnumDeclaration, anal…
Browse files Browse the repository at this point in the history
…ogous to how it works in JavassistClassDeclaration, and add tests for that.
  • Loading branch information
WimTibackx committed Oct 18, 2017
1 parent 849a30b commit 19b626c
Show file tree
Hide file tree
Showing 9 changed files with 164 additions and 1 deletion.
Expand Up @@ -29,6 +29,7 @@
import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
import com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic; import com.github.javaparser.symbolsolver.resolution.MethodResolutionLogic;
import javassist.CtClass; import javassist.CtClass;
import javassist.CtField;
import javassist.CtMethod; import javassist.CtMethod;
import javassist.NotFoundException; import javassist.NotFoundException;
import javassist.bytecode.AccessFlag; import javassist.bytecode.AccessFlag;
Expand Down Expand Up @@ -231,4 +232,25 @@ public boolean hasInternalType(String name) {
*/ */
return this.internalTypes().stream().anyMatch(f -> f.getName().endsWith(name)); return this.internalTypes().stream().anyMatch(f -> f.getName().endsWith(name));
} }

public SymbolReference<? extends ResolvedValueDeclaration> solveSymbol(String name, TypeSolver typeSolver) {
for (CtField field : ctClass.getDeclaredFields()) {
if (field.getName().equals(name)) {
return SymbolReference.solved(new JavassistFieldDeclaration(field, typeSolver));
}
}

try {
for (CtClass interfaze : ctClass.getInterfaces()) {
SymbolReference<? extends ResolvedValueDeclaration> ref = new JavassistInterfaceDeclaration(interfaze, typeSolver).solveSymbol(name, typeSolver);
if (ref.isSolved()) {
return ref;
}
}
} catch (NotFoundException e) {
throw new RuntimeException(e);
}

return SymbolReference.unsolved(ResolvedValueDeclaration.class);
}
} }
Expand Up @@ -31,6 +31,7 @@
import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserEnumDeclaration; import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserEnumDeclaration;
import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserInterfaceDeclaration; import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserInterfaceDeclaration;
import com.github.javaparser.symbolsolver.javassistmodel.JavassistClassDeclaration; import com.github.javaparser.symbolsolver.javassistmodel.JavassistClassDeclaration;
import com.github.javaparser.symbolsolver.javassistmodel.JavassistEnumDeclaration;
import com.github.javaparser.symbolsolver.model.resolution.SymbolReference; import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
import com.github.javaparser.symbolsolver.model.resolution.TypeSolver; import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
import com.github.javaparser.symbolsolver.model.resolution.Value; import com.github.javaparser.symbolsolver.model.resolution.Value;
Expand Down Expand Up @@ -145,6 +146,9 @@ public SymbolReference<? extends ResolvedValueDeclaration> solveSymbolInType(Res
if (typeDeclaration instanceof JavassistClassDeclaration) { if (typeDeclaration instanceof JavassistClassDeclaration) {
return ((JavassistClassDeclaration) typeDeclaration).solveSymbol(name, typeSolver); return ((JavassistClassDeclaration) typeDeclaration).solveSymbol(name, typeSolver);
} }
if (typeDeclaration instanceof JavassistEnumDeclaration) {
return ((JavassistEnumDeclaration) typeDeclaration).solveSymbol(name, typeSolver);
}
return SymbolReference.unsolved(ResolvedValueDeclaration.class); return SymbolReference.unsolved(ResolvedValueDeclaration.class);
} }


Expand Down
Expand Up @@ -72,7 +72,7 @@ public void testSolveSymbolInTypeCanSolveSecondOwnField() {
} }


@Test @Test
public void testSolveSymbolInTypeCantResolveNonExistantField() { public void testSolveSymbolInTypeCantResolveNonExistentField() {
SymbolReference<? extends ResolvedValueDeclaration> solvedSymbol = symbolSolver.solveSymbolInType(classDeclarationConcreteClass, "FIELD_THAT_DOES_NOT_EXIST"); SymbolReference<? extends ResolvedValueDeclaration> solvedSymbol = symbolSolver.solveSymbolInType(classDeclarationConcreteClass, "FIELD_THAT_DOES_NOT_EXIST");


assertFalse(solvedSymbol.isSolved()); assertFalse(solvedSymbol.isSolved());
Expand Down
@@ -0,0 +1,108 @@
package com.github.javaparser.symbolsolver.resolution;

import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
import com.github.javaparser.symbolsolver.AbstractTest;
import com.github.javaparser.symbolsolver.javassistmodel.JavassistEnumDeclaration;
import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
import com.github.javaparser.symbolsolver.resolution.typesolvers.JarTypeSolver;
import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
import javassist.NotFoundException;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;

import java.io.IOException;

import static org.junit.Assert.*;
import static org.junit.Assert.fail;

public class SymbolSolverWithJavassistEnumTest extends AbstractTest {
private TypeSolver typeSolver;
private SymbolSolver symbolSolver;
private JavassistEnumDeclaration enumDeclarationConcrete;
private JavassistEnumDeclaration enumDeclarationInterfaceUserOwnJar;
private JavassistEnumDeclaration enumDeclarationInterfaceUserIncludedJar;
private JavassistEnumDeclaration enumDeclarationInterfaceUserExcludedJar;

@Before
public void setup() throws IOException {
final String pathToMainJar = adaptPath("src/test/resources/javassist_symbols/main_jar/main_jar.jar");
final String pathToIncludedJar = adaptPath("src/test/resources/javassist_symbols/included_jar/included_jar.jar");
typeSolver = new CombinedTypeSolver(new JarTypeSolver(pathToIncludedJar), new JarTypeSolver(pathToMainJar), new ReflectionTypeSolver());

symbolSolver = new SymbolSolver(typeSolver);

enumDeclarationConcrete = (JavassistEnumDeclaration) typeSolver.solveType("com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar.ConcreteEnum");
enumDeclarationInterfaceUserOwnJar = (JavassistEnumDeclaration) typeSolver.solveType("com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar.EnumInterfaceUserOwnJar");
enumDeclarationInterfaceUserIncludedJar = (JavassistEnumDeclaration) typeSolver.solveType("com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar.EnumInterfaceUserIncludedJar");
enumDeclarationInterfaceUserExcludedJar = (JavassistEnumDeclaration) typeSolver.solveType("com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar.EnumInterfaceUserExcludedJar");
}

@Test
public void testSolveSymbolInTypeCanResolveFirstEnumValue() {
assertCanSolveSymbol("ENUM_VAL_ONE", enumDeclarationConcrete);
}

@Test
public void testSolveSymbolInTypeCanResolveSecondEnumValue() {
assertCanSolveSymbol("ENUM_VAL_TWO", enumDeclarationConcrete);
}

@Test
public void testSolveSymbolInTypeCanResolveFirstNormalField() {
assertCanSolveSymbol("STATIC_STRING", enumDeclarationConcrete);
}

@Test
public void testSolveSymbolInTypeCanResolveSecondNormalField() {
assertCanSolveSymbol("SECOND_STRING", enumDeclarationConcrete);
}

@Test
public void testSolveSymbolInTypeCantResolveNonExistentField() {
SymbolReference<? extends ResolvedValueDeclaration> solvedSymbol = symbolSolver.solveSymbolInType(enumDeclarationConcrete, "FIELD_THAT_DOES_NOT_EXIST");

assertFalse(solvedSymbol.isSolved());

try {
solvedSymbol.getCorrespondingDeclaration();
} catch (Exception e) {
assertTrue(e instanceof UnsupportedOperationException);
assertNull(e.getMessage());
return;
}
fail("Expected UnsupportedOperationException when requesting CorrespondingDeclaration on unsolved SymbolRefernce");
}

@Test
public void testSolveSymbolInTypeCanResolveFieldInInterface() {
assertCanSolveSymbol("INTERFACE_FIELD", enumDeclarationInterfaceUserOwnJar);
}

@Test
@Ignore // TODO This fails at the moment, I think it might be an issue -- discussion ongoing on Gitter
public void testSolveSymbolInTypeCanResolveFieldInInterfaceIncludedJar() {
assertCanSolveSymbol("INTERFACE_FIELD", enumDeclarationInterfaceUserIncludedJar);
}

@Test
public void testSolveSymbolInTypeThrowsExceptionOnResolveFieldInInterfaceExcludedJar() {
try {
symbolSolver.solveSymbolInType(enumDeclarationInterfaceUserExcludedJar, "INTERFACE_FIELD");
} catch (Exception e) {
assertTrue(e.getCause() instanceof NotFoundException);
assertEquals("com.github.javaparser.javasymbolsolver.javassist_symbols.excluded_jar.InterfaceExcludedJar", e.getCause().getMessage());
return;
}
fail("Excepted NotFoundException wrapped in a RuntimeException, but got no exception.");
}

private void assertCanSolveSymbol(String symbolName, JavassistEnumDeclaration enumDeclaration) {
SymbolReference<? extends ResolvedValueDeclaration> solvedSymbol = symbolSolver.solveSymbolInType(enumDeclaration, symbolName);

assertTrue(solvedSymbol.isSolved());
assertEquals(symbolName, solvedSymbol.getCorrespondingDeclaration().asField().getName());
}
}
Binary file not shown.
@@ -0,0 +1,10 @@
package com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar;

public enum ConcreteEnum {
ENUM_VAL_ONE,
ENUM_VAL_TWO;

public static final String STATIC_STRING = "ThisIsAString";
public static final String SECOND_STRING = "ThisIsASecondString";

}
@@ -0,0 +1,7 @@
package com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar;

import com.github.javaparser.javasymbolsolver.javassist_symbols.excluded_jar.InterfaceExcludedJar;

public enum EnumInterfaceUserExcludedJar implements InterfaceExcludedJar {
OWN_ENUM_VAL
}
@@ -0,0 +1,7 @@
package com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar;

import com.github.javaparser.javasymbolsolver.javassist_symbols.included_jar.InterfaceIncludedJar;

public enum EnumInterfaceUserIncludedJar implements InterfaceIncludedJar {
OWN_ENUM_VAL
}
@@ -0,0 +1,5 @@
package com.github.javaparser.javasymbolsolver.javassist_symbols.main_jar;

public enum EnumInterfaceUserOwnJar implements InterfaceOwnJar {
OWN_ENUM_VAL
}

0 comments on commit 19b626c

Please sign in to comment.