-1

I'm using JavaParser library and I would like how to do this: I want to parse a method and If there is a RestTemplate call, I want to get the "url" value. This is my method:

    public void myMethod() {
        try {
            String url = "http://www.google.com";
            ResponseEntity<String> response = restTemplate
                    .exchange(url, HttpMethod.GET, HttpEntity.EMPTY, String.class);
                    
        } catch (Exception exception) {
            //Error
        }
    }

So I want to extract the value of "url" but only if I find a restTemplate call before. In other words that it also serves me, I need the "url" value of the restTemplate call.

What I'm doing now is:

I assume that Url variable has a constant value, like: url = "google.com". So I want to read a MethodCallExpr that contains an "exchange" word, then I want to read the first param of the method (in this case, the param is "url") so I need to go "backward" to read the value of url, in this case "google.com". What I'm doing now is: Set an ArrayList with all class VariableDeclarators. Then read MethodCallExpr that contains RestTemplate. And finally, extract the first param of the method to get the value from the ArrayList. That's work but It's not very fancy.

But I want to know If there is a way to read "backwards" and remove my ArrayList that contains all class VariableDeclarations.

Luisao
  • 455
  • 2
  • 9
  • 20
  • Could you explain what it means "extract the value of 'url'"? Javaparser can give you an AST (abstract syntax tree) and resolves types. For example if you want to know the type of url parameter, sumbol solver can do it for you. But if you want to know the runtime value of url you have to chosse another "tool". In this case AOP can extract the value at runtime. – jpl Nov 15 '20 at 09:30
  • Hi, I assume that Url variable has a constant value, like: url = "http://www.google.com". So I want to read a MethodCallExpr that contains an "exchange" word, then I want to read the first param of the method (in this case, the param is "url") so I need to go "backward" to read the value of url, in this case "http://www.google.com". What I'm doing now is: Set an ArrayList with all class VariableDeclarators. Then read MethodCallExpr that contains RestTemplate. And finally, extract the first param of the method to get the value from the ArrayList. That's work but It's not very fancy. Thanks! – Luisao Nov 15 '20 at 10:00

2 Answers2

1

"But I want to know If there is a way to read "backwards" and remove my ArrayList that contains all class VariableDeclarations."

No need to read backwards. Once you get the parameter you can resolve it with symbol solver to obtain the declaration. At this stage if you want to analyze the AST you can use getWrapped method on the declaration. Below a simple example

CompilationUnit cu = StaticJavaParser.parse(code);
List<MethodCallExpr> methodCallExpr = cu.findAll(MethodCallExpr.class);
for (MethodCallExpr expr : methodCallExpr) {
    Expression arg = expr.getArgument(0);
    // test if it's a NameExpr
    ResolvedValueDeclaration vd = arg.asNameExpr().resolve();
    if (vd.isField()) {
        FieldDeclaration vde = ((JavaParserFieldDeclaration)vd).getWrappedNode();
        System.out.println(vde.getVariable(0).getInitializer().get());
    }
}
jpl
  • 347
  • 3
  • 11
  • Ok thank you, at the moment I receive: Symbol resolution not configured; but I suppose I have to configure more things. But I get the idea, thank you so much! – Luisao Nov 16 '20 at 07:48
0

With your own Visitor (inherited from VoidVisitorAdapter facility class) you can redefine the visit method public void visit(final MethodCallExpr n, final A arg) and then try to resolve the scope of this expression (if it exists). This also involves configuring the symbol solver with a JarTypeSolver for each libraries of your project and probably a ReflexionTypeSolver and JavaParserTypeSolver (for your source files). Below a example of the configuration

ParserConfiguration config = new ParserConfiguration();
CombinedTypeSolver cts = new CombinedTypeSolver(new ReflectionTypeSolver(false),new JavaParserTypeSolver(rootSourceDir.toFile()));
// for each library dependency 
cts.add(new JarTypeSolver(<path to the jar file>));
config.setSymbolResolver(new JavaSymbolSolver(cts));
StaticJavaParser.setConfiguration(config);
jpl
  • 347
  • 3
  • 11