diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java b/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java index 88d14aa13d77..c2ce494ab957 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/ConstructorInsertHandler.java @@ -58,7 +58,7 @@ public class ConstructorInsertHandler implements InsertHandler= 0 && plEnd >= 0) { diff --git a/platform/lang-api/src/com/intellij/codeInsight/completion/OffsetMap.java b/platform/lang-api/src/com/intellij/codeInsight/completion/OffsetMap.java index 90a9b12292e9..8f28dffa0dcb 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/completion/OffsetMap.java +++ b/platform/lang-api/src/com/intellij/codeInsight/completion/OffsetMap.java @@ -19,10 +19,10 @@ import com.intellij.openapi.Disposable; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.RangeMarker; import com.intellij.openapi.progress.ProgressManager; +import com.intellij.util.containers.ContainerUtil; import gnu.trove.THashMap; import gnu.trove.THashSet; -import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; @@ -48,10 +48,10 @@ public class OffsetMap implements Disposable { public int getOffset(OffsetKey key) { synchronized (myMap) { final RangeMarker marker = myMap.get(key); - if (marker == null) return -1; + if (marker == null) throw new IllegalArgumentException("Offset " + key + " is not registered"); if (!marker.isValid()) { removeOffset(key); - return -1; + throw new IllegalStateException("Offset " + key + " is invalid: " + marker); } final int endOffset = marker.getEndOffset(); @@ -62,6 +62,11 @@ public class OffsetMap implements Disposable { } } + public boolean containsOffset(OffsetKey key) { + final RangeMarker marker = myMap.get(key); + return marker != null && marker.isValid(); + } + /** * Register key-offset binding. Offset will change together with {@link Document} editing operations * unless an operation replaces completely the offset vicinity. @@ -108,7 +113,7 @@ public class OffsetMap implements Disposable { synchronized (myMap) { ProgressManager.checkCanceled(); assert !myDisposed; - return new ArrayList(myMap.keySet()); + return ContainerUtil.filter(myMap.keySet(), this::containsOffset); } } 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 34a67a149b82..bb8e159880e0 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java @@ -566,10 +566,9 @@ public class CodeCompletionHandlerBase { final Editor editor = indicator.getEditor(); final int caretOffset = indicator.getCaret().getOffset(); - int idEndOffset = indicator.getIdentifierEndOffset(); - if (idEndOffset < 0) { - idEndOffset = CompletionInitializationContext.calcDefaultIdentifierEnd(editor, caretOffset); - } + final int idEndOffset = indicator.getOffsetMap().containsOffset(CompletionInitializationContext.IDENTIFIER_END_OFFSET) ? + indicator.getIdentifierEndOffset() : + CompletionInitializationContext.calcDefaultIdentifierEnd(editor, caretOffset); final int idEndOffsetDelta = idEndOffset - caretOffset; CompletionAssertions.WatchingInsertionContext context; diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java index 1a4be6bf4c56..20a099c0dfb9 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionLookupArranger.java @@ -462,6 +462,10 @@ public class CompletionLookupArranger extends LookupArranger { return; } + if (!context.getOffsetMap().containsOffset(CompletionInitializationContext.START_OFFSET)) { + return; + } + final Document document = context.getDocument(); int startOffset = context.getStartOffset(); int tailOffset = context.getEditor().getCaretModel().getOffset(); @@ -550,7 +554,9 @@ public class CompletionLookupArranger extends LookupArranger { public void addSparedChars(CompletionProgressIndicator indicator, LookupElement item, InsertionContext context, char completionChar) { String textInserted; - if (context.getStartOffset() >= 0 && context.getTailOffset() >= context.getStartOffset()) { + if (context.getOffsetMap().containsOffset(CompletionInitializationContext.START_OFFSET) && + context.getOffsetMap().containsOffset(InsertionContext.TAIL_OFFSET) && + context.getTailOffset() >= context.getStartOffset()) { textInserted = context.getDocument().getImmutableCharSequence().subSequence(context.getStartOffset(), context.getTailOffset()).toString(); } else { textInserted = item.getLookupString();