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

MethodCallExpr inside lambda in assignment expression cannot be resolved #4399

Open
YXL-123 opened this issue Apr 29, 2024 · 4 comments
Open

Comments

@YXL-123
Copy link

YXL-123 commented Apr 29, 2024

    public static void main(String[] args) throws IOException {
        String code = """
                import java.util.ArrayList;
                import java.util.List;
                public class Lambda {
                    interface MyInterface {
                        void doSomething(int a);
                    }
                      
                    void test(){
                        MyInterface myInterface;
                        ArrayList<Integer> list = new ArrayList<>();
                        list.forEach(val -> System.out.println(val));
                        myInterface = arg -> System.out.println(arg);
                    }
                }
                """;
        JavaParser javaParser = new JavaParser();
        TypeSolver typeSolver = new CombinedTypeSolver(new ReflectionTypeSolver());
        JavaSymbolSolver symbolSolver = new JavaSymbolSolver(typeSolver);
        javaParser.getParserConfiguration().setSymbolResolver(symbolSolver);
        javaParser.getParserConfiguration().setLanguageLevel(ParserConfiguration.LanguageLevel.JAVA_17);
        ParseResult<CompilationUnit> result = javaParser.parse(code);
        ModifierVisitor<Void> visit = new ModifierVisitor<>(){
            public Visitable visit(MethodCallExpr n, Void arg) {
                ResolvedMethodDeclaration resolve = n.resolve();
                System.out.println(resolve.getQualifiedSignature());
                return super.visit(n, arg);
            }
        };
        visit.visit(result.getResult().get(), null);
        System.out.println(result.getResult().get());
    }

Hi, I'm trying to get the QualifiedSignature of MethodCallExpr but I'm getting a parsing error when MethodCallEcpr is in the lambda expression. In the above example, the lambda in the foreach does not give an error, but when it is used as the value of the assignment statement, the following error occurs. Is my usage wrong? Thank you.

Exception in thread "main" java.lang.UnsupportedOperationException: Unknown node type: AssignExpr
at com.github.javaparser.symbolsolver.javaparsermodel.contexts.LambdaExprContext.solveSymbolAsValue(LambdaExprContext.java:198)
at com.github.javaparser.symbolsolver.javaparsermodel.declarations.JavaParserParameterDeclaration.getType(JavaParserParameterDeclaration.java:63)
at com.github.javaparser.resolution.model.Value.from(Value.java:45)
at com.github.javaparser.resolution.Context.solveSymbolAsValueInParentContext(Context.java:199)
at com.github.javaparser.symbolsolver.javaparsermodel.contexts.MethodCallExprContext.solveSymbolAsValue(MethodCallExprContext.java:145)
at com.github.javaparser.symbolsolver.resolution.SymbolSolver.solveSymbolAsValue(SymbolSolver.java:76)
at com.github.javaparser.symbolsolver.resolution.SymbolSolver.solveSymbolAsValue(SymbolSolver.java:82)
at com.github.javaparser.symbolsolver.javaparsermodel.TypeExtractor.visit(TypeExtractor.java:334)
at com.github.javaparser.symbolsolver.javaparsermodel.TypeExtractor.visit(TypeExtractor.java:64)
at com.github.javaparser.ast.expr.NameExpr.accept(NameExpr.java:81)

@jlerbsc
Copy link
Collaborator

jlerbsc commented Apr 29, 2024

This case is not currently covered. Thank you for reporting this bug.

@YXL-123
Copy link
Author

YXL-123 commented Apr 29, 2024

OK, thank you for your reply.

@jlerbsc
Copy link
Collaborator

jlerbsc commented Apr 29, 2024

This is not trivial, because to resolve the println(..) method Javaparser has to resolve the type of the parameter, which is undefined at this stage. I don't see any precision on this point in the JLS. If you can clarify what needs to be done, I can try to resolve this bug quickly.

            public class Lambda {
                interface MyInterface {
                    void doSomething(int a);
                }

                void test(){
                    MyInterface myInterface;
                    myInterface = arg -> System.out.println(arg);
                }
            }

Decompiling the class doesn't provide any information either.

Compiled from "Lambda.java"
public class Lambda {
  public Lambda();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  void test();
    Code:
       0: invokedynamic #2,  0              // InvokeDynamic #0:doSomething:()LLambda$MyInterface;
       5: astore_1
       6: return
}

@YXL-123
Copy link
Author

YXL-123 commented May 11, 2024

Thanks, we try to distinguish function overloading by getting the QualifiedSignature of MethodCallExpr and get its method descriptor.

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

No branches or pull requests

2 participants