コード例 #1
0
  // returns (injected psi, leaf element at the offset, language of the leaf element)
  // since findElementAt() is expensive, we trying to reuse its result
  @NotNull
  private static Trinity<PsiElement, PsiElement, Language> tryOffset(
      @NotNull PsiFile hostFile, final int offset, @NotNull PsiDocumentManager documentManager) {
    FileViewProvider provider = hostFile.getViewProvider();
    Language leafLanguage = null;
    PsiElement leafElement = null;
    for (Language language : provider.getLanguages()) {
      PsiElement element = provider.findElementAt(offset, language);
      if (element != null) {
        if (leafLanguage == null) {
          leafLanguage = language;
          leafElement = element;
        }
        PsiElement injected = findInside(element, hostFile, offset, documentManager);
        if (injected != null) return Trinity.create(injected, element, language);
      }
      // maybe we are at the border between two psi elements, then try to find injection at the end
      // of the left element
      if (offset != 0 && (element == null || element.getTextRange().getStartOffset() == offset)) {
        PsiElement leftElement = provider.findElementAt(offset - 1, language);
        if (leftElement != null && leftElement.getTextRange().getEndOffset() == offset) {
          PsiElement injected = findInside(leftElement, hostFile, offset, documentManager);
          if (injected != null) return Trinity.create(injected, element, language);
        }
      }
    }

    return Trinity.create(null, leafElement, leafLanguage);
  }
コード例 #2
0
 // consider injected elements
 public static PsiElement findElementAtNoCommit(@NotNull PsiFile file, int offset) {
   FileViewProvider viewProvider = file.getViewProvider();
   Trinity<PsiElement, PsiElement, Language> result = null;
   if (!(viewProvider instanceof InjectedFileViewProvider)) {
     PsiDocumentManager documentManager = PsiDocumentManager.getInstance(file.getProject());
     result = tryOffset(file, offset, documentManager);
     PsiElement injected = result.first;
     if (injected != null) {
       return injected;
     }
   }
   Language baseLanguage = viewProvider.getBaseLanguage();
   if (result != null && baseLanguage == result.third) {
     return result.second; // already queried
   }
   return viewProvider.findElementAt(offset, baseLanguage);
 }