@Nullable private String evaluateExpression( final @NotNull String isolateId, final @Nullable Frame vmTopFrame, final @Nullable XExpression xExpression) { final String evalText = xExpression == null ? null : xExpression.getExpression(); if (vmTopFrame == null || StringUtil.isEmptyOrSpaces(evalText)) return null; final Ref<String> evalResult = new Ref<>(); final Semaphore semaphore = new Semaphore(); semaphore.down(); myDebugProcess .getVmServiceWrapper() .evaluateInFrame( isolateId, vmTopFrame, evalText, new XDebuggerEvaluator.XEvaluationCallback() { @Override public void evaluated(@NotNull final XValue result) { if (result instanceof DartVmServiceValue) { evalResult.set( getSimpleStringPresentation(((DartVmServiceValue) result).getInstanceRef())); } semaphore.up(); } @Override public void errorOccurred(@NotNull final String errorMessage) { evalResult.set( "Failed to evaluate log expression [" + evalText + "]: " + errorMessage); semaphore.up(); } }, true); semaphore.waitFor(1000); return evalResult.get(); }
@Override public void received(@NotNull final String streamId, @NotNull final Event event) { switch (event.getKind()) { case BreakpointAdded: // TODO Respond to breakpoints added by the observatory. // myBreakpointHandler.vmBreakpointAdded(null, event.getIsolate().getId(), // event.getBreakpoint()); break; case BreakpointRemoved: break; case BreakpointResolved: myBreakpointHandler.breakpointResolved(event.getBreakpoint()); break; case Extension: break; case GC: break; case Inspect: break; case IsolateExit: myDebugProcess.isolateExit(event.getIsolate()); break; case IsolateRunnable: break; case IsolateStart: break; case IsolateUpdate: break; case None: break; case PauseBreakpoint: case PauseException: case PauseInterrupted: myDebugProcess.isolateSuspended(event.getIsolate()); ApplicationManager.getApplication() .executeOnPooledThread( () -> { final ElementList<Breakpoint> breakpoints = event.getKind() == EventKind.PauseBreakpoint ? event.getPauseBreakpoints() : null; final InstanceRef exception = event.getKind() == EventKind.PauseException ? event.getException() : null; onIsolatePaused( event.getIsolate(), breakpoints, exception, event.getTopFrame(), event.getAtAsyncSuspension()); }); break; case PausePostRequest: // We get this event after an isolate reload call, when pause after reload has been // requested. // TODO: Set current breakpoints; resume the isolate. myDebugProcess.getVmServiceWrapper().resumeIsolate(event.getIsolate().getId(), null); break; case PauseExit: break; case PauseStart: myDebugProcess.getVmServiceWrapper().handleIsolate(event.getIsolate(), true); break; case Resume: myDebugProcess.isolateResumed(event.getIsolate()); break; case ServiceExtensionAdded: break; case VMUpdate: break; case WriteEvent: myDebugProcess.handleWriteEvent(event.getBytes()); break; case Unknown: break; } }
void onIsolatePaused( @NotNull final IsolateRef isolateRef, @Nullable final ElementList<Breakpoint> vmBreakpoints, @Nullable final InstanceRef exception, @Nullable final Frame vmTopFrame, boolean atAsyncSuspension) { if (vmTopFrame == null) { myDebugProcess.getSession().positionReached(new XSuspendContext() {}); return; } final DartVmServiceSuspendContext suspendContext = new DartVmServiceSuspendContext( myDebugProcess, isolateRef, vmTopFrame, exception, atAsyncSuspension); final XStackFrame xTopFrame = suspendContext.getActiveExecutionStack().getTopFrame(); final XSourcePosition sourcePosition = xTopFrame == null ? null : xTopFrame.getSourcePosition(); if (vmBreakpoints == null || vmBreakpoints.isEmpty()) { final StepOption latestStep = myDebugProcess.getVmServiceWrapper().getLatestStep(); if (latestStep == StepOption.Over && equalSourcePositions(myLatestSourcePosition, sourcePosition)) { // continue stepping to change current line myDebugProcess.getVmServiceWrapper().resumeIsolate(isolateRef.getId(), latestStep); } else { myLatestSourcePosition = sourcePosition; myDebugProcess.getSession().positionReached(suspendContext); } } else { if (vmBreakpoints.size() > 1) { // Shouldn't happen. IDE doesn't allow to set 2 breakpoints on one line. LOG.error(vmBreakpoints.size() + " breakpoints hit in one shot."); } // Remove any temporary (run to cursor) breakpoints. myBreakpointHandler.removeTemporaryBreakpoints(isolateRef.getId()); final XLineBreakpoint<XBreakpointProperties> xBreakpoint = myBreakpointHandler.getXBreakpoint(vmBreakpoints.get(0)); if (xBreakpoint == null) { // breakpoint could be set in the Observatory myLatestSourcePosition = sourcePosition; myDebugProcess.getSession().positionReached(suspendContext); return; } if ("false" .equals( evaluateExpression( isolateRef.getId(), vmTopFrame, xBreakpoint.getConditionExpression()))) { myDebugProcess.getVmServiceWrapper().resumeIsolate(isolateRef.getId(), null); return; } myLatestSourcePosition = sourcePosition; final String logExpression = evaluateExpression(isolateRef.getId(), vmTopFrame, xBreakpoint.getLogExpressionObject()); final boolean suspend = myDebugProcess.getSession().breakpointReached(xBreakpoint, logExpression, suspendContext); if (!suspend) { myDebugProcess.getVmServiceWrapper().resumeIsolate(isolateRef.getId(), null); } } }