dotty.tools.dotc.transform.init
Members list
Type members
Classlikes
The co-inductive cache used for analysis
The co-inductive cache used for analysis
The cache contains two maps from (Config, Tree)
to Res
:
- input cache (
this.last
) - output cache (
this.current
)
The two caches are required because we want to make sure in a new iteration, an expression is evaluated exactly once. The monotonicity of the analysis ensures that the cache state goes up the lattice of the abstract domain, consequently the algorithm terminates.
The general skeleton for usage of the cache is as follows
def analysis(entryExp: Expr) = {
def iterate(entryExp: Expr)(using Cache) =
eval(entryExp, initConfig)
if cache.hasChanged && noErrors then
cache.last = cache.current
cache.current = Empty
cache.changed = false
iterate(entryExp)
else
reportErrors
def eval(expr: Expr, config: Config)(using Cache) =
cache.cachedEval(config, expr) {
// Actual recursive evaluation of expression.
//
// Only executed if the entry `(exp, config)` is not in the output cache.
}
iterate(entryExp)(using new Cache)
}
See the documentation for the method Cache.cachedEval
for more information.
What goes to the configuration (Config
) and what goes to the result (Res
) need to be decided by the specific analysis and justified by reasoning about soundness.
Type parameters
- Config
-
The analysis state that matters for evaluating an expression.
- Res
-
The result from the evaluation the given expression.
Attributes
Logic related to evaluation trace for showing friendly error messages
Logic related to evaluation trace for showing friendly error messages
A trace is a sequence of program positions which tells the evaluation order that leads to an error. It is usually more informative than the stack trace by tracking the exact sub-expression in the trace instead of only methods.
Attributes
- Supertypes
- Self type
-
Trace.type