diff --git a/platform/core-api/src/com/intellij/lang/injection/InjectedLanguageManager.java b/platform/core-api/src/com/intellij/lang/injection/InjectedLanguageManager.java index 74691a2a42e7..64e30b64354c 100644 --- a/platform/core-api/src/com/intellij/lang/injection/InjectedLanguageManager.java +++ b/platform/core-api/src/com/intellij/lang/injection/InjectedLanguageManager.java @@ -79,6 +79,12 @@ public abstract class InjectedLanguageManager { public abstract boolean isInjectedFragment(@NotNull PsiFile file); + /** + * Finds PSI element in injected fragment (if any) at the given offset in the host file.

+ * E.g. if you injected XML {@code ""} into Java string literal {@code "String s = "";"} and the caret is at {@code "xxx"} then + * this method will return XmlToken(XML_TAG_START) with the text {@code "xxx"}.
+ * Invocation of this method on uncommitted {@code hostFile} can lead to unexpected results, including throwing an exception! + */ @Nullable public abstract PsiElement findInjectedElementAt(@NotNull PsiFile hostFile, int hostDocumentOffset); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java index 35427167701c..5f349b2381da 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java @@ -29,6 +29,7 @@ import com.intellij.featureStatistics.FeatureUsageTracker; import com.intellij.ide.DataManager; import com.intellij.injected.editor.DocumentWindow; import com.intellij.lang.Language; +import com.intellij.lang.injection.InjectedLanguageManager; import com.intellij.openapi.actionSystem.ActionManager; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.DataContext; @@ -240,7 +241,7 @@ public class CodeCompletionHandlerBase { int offset = editor.getCaretModel().getOffset(); int psiOffset = Math.max(0, offset - 1); - PsiElement elementAt = InjectedLanguageUtil.findInjectedElementNoCommit(psiFile, psiOffset); + PsiElement elementAt = InjectedLanguageManager.getInstance(psiFile.getProject()).findInjectedElementAt(psiFile, psiOffset); if (elementAt == null) { elementAt = psiFile.findElementAt(psiOffset); } diff --git a/platform/lang-impl/src/com/intellij/codeInsight/highlighting/BraceHighlightingHandler.java b/platform/lang-impl/src/com/intellij/codeInsight/highlighting/BraceHighlightingHandler.java index 32d1030800b0..e36d54d244a3 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/highlighting/BraceHighlightingHandler.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/highlighting/BraceHighlightingHandler.java @@ -20,6 +20,7 @@ import com.intellij.codeInsight.CodeInsightSettings; import com.intellij.codeInsight.hint.EditorFragmentComponent; import com.intellij.injected.editor.EditorWindow; import com.intellij.lang.Language; +import com.intellij.lang.injection.InjectedLanguageManager; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ModalityState; import com.intellij.openapi.application.ex.ApplicationManagerEx; @@ -190,7 +191,7 @@ public class BraceHighlightingHandler { Document document = editor.getDocument(); // when document is committed, try to highlight braces in injected lang - it's fast if (PsiDocumentManager.getInstance(project).isCommitted(document)) { - final PsiElement injectedElement = InjectedLanguageUtil.findInjectedElementNoCommit(psiFile, offset); + final PsiElement injectedElement = InjectedLanguageManager.getInstance(psiFile.getProject()).findInjectedElementAt(psiFile, offset); if (injectedElement != null /*&& !(injectedElement instanceof PsiWhiteSpace)*/) { final PsiFile injected = injectedElement.getContainingFile(); if (injected != null) { diff --git a/platform/lang-impl/src/com/intellij/codeInsight/template/CustomTemplateCallback.java b/platform/lang-impl/src/com/intellij/codeInsight/template/CustomTemplateCallback.java index c6e70ef954c2..2fb67a7e165e 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/template/CustomTemplateCallback.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/template/CustomTemplateCallback.java @@ -59,7 +59,7 @@ public class CustomTemplateCallback { myTemplateManager = TemplateManager.getInstance(myProject); myOffset = getOffset(editor); - PsiElement element = InjectedLanguageUtil.findInjectedElementNoCommit(file, myOffset); + PsiElement element = InjectedLanguageManager.getInstance(file.getProject()).findInjectedElementAt(file, myOffset); myFile = element != null ? element.getContainingFile() : file; myInInjectedFragment = InjectedLanguageManager.getInstance(myProject).isInjectedFragment(myFile); @@ -171,7 +171,7 @@ public class CustomTemplateCallback { AttachmentFactory.createAttachment(file.getVirtualFile())); } else { - element = InjectedLanguageUtil.findInjectedElementNoCommit(file, offset); + element = InjectedLanguageManager.getInstance(file.getProject()).findInjectedElementAt(file, offset); } } if (element == null) { diff --git a/platform/lang-impl/src/com/intellij/psi/formatter/PsiBasedFormattingModel.java b/platform/lang-impl/src/com/intellij/psi/formatter/PsiBasedFormattingModel.java index 23f6c03e419d..6f66f81ddeab 100644 --- a/platform/lang-impl/src/com/intellij/psi/formatter/PsiBasedFormattingModel.java +++ b/platform/lang-impl/src/com/intellij/psi/formatter/PsiBasedFormattingModel.java @@ -20,6 +20,7 @@ import com.intellij.formatting.Block; import com.intellij.formatting.FormattingDocumentModel; import com.intellij.formatting.FormattingModelEx; import com.intellij.lang.ASTNode; +import com.intellij.lang.injection.InjectedLanguageManager; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; @@ -86,7 +87,7 @@ public class PsiBasedFormattingModel implements FormattingModelEx { if (leafElement != null) { PsiFile hostFile = myASTNode.getPsi().getContainingFile(); - PsiElement injectedElement = InjectedLanguageUtil.findInjectedElementNoCommit(hostFile, offset); + PsiElement injectedElement = InjectedLanguageManager.getInstance(hostFile.getProject()).findInjectedElementAt(hostFile, offset); TextRange effectiveRange = injectedElement != null ? rangeInInjectedDocument(textRange, injectedElement) : null; if (effectiveRange == null) { @@ -151,7 +152,8 @@ public class PsiBasedFormattingModel implements FormattingModelEx { assert !PsiDocumentManager.getInstance(project).isUncommited(myDocumentModel.getDocument()); // TODO:default project can not be used for injections, because latter might wants (unavailable) indices - PsiElement psiElement = project.isDefault() ? null : InjectedLanguageUtil.findInjectedElementNoCommit(containingFile, offset); + PsiElement psiElement = project.isDefault() ? null : InjectedLanguageManager.getInstance(containingFile.getProject()) + .findInjectedElementAt(containingFile, offset); if (psiElement != null) { return psiElement.getNode(); } diff --git a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java index 38c81df7c5bb..ae5fcca62bf5 100644 --- a/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/psi/impl/source/codeStyle/CodeStyleManagerImpl.java @@ -43,7 +43,6 @@ import com.intellij.psi.impl.source.SourceTreeToPsiMap; import com.intellij.psi.impl.source.tree.FileElement; import com.intellij.psi.impl.source.tree.RecursiveTreeElementWalkingVisitor; import com.intellij.psi.impl.source.tree.TreeElement; -import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; import com.intellij.psi.util.PsiUtilBase; import com.intellij.util.CharTable; import com.intellij.util.IncorrectOperationException; @@ -560,7 +559,7 @@ public class CodeStyleManagerImpl extends CodeStyleManager implements Formatting if (!(astNode instanceof FileElement)) { return new Pair<>(null, null); } - PsiElement elementAt = InjectedLanguageUtil.findInjectedElementNoCommit(file, offset); + PsiElement elementAt = InjectedLanguageManager.getInstance(file.getProject()).findInjectedElementAt(file, offset); final CharTable charTable = ((FileElement)astNode).getCharTable(); if (elementAt == null) { elementAt = findElementInTreeWithFormatterEnabled(file, offset); diff --git a/python/testSrc/com/jetbrains/python/PyWrapTest.java b/python/testSrc/com/jetbrains/python/PyWrapTest.java index 825d6d8bca8b..4eb1fd80ead1 100644 --- a/python/testSrc/com/jetbrains/python/PyWrapTest.java +++ b/python/testSrc/com/jetbrains/python/PyWrapTest.java @@ -15,10 +15,11 @@ */ package com.jetbrains.python; +import com.intellij.lang.injection.InjectedLanguageManager; +import com.intellij.psi.PsiFile; import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.codeStyle.CodeStyleSettingsManager; import com.intellij.psi.codeStyle.CommonCodeStyleSettings; -import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; import com.jetbrains.python.fixtures.PyTestCase; /** @@ -75,7 +76,9 @@ public class PyWrapTest extends PyTestCase { myFixture.configureByFile("wrap/WrapInStringLiteral.py"); final int stringLiteralOffset = 114; - assertNotNull(InjectedLanguageUtil.findInjectedElementNoCommit(myFixture.getFile(), stringLiteralOffset + "\"".length())); + PsiFile hostFile = myFixture.getFile(); + assertNotNull( + InjectedLanguageManager.getInstance(hostFile.getProject()).findInjectedElementAt(hostFile, stringLiteralOffset + "\"".length())); myFixture.type(" AND field"); myFixture.checkResultByFile("wrap/WrapInStringLiteral.after.py", true);