private void doSetInitialBreakpointsAndResume(@NotNull final IsolateRef isolateRef) { final Set<XLineBreakpoint<XBreakpointProperties>> xBreakpoints = myBreakpointHandler.getXBreakpoints(); if (xBreakpoints.isEmpty()) { myIsolatesInfo.setBreakpointsSet(isolateRef); checkInitialResume(isolateRef); return; } final AtomicInteger counter = new AtomicInteger(xBreakpoints.size()); for (final XLineBreakpoint<XBreakpointProperties> xBreakpoint : xBreakpoints) { addBreakpoint( isolateRef.getId(), xBreakpoint.getSourcePosition(), new VmServiceConsumers.BreakpointConsumerWrapper() { @Override void sourcePositionNotApplicable() { checkDone(); } @Override public void received(Breakpoint vmBreakpoint) { myBreakpointHandler.vmBreakpointAdded(xBreakpoint, isolateRef.getId(), vmBreakpoint); checkDone(); } @Override public void onError(RPCError error) { myBreakpointHandler.breakpointFailed(xBreakpoint); checkDone(); } private void checkDone() { if (counter.decrementAndGet() == 0) { myIsolatesInfo.setBreakpointsSet(isolateRef); checkInitialResume(isolateRef); } } }); } }
@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); } } }