diff --git a/platform/core-api/src/com/intellij/psi/util/PsiTreeUtil.java b/platform/core-api/src/com/intellij/psi/util/PsiTreeUtil.java index 82e308c50fb5..20527ef19c93 100644 --- a/platform/core-api/src/com/intellij/psi/util/PsiTreeUtil.java +++ b/platform/core-api/src/com/intellij/psi/util/PsiTreeUtil.java @@ -332,11 +332,20 @@ public class PsiTreeUtil { @Nullable public static PsiElement findFirstParent(@Nullable PsiElement element, boolean strict, Condition condition) { + //noinspection unchecked + return findFirstParent(element, strict, condition, Condition.FALSE); + } + + @Nullable + public static PsiElement findFirstParent(@Nullable PsiElement element, boolean strict, + @NotNull final Condition condition, + @NotNull final Condition stopCondition) { if (strict && element != null) { element = element.getParent(); } while (element != null) { + if (stopCondition.value(element)) return null; if (condition.value(element)) { return element; } diff --git a/platform/lang-api/src/com/intellij/psi/util/PsiUtilBase.java b/platform/lang-api/src/com/intellij/psi/util/PsiUtilBase.java index 1052ba973f20..f6c13896f0e9 100644 --- a/platform/lang-api/src/com/intellij/psi/util/PsiUtilBase.java +++ b/platform/lang-api/src/com/intellij/psi/util/PsiUtilBase.java @@ -133,7 +133,14 @@ public class PsiUtilBase extends PsiUtilCore implements PsiEditorUtil { lang = language; } else if (lang != language) { - return null; + // correctly process the case when leaf element is a part of embedded fragment, but it is totally contained inside + // "parent" language + Language finalLang = lang; + final TextRange range = new TextRange(start, end); + final PsiElement wrappingParent = PsiTreeUtil.findFirstParent( + elt, false, element -> file.equals(element.getContainingFile()) && finalLang.equals(element.getLanguage()), + element -> element.getTextRange() != null && !range.contains(element.getTextRange())); + if (wrappingParent == null) return null; } } TextRange range = elt.getTextRange();