refactor some code out into a helper class QueryDoc

This commit is contained in:
erik-krogh
2022-08-17 22:56:46 +02:00
parent 5e53124217
commit f738567f96
2 changed files with 32 additions and 10 deletions

View File

@@ -176,6 +176,29 @@ class QLDoc extends TQLDoc, Comment {
override AstNode getParent() { result.getQLDoc() = this }
}
/** The QLDoc for a query (i.e. the top comment in a .ql file). */
class QueryDoc extends QLDoc {
QueryDoc() {
this.getLocation().getFile().getExtension() = "ql" and
this = any(TopLevel t).getQLDoc()
}
override string getAPrimaryQlClass() { result = "QueryDoc" }
/** Gets the @kind for the query */
string getQueryKind() { result = this.getContents().regexpCapture("(?s).*@kind (\\w+)\\s.*", 1) }
/** Gets the id part (without language) of the @id */
string getQueryId() {
result = this.getContents().regexpCapture("(?s).*@id (\\w+)/([\\w\\-]+)\\s.*", 2)
}
/** Gets the language of the @id */
string getQueryLanguage() {
result = this.getContents().regexpCapture("(?s).*@id (\\w+)/([\\w\\-]+)\\s.*", 1)
}
}
class BlockComment extends TBlockComment, Comment {
QL::BlockComment comment;
@@ -237,6 +260,8 @@ class Select extends TSelect, AstNode {
}
override string getAPrimaryQlClass() { result = "Select" }
QueryDoc getQueryDoc() { result.getLocation().getFile() = this.getLocation().getFile() }
}
class PredicateOrBuiltin extends TPredOrBuiltin, AstNode {

View File

@@ -31,13 +31,10 @@ string getMessage(Select sel) {
* This fingerprint avoid false positives where two queries with the same ID behave differently (which is OK).
*/
string getSelectFingerPrint(Select sel) {
exists(File file, QLDoc doc |
sel.getLocation().getFile() = file and
any(TopLevel top | top.getLocation().getFile() = file).getQLDoc() = doc
|
exists(QueryDoc doc | doc = sel.getQueryDoc() |
result =
doc.getContents().regexpCapture("(?s).*@id (\\w+)/([\\w\\-]+)\\s.*", 2) // query ID (without lang)
+ "-" + doc.getContents().regexpCapture("(?s).*@kind (\\w+)\\s.*", 1) // @kind
doc.getQueryId() // query ID (without lang)
+ "-" + doc.getQueryKind() // @kind
+ "-" +
strictcount(String e | e.getParent*() = sel.getExpr(any(int i | i % 2 = 1))) // the number of string constants in the select
+ "-" + count(sel.getExpr(_)) // and the total number of expressions in the select
@@ -49,10 +46,10 @@ string getSelectFingerPrint(Select sel) {
* The query-id (without language), the language, the message from the select, and a language agnostic fingerprint.
*/
Select parseSelect(string id, string lang, string msg, string fingerPrint) {
exists(File file, QLDoc doc | result.getLocation().getFile() = file |
any(TopLevel top | top.getLocation().getFile() = file).getQLDoc() = doc and
id = doc.getContents().regexpCapture("(?s).*@id (\\w+)/([\\w\\-]+)\\s.*", 2) and
lang = doc.getContents().regexpCapture("(?s).*@id (\\w+)/([\\w\\-]+)\\s.*", 1) and
exists(QueryDoc doc |
doc = result.getQueryDoc() and
id = doc.getQueryId() and
lang = doc.getQueryLanguage() and
fingerPrint = getSelectFingerPrint(result) and
msg = getMessage(result).toLowerCase() // case normalize, because some languages upper-case methods.
) and