Skip to content

Commit 04e3acb

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 6230d2f commit 04e3acb

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
@@ -128,6 +128,8 @@ signature module InlineExpectationsTestSig {
128128
* Module implementing inline expectations.
129129
*/
130130
module Make<InlineExpectationsTestSig Impl> {
131+
private import ExpectationParser<Impl>
132+
131133
/**
132134
* A signature specifying the required parts of an inline expectation test.
133135
*/
@@ -385,32 +387,6 @@ module Make<InlineExpectationsTestSig Impl> {
385387
}
386388
}
387389

388-
private predicate getAnExpectation(
389-
Impl::ExpectationComment comment, TColumn column, string expectation, string tags, string value
390-
) {
391-
exists(string content |
392-
content = comment.getContents().regexpCapture(expectationCommentPattern(), 1) and
393-
(
394-
column = TDefaultColumn() and
395-
exists(int end |
396-
end = getEndOfColumnPosition(0, content) and
397-
expectation = content.prefix(end).regexpFind(expectationPattern(), _, _).trim()
398-
)
399-
or
400-
exists(string name, int start, int end |
401-
column = TNamedColumn(name) and
402-
start = content.indexOf(name + ":") + name.length() + 1 and
403-
end = getEndOfColumnPosition(start, content) and
404-
expectation = content.substring(start, end).regexpFind(expectationPattern(), _, _).trim()
405-
)
406-
)
407-
) and
408-
tags = expectation.regexpCapture(expectationPattern(), 1) and
409-
if exists(expectation.regexpCapture(expectationPattern(), 2))
410-
then value = expectation.regexpCapture(expectationPattern(), 2)
411-
else value = ""
412-
}
413-
414390
/**
415391
* A module that merges two test signatures.
416392
*
@@ -589,6 +565,50 @@ private string expectationPattern() {
589565
/** Gets the string `#select` or `problems`, which are equivalent result sets for a `problem` or `path-problem` query. */
590566
private string mainResultSet() { result = ["#select", "problems"] }
591567

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

0 commit comments

Comments
 (0)