Repository: javaparser/javaparser

Issue #4568: Resolution of ObjectCreationExprs broken 3.26.2
Created: 2024-09-29T15:07:33Z
Hi,
this is the other problem I mentioned in #4557. Since 3.26.2 the resolution of ObjectCreationExprs is broken. I don't know exactly which change triggers this, but the test (see below) runs without problems with tag 3.26.1 but with tag 3.26.2 the ObjectCreationExpr resolution fails. I have tried to find the change causing this, but without success. There were a lot of changes between the two tags and, above all, none that I could blame at first glance. I am also not sure if this is the only expression that cannot be resolved.

  Test
package com.github.javaparser.symbolsolver;

import com.github.javaparser.StaticJavaParser;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.expr.Expression;
import com.github.javaparser.ast.expr.NameExpr;
import com.github.javaparser.ast.expr.ObjectCreationExpr;
import com.github.javaparser.resolution.declarations.ResolvedConstructorDeclaration;
import com.github.javaparser.resolution.declarations.ResolvedValueDeclaration;
import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;

import java.util.List;

public class Test {

    @org.junit.jupiter.api.Test
    public void test() {
        String code = "public class Board {\n" +
                      "\n" +
                      "    class Field {\n" +
                      "        private final Board board;\n" +
                      "        private final int x;\n" +
                      "        private final int y;\n" +
                      "\n" +
                      "        public Field(Board board, int x, int y) {\n" +
                      "            this.board = board;\n" +
                      "            this.x = x;\n" +
                      "            this.y = y;\n" +
                      "        }\n" +
                      "    }\n" +
                      "\n" +
                      "    /**\n" +
                      "     * Edge size of the Sudoku board.\n" +
                      "     */\n" +
                      "    public static final int SIZE = 9;\n" +
                      "    private final Field[] board = new Field[SIZE * SIZE];\n" +
                      "\n" +
                      "    /**\n" +
                      "     * Creates a Sudoku board with all of its fields being empty.\n" +
                      "     */\n" +
                      "    public Board() {\n" +
                      "        for (int x = 0; x < SIZE; x++)\n" +
                      "            for (int y = 0; y < SIZE; y++)\n" +
                      "                board[SIZE * y + x] = new Field(this, x, y);\n" +
                      "    }\n" +
                      "}";
        StaticJavaParser.getParserConfiguration().setSymbolResolver(new JavaSymbolSolver(new ReflectionTypeSolver()));
        CompilationUnit cu = StaticJavaParser.parse(code);

        final List<ObjectCreationExpr> objectCreationExprs = cu.findAll(ObjectCreationExpr.class);

        for (ObjectCreationExpr objectCreationExpr : objectCreationExprs) {
            System.err.println(objectCreationExpr.toString());
            for (Expression e : objectCreationExpr.getArguments()) {
                System.err.println(e.toString());
                if (e.isNameExpr()) {
                    NameExpr ne = e.asNameExpr();
                    final ResolvedValueDeclaration resolve = ne.resolve();
                    System.err.println(resolve);
                    System.err.println(resolve.getType().describe());
                }
            }
            final ResolvedConstructorDeclaration resolve = objectCreationExpr.resolve();
            System.err.println(resolve.getQualifiedName());
            System.err.println(resolve.getQualifiedSignature());
        }
    }
}

Output 3.26.1
[INFO] Running com.github.javaparser.symbolsolver.Test
new Field(this, x, y)
this
x
JavaParserVariableDeclaration{x}
int
y
JavaParserVariableDeclaration{y}
int
Board.Field.Field
Board.Field.Field(Board, int, int)

Output 3.26.2
[INFO] Running com.github.javaparser.symbolsolver.Test
new Field(this, x, y)
this
x
JavaParserVariableDeclaration{x}
int
y
JavaParserVariableDeclaration{y}
int
[ERROR] Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.326 s <<< FAILURE! -- in com.github.javaparser.symbolsolver.Test
[ERROR] com.github.javaparser.symbolsolver.Test.test -- Time elapsed: 0.302 s <<< ERROR!
UnsolvedSymbolException{context='x', name='Solving x', cause='null'}
        at com.github.javaparser.symbolsolver.javaparsermodel.TypeExtractor.visit(TypeExtractor.java:339)
        at com.github.javaparser.symbolsolver.javaparsermodel.TypeExtractor.visit(TypeExtractor.java:63)
        at com.github.javaparser.ast.expr.NameExpr.accept(NameExpr.java:80)
        at com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getTypeConcrete(JavaParserFacade.java:533)
        at com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.getType(JavaParserFacade.java:394)
        at com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.solveArguments(JavaParserFacade.java:273)
        at com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.solve(JavaParserFacade.java:231)
        at com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade.solve(JavaParserFacade.java:141)
        at com.github.javaparser.symbolsolver.JavaSymbolSolver.resolveDeclaration(JavaSymbolSolver.java:202)
        at com.github.javaparser.ast.expr.ObjectCreationExpr.resolve(ObjectCreationExpr.java:379)
        at com.github.javaparser.symbolsolver.Test.test(Test.java:63)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
        at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)

I'm happy to provide more information and try to help with the solution, but I can't get any further for now.
best regards,
Kim

Duplicate issue #4585: fail to resolve for loop variable
Created: 2024-10-16T13:26:04Z
Consider the following scenario, where every NameExpr is being resolved.
val src = """
           class Dummy { 
               Dummy(int a, int b) {
               
               }
           }
          class Test {
           static Dummy[] test(int n) {
               Dummy[] array = new Dummy[n];
               for(int i = 0; i < n; i++) {
                   array[i] = new Dummy(i, i);
                }
               return array;
           }
         
        }
       """.trimIndent()
StaticJavaParser.getParserConfiguration().setLanguageLevel(ParserConfiguration.LanguageLevel.JAVA_20)
StaticJavaParser.getParserConfiguration().setSymbolResolver(JavaSymbolSolver(CombinedTypeSolver()))

val cu = StaticJavaParser.parse(src)
cu.findAll(NameExpr::class.java).forEach {
     val r = it.calculateResolvedType()
     println(it.nameAsString + ": " + r.toString())
}
For some reason, on "new Dummy(i, i)", i fails to resolve.
Note: when having the declaration outside the loop, it resolves fine.
int i = 0;
for( ; i < n; i++) {
   array[i] = new Dummy(i, i);
}

Closing comment (2024-10-16T14:18:14Z): This could be a duplicate of #4568, which was fixed with #4577, but is not yet published.

You could be right. I kept debugging and noticed the resolution of i in array[i] ended up calling the solveSymbol method of the ForStatementContext class, which takes into account the initialisation.
Thanks for the (very) quick input!