SEXP RDebugger::doStep()

in src/debugger/RDebugger.cpp [254:335]


SEXP RDebugger::doStep(SEXP expr, SEXP env, SEXP srcref, bool alwaysStop, RContext *callContext) {
  bool suspend = false;
  if (rDebugger.isEnabled()) {
    auto position = getPosition(srcref);
    VirtualFileInfo* virtualFile = position.first;
    switch (currentCommand) {
    case CONTINUE:
      break;
    case PAUSE:
      suspend = true;
      break;
    case STEP_INTO:
      suspend = true;
      break;
    case STEP_INTO_MY_CODE:
      suspend = virtualFile != nullptr && !virtualFile->isGenerated;
      break;
    case ABORT:
      setCommand(CONTINUE);
      R_interrupts_pending = 1;
      R_CheckUserInterrupt();
      return R_NilValue;
    case STEP_OVER:
    case STEP_OUT: {
      if (callContext == nullptr) callContext = getCurrentCallContext();
      SEXP callEnv = callContext == bottomContext ? bottomContextRealEnv : getEnvironment(callContext);
      auto it = contextsToStop.find(callEnv);
      if (it != contextsToStop.end() && it->second >= getEvalDepth(callContext)) {
        suspend = true;
      }
      break;
    }
    case RUN_TO_POSITION:
      suspend = virtualFile != nullptr && virtualFile->extPtr == runToPositionTarget.first && position.second == runToPositionTarget.second;
      break;
    }
    int line = position.second;
    Breakpoint* breakpoint;
    if (virtualFile == nullptr || virtualFile->breakpointsByLine.size() <= line) {
      breakpoint = nullptr;
    } else {
      auto const& vector = virtualFile->breakpointsByLine[line];
      breakpoint = vector.empty() ? nullptr : vector[0];
    }
    if (!breakpointsMuted && breakpoint != nullptr && breakpoint->enabled && (breakpoint->master == nullptr || breakpoint->masterWasHit) &&
        Rf_getAttrib(srcref, RI->noBreakpointFlag) == R_NilValue) {
      CPP_BEGIN
        if (checkCondition(breakpoint->condition, env)) {
          if (!breakpoint->slaveLeaveEnabled) breakpoint->masterWasHit = false;
          for (Breakpoint *slave : breakpoint->slaves) {
            slave->masterWasHit = true;
          }
          if (breakpoint->hitMessage) {
            printHitMessage(virtualFile, line);
          }
          if (breakpoint->printStack) {
            printStack(buildStack(getContextDump(expr)));
          }
          evaluateAndLog(breakpoint->evaluateAndLog, env);
          if (breakpoint->suspend) {
            suspend = true;
          }
          if (breakpoint->removeAfterHit) {
            AsyncEvent e;
            e.set_debugremovebreakpointrequest(breakpoint->id);
            rDebugger.removeBreakpointById(breakpoint->id);
            rpiService->sendAsyncEvent(e);
          }
        }
      CPP_END_VOID
    }
    if (alwaysStop) suspend = true;
  }

  if (suspend) {
    CPP_BEGIN
    sendDebugPrompt(expr);
    CPP_END_VOID
  }

  return Rf_eval(expr, env);
}