Package com.jetbrains.lang.dart.ide.runner.server

Source Code of com.jetbrains.lang.dart.ide.runner.server.DartCommandLineDebugProcess

package com.jetbrains.lang.dart.ide.runner.server;

import com.intellij.execution.ExecutionResult;
import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.ui.ConsoleViewContentType;
import com.intellij.execution.ui.ExecutionConsole;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.Computable;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.util.Consumer;
import com.intellij.util.TimeoutUtil;
import com.intellij.xdebugger.*;
import com.intellij.xdebugger.breakpoints.XBreakpointHandler;
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
import com.intellij.xdebugger.frame.XStackFrame;
import com.jetbrains.lang.dart.DartBundle;
import com.jetbrains.lang.dart.ide.runner.base.DartDebuggerEditorsProvider;
import com.jetbrains.lang.dart.ide.runner.server.frame.DartStackFrame;
import com.jetbrains.lang.dart.ide.runner.server.google.VmConnection;
import com.jetbrains.lang.dart.ide.runner.server.google.VmIsolate;
import com.jetbrains.lang.dart.util.DartUrlResolver;
import gnu.trove.THashSet;
import org.jetbrains.annotations.NotNull;

import java.io.IOException;
import java.util.LinkedList;
import java.util.Set;

public class DartCommandLineDebugProcess extends XDebugProcess {
  public static final Logger LOG = Logger.getInstance(DartCommandLineDebugProcess.class.getName());

  private final @NotNull ExecutionResult myExecutionResult;
  private final @NotNull DartUrlResolver myDartUrlResolver;
  private final @NotNull XBreakpointHandler[] myBreakpointHandlers;
  private final @NotNull VmConnection myVmConnection;
  private final int myObservatoryPort;

  private final @NotNull LinkedList<VmIsolate> myAllIsolates = new LinkedList<VmIsolate>();
  private final @NotNull Set<VmIsolate> mySuspendedIsolates = new THashSet<VmIsolate>();
  private VmIsolate myLatestCurrentIsolate;

  private boolean myVmConnected = false;

  public DartCommandLineDebugProcess(@NotNull final XDebugSession session,
                                     @NotNull final DartCommandLineRunningState commandLineState,
                                     @NotNull final ExecutionResult executionResult,
                                     @NotNull final VirtualFile dartFile) {
    super(session);
    myExecutionResult = executionResult;
    myDartUrlResolver = DartUrlResolver.getInstance(session.getProject(), dartFile);
    myObservatoryPort = commandLineState.getObservatoryPort();

    final DartCommandLineBreakpointHandler dartBreakpointHandler = new DartCommandLineBreakpointHandler(this);
    myBreakpointHandlers = new XBreakpointHandler[]{dartBreakpointHandler};

    // see com.google.dart.tools.debug.core.server.ServerDebugTarget
    myVmConnection = new VmConnection(null, commandLineState.getDebuggingPort());
    myVmConnection.addListener(new DartVmListener(this, dartBreakpointHandler));

    session.addSessionListener(new XDebugSessionAdapter() {
      @Override
      public void sessionPaused() {
        stackFrameChanged();
      }

      @Override
      public void stackFrameChanged() {
        final XStackFrame stackFrame = getSession().getCurrentStackFrame();
        myLatestCurrentIsolate = stackFrame instanceof DartStackFrame ? ((DartStackFrame)stackFrame).getIsolate() : null;
      }
    });

    connect();
  }

  private void connect() {
    // see com.google.dart.tools.debug.core.server.ServerDebugTarget.connect()

    ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
      public void run() {
        long timeout = 10000;
        long startTime = System.currentTimeMillis();

        try {
          TimeoutUtil.sleep(50);

          while (true) {
            try {
              myVmConnection.connect();
              break;
            }
            catch (IOException ioe) {
              if (!myVmConnection.isConnected()) {
                throw ioe;
              }

              if (System.currentTimeMillis() > startTime + timeout) {
                throw ioe;
              }
              else {
                TimeoutUtil.sleep(20);
              }
            }
          }
        }
        catch (IOException ioe) {
          getSession().getConsoleView()
            .print("Unable to connect debugger to the Dart VM: " + ioe.getMessage(), ConsoleViewContentType.ERROR_OUTPUT);
          getSession().stop();
        }
      }
    });
  }

  @Override
  protected ProcessHandler doGetProcessHandler() {
    return myExecutionResult.getProcessHandler();
  }

  @NotNull
  @Override
  public ExecutionConsole createConsole() {
    return myExecutionResult.getExecutionConsole();
  }

  @NotNull
  @Override
  public XDebuggerEditorsProvider getEditorsProvider() {
    return new DartDebuggerEditorsProvider();
  }

  @Override
  @NotNull
  public XBreakpointHandler<?>[] getBreakpointHandlers() {
    return myBreakpointHandlers;
  }

  @Override
  public void startStepOver() {
    if (myLatestCurrentIsolate != null && mySuspendedIsolates.contains(myLatestCurrentIsolate)) {
      try {
        myVmConnection.stepOver(myLatestCurrentIsolate);
      }
      catch (IOException e) {
        LOG.error(e);
      }
    }
  }

  @Override
  public void startStepInto() {
    if (myLatestCurrentIsolate != null && mySuspendedIsolates.contains(myLatestCurrentIsolate)) {
      try {
        myVmConnection.stepInto(myLatestCurrentIsolate);
      }
      catch (IOException e) {
        LOG.error(e);
      }
    }
  }

  @Override
  public void startStepOut() {
    if (myLatestCurrentIsolate != null && mySuspendedIsolates.contains(myLatestCurrentIsolate)) {
      try {
        myVmConnection.stepOut(myLatestCurrentIsolate);
      }
      catch (IOException e) {
        LOG.error(e);
      }
    }
  }

  @Override
  public void stop() {
    try {
      LOG.debug("closing connection");
      myVmConnection.close();
    }
    catch (IOException e) {
      LOG.warn(e);
    }
  }

  @Override
  public void resume() {
    try {
      for (VmIsolate isolate : new THashSet<VmIsolate>(mySuspendedIsolates)) {
        myVmConnection.resume(isolate);
      }
    }
    catch (IOException e) {
      LOG.error(e);
    }
  }

  @Override
  public void startPausing() {
    if (!myAllIsolates.isEmpty() && mySuspendedIsolates.isEmpty()) {
      try {
        for (VmIsolate isolate : myAllIsolates) {
          myVmConnection.interrupt(isolate);
        }
      }
      catch (IOException e) {
        LOG.error(e);
      }
    }
  }

  @Override
  public void runToPosition(@NotNull XSourcePosition position) {
    // todo implement
  }

  @NotNull
  public DartUrlResolver getDartUrlResolver() {
    return myDartUrlResolver;
  }

  @NotNull
  public VmConnection getVmConnection() {
    return myVmConnection;
  }

  public void setVmConnected(final boolean vmConnected) {
    myVmConnected = vmConnected;
    getSession().rebuildViews();
  }

  public void isolateCreated(final VmIsolate isolate) {
    myAllIsolates.add(isolate);
  }

  public void isolateShutdown(final VmIsolate isolate) {
    myAllIsolates.remove(isolate);
  }

  public void isolateSuspended(@NotNull final VmIsolate isolate) {
    mySuspendedIsolates.add(isolate);
  }

  public void isolateResumed(@NotNull final VmIsolate isolate) {
    mySuspendedIsolates.remove(isolate);
  }

  public void processAllIsolates(@NotNull final Consumer<VmIsolate> isolateConsumer) {
    if (!myVmConnected) return;

    for (VmIsolate isolate : myAllIsolates) {
      isolateConsumer.consume(isolate);
    }
  }

  public boolean isIsolateSuspended(@NotNull final VmIsolate isolate) {
    return mySuspendedIsolates.contains(isolate);
  }

  @Override
  public String getCurrentStateMessage() {
    return getSession().isStopped()
           ? XDebuggerBundle.message("debugger.state.message.disconnected")
           : myVmConnected
             ? XDebuggerBundle.message("debugger.state.message.connected")
             : DartBundle.message("debugger.waiting.vm.to.connect");
  }

  @Override
  public void registerAdditionalActions(@NotNull final DefaultActionGroup leftToolbar,
                                        @NotNull final DefaultActionGroup topToolbar,
                                        @NotNull final DefaultActionGroup settings) {
    // For Run tool window this action is added in DartCommandLineRunningState.createActions()
    topToolbar.addSeparator();

    topToolbar.addAction(new OpenDartObservatoryUrlAction(myObservatoryPort, new Computable<Boolean>() {
      @Override
      public Boolean compute() {
        return myVmConnected && !getSession().isStopped();
      }
    }));
  }
}
TOP

Related Classes of com.jetbrains.lang.dart.ide.runner.server.DartCommandLineDebugProcess

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.