Custom NodeRenderer for debug view

I'm writing a plugin that adds custom NodeRenderer objects to the debugger view.
I'm basically writing custom renderers in java instead of using the built-in Data Type Renderer expression language.


Plugin component:

public void projectOpened() {
  NodeRendererSettings.getInstance().addPluginRenderer(
    new CustomNodeRenderer("custom.renderer"));
}


Custom renderer:

public class CustomNodeRenderer extends NodeRendererImpl {
  public String calcLabel(
    final ValueDescriptor valueDescriptor,
    EvaluationContext evaluationContext,
    final DescriptorLabelListener labelListener)
  throws EvaluateException
  {
    final Value value = valueDescriptor.getValue();
    ToStringCommand command =
      createRendererCommand(
        valueDescriptor,
        evaluationContext,
        labelListener,
        value);
    BatchEvaluator batchEvaluator =
      BatchEvaluator.getBatchEvaluator(evaluationContext.getDebugProcess());
    batchEvaluator.invoke(command);
    return XDebuggerUIConstants.COLLECTING_DATA_MESSAGE;
  }
}



My problem is that the ToStringCommand.action() method never gets called.  Everything gets called correctly on my custom ToStringCommand (getValue() and evaluationResult()) but not the method that does the actual work.

I tested this by making a small example project and breaking in with a basic breakpoint then stepping across the instantiation of a simple example object.  
It all works fine if I just return my custom rendered string from calcLabel directly, but I don't want to do that (see below).

There's code inside BatchEvaluator.invoke(ToStringCommand) to execute the ToStringCommand.action() method - but it never gets called.
Instead, what happens is that the code (eventually) ends up calling com.intellij.rt.debugger.BatchEvaluatorServer.evaluate() - and that just calls the toString() method on the result of calling my custom ToStringCommand's getValue() method.

Some questions:
1) Am I adding the renderer the right way?  (ie. calling the addPluginRenderer() method)
2) Why does the BatchEvaluator go to all this effort with ToStringCommand objects and then just call toString() anyway?
3) Is my implementation of calcLabel() listed above correct?  It's pretty much copy/pasted from ToStringRenderer, but maybe I messed something up.  Should I just put my custom renderer implementation here instead of using ToStringCommand?  I actually like the multi-threaded setup from ToStringRenderer: I reckon my custom renderer will take longer than the IDEA code, so I'm pretty sure I want to be doing something like this.

Please sign in to leave a comment.