Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

<enum>::values() can not be resolved without the enum name #4416

Closed
Kimmmey opened this issue May 7, 2024 · 3 comments
Closed

<enum>::values() can not be resolved without the enum name #4416

Kimmmey opened this issue May 7, 2024 · 3 comments

Comments

@Kimmmey
Copy link
Contributor

Kimmmey commented May 7, 2024

Hi,

I have a problem with resolving the implicit method "values()" of an enum. Resolving is only possible, if the enum is given as the scope.

Example (does not work):

    @Test
    public void testResolveValuesMethod() {
        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 SecurityPolicyScopedTemplatesKeys m(int id) {\n" +
                "        return values()[id];\n" +
                "    }\n" +
                "}";
        TypeSolver typeSolver = new ReflectionTypeSolver();
        StaticJavaParser.getParserConfiguration().setSymbolResolver(new JavaSymbolSolver(typeSolver));
        CompilationUnit cu = StaticJavaParser.parse(s);
        MethodCallExpr methodCallExpr = cu.findFirst(MethodCallExpr.class).get();
        ResolvedMethodDeclaration rd = methodCallExpr.resolve();
        assertEquals("values", rd.getName());
        assertEquals("ClassTest.SecurityPolicyScopedTemplatesKeys[]", rd.getReturnType().describe());
    }

Example (does work):

    @Test
    public void testResolveValuesMethod() {
        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 SecurityPolicyScopedTemplatesKeys m(int id) {\n" +
                "        return SecurityPolicyScopedTemplatesKeys.values()[id];\n" +
                "    }\n" +
                "}";
        TypeSolver typeSolver = new ReflectionTypeSolver();
        StaticJavaParser.getParserConfiguration().setSymbolResolver(new JavaSymbolSolver(typeSolver));
        CompilationUnit cu = StaticJavaParser.parse(s);
        MethodCallExpr methodCallExpr = cu.findFirst(MethodCallExpr.class).get();
        ResolvedMethodDeclaration rd = methodCallExpr.resolve();
        assertEquals("values", rd.getName());
        assertEquals("ClassTest.SecurityPolicyScopedTemplatesKeys[]", rd.getReturnType().describe());
    }

I used EnumResolutionTest#testResolveValueOfMethod as a template for the example test.

Tested with 73d9c4f.

Best regards
Kim

@Kimmmey Kimmmey closed this as completed May 16, 2024
@Kimmmey
Copy link
Contributor Author

Kimmmey commented May 16, 2024

The tests have failures. A push request with optimized tests and a fix is incoming.

@jlerbsc
Copy link
Collaborator

jlerbsc commented May 16, 2024

The tests have failures

Could you be more specific?

@Kimmmey
Copy link
Contributor Author

Kimmmey commented May 17, 2024

Hi @jlerbsc,

yes, I can. The upper code fragment will never work, because method m is not inside of the enum but inside of the class ClassTest. So the values() method does not exist and therefore is not resolvable. It is easier to see, if we remove the String concatenation:

public class ClassTest {
    public enum SecurityPolicyScopedTemplatesKeys {
        SUSPICIOUS(\"suspicious\");
        private String displayName;

        private SecurityPolicyScopedTemplatesKeys(String displayName) {
            this.displayName = displayName;
        }

        public String getDisplayName() {
            return this.displayName;
        }
    }

    public SecurityPolicyScopedTemplatesKeys m(int id) {
        return values()[id];
    }
}

There is still an issue with the resolution of the implicit method values(), but resolving the MethocCallExpr works fine.

The remaining issue throws an exception, if I try to calculateResolvedType() of an expression containing the implicit method values(). Because calculateResolvedType() uses the method solveMethodAsUsage(...) and this method is not able to resolve the implicit method. Therefore, I will create a pull request with an additional test and a fix.

Best regards

Kim

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants