static void updateHighlightersByTyping(@NotNull Project project, @NotNull DocumentEvent e) {
    ThreadingAssertions.assertEventDispatchThread();

    Document document = e.getDocument();
    if (document.isInBulkUpdate()) return;

    int start = e.getOffset() - 1;
    int end = start + e.getOldLength();

    List<HighlightInfo> toRemove = new ArrayList<>();
    DaemonCodeAnalyzerEx.processHighlights(document, project, null, start, end, info -> {
      if (!info.needUpdateOnTyping()) return true;

      RangeHighlighter highlighter = info.getHighlighter();
      int highlighterStart = highlighter.getStartOffset();
      int highlighterEnd = highlighter.getEndOffset();
      if (info.isAfterEndOfLine()) {
        if (highlighterStart < document.getTextLength()) {
          highlighterStart += 1;
        }
        if (highlighterEnd < document.getTextLength()) {
          highlighterEnd += 1;
        }
      }
      if (!highlighter.isValid() || start < highlighterEnd && highlighterStart <= end) {
        toRemove.add(info);
      }
      return true;
    });

    for (HighlightInfo info : toRemove) {
      RangeHighlighterEx highlighter = info.getHighlighter();
      if (!highlighter.isValid() || info.type.equals(HighlightInfoType.WRONG_REF)) {
        disposeWithFileLevelIgnoreErrors(highlighter, project, info);
      }
    }

    if (!toRemove.isEmpty()) {
      disableWhiteSpaceOptimization(document);
    }
  }
static void updateHighlightersByTyping(@NotNull Project project, @NotNull DocumentEvent e)