IDEA-91292 Instant completion after new keyword

GitOrigin-RevId: 309d8eca41fb84a81bbc8ea1eab939f4da09b53a
This commit is contained in:
Peter Gromov
2020-06-09 20:35:16 +03:00
committed by intellij-monorepo-bot
parent 9005a1cad4
commit 802f71e3d3
7 changed files with 50 additions and 10 deletions
@@ -714,12 +714,19 @@ public class JavaKeywordCompletion {
return;
}
boolean afterNew = psiElement().afterLeaf(
psiElement().withText(PsiKeyword.NEW).andNot(psiElement().afterLeaf(PsiKeyword.THROW, "."))).accepts(position);
boolean afterNew = JavaSmartCompletionContributor.AFTER_NEW.accepts(position) &&
!psiElement().afterLeaf(psiElement().afterLeaf(".")).accepts(position);
if (afterNew) {
Set<PsiType> expected = ContainerUtil.map2Set(JavaSmartCompletionContributor.getExpectedTypes(position, false),
ExpectedTypeInfo::getDefaultType);
boolean addAll = expected.isEmpty() || ContainerUtil.exists(expected, t ->
t.equalsToText(CommonClassNames.JAVA_LANG_OBJECT) || t.equalsToText(CommonClassNames.JAVA_IO_SERIALIZABLE));
PsiElementFactory factory = JavaPsiFacade.getElementFactory(position.getProject());
for (String primitiveType : PRIMITIVE_TYPES) {
result.consume(PsiTypeLookupItem.createLookupItem(factory.createTypeFromText(primitiveType + "[]", null), null));
PsiType array = factory.createTypeFromText(primitiveType + "[]", null);
if (addAll || expected.contains(array)) {
result.consume(PsiTypeLookupItem.createLookupItem(array, null));
}
}
return;
}
@@ -47,11 +47,7 @@ public class JavaSmartCompletionContributor {
};
private static final ElementExtractorFilter THROWABLES_FILTER = new ElementExtractorFilter(new AssignableFromFilter(CommonClassNames.JAVA_LANG_THROWABLE));
public static final ElementPattern<PsiElement> AFTER_NEW =
psiElement().afterLeaf(
psiElement().withText(PsiKeyword.NEW).andNot(
psiElement().afterLeaf(
psiElement().withText(PsiKeyword.THROW))));
static final ElementPattern<PsiElement> AFTER_NEW = psiElement().afterLeaf(psiElement().withText(PsiKeyword.NEW));
static final ElementPattern<PsiElement> AFTER_THROW_NEW = psiElement().afterLeaf(psiElement().withText(PsiKeyword.NEW).afterLeaf(PsiKeyword.THROW));
public static final ElementPattern<PsiElement> INSIDE_EXPRESSION = or(
psiElement().withParent(PsiExpression.class)
@@ -17,6 +17,7 @@ package com.intellij.codeInsight.editorActions;
import com.intellij.codeInsight.AutoPopupController;
import com.intellij.codeInsight.CodeInsightSettings;
import com.intellij.codeInsight.completion.CompletionType;
import com.intellij.codeInsight.completion.JavaClassReferenceCompletionContributor;
import com.intellij.codeInsight.editorActions.smartEnter.JavaSmartEnterProcessor;
import com.intellij.ide.highlighter.JavaFileType;
@@ -32,6 +33,7 @@ import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.registry.Registry;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.patterns.PsiJavaPatterns;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.javadoc.PsiDocComment;
@@ -84,6 +86,23 @@ public class JavaTypedHandler extends TypedHandlerDelegate {
});
}
@Override
public @NotNull Result checkAutoPopup(char charTyped, @NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) {
int offset = editor.getCaretModel().getOffset();
if (charTyped == ' ' &&
StringUtil.endsWith(editor.getDocument().getImmutableCharSequence(), 0, offset, PsiKeyword.NEW)) {
AutoPopupController.getInstance(project).scheduleAutoPopup(editor, CompletionType.BASIC, f -> {
PsiElement leaf = f.findElementAt(offset - PsiKeyword.NEW.length());
return leaf instanceof PsiKeyword &&
leaf.textMatches(PsiKeyword.NEW) &&
!PsiJavaPatterns.psiElement().insideStarting(PsiJavaPatterns.psiExpressionStatement()).accepts(leaf);
});
return Result.STOP;
}
return super.checkAutoPopup(charTyped, project, editor, file);
}
@NotNull
@Override
public Result beforeCharTyped(final char c, @NotNull final Project project, @NotNull final Editor editor, @NotNull final PsiFile file, @NotNull final FileType fileType) {
@@ -0,0 +1,5 @@
class C {
public static void main(String[] args) {
throw new <caret>
}
}
@@ -39,6 +39,7 @@ import com.intellij.psi.NavigatablePsiElement
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiJavaFile
import com.intellij.psi.PsiMethod
import com.intellij.psi.util.InheritanceUtil
import com.intellij.testFramework.TestModeFlags
import com.intellij.testFramework.fixtures.CodeInsightTestUtil
import com.intellij.util.ThrowableRunnable
@@ -1809,4 +1810,12 @@ ita<caret>
assert lookup
}
void "test autopopup after new"() {
myFixture.configureByText('a.java', 'class Foo { { java.util.List<String> l = new<caret> }}')
type ' '
assert lookup
def firstItems = myFixture.lookupElements[0..<4]
assert firstItems.each { InheritanceUtil.isInheritor(it.object as PsiClass, List.name) }
}
}
@@ -136,6 +136,10 @@ class NormalCompletionOrderingTest extends CompletionSortingTestCase {
assertPreferredItems(0, "XxxImpl", "Xxx")
}
void testAfterThrowNew() {
checkPreferredItems(0, "Exception", "RuntimeException")
}
void testPreferLessHumps() throws Throwable {
myFixture.addClass("package foo; public interface XaYa {}")
myFixture.addClass("package foo; public interface XyYa {}")
@@ -218,7 +218,7 @@ public class SmartTypeCompletionTest extends LightFixtureCompletionTestCase {
String path = "/afterNew";
configureByFile(path + "/before14.java");
//select();
select();
checkResultByFile(path + "/after14.java");
}
@@ -234,7 +234,7 @@ public class SmartTypeCompletionTest extends LightFixtureCompletionTestCase {
String path = "/afterNew";
configureByFile(path + "/before16.java");
//select();
select();
checkResultByFile(path + "/after16.java");
}