@@ -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