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

Static MethodCallExpr Resolving Problem #1491

Closed
seoj135 opened this issue Apr 3, 2018 · 9 comments
Closed

Static MethodCallExpr Resolving Problem #1491

seoj135 opened this issue Apr 3, 2018 · 9 comments
Assignees
Labels
Improvement Not a bug, but a way that JP can be be enhanced to work better. Symbol Solver
Milestone

Comments

@seoj135
Copy link

seoj135 commented Apr 3, 2018

Hello. When I tried to resolve methodcallexpr, I found some bug.
This is on 3.5.20.

  1. Call Static Function on Iterable, ForeachStmt problem.
    MethodCallExprContext line 157: context return null. So It Throw RuntimeException
    I guess some errors on solveType() function on StatementContext(Wrapped BlockStmt).
    Here is target project from git: https://github.com/davidar/lljvm
    and positions is src/lljvm/runtime/Function.java line 22.
TypeSolver Settings: 
   ReflectionTypeSolver
   JavaParserTypeSolver(Root of project)
   JavaParserTypeSolver(Root of Java base libraries, I zipped out it to my custom directory)
  1. visit NameExpr problem.
    So To find the solution to the first bug, I make some short code and found another bug.
    How to fix UnsolvedSymbolException?
    Why does not some nodes resolve?
    !ref.isSolved()

Here is my whole test code:

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;

import com.github.javaparser.JavaParser;
import com.github.javaparser.ParserConfiguration;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.expr.MethodCallExpr;
import com.github.javaparser.ast.expr.NameExpr;
import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
import com.github.javaparser.resolution.declarations.ResolvedMethodDeclaration;
import com.github.javaparser.resolution.types.ResolvedType;
import com.github.javaparser.symbolsolver.JavaSymbolSolver;
import com.github.javaparser.symbolsolver.javaparsermodel.JavaParserFacade;
import com.github.javaparser.symbolsolver.resolution.typesolvers.CombinedTypeSolver;
import com.github.javaparser.symbolsolver.resolution.typesolvers.JavaParserTypeSolver;
import com.github.javaparser.symbolsolver.resolution.typesolvers.ReflectionTypeSolver;

public class test {
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public static void main(String[] args) {
		String code = 
			"public class A { " + 
				"public int FUNC() { Class<?> cls = null; if(cls == null) return 0; else { B.FUNC3(cls); return 1;} } " +
				"public void FUNC2(Class<?> arg) { return; }" +
			"}" + 
			"class B {" + 
				"public static void FUNC3(Class<?> arg) { return; }" +
			"}" +
			"";
		File file = new File("A.java");
		try {
			file.createNewFile();
			FileWriter fw = new FileWriter(file);
			fw.write(code);
			fw.flush();
			fw.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		CombinedTypeSolver localCts = new CombinedTypeSolver();
		localCts.add(new ReflectionTypeSolver());
		localCts.add(new JavaParserTypeSolver(file.getAbsoluteFile().getParentFile()));
		
		ParserConfiguration parserConfiguration = new ParserConfiguration().setSymbolResolver(new JavaSymbolSolver(localCts));
		JavaParser.setStaticConfiguration(parserConfiguration);
		
		CompilationUnit cu = JavaParser.parse(code);
		cu.accept(new VoidVisitorAdapter() {
			public void visit(NameExpr n, Object arg) {				
				ResolvedType type = JavaParserFacade.get(localCts) .getType(n);
				super.visit(n, args);
			}
			public void visit(MethodCallExpr n, Object arg) {
				ResolvedMethodDeclaration decl = JavaParserFacade.get(localCts).solve(n).getCorrespondingDeclaration();
				super.visit(n, args);       // <---------- bug is occur.
                                // Exception in thread "main" UnsolvedSymbolException{context='Solving B', name='B', typeSolver=null}
			}
		}, null);
	}
}
@malteskoruppa
Copy link
Collaborator

malteskoruppa commented Apr 4, 2018

Concerning your second problem, I can answer the question. (But I don't know about the first problem you mentioned).

What's happening here is that in this part of your code:

public void visit(NameExpr n, Object arg) {				
	ResolvedType type = JavaParserFacade.get(localCts) .getType(n);
	super.visit(n, args);
}

...you are visiting the scope of the method call expression B.FUNC3(cls); within the function A#FUNC() of the code that you are parsing. This scope is a NameExpr with the name B.

You then try to resolve the type of the NameExpr with the name B. However, B is already a type. Java Symbol Solver (understandably) can't resolve the type of a type, so it throws the UnsolvedSymbolException{context='Solving B', name='B', typeSolver=null} that you are seeing.

If you only wish to resolve the called method, you can simply resolve the entire MethodCallExpr as you are already doing in your visit method for MethodCallExpr. Basically, just throw away your visit method for NameExpr and you'll be fine.

If, however, you do wish to resolve the type of the scope, then make sure that you only try to do so when the scope is an expression that can be resolved to a type but not a type by itself. Unfortunately, JSS provides no way to distinguish these two cases. This is a known problem (see #1439, #1480 for ample discussions about this problem).

@ftomassetti
Copy link
Member

Reading the first problem: the indicated file on line 22 has a blank line.

I am ignoring the first point and looking at the test code.

ftomassetti added a commit to ftomassetti/javaparser that referenced this issue Jul 8, 2018
@ftomassetti
Copy link
Member

I think the issue here is that getType is invoked on the name of a type (as it is used on static field accesses). The problem is that getType was intended only to be used on values. So I changed it to allow to be used also on names of types because this seems a common misconception about that method.

@ftomassetti
Copy link
Member

Which by the way was what @malteskoruppa correctly figured out months ago :D

@ftomassetti
Copy link
Member

Removing bug report label as in my opinion is not a bug but it is clearly a confusing API that we should clarify and improve.

@matozoid
Copy link
Contributor

matozoid commented Jul 8, 2018

Isn't it more or less solved now?

ftomassetti added a commit to ftomassetti/javaparser that referenced this issue Jul 8, 2018
@ftomassetti
Copy link
Member

Yes, my understanding is that we can merge the PR and then close this task

matozoid added a commit that referenced this issue Jul 8, 2018
Add a test for #1491 and modify the behavior of JavaParserFacade.getType
@matozoid matozoid added this to the next release milestone Jul 8, 2018
@matozoid matozoid added the Improvement Not a bug, but a way that JP can be be enhanced to work better. label Jul 9, 2018
@malteskoruppa
Copy link
Collaborator

@ftomassetti Awesome, thanks for this! :-)

@ftomassetti
Copy link
Member

Thank you @malteskoruppa !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Improvement Not a bug, but a way that JP can be be enhanced to work better. Symbol Solver
Projects
None yet
Development

No branches or pull requests

4 participants