Class StreamGuardOrError


final class StreamGuardOrError extends PossibleExpressionConstruct
Checks a stream pipeline whose source is a for carrying a pre-flow guard.

streamFor is forRange, so a stream source takes exactly the same pre-flow as the statement form - for g <- getLimit() then i in 1 ... 3 > stdout. Every other guard-accepting construct has a phase-5 checker (IfStatementOrError, WhileStatementOrError, TryStatementOrError, ForStatementOrError, SwitchStatementOrError); the stream form had none, because it belongs to both the loop family and the stream family and was enrolled in neither.

Two responsibilities, mirroring ForStatementOrError:

  1. A ?= guard variable may become initialised by the guard itself, so that has to be pulled up into the enclosing scope exactly as the other constructs do.
  2. The expression form is rejected when the guard can skip the body (E08056). Every other expression form answers "what is the result if the body is skipped?" with the returning param's initialiser - <- rtn as String: "init". A stream expression terminates in | collect as T and has no returning param, so there is nowhere to say it: the result is whatever T's default constructor produces. For a collection that is an empty (and set) collection, but for a scalar such as Integer it is UNSET, silently, with the difference invisible at the call site.

Guard classification is delegated to PreFlowCanSkipBody, the sole authority shared with phase 7, so a plain := pre-flow is correctly NOT a guard here and the body always runs.

  • Constructor Details

  • Method Details

    • statementForm

      Statement form: for g &lt;- getLimit() then i in 1 ... 3 > stdout. Legal with a guard - there is no result to leave undeclared - so only the guard variable's initialisation needs pulling up.
    • expressionForm

      Expression form: result &lt;- for g &lt;- getLimit() then i in 1 ... 3 | collect as T.