org.eclipse.ocl.examples.impactanalyzer.instanceScope
Class TracebackCache
java.lang.Object
org.eclipse.ocl.examples.impactanalyzer.instanceScope.TracebackCache
public class TracebackCache
- extends java.lang.Object
During the navigation of a NavigationStep
tree, starting from an EObject
, navigation steps may be reached
several times with the same EObject
at hand. To avoid endless recursion and to accelerate the computation, an object of
this class is passed through an evaluation of a NavigationStep
tree.
In addition to remembering traceback navigation results, this cache also stores variable values inferred during the traceback.
Those can be used for partial evaluations, e.g., when trying to determine if a subexpression may be reached at all based on the
current variable values.
Variable values are valid only in a scope, called a "dynamic scope." While syntactically the variable's static scope is limited
to a certain OCLExpression
, e.g., the in
expression of a
let expression for the variable defined by the let
expression, the same expression may be evaluated
several times during the evaluation of some other expression. Each evaluation of the static scope expression represents a
dynamic scope for the variables whose static scope is being evaluated.
When the unused
function is trying a partial evaluation and is missing a variable to complete the evaluation, we
check if the missing variable is a let
variable. If not, the unused
evaluation request is stored in
this cache together with the values of all variables known at that time, as well as the unknown variable that caused the
evaluation to fail. If the missing variable is a let
variable, we also try to evaluate the corresponding
initialization expression
. If that fails too, we store a nested unused
evaluation request which has as its unknown variable the one from the let
variable's initialization expression. If
that variable's value is inferred, the initialization expression is evaluated again. If successful (either deferred or
immediately), this triggers the inner request which will then have its unknown let
variable set to the result of
evaluating the initialization expression.
When during traceback a variable's value is inferred, the unused
evaluations that have this variable as their
unknown variable can be given another try, based on the variable values remembered, as well as the freshly-inferred value for
the variable whose value was formerly unknown. If the evaluation succeeds and proves that the expression for which
unused
was evaluated is actually not used, the traceback can be stopped immediately and simply return an empty
set. If the evaluation fails again for another variable with unknown value, the procedure is repeated: the freshly-inferred
value is added to the known variable values for the unused
evaluation request, and the variable whose value now is
unknown is remembered with the request such that when it's value is inferred by the traceback procedure, the
unused
evaluation can be attempted again.
When the traceback function leaves an expression that is the static scope of an unknown variable, the corresponding
unused
evaluation requests are canceled because we cannot hope for the traceback process to ever infer it anymore.
Which scopes are left when moving from one expression to the next can be a bit tricky. For example, when jumping from an
iterator variable expression to the LoopExp
's source expression, all kinds of in-between expressions that are containers to
the iterator variable expression are left as well. Therefore, the common container of the from/to expressions needs to be
determined, and all variables whose static scope is any of from, or any of from's direct or transitive containers that
are still contained (directly or transitively) in the common container of from/to, are considered out of scope.
- Author:
- Axel Uhl (D043530)
Methods inherited from class java.lang.Object |
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait |
TracebackCache
public TracebackCache()
get
public java.util.Set<AnnotatedEObject> get(NavigationStep step,
AnnotatedEObject from)
- Looks up a previously
entered
result for the step
where navigation
started at the from
object. If not found, null
is returned.
put
public void put(NavigationStep step,
AnnotatedEObject from,
java.util.Set<AnnotatedEObject> result)