Class StreamGuardOrError
java.lang.Object
org.ek9lang.compiler.common.RuleSupport
org.ek9lang.compiler.common.TypedSymbolAccess
org.ek9lang.compiler.phase5.PossibleExpressionConstruct
org.ek9lang.compiler.phase5.StreamGuardOrError
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:
- 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. - 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 Tand has no returning param, so there is nowhere to say it: the result is whateverT's default constructor produces. For a collection that is an empty (and set) collection, but for a scalar such asIntegerit 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.
-
Field Summary
Fields inherited from class RuleSupport
errorListener, symbolsAndScopes -
Constructor Summary
ConstructorsConstructorDescriptionStreamGuardOrError(SymbolsAndScopes symbolsAndScopes, ErrorListener errorListener) -
Method Summary
Modifier and TypeMethodDescription(package private) Consumer<EK9Parser.StreamExpressionContext> Expression form:result <- for g <- getLimit() then i in 1 ... 3 | collect as T.(package private) Consumer<EK9Parser.StreamStatementContext> Statement form:for g <- getLimit() then i in 1 ... 3 > stdout.Methods inherited from class PossibleExpressionConstruct
getGuardExpressionVariable, getGuardExpressionVariable, isVariableInitialisedInScopes, processPossibleGuardInitialisation, pullUpAcceptableCriteriaToHigherScope, returningVariableValidOrErrorMethods inherited from class TypedSymbolAccess
getRecordedAndTypedSymbol, isProcessingScopePure, recordATypedSymbol
-
Constructor Details
-
StreamGuardOrError
StreamGuardOrError(SymbolsAndScopes symbolsAndScopes, ErrorListener errorListener)
-
-
Method Details
-
statementForm
Consumer<EK9Parser.StreamStatementContext> statementForm()Statement form:for g <- 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
Consumer<EK9Parser.StreamExpressionContext> expressionForm()Expression form:result <- for g <- getLimit() then i in 1 ... 3 | collect as T.
-