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

nameExpr.resolve().isField() resolves incorrectly in certain context #4344

Open
YXL-123 opened this issue Mar 15, 2024 · 2 comments
Open

nameExpr.resolve().isField() resolves incorrectly in certain context #4344

YXL-123 opened this issue Mar 15, 2024 · 2 comments

Comments

@YXL-123
Copy link

YXL-123 commented Mar 15, 2024

I want to add this to the field reference that omits this in the method, but when there is a variable declaration with the same name in the method, the field reference before the variable declaration will be resolved as a variable instead of a field.
Main function

    public static void main(String[] args) throws IOException {
        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(Paths.get("This.java"));
        ModifierVisitor visit = new ModifierVisitor(){
            public Visitable visit(MethodDeclaration n, Void arg) {
                List<NameExpr> all = n.findAll(NameExpr.class);
                all.stream().filter(nameExpr -> {
                    try {
                        if (nameExpr.resolve().isField())
                            return true;
                    } catch (UnsolvedSymbolException e){
                        return false;
                    }
                    return false;
                }).forEach(nameExpr -> {
                    Node parent = nameExpr.getParentNode().get();
                    if(parent instanceof FieldAccessExpr && ((FieldAccessExpr) parent).getScope() instanceof ThisExpr) return;
                    FieldAccessExpr fieldAccessExpr = NodeFactory.getFieldAccessExpr(new ThisExpr(), nameExpr.getName());
                    nameExpr.replace(fieldAccessExpr);
                });
                return super.visit(n, arg);
            }
        };
        visit.visit(result.getResult().get(), null);
        System.out.println(result.getResult().get());
    }

This.java

public class This {
    int x = 5;

    void test(){
        System.out.println(x++);  // x here is field
        int x = 0;
        System.out.println(x++);  // x here is the variable
    }
}

output:

public class This {

int x = 5;

void test() {
    // x here is field
    System.out.println(x++);
    int x = 0;
    // x here is the variable
    System.out.println(x++);
}

}

@jlerbsc
Copy link
Collaborator

jlerbsc commented Mar 15, 2024

This is a bug that has already been identified but for which we do not yet have a solution.

It appears when JP tries to resolve a symbol in a block. JP tries to search for a variable declaration from the last statement in the block when it should be searching from the statement preceding the node being processed.

At this stage JP doesn't have this notion (current node) so it can't position itself correctly.

Fixing this problem would require an in-depth modification of the API. Uunfortunately, this is a design problem which will take time to fix.

@jlerbsc
Copy link
Collaborator

jlerbsc commented Mar 15, 2024

Related to #3674

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