Class StatementOwnedCloseables
CloseableLocalOrError).
This class only EMITS. Which calls make a closeable the statement owns is decided in phase 5, on the call's own
resolved symbol (phase5/StatementOwnedCloseableCalls), and arrives here on the CALL
(CallInstr.isStatementOwned()). For each such call the statement always makes it declares an owner
variable before the statement, stores the temporary into it right after the call, and makes the statement the
body of THE owned region (ResourceCloser.closingRegion(List, List, ResourceCloser.FirstFailure, DebugInfo)) that closes the owners that are present, last
created first - the same region, and the same failure rule (shape B), try-with-resources uses. So
cat TextFile(path).input() > lines closes the input on normal completion, when a stage ends the stream
early, and when an exception leaves the statement.
A marked call is looked for at the evaluation's own level and in the setup of a string interpolation, a List literal or a Dict literal (all evaluated unconditionally, before the instruction that uses them). Calls inside a nested block belong to that block's statements (each wrapped on its own). A variable the evaluation declares is declared BEFORE the wrapping so it is still in reach after it.
🔑 The owning region is wherever the evaluation is that phase 5 found the call in (Steve, 2026-10-06, lane initialiser-owned-closeables): the region is THE same one, only its body differs.
- a block statement -
apply(ParserRuleContext, List), fromBlockStmtInstrGenerator; - a returning variable's declaration -
apply(ParserRuleContext, List), fromOperationDfnGeneratorandReturningParamProcessor(so the expression forms' returning variables too); - a property's initialiser, inside
_i_init-apply(ParserRuleContext, List), fromPropertyInitialisers; - an evaluation that is nested INSIDE another instruction and hands one value on - an if or loop condition, a
ternary's control, the left of a coalescing or logical operator, the operand of
?, a range bound -ownedEvaluation(ParserRuleContext, List, String, ISymbol). A statement's own level never reaches into those instructions, and a loop condition runs again on every iteration, so each closes what it made as it finishes. - an operand evaluated only CONDITIONALLY (Steve, 2026-10-06, lane conditional-closeables: "an unnamed closeable
is closed as soon as the evaluation that made it finishes") - the right of
and/orand of??/?:/<?..., a ternary arm, a condition after a guard, a case value -ownedEvaluation(ParserRuleContext, List, String, ISymbol); the right of:=?-apply(ParserRuleContext, List). Its region is inside the operand's own instructions, so it runs, and closes, only when the operand does. (A laterelse ifcondition already went through the condition site above.)
🔑 A value that IS a conditional's result is DEFERRED: an arm whose value is a closeable cannot close it when
it finishes, so ownedEvaluation(ParserRuleContext, List, String, ISymbol) stores each marked temporary it makes into an owner as it is made and leaves
the owner to the nearest enclosing evaluation that owns its temporaries (own(List, DebugInfo) finds the store however deeply
it is nested, declares and registers the owner before its region and closes it if present). Only the arm that ran
is closed, and a named value the same conditional chose is never closed by it.
A marked call nested anywhere else (a structure none of these sites wraps) stays open - a possible leak, never a wrong close.
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic final recordstatic final recordWhatown(List, DebugInfo)found. -
Field Summary
Fields inherited from class AbstractGenerator
constantCopyOnAccessLoader, debugInfoCreator, instructionBuilder, MAX_MESSAGE_LENGTH, stackContext, synthesisedCallMetaData, typeNameOrException -
Constructor Summary
ConstructorsConstructorDescriptionStatementOwnedCloseables(IRGenerationContext stackContext, GeneratorSet generators) -
Method Summary
Modifier and TypeMethodDescriptionThe statement's (or initialiser's) instructions, wrapped so it closes the closeable temporaries it created - or unchanged when it creates none.The closeable temporaries these instructions make that phase 5 marked as owned: the owner declarations (emit them before the region that closes them), the same instructions with each temporary handed over to its owner right after the call that made it, and oneResourceCloser.Closingper owner, in the order the temporaries are made.ownedEvaluation(org.antlr.v4.runtime.ParserRuleContext ctx, List<IRInstr> evaluation, String resultVariable, ISymbol resultType) An evaluation nested inside another instruction (a condition, a control, an operand) that hands ONE value on: the evaluation wrapped, like a statement, in THE owned region that closes the closeable temporaries it made - and the variable that now holds its value after the region.
-
Constructor Details
-
StatementOwnedCloseables
StatementOwnedCloseables(IRGenerationContext stackContext, GeneratorSet generators)
-
-
Method Details
-
apply
-
ownedEvaluation
public StatementOwnedCloseables.OwnedEvaluation ownedEvaluation(org.antlr.v4.runtime.ParserRuleContext ctx, List<IRInstr> evaluation, String resultVariable, ISymbol resultType) An evaluation nested inside another instruction (a condition, a control, an operand) that hands ONE value on: the evaluation wrapped, like a statement, in THE owned region that closes the closeable temporaries it made - and the variable that now holds its value after the region. That variable is declared before the region (null, so it is definitely assigned on every path to the code after it) and the value is stored into it as the region's last act. Unchanged - the same instructions andresultVariable- when the evaluation owns no temporary.The value must not be closed here when it is the temporary itself: a value of a closeable type is used after the evaluation (a ternary arm, either side of a coalescing operator, the operand of
?). Its temporaries are then DEFERRED (deferToEnclosing(List)): each is stored, as it is made, into an owner that the nearest enclosing evaluation which owns its temporaries declares and closes, if present, when it finishes.- Parameters:
ctx- the evaluated expression, for debug informationevaluation- its instructions, leaving the value inresultVariableresultVariable- the variable the evaluation leaves its value inresultType- that value's type
-
own
public StatementOwnedCloseables.OwnedTemporaries own(List<IRInstr> instructions, DebugInfo debugInfo) The closeable temporaries these instructions make that phase 5 marked as owned: the owner declarations (emit them before the region that closes them), the same instructions with each temporary handed over to its owner right after the call that made it, and oneResourceCloser.Closingper owner, in the order the temporaries are made.apply(ParserRuleContext, List)closes them around a statement; try-with-resources closes the temporaries a resource's initialiser makes in its own region, beside the resources.
-