Skip to content

Commit 84b5117

Browse files
d10cCopilot
andcommitted
Extract the inline-expectation parser into its own module
`getAnExpectation` -- the low-level parse of a `// $ ...` expectation comment -- lived as a private predicate inside `Make<Impl>`, reachable only by that module's expectation classes. The upcoming `--learn` postprocessing needs the same parse (to see every expectation on a comment, including ones the running test ignores, so it can preserve them), but it lives in `TestPostProcessing`, outside `Make`. Move the predicate into a new top-level `private module ExpectationParser<Impl>` that both consumers `private import`, so neither has to expose the parse as part of its API nor reach into the other's internals. This is a pure refactor: the predicate body and its callers' behavior are unchanged. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: 1adfa307-c48e-43f5-94e3-8286e4a8c083
1 parent b0fa3e7 commit 84b5117

1 file changed

Lines changed: 46 additions & 26 deletions

File tree

‎shared/util/codeql/util/test/InlineExpectationsTest.qll‎

Lines changed: 46 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,8 @@ signature module InlineExpectationsTestSig {
125125
* Module implementing inline expectations.
126126
*/
127127
module Make<InlineExpectationsTestSig Impl> {
128+
private import ExpectationParser<Impl>
129+
128130
/**
129131
* A signature specifying the required parts of an inline expectation test.
130132
*/
@@ -378,32 +380,6 @@ module Make<InlineExpectationsTestSig Impl> {
378380
}
379381
}
380382

381-
private predicate getAnExpectation(
382-
Impl::ExpectationComment comment, TColumn column, string expectation, string tags, string value
383-
) {
384-
exists(string content |
385-
content = comment.getContents().regexpCapture(expectationCommentPattern(), 1) and
386-
(
387-
column = TDefaultColumn() and
388-
exists(int end |
389-
end = getEndOfColumnPosition(0, content) and
390-
expectation = content.prefix(end).regexpFind(expectationPattern(), _, _).trim()
391-
)
392-
or
393-
exists(string name, int start, int end |
394-
column = TNamedColumn(name) and
395-
start = content.indexOf(name + ":") + name.length() + 1 and
396-
end = getEndOfColumnPosition(start, content) and
397-
expectation = content.substring(start, end).regexpFind(expectationPattern(), _, _).trim()
398-
)
399-
)
400-
) and
401-
tags = expectation.regexpCapture(expectationPattern(), 1) and
402-
if exists(expectation.regexpCapture(expectationPattern(), 2))
403-
then value = expectation.regexpCapture(expectationPattern(), 2)
404-
else value = ""
405-
}
406-
407383
/**
408384
* A module that merges two test signatures.
409385
*
@@ -582,6 +558,50 @@ private string expectationPattern() {
582558
/** Gets the string `#select` or `problems`, which are equivalent result sets for a `problem` or `path-problem` query. */
583559
private string mainResultSet() { result = ["#select", "problems"] }
584560

561+
/**
562+
* Provides the low-level parse of an inline expectation comment, shared by the expectation classes
563+
* in `Make<Impl>::MakeTest` and by the `--learn` postprocessing in `TestPostProcessing`.
564+
*
565+
* It is a separate module so that both consumers can `private import` it without either exposing
566+
* the parse as part of a `MakeTest` consumer's API or forcing the postprocessing to reach into
567+
* `MakeTest`'s internals.
568+
*/
569+
private module ExpectationParser<InlineExpectationsTestSig Impl> {
570+
/**
571+
* Holds if `comment` carries the expectation `expectation` (its verbatim text, for example
572+
* `Alert[q]=v`) in `column` (`TDefaultColumn`, or a `TNamedColumn` such as `MISSING`/`SPURIOUS`),
573+
* whose comma-separated tags are `tags` and whose expected value is `value` (`""` if none).
574+
*
575+
* The `--learn` postprocessing needs to see *every* parsed expectation on a comment - including
576+
* ones the running test ignores - so it can preserve them when rewriting.
577+
*/
578+
predicate getAnExpectation(
579+
Impl::ExpectationComment comment, TColumn column, string expectation, string tags, string value
580+
) {
581+
exists(string content |
582+
content = comment.getContents().regexpCapture(expectationCommentPattern(), 1) and
583+
(
584+
column = TDefaultColumn() and
585+
exists(int end |
586+
end = getEndOfColumnPosition(0, content) and
587+
expectation = content.prefix(end).regexpFind(expectationPattern(), _, _).trim()
588+
)
589+
or
590+
exists(string name, int start, int end |
591+
column = TNamedColumn(name) and
592+
start = content.indexOf(name + ":") + name.length() + 1 and
593+
end = getEndOfColumnPosition(start, content) and
594+
expectation = content.substring(start, end).regexpFind(expectationPattern(), _, _).trim()
595+
)
596+
)
597+
) and
598+
tags = expectation.regexpCapture(expectationPattern(), 1) and
599+
if exists(expectation.regexpCapture(expectationPattern(), 2))
600+
then value = expectation.regexpCapture(expectationPattern(), 2)
601+
else value = ""
602+
}
603+
}
604+
585605
/**
586606
* Provides logic for creating a `@kind test-postprocess` query that checks
587607
* inline test expectations using `$ Alert` markers.

0 commit comments

Comments
 (0)