private boolean toggleAtLine(PsiFile psiFile, int lineNumber) {
   XDebuggerUtil debuggerUtil = XDebuggerUtil.getInstance();
   if (debuggerUtil.canPutBreakpointAt(myProject, psiFile.getVirtualFile(), lineNumber)) {
     debuggerUtil.toggleLineBreakpoint(myProject, psiFile.getVirtualFile(), lineNumber);
     return true;
   }
   return false;
 }
  @Override
  public boolean canPutAt(
      @NotNull final VirtualFile file, final int line, @NotNull final Project project) {
    final Ref<Boolean> stoppable = Ref.create(false);
    final Document document = FileDocumentManager.getInstance().getDocument(file);
    if (document != null) {
      if (file.getFileType() == PythonFileType.INSTANCE) {
        XDebuggerUtil.getInstance()
            .iterateLine(
                project,
                document,
                line,
                new Processor<PsiElement>() {
                  @Override
                  public boolean process(PsiElement psiElement) {
                    if (psiElement instanceof PsiWhiteSpace || psiElement instanceof PsiComment)
                      return true;
                    if (psiElement.getNode() != null
                        && notStoppableElementType(psiElement.getNode().getElementType()))
                      return true;

                    // Python debugger seems to be able to stop on pretty much everything
                    stoppable.set(true);
                    return false;
                  }
                });

        if (PyDebugSupportUtils.isContinuationLine(document, line - 1)) {
          stoppable.set(false);
        }
      }
    }

    return stoppable.get();
  }
  public XValueHint(
      @NotNull Project project,
      @NotNull Editor editor,
      @NotNull Point point,
      @NotNull ValueHintType type,
      @NotNull ExpressionInfo expressionInfo,
      @NotNull XDebuggerEvaluator evaluator,
      @NotNull XDebugSession session) {
    super(project, editor, point, type, expressionInfo.getTextRange());

    myEvaluator = evaluator;
    myDebugSession = session;
    myExpression =
        XDebuggerEvaluateActionHandler.getExpressionText(expressionInfo, editor.getDocument());
    myValueName =
        XDebuggerEvaluateActionHandler.getDisplayText(expressionInfo, editor.getDocument());
    myExpressionInfo = expressionInfo;

    VirtualFile file;
    ConsoleView consoleView = ConsoleViewImpl.CONSOLE_VIEW_IN_EDITOR_VIEW.get(editor);
    if (consoleView instanceof LanguageConsoleView) {
      LanguageConsoleImpl console = ((LanguageConsoleView) consoleView).getConsole();
      file = console.getHistoryViewer() == editor ? console.getVirtualFile() : null;
    } else {
      file = FileDocumentManager.getInstance().getFile(editor.getDocument());
    }

    myExpressionPosition =
        file != null
            ? XDebuggerUtil.getInstance()
                .createPositionByOffset(file, expressionInfo.getTextRange().getStartOffset())
            : null;
  }
 @NotNull
 public ExceptionBreakpoint addExceptionBreakpoint(
     @NotNull final String exceptionClassName, final String packageName) {
   ApplicationManager.getApplication().assertIsDispatchThread();
   final JavaExceptionBreakpointType type =
       (JavaExceptionBreakpointType)
           XDebuggerUtil.getInstance().findBreakpointType(JavaExceptionBreakpointType.class);
   return ApplicationManager.getApplication()
       .runWriteAction(
           new Computable<ExceptionBreakpoint>() {
             @Override
             public ExceptionBreakpoint compute() {
               XBreakpoint<JavaExceptionBreakpointProperties> xBreakpoint =
                   XDebuggerManager.getInstance(myProject)
                       .getBreakpointManager()
                       .addBreakpoint(
                           type,
                           new JavaExceptionBreakpointProperties(exceptionClassName, packageName));
               ExceptionBreakpoint breakpoint =
                   new ExceptionBreakpoint(
                       myProject, exceptionClassName, packageName, xBreakpoint);
               addBreakpoint(breakpoint);
               if (LOG.isDebugEnabled()) {
                 LOG.debug("ExceptionBreakpoint Added");
               }
               return breakpoint;
             }
           });
 }
  protected void runToLine(int line) throws InvocationTargetException, InterruptedException {
    XDebugSession currentSession = XDebuggerManager.getInstance(getProject()).getCurrentSession();
    XSourcePosition position = currentSession.getCurrentPosition();

    currentSession.runToPosition(
        XDebuggerUtil.getInstance().createPosition(position.getFile(), line), false);

    waitForPause();
  }
 @Nullable
 public static XSourcePosition calcSourcePosition(@Nullable PsiElement element) {
   if (element != null) {
     PsiElement navigationElement = element.getNavigationElement();
     VirtualFile file = navigationElement.getContainingFile().getVirtualFile();
     if (file != null) {
       return XDebuggerUtil.getInstance().createPositionByElement(navigationElement);
     }
   }
   return null;
 }
 private <B extends XBreakpoint<?>> XBreakpoint createXBreakpoint(
     Class<? extends XBreakpointType<B, ?>> typeCls, Element breakpointNode)
     throws InvalidDataException {
   final XBreakpointType<B, ?> type = XDebuggerUtil.getInstance().findBreakpointType(typeCls);
   return ApplicationManager.getApplication()
       .runWriteAction(
           new Computable<XBreakpoint>() {
             @Override
             public XBreakpoint compute() {
               return XDebuggerManager.getInstance(myProject)
                   .getBreakpointManager()
                   .addBreakpoint((XBreakpointType) type, type.createProperties());
             }
           });
 }
 public boolean isEnabled(@NotNull final Project project, final AnActionEvent event) {
   XLineBreakpointType<?>[] breakpointTypes = XDebuggerUtil.getInstance().getLineBreakpointTypes();
   final XBreakpointManager breakpointManager =
       XDebuggerManager.getInstance(project).getBreakpointManager();
   for (XSourcePosition position :
       XDebuggerUtilImpl.getAllCaretsPositions(project, event.getDataContext())) {
     for (XLineBreakpointType<?> breakpointType : breakpointTypes) {
       final VirtualFile file = position.getFile();
       final int line = position.getLine();
       if (breakpointType.canPutAt(file, line, project)
           || breakpointManager.findBreakpointAtLine(breakpointType, file, line) != null) {
         return true;
       }
     }
   }
   return false;
 }
 public XValueHint(
     final Project project,
     final Editor editor,
     final Point point,
     final ValueHintType type,
     final TextRange textRange,
     final XDebuggerEvaluator evaluator,
     final XDebugSession session) {
   super(project, editor, point, type, textRange);
   myEvaluator = evaluator;
   myDebugSession = session;
   final Document document = editor.getDocument();
   myExpression = document.getText(textRange);
   final VirtualFile file = FileDocumentManager.getInstance().getFile(document);
   myExpressionPosition =
       file != null
           ? XDebuggerUtil.getInstance().createPositionByOffset(file, textRange.getStartOffset())
           : null;
 }
 private <B extends XBreakpoint<?>> XLineBreakpoint addXLineBreakpoint(
     Class<? extends XBreakpointType<B, ?>> typeCls, Document document, final int lineIndex) {
   final XBreakpointType<B, ?> type = XDebuggerUtil.getInstance().findBreakpointType(typeCls);
   final VirtualFile file = FileDocumentManager.getInstance().getFile(document);
   return ApplicationManager.getApplication()
       .runWriteAction(
           new Computable<XLineBreakpoint>() {
             @Override
             public XLineBreakpoint compute() {
               return XDebuggerManager.getInstance(myProject)
                   .getBreakpointManager()
                   .addLineBreakpoint(
                       (XLineBreakpointType) type,
                       file.getUrl(),
                       lineIndex,
                       ((XLineBreakpointType) type).createBreakpointProperties(file, lineIndex));
             }
           });
 }
  @Override
  @NotNull
  public List<PySmartStepIntoVariant> computeSmartStepVariants(@NotNull XSourcePosition position) {
    final Document document = FileDocumentManager.getInstance().getDocument(position.getFile());
    final List<PySmartStepIntoVariant> variants = Lists.newArrayList();
    final Set<PyCallExpression> visitedCalls = Sets.newHashSet();

    final int line = position.getLine();
    XDebuggerUtil.getInstance()
        .iterateLine(
            mySession.getProject(),
            document,
            line,
            psiElement -> {
              addVariants(document, line, psiElement, variants, visitedCalls);
              return true;
            });

    return variants;
  }
 public void setBreakpointDefaults(
     Key<? extends Breakpoint> category, BreakpointDefaults defaults) {
   Class typeCls = null;
   if (LineBreakpoint.CATEGORY.toString().equals(category.toString())) {
     typeCls = JavaLineBreakpointType.class;
   } else if (MethodBreakpoint.CATEGORY.toString().equals(category.toString())) {
     typeCls = JavaMethodBreakpointType.class;
   } else if (FieldBreakpoint.CATEGORY.toString().equals(category.toString())) {
     typeCls = JavaFieldBreakpointType.class;
   } else if (ExceptionBreakpoint.CATEGORY.toString().equals(category.toString())) {
     typeCls = JavaExceptionBreakpointType.class;
   }
   if (typeCls != null) {
     XBreakpointType<XBreakpoint<?>, ?> type =
         XDebuggerUtil.getInstance().findBreakpointType(typeCls);
     ((XBreakpointManagerImpl) getXBreakpointManager())
         .getBreakpointDefaults(type)
         .setSuspendPolicy(Breakpoint.transformSuspendPolicy(defaults.getSuspendPolicy()));
   }
   // myBreakpointDefaults.put(category, defaults);
 }
 public boolean canPutBreakpointAt(Project project, String file, int line) {
   VirtualFile vFile = LocalFileSystem.getInstance().findFileByPath(file);
   Assert.assertNotNull(vFile);
   return XDebuggerUtil.getInstance().canPutBreakpointAt(project, vFile, line);
 }
 @NotNull
 public Comparator<XLineBreakpoint<P>> getBreakpointComparator() {
   return XDebuggerUtil.getInstance().getDefaultLineBreakpointComparator();
 }
  public static boolean canAddLineBreakpoint(
      Project project, final Document document, final int lineIndex) {
    if (lineIndex < 0 || lineIndex >= document.getLineCount()) {
      return false;
    }
    final BreakpointManager breakpointManager =
        DebuggerManagerEx.getInstanceEx(project).getBreakpointManager();
    final LineBreakpoint breakpointAtLine =
        breakpointManager.findBreakpoint(
            document, document.getLineStartOffset(lineIndex), CATEGORY);
    if (breakpointAtLine != null) {
      // there already exists a line breakpoint at this line
      return false;
    }
    PsiDocumentManager.getInstance(project).commitDocument(document);

    final boolean[] canAdd = new boolean[] {false};
    XDebuggerUtil.getInstance()
        .iterateLine(
            project,
            document,
            lineIndex,
            new Processor<PsiElement>() {
              @Override
              public boolean process(PsiElement element) {
                if ((element instanceof PsiWhiteSpace)
                    || (PsiTreeUtil.getParentOfType(element, PsiComment.class, false) != null)) {
                  return true;
                }
                PsiElement child = element;
                while (element != null) {

                  final int offset = element.getTextOffset();
                  if (offset >= 0) {
                    if (document.getLineNumber(offset) != lineIndex) {
                      break;
                    }
                  }
                  child = element;
                  element = element.getParent();
                }

                if (child instanceof PsiMethod
                    && child.getTextRange().getEndOffset()
                        >= document.getLineEndOffset(lineIndex)) {
                  PsiCodeBlock body = ((PsiMethod) child).getBody();
                  if (body == null) {
                    canAdd[0] = false;
                  } else {
                    PsiStatement[] statements = body.getStatements();
                    canAdd[0] =
                        statements.length > 0
                            && document.getLineNumber(statements[0].getTextOffset()) == lineIndex;
                  }
                } else {
                  canAdd[0] = true;
                }
                return false;
              }
            });

    return canAdd[0];
  }
 protected static <S extends XDebuggerSettings<?>> S getInstance(Class<S> aClass) {
   return XDebuggerUtil.getInstance().getDebuggerSettings(aClass);
 }
  @Override
  public final boolean canPutAt(
      @NotNull final VirtualFile file, final int line, @NotNull Project project) {
    final PsiFile psiFile = PsiManager.getInstance(project).findFile(file);
    // JSPX supports jvm debugging, but not in XHTML files
    if (psiFile == null || psiFile.getVirtualFile().getFileType() == StdFileTypes.XHTML) {
      return false;
    }

    if (!StdFileTypes.CLASS.equals(psiFile.getFileType())
        && !DebuggerUtils.isBreakpointAware(psiFile)) {
      return false;
    }

    final Document document = FileDocumentManager.getInstance().getDocument(file);
    final Ref<Class<? extends JavaLineBreakpointTypeBase>> result = Ref.create();
    XDebuggerUtil.getInstance()
        .iterateLine(
            project,
            document,
            line,
            new Processor<PsiElement>() {
              @Override
              public boolean process(PsiElement element) {
                // avoid comments
                if ((element instanceof PsiWhiteSpace)
                    || (PsiTreeUtil.getParentOfType(element, PsiComment.class, false) != null)) {
                  return true;
                }
                PsiElement parent = element;
                while (element != null) {
                  // skip modifiers
                  if (element instanceof PsiModifierList) {
                    element = element.getParent();
                    continue;
                  }

                  final int offset = element.getTextOffset();
                  if (offset >= 0) {
                    if (document.getLineNumber(offset) != line) {
                      break;
                    }
                  }
                  parent = element;
                  element = element.getParent();
                }

                if (parent instanceof PsiMethod) {
                  if (parent.getTextRange().getEndOffset() >= document.getLineEndOffset(line)) {
                    PsiCodeBlock body = ((PsiMethod) parent).getBody();
                    if (body != null) {
                      PsiStatement[] statements = body.getStatements();
                      if (statements.length > 0
                          && document.getLineNumber(statements[0].getTextOffset()) == line) {
                        result.set(JavaLineBreakpointType.class);
                      }
                    }
                  }
                  if (result.isNull()) {
                    result.set(JavaMethodBreakpointType.class);
                  }
                } else if (parent instanceof PsiField) {
                  if (result.isNull()) {
                    result.set(JavaFieldBreakpointType.class);
                  }
                } else {
                  result.set(JavaLineBreakpointType.class);
                }
                return true;
              }
            });
    return result.get() == getClass();
  }
  /**
   * Toggle line breakpoint with editor support: - unfolds folded block on the line - if folded,
   * checks if line breakpoints could be toggled inside folded text
   */
  @NotNull
  public static Promise toggleLineBreakpoint(
      @NotNull Project project,
      @NotNull XSourcePosition position,
      @Nullable Editor editor,
      boolean temporary,
      boolean moveCarret) {
    int lineStart = position.getLine();
    VirtualFile file = position.getFile();
    // for folded text check each line and find out type with the biggest priority
    int linesEnd = lineStart;
    if (editor != null) {
      FoldRegion region = FoldingUtil.findFoldRegionStartingAtLine(editor, lineStart);
      if (region != null && !region.isExpanded()) {
        linesEnd = region.getDocument().getLineNumber(region.getEndOffset());
      }
    }

    final XBreakpointManager breakpointManager =
        XDebuggerManager.getInstance(project).getBreakpointManager();
    XLineBreakpointType<?>[] lineTypes = XDebuggerUtil.getInstance().getLineBreakpointTypes();
    XLineBreakpointType<?> typeWinner = null;
    int lineWinner = -1;
    for (int line = lineStart; line <= linesEnd; line++) {
      int maxPriority = 0;
      for (XLineBreakpointType<?> type : lineTypes) {
        maxPriority = Math.max(maxPriority, type.getPriority());
        final XLineBreakpoint<? extends XBreakpointProperties> breakpoint =
            breakpointManager.findBreakpointAtLine(type, file, line);
        if (breakpoint != null && temporary && !breakpoint.isTemporary()) {
          breakpoint.setTemporary(true);
        } else if (type.canPutAt(file, line, project) || breakpoint != null) {
          if (typeWinner == null || type.getPriority() > typeWinner.getPriority()) {
            typeWinner = type;
            lineWinner = line;
          }
        }
      }
      // already found max priority type - stop
      if (typeWinner != null && typeWinner.getPriority() == maxPriority) {
        break;
      }
    }

    if (typeWinner != null) {
      XSourcePosition winPosition =
          (lineStart == lineWinner) ? position : XSourcePositionImpl.create(file, lineWinner);
      if (winPosition != null) {
        Promise<XLineBreakpoint> res =
            XDebuggerUtilImpl.toggleAndReturnLineBreakpoint(
                project, typeWinner, winPosition, temporary, editor);

        if (editor != null && lineStart != lineWinner) {
          int offset = editor.getDocument().getLineStartOffset(lineWinner);
          ExpandRegionAction.expandRegionAtOffset(project, editor, offset);
          if (moveCarret) {
            editor.getCaretModel().moveToOffset(offset);
          }
        }
        return res;
      }
    }

    return PromiseKt.rejectedPromise();
  }