QL4QL: Restrict ql/qlref-inline-expectations to (path-)problem queries

This commit is contained in:
Tom Hvitved
2025-04-10 14:40:59 +02:00
parent d2a4f1e17a
commit a578f44af4
9 changed files with 94 additions and 7 deletions

View File

@@ -30,6 +30,8 @@ class Container = Impl::Container;
class Folder = Impl::Folder;
module Folder = Impl::Folder;
/** A file. */
class File extends Container, Impl::File {
/** Gets a token in this file. */

View File

@@ -6,6 +6,7 @@
*/
private import codeql.yaml.Yaml as LibYaml
private import codeql.files.FileSystem
private module YamlSig implements LibYaml::InputSig {
import codeql.Locations
@@ -49,6 +50,58 @@ private module YamlSig implements LibYaml::InputSig {
import LibYaml::Make<YamlSig>
/** A `qlpack.yml` document. */
class QlPackDocument extends YamlDocument {
QlPackDocument() { this.getFile().getBaseName() = ["qlpack.yml", "qlpack.test.yml"] }
/** Gets the name of this QL pack. */
string getPackName() {
exists(YamlMapping n |
n.getDocument() = this and
result = n.lookup("name").(YamlScalar).getValue()
)
}
private string getADependencyName() {
exists(YamlMapping n, YamlScalar key |
n.getDocument() = this and
n.lookup("dependencies").(YamlMapping).maps(key, _) and
result = key.getValue()
)
}
/** Gets a dependency of this QL pack. */
QlPackDocument getADependency() { result.getPackName() = this.getADependencyName() }
private Folder getRootFolder() { result = this.getFile().getParentContainer() }
/** Gets a folder inside this QL pack. */
pragma[nomagic]
Folder getAFolder() {
result = this.getRootFolder()
or
exists(Folder mid |
mid = this.getAFolder() and
result.getParentContainer() = mid and
not result = any(QlPackDocument other).getRootFolder()
)
}
}
private predicate shouldAppend(QlRefDocument qlref, Folder f, string relativePath) {
relativePath = qlref.getRelativeQueryPath() and
(
exists(QlPackDocument pack |
pack.getAFolder() = qlref.getFile().getParentContainer() and
f = [pack, pack.getADependency()].getFile().getParentContainer()
)
or
f = qlref.getFile().getParentContainer()
)
}
private predicate shouldAppend(Folder f, string relativePath) { shouldAppend(_, f, relativePath) }
/** A `.qlref` YAML document. */
class QlRefDocument extends YamlDocument {
QlRefDocument() { this.getFile().getExtension() = "qlref" }
@@ -65,6 +118,24 @@ class QlRefDocument extends YamlDocument {
)
}
/** Gets the relative path of the query in this `.qlref` file. */
string getRelativeQueryPath() {
exists(YamlMapping n | n.getDocument() = this |
result = n.lookup("query").(YamlScalar).getValue()
)
or
not exists(YamlMapping n | n.getDocument() = this) and
result = this.eval().(YamlScalar).getValue()
}
/** Gets the query file referenced in this `.qlref` file. */
File getQueryFile() {
exists(Folder f, string relativePath |
shouldAppend(this, f, relativePath) and
result = Folder::Append<shouldAppend/2>::append(f, relativePath)
)
}
predicate isPrintAst() {
this.getFile().getStem() = "PrintAst"
or

View File

@@ -10,8 +10,10 @@
import ql
import codeql_ql.ast.Yaml
from QlRefDocument f
from QlRefDocument f, TopLevel t, QueryDoc doc
where
not f.usesInlineExpectations() and
not f.isPrintAst()
t.getFile() = f.getQueryFile() and
doc = t.getQLDoc() and
doc.getQueryKind() in ["problem", "path-problem"]
select f, "Query test does not use inline test expectations."

View File

@@ -0,0 +1,13 @@
/**
* @name Problem query
* @description Description of the problem
* @kind problem
* @problem.severity warning
* @id ql/problem-query
*/
import ql
from VarDecl decl
where none()
select decl, "Problem"

View File

@@ -1,2 +1 @@
| QlRefInlineExpectations.qlref:1:1:1:40 | queries ... ions.ql | Query test does not use inline test expectations. |
| Test3.qlref:1:1:1:39 | query: ... ists.ql | Query test does not use inline test expectations. |
| Test3.qlref:1:1:1:22 | query: ... uery.ql | Query test does not use inline test expectations. |

View File

@@ -1,2 +1,2 @@
query: queries/style/OmittableExists.ql
query: ProblemQuery.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1,3 +1,3 @@
query: queries/style/OmittableExists.ql
query: ProblemQuery.ql
postprocess:
- utils/test/InlineExpectationsTestQuery.ql

View File

@@ -1 +1 @@
query: queries/style/OmittableExists.ql
query: ProblemQuery.ql