Expression evaluator new
Scala debugger uses new expression evaluator, which translates user code into invocations of
JDI remote calls. This allows evaluation of expression in context of some breakpoint, with access to local variables and methods.
Main entry point into expression evaluation in Scala IDE debugger is
ExpressionManager object which takes care of holding debug session state, and evaluating expressions in GUI friendly way.
Expression evaluation is done in
ExpressionEvaluator which parses the code using
ToolBox, applies several transformations to it and then compiles the result with
Before evaluation multiple AST transformations (called
phases) are performed.
Those are split into 3 groups:
- First few of them are necessary to make user-defined code type-check. Unbound variables, lambdas, usages of
superetc. are mocked.
- Next comes type-check (from
ToolBox), which expands implicits, assigns types and make some other Scala magic.
- After type-check code is transformed further to allow remote execution. All mocks and method calls are replaced with code mimicking their behavior using
JDIcalls to debugged jvm.
Every type used in evaluated expression is replaced with
JdiProxy. Those proxies uses
scala.Dynamic trait to intercept all method calls and proxy them to debugged jvm.
Because of different handling of arrays, primitives and
Strings on jvm, we had to create a separate proxy flavors for each of those.
All methods related to debugged jvm are encapsulated within a
JdiContext instance. It provides abilities to:
- run methods on debugged jvm,
- access types and values in context of debugged jvm,
- load new classes on debugged jvm,
- create proxies for values and object by name,
- create String representations of proxies etc.
Support for conditional breakpoints is placed in
ConditionManager and relies on
ExpressionManager to do all heavy lifting.