Package org.ek9lang.compiler.phase5
At this point, before the compiler builds the intermediate representation it completes some more checks.
PreIntermediateRepresentationChecks is the main entry point for this phase.
Most of the processing is delegated to PreIRListener.
This now follows the same pattern as most of the other Listeners, using
SymbolsAndScopes for handling scope traversals and locating recorded
symbols and scopes.
There is a 'complexity' calculator built into this phase, it is quite tolerant of high complexity. It does emit compiler errors if a single method/function has complexity at level 50 or higher or if an aggregate has a total complexity of 500 or higher. The rules for calculating complexity are based on a modified McCabe region algorithm. It is quite simple in its approach, as code elements are encountered a level of complexity is incremented.
There are additional checks around simple evaluation of whether variables have been initialised or not. In some cases properties on aggregates may need to be defined in uninitialised for i.e.
prop1 as String?
In such cases the EK9 compiler will mandate that the EK9 developer create all necessary coded constructors, it will not mandate that 'prop1' is then initialised - it will leave that to the Ek9 developer to 'take the risk' and understand what may or may not go wrong in their code.
Ideally, all properties and variables are always declared in initialised form (even if the value is 'un-set'). But this cannot always be mandated, so the EK9 compiler has some tolerance for these uninitialised variables.
-
ClassDescriptionOnce an expression has been assessed as being simple enough to process, this consumer is called to mark the appropriate symbol(s) used in the expression as safe if the appropriate methods are called.Validates that application blocks do not have too many registrations (E11042).Emit error if there are too many arguments.Validates class design patterns for Construct Misuse Detection (E11022-E11025).Checks cognitive complexity at function/method/operator exit and emits error if too high.Checks LCOM4 cohesion against thresholds and emits errors if exceeded.Checks the combined complexity and statement count at function/method/operator exit.Looks for the complexity value in the complexityCounter and adds the value to the appropriate symbol.Checks efferent coupling (Ce) against thresholds and emits errors if exceeded.Checks expression complexity when a coalescing expression tree completes.Checks inheritance depth (DIT) against thresholds and emits errors if exceeded.Validates DI injection design quality for components (E11040).Validates DI injection design quality for a single callable (E11043).Validates module-level cohesion against threshold and emits E11017 error if exceeded.Validates module-level efferent coupling against threshold and emits E11016 error if exceeded.Validates the number of constructs declared in a module against
MetricLimits.MODULE_SIZEand emits E11027 if exceeded.Checks nesting depth at function/method/operator exit and emits error if too deep.Checks statement count at function/method/operator exit and emits error if too many.Enforces 'allow only' constraints on traits and classes (sealed type pattern).Checks call sites for ambiguous positional arguments.THE registrations of every application in the program (EK9_NATIVE_CYCLE_COLLECTOR_DESIGN.md §13.11): eachregister X() as Y with aspect of A()of every general and service application.THE check of an assign-if-unset statement (:=?) whose outcome the value tracker has DECIDED - both outcomes, one class, one reading of the target (E08095 and E08097).Check the assignment to a variable can be a single assignment or a deep copy type assignment.THE assignment statement an identifier is the TARGET of - on its left-hand side, reached directly or through an object access (this.count: 1) - or empty.THE reading of what one callable does with its own parameters (and with each local made to refer to one): every occurrence of such a variable is judged throughObjectSharingand handed toCloseableArgumentKeeping, which decides - after every source is walked - which parameters the callable KEEPS beyond the call.CallableReturnsInitialisedOrError<C extends org.antlr.v4.runtime.ParserRuleContext>THE shared check that a callable's returning values have been initialised: one class for methods, operators, service operations and functions (it was four copies, one of which had drifted and dropped two guards).Checks that gated system types are only used in publishable packages when the corresponding capability has been declared.THE entry state of a dynamic class's capture constructor: its captures are stored before its first statement (before_i_init, and before athis(...)call), so each one is set from the start of its body.Capture ownership by FRESHNESS (R-E, Steve 2026-10-06) - never by the named/unnamed syntax of the capture.THE record of which constructor parameters a constructor KEEPS as a closeable property, and the deferred verdict on every construction that hands such a parameter a value that is not new (R4 of the fresh-store rule, E81062).What a construction does with the argument it is given at one position - decided only after every source has been walked (CloseableArgumentKeeping.check()).A variable of one callable's body - one of its parameters, or a local that may refer to the same object - compared by identity.R7 of the closeable ownership rules (Steve, 2026-10-05): closeability cannot be erased by a store (E81059).If you hold it, you close it (E81067, Steve 2026-10-06, D8/C5): a class, record, component or dynamic class with a closeable property - or a capture it owns (R-E) - must DECLARE its ownoperator close:default operator closeor one it writes.The NAMED half of the closeable ownership rule (Steve, 2026-10-05): "A closeable value you never NAME is owned by the statement that created it and closed when that statement finishes; a closeable value you NAME must be declared as a try-with-resources resource." (E81056).R5 (Steve, 2026-10-05): a method, operator, function or dynamic function whose DECLARED return type is closeable must return a NEW instance (E81057).THE fresh-store rule for closeable SLOTS (R-A, Steve 2026-10-06, decisions D3 and D9, with R-D): every closeable object has exactly ONE owner, so a closeable value may enter a slot that will close it only when nothing else already owns it.Tracks cognitive complexity within functions/methods/operators.Tracks method-field relationships to calculate LCOM4 (Lack of Cohesion of Methods v4).Is the value of an expression KNOWN WHEN THE PROGRAM IS COMPILED - that is, made only from text written in the source? Used byUrlTextKnownAtCompileTimeOrError(E08275, decision U3 of docs/architecture/EK9_URL_TYPE_DESIGN.md §0).Designed to give a broad indication of complexity, this is not true pure Cyclometric Complexity.One popped region: its total complexity, and how much of that came from expressions.Detects tautological and contradictory compound conditions using range algebra (E08086/E08087).Finds all concrete (non-abstract) subtypes of a given abstract aggregate type.Propagates theCONCURRENT_ENTRY_POINT = "TRUE"squirrelled marker transitively along the call graph (Step 6b, slice 1).THE confined-type fact (EK9_NATIVE_CYCLE_COLLECTOR_DESIGN.md §13.11, T12; Steve, 2026-10-31: "at compile time we can check which types have no connection to long lived application based components, so they could never be long lived").Detects confusingly similar variable, parameter, and field names within the same scope.Detects arithmetic expressions that always produce a constant result (E08083).Detects coalescing expressions whose result is predetermined (E08094).Detects comparisons where both operands are literals (E08082).A constrained-type construction whose argument value is KNOWN at compile time and provably violates the constraint is an error (E08260), not a runtime Panic.THE shared resolver for a constrained-type construction site — a constructor call whose constructed type is aCLASS_CONSTRAINEDaggregate carrying a constraint, together with its single base-type argument symbol.THE human-readable label of the construct a symbol represents ("service operation", "operator", "method", "function", "callable"), for the size diagnostics that judge it against itsStatementBudgetOf(AcceptableStatementCountOrError,AcceptableCombinedComplexitySizeOrError).The per-construct obligation rollup accumulated during the phase-5 walk of one callable body, then squirrelled asOBLIGATIONS_TOTAL/DISCHARGED/UNDISCHARGEDat construct exit (docs/tooling/EK9_SYMBOLIC_SCANNER_IMPLEMENTATION_SPEC.md §2.1/§2.4).Walk 0 of PRE_IR_CHECKS — the "all-constructors initialise the field" pre-pass.ConstructSafeAccessMarker<C extends org.antlr.v4.runtime.ParserRuleContext>THE marker of what a construct's pre-flow and control expression prove safe for Optional / Result / Iterator access (E08030) - one class forif,switch,try,while,forand the ternary (it was six near-identical subclasses).THE maker of the E08030 construct markers (ConstructSafeAccessMarker), one per construct that can prove an Optional / Result / Iterator access safe:ConstructSafeAccessMarkers.forIfBlock(),ConstructSafeAccessMarkers.forSwitch(),ConstructSafeAccessMarkers.forTry(),ConstructSafeAccessMarkers.forWhile(),ConstructSafeAccessMarkers.forFor()andConstructSafeAccessMarkers.forTernary().CollectsCONTAINER_UNWRAPobligations from an object-access chain for the census — one perOptional.get/Result.ok/error/Iterator.nextcall, discharged byGUARDwhen the access is safe.Tracks efferent coupling (Ce) - the number of external types a construct depends on.Validates that a module does not contain data clumps (E11053).Tracks function/method/constructor parameter signatures for data clump detection (E11053).An immutable (type, name) pair from a parameter, ordered for deterministic comparison.One callable's parameter signature for data clump analysis.Walk 3 of phase 5: dedicated AST walk for the data-race check (slice 1, step 7).PRE_IR_CHECKS confirm-or-retract for the BAREdefault operatorcomparison family.The generated copy of a closeable holder is refused (R-A, Steve 2026-10-06, decision D9; E81065).After a this(...) call, the properties the delegated-to constructor sets have a value for the rest of the delegating constructor - and only those.Reports DI/AOP analysis to stderr when the-diflag is set.Detects discarded return values in bare statement calls (E11050, E11051, E11052, E11055).Why an obligation is considered discharged (proven safe) by an existing analysis, orDischargeReason.UNDISCHARGEDwhen no analysis proves it — the discharge-detection order of docs/tooling/EK9_SYMBOLIC_SCANNER_IMPLEMENTATION_SPEC.md §2.3.THE dispatcher half of "what may a call through this declaration run" (the closeable route-matrix verifier, 2026-10-22): a call to a dispatcher entry point runs, at run time, the handler most specific to its argument's type - so the entry returns and keeps whatever any of its handlers does.Validates that no reachable type in a dispatcher's hierarchy resolves ambiguously between two or more handlers at equal cost.Validates that dispatchers on sealed traits have handlers for all permitted types.Reports a dispatcher handler whose parameter type has no concrete form anywhere in the program, so no value can ever have that runtime type and the handler is dead code that looks live.Validates that dispatcher handler parameter types are reachable from the base dispatch type's hierarchy.D62 (Steve's rule, D55/D58): the retraction of a baredefault operator's ordering family reaches the dynamic classes too.Deals with handling any returning values in a dynamic function.THE rule that an Exception, or any sub-type of one, has nooperator close(E81074, Steve 2026-10-26, decision (b) of the closeables lane): an exception is a VALUE carried to a handler, not a resource.Detects call chains deeper than one level (E11069).Checks for excessive type traversal in method chains (Law of Demeter).Tracks complexity of coalescing expression trees with depth-based multiplier.Classifies fields in an aggregate as service-type (abstract/interface) or data-type (concrete).Result of field classification for an aggregate.Detects conditions that are always true or always false based on data flow analysis (E08086/E08087).Predicate to determine if an expression is a Boolean logical operator (and/or) with Boolean type operands.When looking to calculate complexity of methods/functions it is important to work out if parts of an expression are in some way conditional.Checks the for structure via the code analysers.Widens a GENERIC construct's input-variety denominator to span the types it is actually parameterised with (design D11/W5b).Extracts the EXISTING variable a pre-flow assigns: the target of a blind assignment (v := e()) or an assign-if-unset (v :=? e()).E08270 (Steve, 2026-10-07, Q4): reading a<-guard's variable in a LATERelse if/elseblock of the sameifchain, before anything assigns it there.Given an identifier, this consumer checks if it is a property of some aggregate.THE check of a READ of a local or returning variable that may still be uninitialised (E08020): every grammar position that loads a variable's value hands its read node here - this is the one consumer, do not write another.The position of a symbol in a list by IDENTITY, or -1: symbols of the same name in different scopes must not match (a parameter list read for occurrences,CallableParameterOccurrences, and for closeable slot stores,CloseableSlotStoreOrError).Deals with checking if all paths through if/else/else-if/else result in variables meeting criteria.A construction call that reaches a constructor which leaves properties without a value (E08264).A stream whose source the compiler can PROVE infinite may not reach a stage that waits for the end of the stream (E10050) - decision 15(a), phase 1.Calculates the Depth of Inheritance Tree (DIT) for aggregate symbols.Tracks injection counts within functions/methods/operators.Pops the injection count from the counter and stores it as squirrelled data on the symbol.Detects circular dependencies in component injection chains per application (E08190).THE components of an application that sit on a circular injection chain (E08190), asInjectionCycleOrErrorfound them - and THE rule that E08190 suppresses E08200 for them (Steve, 2026-10-11): in a cycle no registration order works, so "reorder registrations" is advice that cannot be followed.Validates ordering in application blocks (E08200).Validates DI injection design quality across a construct's methods (E11041).Parallel toInjectionCounter, but tracks the DISTINCT injected component TYPE (fully-qualified names) per scope rather than just the site count.Records the input-variation figures — the 1-wise FLOOR (headline) and the pairwise DENOMINATOR (ceiling) plus the per-leaf confidence — on each callable (method / function / operator), squirrelled for the metrics / MCP surface next toCOMPLEXITY.A stack of integer counters, one per nested function/method/operator scope, accumulated during AST traversal.THE "is this symbol a capture of the callable whose returning variable is being read" of the return-source readings (ReturnSourceClassifier,ReturnSourceOrigins): by IDENTITY (IsCapturedVariable), one the callable (a dynamic function) or the type it belongs to (a dynamic class) captured.Is this store a construct's pre-flow - which its construct's marker (ConstructSafeAccessMarker) judges for E08040, before it marks the construct safe, so the store's own check (SafeAccessRepointOrError) leaves it.THE test of E08270's domain (GuardVariableReadWhereUnsetOrError), for a rule that must not report the same use a second time (E08096,OperatorKeepsValueUnsetOrError): isatinside a later block of anifchain (anelse ifor theelse) whose earlier block's<-guard declarestarget, provably unset there (ProvablyUnsetGuardOf).Is the property this identifier names reached through some object other than this one:from.name, orthis.partner.value? Only a first member afterthis- or no receiver at all - is this object's own property.Is this recorded symbol a property field (a property, or a capture held in one) - false for no symbol.A declaration whose retention was not DECLARED by a built-in: it carries no RETAINS, or only derived marks (IsDerivedRetention).The callable aCloseableArgumentKeepingrecord is about: a member of a parameterised type is judged by the generic's own declaration (GenericTemplateMember), anything else by itself.Walk 4 of phase 5: data-collection walk for slice-2 deadlock detection (Phase B.1 — intra-function scope).Detects logical tautologies and contradictions (E08085).Validates that a module does not contain repeated magic literals (E11065).THE contexts in which a literal is never a magic literal, for both magic-literal checks (E11064, a number in a comparison, and E11065, a repeated String): the fix itself (a constant declaration), a pre/post-condition (require,assert), aconstraindeclaration, and a NAMED argument - the label documents the value and the compiler checks it against the declared parameter (E06240/E06250), so it cannot lie.Detects bare literals used as operands in comparison, relational, matching, and range expressions (E11064).Tracks literal occurrences across files for repeated magic literal detection (E11065).One recorded occurrence of a literal.A bit of a catch 22, need to issue errors and the like when traversing an identifier in some circumstances.The reason a dynamic class (or closed class) never ends - its effectivehasNext()'sNEVER_ENDING_ITERATIONmark, made byNeverEndingIterationMarker- if it has one.May a call through another declaration run this callable - a method of an aggregate (dynamic classes included, constructors not), or a function (dynamic functions included)? The callables the dispatch union of the RETAINS derivations (ReceiverInteriorReturns,CloseableArgumentKeeping) unions over.THE shared steps of everyAcceptable*OrErrorquality-metric check: find the symbol the metric belongs to (MetricSymbolOf, one null policy), squirrel the measured integer (RecordMetric, one encoding) and raise the error when it is over the limit (this).THE first step of everyAcceptable*OrErrorquality-metric check (withRecordMetricandMetricLimitCheck): the symbol the metric is recorded against - one null policy, an assertion, because a metric scope is pushed on entry for a construct that has a symbol (the node, not the symbol, is never null).Tracks module-level cohesion by recording constructs and their intra-module type references.Tracks module-level efferent coupling (Ce) - the number of distinct external modules that a module depends on.THE module-to-ErrorListenerlookup every module-level check takes (coupling, cohesion, size, data clumps, magic literals), besidecallgraph/CallableErrorListenerLookup, which does the same for a callable.Item 5, step 1: the E08090 (NOT_REFERENCED) verdict FULL_RESOLUTION deferred, on a local initialised by a call and afterwards only mutated in place, never read (view <- config.get("server"); view :~: overrides).What PRE_IR_CHECKS needs, collected during Walk 1 (byPreIRListener, every source in parallel), to decide the E08090 verdicts FULL_RESOLUTION deferred (item 5): every local markedNOT_REFERENCED_DEFERRED- initialised by a call, afterwards only mutated in place, never read - with the expression it was initialised by (MutatedOnlyVariableOrError); every user method, operator, function and dynamic function with a returning variable, with each expression that variable is made to REFER to (its initialiser, every pointer assignment (pre-flows included), and through an arm-shaped value the returning variable it yields), soReceiverInteriorReturnscan derive whether a method returns (part of) its receiver andCloseableReturnOrErrorcan require a closeable return to be new - both readingReturnSourceKind. Shared across the parallel walk, so the queues are concurrent; the per-source state is in aMutatedOnlyVariables.Collector.A deferred local and the expression it was initialised by.A user method, operator, function or dynamic function with a returning variable, and every expression that variable is made to refer to.Detects `throw` statements whose expression is a nested call (E11070).Tracks nesting depth within functions/methods/operators.The phase-5 pre-pass that marks iteration the compiler can PROVE never ends (decision 15(a), phase 1: the infinite half).Detects non-descriptive variable names (E11031).In the case of specific variables of type like 'Result' and 'Optional' it is important to check if the method being called needs a previous call to isOk or isError or just '?' before accessing specific methods.An object cannot be used before it is fully constructed (E08061).A single contract/partiality obligation found in a construct body, tagged with the analysis (if any) that discharges it (docs/tooling/EK9_SYMBOLIC_SCANNER_IMPLEMENTATION_SPEC.md §2.1).Layer 1 of the Symbolic/Contract Scanner — the every-build obligation census (docs/tooling/EK9_SYMBOLIC_SCANNER_IMPLEMENTATION_SPEC.md §2).The taxonomy of contract/partiality obligations the census counts, from what already exists in the language and analysis (docs/tooling/EK9_SYMBOLIC_SCANNER_IMPLEMENTATION_SPEC.md §2.2).E08096: an in-place operator applied to a value the compiler is SURE is unset, where the operator is one that keeps an unset value unset -text <- String()thentext += "more", orcount <- Integer()thencount++.Detects variable names that shadow operator keywords (E11032).The per-source half ofOrderingTotality(E07188): for every method, operator and function that returns an Integer, finds where the returning variable can get its value and records the PARTIAL sources - an unsetInteger(), a<=>of a partial type, a call of another callable (decided later, once every source has been walked).THE compile-time check that a hand-written<=>orders every two SET values of its type (E07188; Steve, 2026-10-21, sameness stock-take 4.4: "This is a closed system and we already have code that detects the subtypes").A function used as an ordering where it is not declared one.What makes one callable's Integer result partial, where the walk found it.The declarations a call through which may runcallable: those it overrides, or its super function - THE "what may a call through this declaration run" of the dispatch union, held by both RETAINS derivations (the returns one,ReceiverInteriorReturns, and the callee-keep one,CloseableArgumentKeeping), so what an override RETURNS and what it KEEPS are unioned over the same set.Used as a base for a range of constructs that can be expressions.Detects string concatenation chains with 3 or more parts and recommends string interpolation instead (E11068).At this point all templates should be present and all symbols resolved.Designed to do additional logic checks once everything has been resolved.Checks that reveal() on Sensitive is only called from within a class or trait that is Privileged.Deals with handling any returning values in a dynamic function.Validates that program HTTP wiring is consistent with application service registrations.THE reading of a constructor'sCommonValues.LEAVES_PROPERTIES_UNSETmark: the names of the properties (declared without a value) it leaves unset, following its this(...) chain, as a message shows them; empty when it sets them all.The names of the properties a constructor leaves unset, as a set; empty when it sets them all.Marks the types whose objects can reach themselves through their properties, so phase 7 guards only THEIR generated operators against a cyclic object graph (Steve, 2026-10-05: the hybrid - a compile error on a potentially cyclic type would reject every legitimate tree, a runtime guard on every type would tax the hottest operator in the language).An aggregate's own property fields, in declaration order, as an unmodifiable list.THE property-type graph: which types an object of a given type can reach through its properties.The three kinds of node - see the class javadoc.One node, keyed by kind and fully qualified type name (value equality, as the shared Tarjan requires).The size of the part of the graph that was reached - what the linearity test asserts on.The two whole-program facts the graph needs: the concrete subtypes of a type, and every aggregate.The variable anifblock's pre-flow declares, when that block is skipped ONLY because the variable is unset (E08270): a<-guard that is the whole condition, and not a Boolean truth guard (BooleanTruthGuard, which also skips a setfalse).Central home for the code-quality metric limits that are SHARED across more than one check in this phase.A for-range whose start, end and step are all KNOWN when the program is compiled, and whose step can never take the counter from the start to the end, is an error - E08276 (Steve, D49 compile-time half, 2026-10-21).THE "what does running this callable construct, and what does that construction run with no edge of its own" for the dependency-injection checks that walkCallGraph.getReachableIncludingReferences(Set, Function): DI completeness (ReachableInjectionsOrError, E08210/E08220) and DI ordering (TransitiveInjectionOrderingOrError, E08200).THE injections that can run when the given callables run - transitively, through the phase-5 call graph: an injection (name as T!) in a body the roots reach, or a property injection of a type they construct (a property's injection belongs to its type and runs wherever the type is constructed).THE dependency-injection completeness check for programs (E08220, E08210): every injection that can run when a program runs must be satisfiable - the program needs an application, and that application must register every injected abstract component the program can reach.Item 5, step 2: DERIVE, for user methods and operators, the RETAINS marker the built-ins declare - so a user method that hands back one of its own properties follows the same rule asJSON.get.Record the components on a circular injection chain (E08190) on the application, for the ordering checks that run after the E08190 check - the write half ofInjectionCycles, whoseofreads them back (never a second cycle detector).THE encoding of a measured quality metric (withMetricSymbolOfandMetricLimitCheck, the steps of everyAcceptable*OrErrorcheck): squirrel the integer on the symbol, under the one key this instance is made for, as decimal text throughSmallIntStrings.Detects comparisons of a Boolean expression with a Boolean literal (E08084).THE matrix of the redundant-condition checks - the set check (x?, E08088/E08089) and the empty check (x empty, E08092/E08093) - deciding which error a provable answer earns (F29, 2026-10-20: it was written out twice).Detects empty checks that are always true or always false based on data flow analysis (E08092/E08093).Detects isSet checks that are always true or always false based on data flow analysis (E08088/E08089).Detects when an override method/operator body is textually identical to the super (E11044).THE view of what an application registers for dependency injection: the fully-qualified interface names of every component registration in the list.THE registered-type fact (EK9_NATIVE_CYCLE_COLLECTOR_DESIGN.md §13.11, S2; re-investigation F2): a user type is REGISTERED when a value of it can be reached from what is published for the life of the program - the registrations runtime threads can reach (S2c: every service, and every component code a runtime thread runs can inject -ReachableInjectionsfrom the concurrent entry points; with the type it is registered as and its aspects - the proxy holds each aspect and runs its advice on whichever thread calls the component; review 2026-11-02 H1) and every handler handed to runtime threads byTCP.accept,acceptUntilComplete,HTTP.serveUntilCompleteorSignals.register(the handler itself and what it captures) - throughSharedTypeClosure, which here never enters aMutexLock's payload: the payload is its own domain (T11), never published.PRE_IR_CHECKS use-site check for a RETRACTED bare default comparison operator.Checks if return variables are initialised.Enforces guard-first return ordering (E08055; docs/language-design/EK9_REQUIRE_RETURN_ORDERING_SPEC.md).THE return-source classifier: whichReturnSourceKindone source of a callable's returning variable is (withIsFreshValueExpression, which decidesReturnSourceKind.NEW).THE kinds of what a callable's returning variable is made to refer to - one of theMutatedOnlyVariables.ReturningCallable.sources()collected in Walk 1.What a source of a callable's returning variable may BE, in terms of the callable's own inputs - THE transitive reading of D61 (Steve, 2026-10-21: follow the inner call back): the names of the incoming parameters it may be (or a view of) andReturnSourceOrigins.RECEIVER_ORIGINwhen it may be the receiver's interior.THE conjunct walk for Optional/Result/Iterator safe access (Steve, 2026-10-07, decision Q3) - use it, never re-derive a variant.One fact a conjunct proves:access(ok/error/get/next) onsymbolis safe.THE E08040 rule: an Optional/Result/Iterator that is proven safe to unwrap in the current scope must not be re-pointed there, by ANY store - an assignment statement (o: other,o :=? other) or a construct's assignment pre-flow (if o := other then o?).Marks specific types of variable of specific types (generic Result/Option) in a manner that enables the compiler to check if access to certain methods is safe.Tests specific types of variable of specific types (generic Result/Option) in a manner that enables the compiler to check if access to certain methods is safe.THE shared "which of Result, Optional or Iterator is this symbol" (the containers whose unwrapping methodok()/error(),get()ornext()must be preceded by a check, E08030), and the three-way dispatch ontoSymbolsAndScopes' record, is-safe and mark operations.The container a symbol's type is a parameterisation of.It may be that before calling this you have determined that 'isSet' has been called or you 'know' that the value of the variable is present and set.Walks a callable's parse tree to collect the variable symbols accessible within it - the local variables declared in its (possibly nested) instruction blocks, and the property fields of its enclosing aggregate.Detects hardcoded secrets in string literals at compile time (E11080-E11086).THE walk of a type and its supers for the dependency-injection checks - constructing it constructs the parts its supers declare (D-10:UnsatisfiedInjectionReporteronce had a second, recursive copy of it).Detects self-comparison expressions where both sides resolve to the same symbol (E08081).Links the escaping-return-value contract of service operations into the call graph.Validates that every service declaration has a security posture: either 'open' or 'constrain by X [and Y]'.The principal data-race check (slice 1, step 7): every mutation of shared state inside a function/method markedCONCURRENT_ENTRY_POINTmust occur inside aMutexLock.enter(...)callback.THE closure of the types a value of the root types can reach (EK9_NATIVE_CYCLE_COLLECTOR_DESIGN.md §13.11): through properties (inherited ones included), supers and traits (for what they give it), subtypes of a type a value is declared as (a reference of a base type may hold any of them - never a super's other subtypes), type arguments (List of T), what a method or constructor may KEEP (RetainsArgument- a built-in's fields are not EK9 properties, so aPriorityQueuereaches its comparator this way), and the captures of every function or dynamic class a reached value can be.Who runs beside a signal handler, and what it reaches (EK9_NATIVE_CYCLE_COLLECTOR_DESIGN.md §13.11, S2c - option A, Steve 2026-11-02).THE "may this slot already hold a value here?" test for a slot that may be assigned AT MOST ONCE ON ANY PATH: a closeable property in its own constructor, and a closeable returning variable declared unset (D3 extended to every closeable slot, 2026-10-06).THE per-construct statement budget - the maximum number of statements permitted for the construct the symbol represents, keyed off the symbol kind (the limits live inQualityMetricLimits).Tracks statement counts within functions/methods/operators.THE decision of which calls make a closeable value that the block statement making it OWNS - the unnamed half of the closeable ownership rule (Steve, 2026-10-05): "A closeable value you never NAME is owned by the statement that created it and closed when that statement finishes." The named half isCloseableLocalOrError(E81056).THE phase-5 reading of a STORE: a statement that makes a variable, property or returning variable refer to the value an expression evaluates to.TheStoreSitea pointer assignment to an existing variable or property makes, if it makes one (:=,=,:,:=?, asRepointsTargetreads it, to a name or through an object access).TheStoreSitea declaration with an initialiser makes, if it makes one (<-,:=,=,:; never:~:, which merges into a new object).THE check that a stream statement never appends to the very variable it is reading (E08277, Steve 2026-10-21, D82; widened to EVERY type 2026-10-26, Q6/Q8 - one rule, no type list):cat items >> itemsappends toitemswhilecatis still pulling from it - the pull never reaches the end, and at run time the List's iterator says so.Checks a stream pipeline whose source is aforcarrying a pre-flow guard.THE check that a stream statement's>(which REPLACES its target, Steve 2026-10-27: "let's make>consistent") is only written where the target can give the fresh value it is built on (E08278): a concrete type with an accessible no-argument constructor and a:=:.Used with aggregates to check that if they have any properties that are not initialised at declaration the developer has taken appropriate steps to ensure initialisation.Deals with checking if all paths through switch/case/default (return) result in variables meeting criteria.Only triggers the call the retrieve the appropriate symbol for the node.Every user implementation of a handler type a thread-spawning call takes (TCPHandler, the ready handlers,SignalHandler-IsThreadSpawningCall.handlerTypes()) is a concurrent entry point and a published handler, wherever it is written and however it reaches the call (review 2026-11-02, H2).THE test that a block statement cannot throw: it only stores a literal, or the value a variable already holds, into a variable of exactly the same type (size := limit,count <- 0,total as Integer?).Analyzes how traits are implemented in an aggregate to detect E11023 pattern (missing 'by' delegation).Result of analyzing trait implementation for potential missing 'by' delegation.Detects when multiple traits implemented by an aggregate have methods with the same signature.Post-parallel detector for transitive injection ordering validation (E08200), run once the call graph is built.Checks the try/catch/finally structure via the code analysers.Record on each dispatcher entry what its handlers return and keep (MarkOverriddenBy, over the pairsDispatchedHandlerPairsfound); true when an entry gained a rule - one step of a RETAINS derivation's fixpoint.Reports dependency-injection fields that cannot be satisfied at a given point, walking an aggregate's own injection fields plus those of any aggregate types reachable through its property field types and supers.Detects unused captured variables in dynamic functions and classes (E11018).Detects unused parameters in functions, methods, constructors, and service operations (E08091).E08275:Networking().urlOf(text)given text the compiler can know - decision U3 of docs/architecture/EK9_URL_TYPE_DESIGN.md §0.The variables of one source that a signal handler captures, by IDENTITY (design §13.11 S2c, option A): the outer symbol each argument of aSignalHandlerimplementation's capture list names.Accepts a variable only declaration and ensures the variable is recorded if appropriate, for transient flow checks.THE distance E11030 reports (ConfusinglySimilarNamesOrError) - the weighted edit distance its rich message describes, and nothing else: a character inserted, removed or changed costs 2 wherever it is (the first and last positions included), two ADJACENT characters swapped cost 2 (one edit, as Damerau counts it -title/titel) except at the FIRST letter (positions 0-1), where a swap is two changes (latitude/altitude, 4 - Steve, 2026-10-12), and a change of case alone costs 1.Checks the while statement via the code analysers.