Skip to content

Commit e542e71

Browse files
committed
Fix testing methods with 2-qualifier or deeper input specifications
For example, an identity function on lists-of-maps, which might convey MapValue of Element of Argument[0] to MapValue of Element of ReturnValue, requiring `newWithElement(newWithMapValue(source())` on the input side but `getMapValue(getElement(out))` on the output side.
1 parent 0d8124b commit e542e71

File tree

1 file changed

+21
-4
lines changed

1 file changed

+21
-4
lines changed

java/ql/src/utils/GenerateFlowTestCase.qll

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -271,10 +271,26 @@ class RowTestSnippet extends TRowTestSnippet {
271271
*/
272272
string getInputTypeString() { result = getShortNameIfPossible(this.getInputType()) }
273273

274+
/**
275+
* Returns the next-highest stack item in `input`, treating the list as circular, so
276+
* the top item's successor is `baseInput`, the bottom of the stack.
277+
*/
278+
SummaryComponentStack nextInput(SummaryComponentStack prev) {
279+
exists(SummaryComponentStack next | next.tail() = prev and next = input.drop(_) | result = next)
280+
or
281+
not exists(SummaryComponentStack next | next.tail() = prev and next = input.drop(_)) and
282+
result = baseInput
283+
}
284+
274285
/**
275286
* Returns a call to `source()` wrapped in `newWith` methods as needed according to `input`.
276287
* For example, if the input specification is `ArrayElement of MapValue of Argument[0]`, this
277-
* will return `newWithArrayElement(newWithMapValue(source()))`.
288+
* will return `newWithMapValue(newWithArrayElement(source()))`.
289+
*
290+
* This requires a slightly awkward walk, out from the element above the root (`Argument[0]` above)
291+
* climbing up towards the outer `ArrayElement of...`. This is implemented by treating the stack as
292+
* a circular list, walking it backwards and treating the root as a sentinel indicating we should
293+
* emit `source()`.
278294
*/
279295
string getInput(SummaryComponentStack componentStack) {
280296
componentStack = input.drop(_) and
@@ -284,7 +300,7 @@ class RowTestSnippet extends TRowTestSnippet {
284300
else
285301
result =
286302
"newWith" + contentToken(getContent(componentStack.head())) + "(" +
287-
this.getInput(componentStack.tail()) + ")"
303+
this.getInput(nextInput(componentStack)) + ")"
288304
)
289305
}
290306

@@ -364,8 +380,9 @@ class RowTestSnippet extends TRowTestSnippet {
364380
result =
365381
"\t\t{\n\t\t\t// \"" + row + "\"\n\t\t\t" + getShortNameIfPossible(this.getOutputType()) +
366382
" out = null;\n\t\t\t" + this.getInputTypeString() + " in = (" + this.getInputTypeString() +
367-
")" + this.getInput(input) + ";\n\t\t\t" + this.getInstancePrefix() + this.makeCall() +
368-
";\n\t\t\t" + "sink(" + this.getOutput(output) + "); " + this.getExpectation() + "\n\t\t}\n"
383+
")" + this.getInput(this.nextInput(baseInput)) + ";\n\t\t\t" + this.getInstancePrefix() +
384+
this.makeCall() + ";\n\t\t\t" + "sink(" + this.getOutput(output) + "); " +
385+
this.getExpectation() + "\n\t\t}\n"
369386
}
370387
}
371388

0 commit comments

Comments
 (0)