Hi all,
I've been reading the documentation and looked for the answer in the forum here but with no luck so far.
I'm looking for a way to find and print all method declarations that calls a specific method calls within them (1) with a condition (2).
These method calls takes a string as an argument and optionally a parameter from the method deceleration.
The condition (2) I refer to is only these method calls with at least one parameter sent as an argument.
For example:
I want to find justAnExample1 method and print it's deceleration:
public void justAnExample1(String something) {
MyClass cl = method.subMethod("Bla bla bla and "+ something);
//.....some more functionality
}
but not justAnExample2:
public void justAnExample2(String something) {
MyClass cl = method.subMethod("Bla bla bla");
//.....some more functionality
System.out.println(something);
}
Any ideas how to achieve that?
Hi,
My recommendation would be the findAll() methods -- you can then filter the stream using whatever conditions you require, or do the same with more traditional loops if you need the "parent"/"ancestor" nodes.
It would look a little like this:
List<Node> resultNodes = new ArrayList<>();
allMethods = compilationUnit.findAll(MethodDeclarationExpr.class)
for(MethodDeclarationExpr mde : allMethods) {
if(mde.../*e.g. check parameters, or query nodes inside of here*/){
// Maybe you'll have nested conditions here, or maybe nested calls to mde.findAll()
resultNodes.add(mde);
}
}
If you need additional help knowing which nodes to search for, I recommend the book and this article:
Hi @MysterAitch,
Thanks for the quick answer.
The thing is that I read the whole book, been looking for a solution for quite some time now.
Your sketch of a solution looks good but what I'm specifically looking for is the condition inside the for loop. How do I find method calls inside inside method declarations?
I've been trying a different solution namely to find all the method calls of the specific method I'm looking for by using a visitor with MethodCallExpr.
However, I can not find a way to see where these method calls were made specifically under which method deceleration.
No worries -- the book isn't complete and I'm a little fuzzy on what is/isn't in there :)
What you describe is difficulty in a search algorithm, as opposed to anything javaparser-specific.
Consider this revised example which populates matchedMethodDeclarations with method declarations that contain a method call of println.
Specifically, note that nesting inside of the loop allows you to keep the "parent" method declaration (currentMethodDeclaration) in scope while you test conditions on nodes that exist inside of it.
To adapt this for your own needs, you'll need to edit the conditions applied (e.g. you might also want to resolve the method call, or test the number of parameters passed into the method call found).
List<MethodDeclarationExpr > matchedMethodDeclarations= new ArrayList<>();
allMethods = compilationUnit.findAll(MethodDeclarationExpr.class)
for(MethodDeclarationExpr currentMethodDeclaration : allMethods) {
List<MethodCallExpr> allNestedMethodCalls = currentMethodDeclaration.findAll(MethodCallExpr.class);
for(MethodCallExpr currentNestedMethodCall : allNestedMethodCalls) {
if("println".equals(currentMethodCall.getName().toString())) {
matchedMethodDeclarations.add(currentMethodDeclaration);
}
}
}
}
Probably another solution is to visit all MethodCallExpr corresponding to your case and then find a optional parent which is a method declaration (stopping recursion calls at Class declaration)