diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy index 4e4700b484ca..4aabe47f124f 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy @@ -1240,4 +1240,16 @@ class Foo {{ assert myFixture.lookupElementStrings.containsAll(['too', 'command.toString']) } + public void testUnfinishedString() { + myFixture.configureByText 'a.java', ''' +// Date +class Foo { + String s = " + String s2 = s; +} +''' + type 'D' + assert !lookup + } + } diff --git a/platform/lang-api/src/com/intellij/codeInsight/completion/SkipAutopopupInStrings.java b/platform/lang-api/src/com/intellij/codeInsight/completion/SkipAutopopupInStrings.java index e6eab89815c8..699667024930 100644 --- a/platform/lang-api/src/com/intellij/codeInsight/completion/SkipAutopopupInStrings.java +++ b/platform/lang-api/src/com/intellij/codeInsight/completion/SkipAutopopupInStrings.java @@ -17,10 +17,11 @@ package com.intellij.codeInsight.completion; import com.intellij.lang.LanguageParserDefinitions; import com.intellij.lang.ParserDefinition; -import com.intellij.patterns.ElementPattern; import com.intellij.patterns.PlatformPatterns; import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiErrorElement; import com.intellij.psi.PsiFile; +import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtilBase; import com.intellij.util.ThreeState; import org.jetbrains.annotations.NotNull; @@ -42,13 +43,26 @@ public class SkipAutopopupInStrings extends CompletionConfidence { if (contextElement != null) { ParserDefinition definition = LanguageParserDefinitions.INSTANCE.forLanguage(PsiUtilBase.getLanguageAtOffset(psiFile, offset)); if (definition != null) { - ElementPattern pattern = PlatformPatterns.psiElement().withElementType(definition.getStringLiteralElements()); - if (pattern.accepts(contextElement) || pattern.accepts(contextElement.getParent())) { + if (isStringLiteral(contextElement, definition) || isStringLiteral(contextElement.getParent(), definition)) { return ThreeState.YES; } + if (offset > 0) { + PsiElement prev = psiFile.findElementAt(offset - 1); + if (prev != null && (isStringLiteralWithError(prev, definition) || isStringLiteralWithError(prev.getParent(), definition))) { + return ThreeState.YES; + } + } } } return ThreeState.UNSURE; } + + private static boolean isStringLiteral(PsiElement element, ParserDefinition definition) { + return PlatformPatterns.psiElement().withElementType(definition.getStringLiteralElements()).accepts(element); + } + + private static boolean isStringLiteralWithError(PsiElement element, ParserDefinition definition) { + return isStringLiteral(element, definition) && PsiTreeUtil.nextLeaf(element) instanceof PsiErrorElement; + } }