diff --git a/java/testFramework/src/com/intellij/codeInsight/completion/CompletionTestCase.java b/java/testFramework/src/com/intellij/codeInsight/completion/CompletionTestCase.java index 714408dcf566..f453d16d618b 100644 --- a/java/testFramework/src/com/intellij/codeInsight/completion/CompletionTestCase.java +++ b/java/testFramework/src/com/intellij/codeInsight/completion/CompletionTestCase.java @@ -19,6 +19,7 @@ import com.intellij.codeInsight.daemon.DaemonAnalyzerTestCase; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupManager; import com.intellij.codeInsight.lookup.impl.LookupImpl; +import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil; import com.intellij.testFramework.PlatformTestCase; import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; @@ -63,7 +64,8 @@ public abstract class CompletionTestCase extends DaemonAnalyzerTestCase { } protected void complete(final int time) { - new CodeCompletionHandlerBase(myType).invokeCompletion(myProject, myEditor, time); + new CodeCompletionHandlerBase(myType).invokeCompletion(myProject, InjectedLanguageUtil + .getEditorForInjectedLanguageNoCommit(myEditor, getFile()), time); LookupImpl lookup = (LookupImpl)LookupManager.getActiveLookup(myEditor); myItems = lookup == null ? null : lookup.getItems().toArray(new LookupElement[lookup.getItems().size()]); 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 dd506593d942..09e627a1dc24 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java @@ -470,7 +470,7 @@ public class CodeCompletionHandlerBase { InjectedLanguageManager manager = InjectedLanguageManager.getInstance(originalFile.getProject()); final PsiFile hostFile = manager.getTopLevelFile(originalFile); final Editor hostEditor = InjectedLanguageUtil.getTopLevelEditor(initContext.getEditor()); - final OffsetMap hostMap = translateOffsetMapToHost(initContext, originalFile, hostFile, hostEditor); + final OffsetMap hostMap = translateOffsetMapToHost(originalFile, hostFile, hostEditor, initContext.getOffsetMap()); final PsiFile[] hostCopy = {null}; DocumentUtil.writeInRunUndoTransparentAction(new Runnable() { @@ -532,15 +532,11 @@ public class CodeCompletionHandlerBase { } } - private static OffsetMap translateOffsetMapToHost(CompletionInitializationContext initContext, - PsiFile context, - PsiFile hostFile, - Editor hostEditor) { + private static OffsetMap translateOffsetMapToHost(PsiFile originalFile, PsiFile hostFile, Editor hostEditor, OffsetMap map) { final InjectedLanguageManager injectedLanguageManager = InjectedLanguageManager.getInstance(hostFile.getProject()); final OffsetMap hostMap = new OffsetMap(hostEditor.getDocument()); - final OffsetMap original = initContext.getOffsetMap(); - for (final OffsetKey key : original.getAllOffsets()) { - hostMap.addOffset(key, injectedLanguageManager.injectedToHost(context, original.getOffset(key))); + for (final OffsetKey key : map.getAllOffsets()) { + hostMap.addOffset(key, injectedLanguageManager.injectedToHost(originalFile, map.getOffset(key))); } return hostMap; } @@ -570,10 +566,12 @@ public class CodeCompletionHandlerBase { return context; } - private static OffsetMap translateOffsetMapToInjected(OffsetMap hostMap, DocumentWindow injectedDocument) { + private static OffsetMap translateOffsetMapToInjected(OffsetMap hostMap, Document injectedDocument) { + if (!(injectedDocument instanceof DocumentWindow)) return hostMap; + final OffsetMap map = new OffsetMap(injectedDocument); for (final OffsetKey key : hostMap.getAllOffsets()) { - map.addOffset(key, injectedDocument.hostToInjected(hostMap.getOffset(key))); + map.addOffset(key, ((DocumentWindow)injectedDocument).hostToInjected(hostMap.getOffset(key))); } return map; } @@ -630,7 +628,7 @@ public class CodeCompletionHandlerBase { if (marker.isValid()) { int insertionPoint = marker.getStartOffset(); context = insertItem(indicator, item, completionChar, items, update, editor, indicator.getParameters().getOriginalFile(), - insertionPoint, idDelta + insertionPoint); + insertionPoint, idDelta + insertionPoint, indicator.getOffsetMap()); int offset = editor.getCaretModel().getOffset(); caretsAfter.add(document.createRangeMarker(offset, offset)); } @@ -649,16 +647,20 @@ public class CodeCompletionHandlerBase { } else if (editor.getCaretModel().supportsMultipleCarets()) { final List contexts = new ArrayList(); final Editor hostEditor = InjectedLanguageUtil.getTopLevelEditor(editor); + final PsiFile originalFile = indicator.getParameters().getOriginalFile(); + final PsiFile hostFile = InjectedLanguageUtil.getTopLevelFile(originalFile); + final OffsetMap hostMap = translateOffsetMapToHost(originalFile, hostFile, hostEditor, indicator.getOffsetMap()); hostEditor.getCaretModel().runForEachCaret(new CaretAction() { @Override public void perform(Caret caret) { - PsiFile hostFile = InjectedLanguageUtil.getTopLevelFile(indicator.getParameters().getOriginalFile()); PsiFile targetFile = InjectedLanguageUtil.findInjectedPsiNoCommit(hostFile, caret.getOffset()); Editor targetEditor = InjectedLanguageUtil.getInjectedEditorForInjectedFile(hostEditor, targetFile); int targetCaretOffset = targetEditor.getCaretModel().getOffset(); + OffsetMap injectedMap = translateOffsetMapToInjected(hostMap, targetEditor.getDocument()); CompletionAssertions.WatchingInsertionContext currentContext = insertItem(indicator, item, completionChar, items, update, targetEditor, targetFile == null ? hostFile : targetFile, - targetCaretOffset, targetCaretOffset + idEndOffsetDelta); + targetCaretOffset, targetCaretOffset + idEndOffsetDelta, + injectedMap); contexts.add(currentContext); } }, true); @@ -677,7 +679,7 @@ public class CodeCompletionHandlerBase { } } else { context = insertItem(indicator, item, completionChar, items, update, editor, indicator.getParameters().getOriginalFile(), caretOffset, - idEndOffset); + idEndOffset, indicator.getOffsetMap()); } return context; } @@ -729,23 +731,24 @@ public class CodeCompletionHandlerBase { } private static CompletionAssertions.WatchingInsertionContext insertItem(final CompletionProgressIndicator indicator, - final LookupElement item, - final char completionChar, - List items, - final CompletionLookupArranger.StatisticsUpdate update, - final Editor editor, - final PsiFile psiFile, - final int caretOffset, final int idEndOffset) { + final LookupElement item, + final char completionChar, + List items, + final CompletionLookupArranger.StatisticsUpdate update, + final Editor editor, + final PsiFile psiFile, + final int caretOffset, + final int idEndOffset, final OffsetMap offsetMap) { editor.getCaretModel().moveToOffset(caretOffset); final int initialStartOffset = caretOffset - item.getLookupString().length(); assert initialStartOffset >= 0 : "negative startOffset: " + caretOffset + "; " + item.getLookupString(); - indicator.getOffsetMap().addOffset(CompletionInitializationContext.START_OFFSET, initialStartOffset); - indicator.getOffsetMap().addOffset(CompletionInitializationContext.SELECTION_END_OFFSET, caretOffset); - indicator.getOffsetMap().addOffset(CompletionInitializationContext.IDENTIFIER_END_OFFSET, idEndOffset); + offsetMap.addOffset(CompletionInitializationContext.START_OFFSET, initialStartOffset); + offsetMap.addOffset(CompletionInitializationContext.SELECTION_END_OFFSET, caretOffset); + offsetMap.addOffset(CompletionInitializationContext.IDENTIFIER_END_OFFSET, idEndOffset); final CompletionAssertions.WatchingInsertionContext - context = new CompletionAssertions.WatchingInsertionContext(indicator.getOffsetMap(), psiFile, + context = new CompletionAssertions.WatchingInsertionContext(offsetMap, psiFile, completionChar, items, editor); ApplicationManager.getApplication().runWriteAction(new Runnable() { @Override