diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java index 2eacf4bfc08b..4f38e7cdc2ca 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java @@ -791,7 +791,9 @@ public class JavaCompletionUtil { final char completionChar = context.getCompletionChar(); final PsiFile file = context.getFile(); - final TailType tailType = completionChar == '(' ? TailType.NONE : completionChar == ':' ? TailType.COND_EXPR_COLON : LookupItem.handleCompletionChar(context.getEditor(), item, completionChar); + final TailType tailType = completionChar == '(' ? TailType.NONE : + completionChar == ':' ? TailType.COND_EXPR_COLON : + LookupItem.handleCompletionChar(context.getEditor(), item, completionChar); final boolean hasTail = tailType != TailType.NONE && tailType != TailType.UNKNOWN; final boolean smart = completionChar == Lookup.COMPLETE_STATEMENT_SELECT_CHAR; @@ -819,25 +821,31 @@ public class JavaCompletionUtil { AutoPopupController.getInstance(file.getProject()).autoPopupParameterInfo(editor, overloadsMatter ? null : (PsiElement)item.getObject()); } - if (smart || needRightParenth) { - TailType toInsert = tailType; - LookupItem lookupItem = item.as(LookupItem.CLASS_CONDITION_KEY); - if (lookupItem == null || lookupItem.getAttribute(LookupItem.TAIL_TYPE_ATTR) != TailType.UNKNOWN) { - if (!hasTail && item.getObject() instanceof PsiMethod && ((PsiMethod)item.getObject()).getReturnType() == PsiType.VOID) { - PsiDocumentManager.getInstance(file.getProject()).commitAllDocuments(); - if (psiElement().beforeLeaf(psiElement().withText(".")).accepts(file.findElementAt(context.getTailOffset() - 1))) { - return; - } - toInsert = TailType.SEMICOLON; + if (smart || !needRightParenth || !insertTail(context, item, tailType, hasTail)) { + return; + } + + if (completionChar == '.') { + AutoPopupController.getInstance(file.getProject()).autoPopupMemberLookup(context.getEditor(), null); + } else if (completionChar == ',') { + AutoPopupController.getInstance(file.getProject()).autoPopupParameterInfo(context.getEditor(), null); + } + } + + private static boolean insertTail(InsertionContext context, LookupElement item, TailType tailType, boolean hasTail) { + TailType toInsert = tailType; + LookupItem lookupItem = item.as(LookupItem.CLASS_CONDITION_KEY); + if (lookupItem == null || lookupItem.getAttribute(LookupItem.TAIL_TYPE_ATTR) != TailType.UNKNOWN) { + if (!hasTail && item.getObject() instanceof PsiMethod && ((PsiMethod)item.getObject()).getReturnType() == PsiType.VOID) { + PsiDocumentManager.getInstance(context.getProject()).commitAllDocuments(); + if (psiElement().beforeLeaf(psiElement().withText(".")).accepts(context.getFile().findElementAt(context.getTailOffset() - 1))) { + return false; } - } - toInsert.processTail(editor, context.getTailOffset()); - if (completionChar == '.') { - AutoPopupController.getInstance(file.getProject()).autoPopupMemberLookup(context.getEditor(), null); - } else if (completionChar == ',') { - AutoPopupController.getInstance(file.getProject()).autoPopupParameterInfo(context.getEditor(), null); + toInsert = TailType.SEMICOLON; } } + toInsert.processTail(context.getEditor(), context.getTailOffset()); + return true; } //need to shorten references in type argument list diff --git a/java/java-tests/testData/codeInsight/completion/normal/SmartEnterWrapsConstructorCall.java b/java/java-tests/testData/codeInsight/completion/normal/SmartEnterWrapsConstructorCall.java new file mode 100644 index 000000000000..9fb8abd323ec --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/SmartEnterWrapsConstructorCall.java @@ -0,0 +1,13 @@ +class Entity {} +class EntityBuilder {} + +class Tester { + private Entity entity; + + private void build(EntityBuilder builder) { + } + + public void test1() { + buinew EntityBuilder(); + } +} diff --git a/java/java-tests/testData/codeInsight/completion/normal/SmartEnterWrapsConstructorCall_after.java b/java/java-tests/testData/codeInsight/completion/normal/SmartEnterWrapsConstructorCall_after.java new file mode 100644 index 000000000000..43e916863b55 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/SmartEnterWrapsConstructorCall_after.java @@ -0,0 +1,13 @@ +class Entity {} +class EntityBuilder {} + +class Tester { + private Entity entity; + + private void build(EntityBuilder builder) { + } + + public void test1() { + build(new EntityBuilder()); + } +} diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy index aca95baf7d1c..2ca21daa392d 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy @@ -927,6 +927,7 @@ public class ListUtils { assertEquals("fzazzz", list.get(0).getLookupString()); } + public void testSmartEnterWrapsConstructorCall() throws Throwable { doTest(Lookup.COMPLETE_STATEMENT_SELECT_CHAR as String) } public void testTabReplacesMethodNameWithLocalVariableName() throws Throwable { doTest('\t'); } public void testMethodParameterAnnotationClass() throws Throwable { doTest(); } public void testPrimitiveCastOverwrite() throws Throwable { doTest '\t' } 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 fe7b26c87a50..869fb980a11f 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CodeCompletionHandlerBase.java @@ -713,26 +713,7 @@ public class CodeCompletionHandlerBase { PostprocessReformattingAspect.getInstance(project).doPostponedFormatting(); if (context.shouldAddCompletionChar()) { - int tailOffset = context.getTailOffset(); - if (tailOffset < 0) { - LOG.info("tailOffset<0 after inserting " + item + " of " + item.getClass() + "; invalidated at: " + context.invalidateTrace + "\n--------"); - } - else { - editor.getCaretModel().moveToOffset(tailOffset); - } - if (context.getCompletionChar() == Lookup.COMPLETE_STATEMENT_SELECT_CHAR) { - final Language language = PsiUtilBase.getLanguageInEditor(editor, project); - final List processors = SmartEnterProcessors.INSTANCE.forKey(language); - if (processors.size() > 0) { - for (SmartEnterProcessor processor : processors) { - processor.process(project, editor, indicator.getParameters().getOriginalFile()); - } - } - } - else { - DataContext dataContext = DataManager.getInstance().getDataContext(editor.getContentComponent()); - EditorActionManager.getInstance().getTypedAction().getHandler().execute(editor, completionChar, dataContext); - } + addCompletionChar(project, context, item, editor, indicator, completionChar); } context.stopWatching(); editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE); @@ -742,6 +723,32 @@ public class CodeCompletionHandlerBase { return context; } + private static void addCompletionChar(Project project, + WatchingInsertionContext context, + LookupElement item, + Editor editor, CompletionProgressIndicator indicator, char completionChar) { + int tailOffset = context.getTailOffset(); + if (tailOffset < 0) { + LOG.info("tailOffset<0 after inserting " + item + " of " + item.getClass() + "; invalidated at: " + context.invalidateTrace + "\n--------"); + } + else { + editor.getCaretModel().moveToOffset(tailOffset); + } + if (context.getCompletionChar() == Lookup.COMPLETE_STATEMENT_SELECT_CHAR) { + final Language language = PsiUtilBase.getLanguageInEditor(editor, project); + final List processors = SmartEnterProcessors.INSTANCE.forKey(language); + if (processors.size() > 0) { + for (SmartEnterProcessor processor : processors) { + processor.process(project, editor, indicator.getParameters().getOriginalFile()); + } + } + } + else { + DataContext dataContext = DataManager.getInstance().getDataContext(editor.getContentComponent()); + EditorActionManager.getInstance().getTypedAction().getHandler().execute(editor, completionChar, dataContext); + } + } + public static final Key>> FILE_COPY_KEY = Key.create("CompletionFileCopy"); private static boolean isCopyUpToDate(Document document, @NotNull PsiFile file) { diff --git a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java index cad5b0d98fe6..54e5098eec1a 100644 --- a/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java +++ b/platform/testFramework/src/com/intellij/testFramework/fixtures/impl/CodeInsightTestFixtureImpl.java @@ -731,6 +731,11 @@ public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsig return; } } + if (c == Lookup.COMPLETE_STATEMENT_SELECT_CHAR) { + if (_performEditorAction(IdeActions.ACTION_CHOOSE_LOOKUP_ITEM_COMPLETE_STATEMENT)) { + return; + } + } CommandProcessor.getInstance().executeCommand(getProject(), new Runnable() { @Override