Skip to content

Commit

Permalink
Merge pull request #2652 from maartenc/Issue2325
Browse files Browse the repository at this point in the history
  • Loading branch information
MysterAitch committed May 11, 2020
2 parents cac75a4 + 1d1625c commit 756fa45
Show file tree
Hide file tree
Showing 2 changed files with 165 additions and 1 deletion.
Expand Up @@ -206,6 +206,12 @@ public SymbolReference<ResolvedMethodDeclaration> solveMethod(String name, List<
if (name.equals("values") && argumentsTypes.isEmpty()) {
return SymbolReference.solved(new JavaParserEnumDeclaration.ValuesMethod(this, typeSolver));
}
if (name.equals("valueOf") && argumentsTypes.size() == 1) {
ResolvedType argument = argumentsTypes.get(0);
if (argument.isReferenceType() && "java.lang.String".equals(argument.asReferenceType().getQualifiedName())) {
return SymbolReference.solved(new JavaParserEnumDeclaration.ValueOfMethod(this, typeSolver));
}
}
return getContext().solveMethod(name, argumentsTypes, staticOnly);
}

Expand Down Expand Up @@ -305,7 +311,17 @@ public List<ResolvedEnumConstantDeclaration> getEnumConstants() {
.collect(Collectors.toList());
}

// Needed by ContextHelper

/**
* Needed by ContextHelper
*
* An implicitly declared method {@code public static E[] values()}, which returns an array containing the
* enum constants of {@code E}, in the same order as they appear in the body of the declaration of E.
*
* @see <a href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.9.2">https://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.9.2</a>
* @see <a href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.9.3">https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.9.3</a>
* @see <a href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-8.9.3">https://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-8.9.3</a>
*/
public static class ValuesMethod implements ResolvedMethodDeclaration, TypeVariableResolutionCapability {

private JavaParserEnumDeclaration enumDeclaration;
Expand Down Expand Up @@ -390,6 +406,120 @@ public Optional<MethodDeclaration> toAst() {
}
}


/**
* Needed by ContextHelper
* An implicitly declared method {@code public static E valueOf(String name)}, which returns the
* enum constant of {@code E} with the specified name.
*
* @see <a href="https://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.9.2">https://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.9.2</a>
* @see <a href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.9.3">https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.9.3</a>
* @see <a href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-8.9.3">https://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-8.9.3</a>
*/
public static class ValueOfMethod implements ResolvedMethodDeclaration, TypeVariableResolutionCapability {

private JavaParserEnumDeclaration enumDeclaration;
private TypeSolver typeSolver;

public ValueOfMethod(JavaParserEnumDeclaration enumDeclaration, TypeSolver typeSolver) {
this.enumDeclaration = enumDeclaration;
this.typeSolver = typeSolver;
}

@Override
public ResolvedReferenceTypeDeclaration declaringType() {
return enumDeclaration;
}

@Override
public ResolvedType getReturnType() {
return new ReferenceTypeImpl(enumDeclaration, typeSolver);
}

@Override
public int getNumberOfParams() {
return 1;
}

@Override
public ResolvedParameterDeclaration getParam(int i) {
if (i == 0) {
return new ResolvedParameterDeclaration() {
@Override
public String getName() {
return "name";
}

@Override
public ResolvedType getType() {
return new ReferenceTypeImpl(typeSolver.solveType("java.lang.String"), typeSolver);
}

@Override
public boolean isVariadic() {
return false;
}
};
}

throw new IllegalArgumentException("Invalid parameter index!");
}

public MethodUsage getUsage(Node node) {
throw new UnsupportedOperationException();
}

@Override
public MethodUsage resolveTypeVariables(Context context, List<ResolvedType> parameterTypes) {
return new MethodUsage(this);
}

@Override
public boolean isAbstract() {
return false;
}

@Override
public boolean isDefaultMethod() {
return false;
}

@Override
public boolean isStatic() {
return true;
}

@Override
public String getName() {
return "valueOf";
}

@Override
public List<ResolvedTypeParameterDeclaration> getTypeParameters() {
return Collections.emptyList();
}

@Override
public AccessSpecifier accessSpecifier() {
return AccessSpecifier.PUBLIC;
}

@Override
public int getNumberOfSpecifiedExceptions() {
return 0;
}

@Override
public ResolvedType getSpecifiedException(int index) {
throw new UnsupportedOperationException("The valueOf method of an enum does not throw any exception");
}

@Override
public Optional<MethodDeclaration> toAst() {
return Optional.empty();
}
}

@Override
public AccessSpecifier accessSpecifier() {
return wrappedNode.getAccessSpecifier();
Expand Down
Expand Up @@ -34,13 +34,15 @@
import com.github.javaparser.ast.stmt.ReturnStmt;
import com.github.javaparser.ast.stmt.SwitchStmt;
import com.github.javaparser.resolution.declarations.ResolvedEnumConstantDeclaration;
import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
import com.github.javaparser.resolution.types.ResolvedType;
import com.github.javaparser.symbolsolver.JavaSymbolSolver;
import com.github.javaparser.symbolsolver.javaparser.Navigator;
import com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserEnumDeclaration;
import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
import com.github.javaparser.symbolsolver.model.resolution.SymbolReference;
import com.github.javaparser.symbolsolver.model.resolution.TypeSolver;
import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
import org.junit.jupiter.api.Test;

Expand Down Expand Up @@ -123,4 +125,36 @@ void enumAccessSpecifier() {
}
}

@Test
public void testResolveValueOfMethod() {
String s =
"public class ClassTest {\n" +
" public enum SecurityPolicyScopedTemplatesKeys {\n" +
" SUSPICIOUS(\"suspicious\");\n" +
" private String displayName;\n" +
"\n" +
" private SecurityPolicyScopedTemplatesKeys(String displayName) {\n" +
" this.displayName = displayName;\n" +
" }\n" +
"\n" +
" public String getDisplayName() {\n" +
" return this.displayName;\n" +
" }\n" +
" }\n" +
"\n" +
" public void m() {\n" +
" SecurityPolicyScopedTemplatesKeys a = SecurityPolicyScopedTemplatesKeys.valueOf(\"SUSPICIOUS\");\n" +
" }\n" +
"}";
TypeSolver typeSolver = new ReflectionTypeSolver();
StaticJavaParser.getConfiguration().setSymbolResolver(new JavaSymbolSolver(typeSolver));
CompilationUnit cu = StaticJavaParser.parse(s);
MethodCallExpr methodCallExpr = cu.findFirst(MethodCallExpr.class).get();
ResolvedMethodDeclaration rd = methodCallExpr.resolve();
assertEquals("valueOf", rd.getName());
assertEquals("ClassTest.SecurityPolicyScopedTemplatesKeys", rd.getReturnType().describe());
assertEquals(1, rd.getNumberOfParams());
assertEquals("java.lang.String", rd.getParam(0).describeType());
}

}

0 comments on commit 756fa45

Please sign in to comment.