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

Symbol solver is unable to resolve inherited inner classes #3946

Closed
freya022 opened this issue Mar 11, 2023 · 5 comments · Fixed by #4314
Closed

Symbol solver is unable to resolve inherited inner classes #3946

freya022 opened this issue Mar 11, 2023 · 5 comments · Fixed by #4314
Labels
Bug report Symbol Solver Workaround provided Issue for which a resolution is proposed. The issue is no longer a priority.

Comments

@freya022
Copy link
Contributor

Problem

The symbol solver is unable to resolve the return type of ActivityImpl#getTimestamps due to a change introduced in 3.25.1

Test code
import com.github.javaparser.StaticJavaParser;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
import com.github.javaparser.symbolsolver.JavaSymbolSolver;
import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
import org.intellij.lang.annotations.Language;

import java.util.List;

public class JavaParserBugTest {
    public static void main(String[] args) {
        @Language("Java")
        final String code = """
                interface Activity {
                    class Timestamps {}
                    enum ActivityType {}
                
                    @Nonnull
                    ActivityType getType();
                    
                    @Nullable
                    Timestamps getTimestamps();
                }
                
                interface RichPresence extends Activity {}
                
                class ActivityImpl implements Activity {
                    @Nonnull
                    @Override
                    public ActivityType getType() { return type; }
                
                    @Nullable
                    public RichPresence.Timestamps getTimestamps() { return timestamps; }
                }
                
                class RichPresenceImpl extends ActivityImpl implements RichPresence { }
                """;

        final JavaSymbolSolver solver = new JavaSymbolSolver(new ReflectionTypeSolver(false));

        StaticJavaParser.getParserConfiguration().setSymbolResolver(solver);
        final CompilationUnit compilationUnit = StaticJavaParser.parse(code);

        final List<String> returnTypes = compilationUnit.findAll(ClassOrInterfaceDeclaration.class)
                .stream()
                .map(ClassOrInterfaceDeclaration::resolve)
                .flatMap(typeDeclaration -> typeDeclaration.getDeclaredMethods().stream())
                .map(ResolvedMethodDeclaration::getReturnType)
                .map(Object::toString)
                .toList();

        System.out.println("returnTypes = " + returnTypes);
    }
}
Exception
Exception in thread "main" UnsolvedSymbolException{context='null', name='RichPresence.Timestamps', cause='null'}
	at com.github.javaparser.ast.type.ClassOrInterfaceType.convertToUsage(ClassOrInterfaceType.java:347)
	at com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.convertToUsage(JavaParserFacade.java:609)
	at com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.convert(JavaParserFacade.java:642)
	at com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserMethodDeclaration.getReturnType(JavaParserMethodDeclaration.java:87)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
	at java.base/java.util.HashMap$KeySpliterator.forEachRemaining(HashMap.java:1715)
	at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:762)
	at java.base/java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:276)
	at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
	at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625)
	at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
	at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:575)
	at java.base/java.util.stream.AbstractPipeline.evaluateToArrayNode(AbstractPipeline.java:260)
	at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:616)
	at java.base/java.util.stream.ReferencePipeline.toArray(ReferencePipeline.java:622)
	at java.base/java.util.stream.ReferencePipeline.toList(ReferencePipeline.java:627)
	at com.freya02.docs.JavaParserBugTest.main(JavaParserBugTest.java:53)

Workaround

Stay on 3.25.0

Details

The bug may be similar to the one fixed in 3.25.0+ (#3868)

@jlerbsc
Copy link
Collaborator

jlerbsc commented Mar 12, 2023

@freya022 I'm sorry for this setback but I can't move forward on this if your test case doesn't compile. Moreover, all the test cases run correctly, so it was difficult to anticipate the issue that you observed.

This is a special case that can be solved by removing the prefix in the return type "RichPresence.Timestamps" or replacing it with Activity. This is not a satisfactory answer, but it is a workaround that will allow you to avoid encountering this error.

@jlerbsc jlerbsc added Bug report Symbol Solver Workaround provided Issue for which a resolution is proposed. The issue is no longer a priority. labels Mar 12, 2023
@freya022
Copy link
Contributor Author

freya022 commented Mar 12, 2023

To be clear, the earlier issue I linked has no issues, and does still pass the test cases, I was just thinking that this new issue could be related to it.

Here's the unit test:

import com.github.javaparser.StaticJavaParser;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.symbolsolver.resolution.AbstractResolutionTest;
import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;
import org.junit.jupiter.api.Test;

import java.util.List;
import java.util.stream.Collectors;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class Issue3946Test extends AbstractResolutionTest {

    @Test
    void test() {

        String code =
                "interface Activity {\n" +
                "    class Timestamps {}\n" +
                "    \n" +
                "    Timestamps getTimestamps();\n" +
                "}\n" +
                "\n" +
                "interface RichPresence extends Activity {}\n" +
                "\n" +
                "class ActivityImpl implements Activity {\n" +
                "    public RichPresence.Timestamps getTimestamps() { return timestamps; }\n" +
                "}\n" +
                "\n" +
                "class RichPresenceImpl extends ActivityImpl implements RichPresence { }";

        final JavaSymbolSolver solver = new JavaSymbolSolver(new ReflectionTypeSolver(false));
        StaticJavaParser.getParserConfiguration().setSymbolResolver(solver);
        final CompilationUnit compilationUnit = StaticJavaParser.parse(code);

        final List<String> returnTypes = compilationUnit.findAll(MethodDeclaration.class)
                .stream()
                .map(md -> md.resolve())
                .map(rmd -> rmd.getReturnType().describe())
                .collect(Collectors.toList());

        returnTypes.forEach(type -> assertEquals("Activity.Timestamps", type));
    }
}

@jlerbsc
Copy link
Collaborator

jlerbsc commented Mar 12, 2023

Thanks for reporting this new issue.

@jlerbsc
Copy link
Collaborator

jlerbsc commented Mar 18, 2023

To be clear, the earlier issue I linked has no issues

To be clear the error was in the code that JP needs to analyze.

@freya022
Copy link
Contributor Author

To be clear, the earlier issue I linked has no issues

To be clear the error was in the code that JP needs to analyze.

Alright, is the full unit test provided enough?

jlerbsc added a commit that referenced this issue Feb 7, 2024
Fix: issue #3946 Symbol solver is unable to resolve inherited inner classes
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug report Symbol Solver Workaround provided Issue for which a resolution is proposed. The issue is no longer a priority.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants