public static void processTokens(@NotNull PsiFile injectedPsi,
                                   @NotNull List<? extends PsiLanguageInjectionHost.Shred> places,
                                   @NotNull BiConsumer<? super @NotNull TextRange, ? super @NotNull TextAttributesKey @NotNull []> consumer) {
    List<? extends InjectedLanguageUtilBase.TokenInfo> tokens = InjectedLanguageUtil.getHighlightTokens(injectedPsi);
    if (tokens == null) return;

    int shredIndex = -1;
    int injectionHostTextRangeStart = -1;
    for (InjectedLanguageUtil.TokenInfo token : tokens) {
      ProgressManager.checkCanceled();
      TextRange range = token.rangeInsideInjectionHost();
      if (range.getLength() == 0) continue;
      if (shredIndex != token.shredIndex()) {
        shredIndex = token.shredIndex();
        PsiLanguageInjectionHost.Shred shred = places.get(shredIndex);
        PsiLanguageInjectionHost host = shred.getHost();
        if (host == null) return;
        injectionHostTextRangeStart = host.getTextRange().getStartOffset();
      }
      TextRange hostRange = range.shiftRight(injectionHostTextRangeStart);

      consumer.accept(hostRange, token.textAttributesKeys());
    }
  }
public static void processTokens(@NotNull PsiFile injectedPsi,
                                   @NotNull List<? extends PsiLanguageInjectionHost.Shred> places,
                                   @NotNull BiConsumer<? super @NotNull TextRange, ? super @NotNull TextAttributesKey @NotNull []> consumer)