Help: Query for Java methods with and without bodies using CodeQL and chaining queries #14626
-
Hello CodeQL community, I am trying to extract all the method names from a Java project using CodeQL. My objective is to list down all the methods, and if the method has a body, I would like to retrieve the method body as well. But the trouble is to achieve this goal with one query. I tried the following query:
However, I realized that this query only retrieves methods that have bodies and it omits methods without bodies. I have prompted GPT-4 dozens of times, but it kept giving me syntax errors and used grammar that doesn't exist in CodeQL. In addition to the above, I have another question: Is it possible in CodeQL to first write and run a query, save its results, and then write another query that builds upon the results of the first query? For instance, in the example I provided above, can I first query all method(names), save the results in a CSV file, and then write another query that reads from the CSV file to select the body of each method if any? Could someone guide me on how to modify the initial query to include methods without bodies as well? And provide insights on my second question about chaining queries? Any help or guidance would be greatly appreciated! Thank you! |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments
-
Method bodies: these aren't stored in the CodeQL database, but the file and lines where the method can be found are. Try using Storing data and then importing it into a subsequent query run can be done using an |
Beta Was this translation helpful? Give feedback.
-
With CodeQL you cannot Alternatively, you could select a dummy value for methods that do not have a body (for example an empty import java
class EmptyLocation extends Location {
EmptyLocation() { this.hasLocationInfo("", 0, 0, 0, 0) }
}
from Method m, Location body
where
body = m.getBody().getLocation()
or
not exists(m.getBody()) and body instanceof EmptyLocation and m.fromSource()
select m, body Note that I used If you like a result that is formatted as if they were CodeScanning alerts, then the following should work. Here the trick is to use a format string that contains either one /**
* @id methods
* @kind problem
* @severity info
*/
import java
from Method m, Top body, string format, string text
where
body = m.getBody() and format = "body: $@" and text = body.toString()
or
not exists(m.getBody()) and body = m and format = "no body" and text = "" and m.fromSource()
select m, format, body, text |
Beta Was this translation helpful? Give feedback.
-
Hi @aibaars, Suppose I have the following method that I want to extract (declaration + body):
I don't know how to write a query to return the location between 111 - 115. My current query returns two locations:
this assumption is mostly correct because the method name is rarely written in the second line of the method. thats why it fails for the example above because the start line misses |
Beta Was this translation helpful? Give feedback.
With CodeQL you cannot
select
things that do not exist, and CodeQL does not have aNULL
value like SQL does. You could run two queries, one selecting all methods that have a body and another selecting all methods that do not have a bodywhere not exists(m.getBody())
.Alternatively, you could select a dummy value for methods that do not have a body (for example an empty
Location
):Note that I used
m.fromSource()
…