Class ReachableInjectionsOrError

java.lang.Object
org.ek9lang.compiler.phase5.ReachableInjectionsOrError

final class ReachableInjectionsOrError extends Object
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.

Transitive, through the phase-5 call graph. An injection (name as T!) is a load from the application when its declaration runs, wherever it is: in the program's own body, in a function, method, operator, constructor or dynamic function the program reaches, or as a property of a type the program constructs. Checking only the program's own body (as this check once did) let a program with no application call a function that injects - it compiled, and the load failed at runtime (NoClassDefFoundError _Application, or NoSuchFieldError when the application did not register the type).

Sound, never precise. What can run is CallGraph.getReachableIncludingReferences(Set, Function): the call edges (with the override and dispatcher links, RTA-bounded), every function referenced as a value and every dynamic function created (a delegate may call them), and for each type constructed, its property initialisers and ALL its methods and operators - members run with no call site (the runtime calls $, ?, <=>, #?...; a for loop calls iterator()), and the call graph has no edge for them. A program with an application likewise reaches every member of what that application registers (components, services, aspects). A type's injections are the injections in its own declaration, so constructing it requires them all, as the application's own checks already do. Over-reporting is the accepted direction: the alternative is a runtime failure.

A generic's T() has no construction edge (D15 folds the generic's members onto the template and T() onto nothing), so a member that constructs a type parameter is taken to construct every aggregate type argument of every concrete parameterisation of its generic in the program (Parameterisations).

Each unsatisfied injection is reported TWICE: at the program (what it needs and where the first need is) and at the injection itself (which program reaches it), so the error is found from either end.

  • Constructor Details

  • Method Details

    • check

      void check()
      Check every program (including @Test programs - they run too).