String (EvaluationContextImpl context, DescriptorLabelListener labelListener, DebugProcessImpl debugProcess, NodeRenderer renderer) { DebuggerManagerThreadImpl.assertIsManagerThread(); EvaluateException valueException = myValueException; CompletableFuture<Boolean> expandableFuture; if (valueException == null || valueException.getExceptionFromTargetVM() != null) { expandableFuture = getChildrenRenderer(debugProcess) .thenCompose(r -> r.isExpandableAsync(getValue(), context, this)); } else { expandableFuture = CompletableFuture.completedFuture(false); } if (!OnDemandRenderer.isOnDemandForced(debugProcess)) { try { setValueIcon(renderer.calcValueIcon(this, context, labelListener)); } catch (EvaluateException e) { LOG.info(e); setValueIcon(null); } } //set label id if (isShowIdLabel() && renderer instanceof NodeRendererImpl) { setIdLabel(((NodeRendererImpl)renderer).calcIdLabel(this, debugProcess, labelListener)); } if (valueException == null) { long start = renderer instanceof NodeRendererImpl && ((NodeRendererImpl)renderer).hasOverhead() ? System.currentTimeMillis() : 0; try { setValueLabel(renderer.calcLabel(this, context, labelListener)); } catch (EvaluateException e) { setValueLabelFailed(e); } finally { if (start > 0) { OverheadTimings.add(debugProcess, new NodeRendererImpl.Overhead((NodeRendererImpl)renderer), 1, System.currentTimeMillis() - start); } } } else { setValueLabelFailed(valueException); } // only call labelChanged when we have expandable value expandableFuture.whenComplete((res, ex) -> { if (ex == null) { myIsExpandable = res; } else { ex = DebuggerUtilsAsync.unwrap(ex); if (ex instanceof EvaluateException) { LOG.warn(new Throwable(ex)); } else if (!(ex instanceof CancellationException) && !(ex instanceof VMDisconnectedException)) { LOG.error(new Throwable(ex)); } } labelListener.labelChanged(); }); return ""; // we have overridden getLabel }