From 391a9f4e2bf9d56c9430e1d9408a30844c24cd51 Mon Sep 17 00:00:00 2001 From: "peter.gromov" Date: Wed, 10 Nov 2010 20:31:39 +0300 Subject: [PATCH] no superfluous spaces when completing primitive types in for loop (IDEA-61052) --- .../completion/JavaAwareCompletionData.java | 63 +++++++++++++++++-- .../completion/JavaCompletionContributor.java | 58 ----------------- .../completion/JavaCompletionData.java | 1 + .../completion/ModifierChooser.java | 2 +- .../normal/PrimitiveTypesInForLoopSpace.java | 8 +++ .../PrimitiveTypesInForLoopSpace_after.java | 8 +++ .../completion/NormalCompletionTest.groovy | 6 ++ .../codeInsight/lookup/TailTypeDecorator.java | 2 +- 8 files changed, 82 insertions(+), 66 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/completion/normal/PrimitiveTypesInForLoopSpace.java create mode 100644 java/java-tests/testData/codeInsight/completion/normal/PrimitiveTypesInForLoopSpace_after.java diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaAwareCompletionData.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaAwareCompletionData.java index 073e3cf18d1c..0def3c85f6ba 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaAwareCompletionData.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaAwareCompletionData.java @@ -19,6 +19,7 @@ import com.intellij.codeInsight.TailType; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupItem; import com.intellij.codeInsight.lookup.LookupItemUtil; +import com.intellij.codeInsight.lookup.TailTypeDecorator; import com.intellij.psi.*; import com.intellij.psi.filters.ContextGetter; import com.intellij.util.IncorrectOperationException; @@ -32,6 +33,45 @@ import java.util.Set; */ public class JavaAwareCompletionData extends CompletionData{ + @NotNull + static TailType analyzeItem(final Object completion, final PsiElement position) { + if(completion instanceof PsiKeyword){ + final String text = ((PsiKeyword)completion).getText(); + if(PsiKeyword.BREAK.equals(text) || PsiKeyword.CONTINUE.equals(text)) { + PsiElement scope = position; + while(true){ + if (scope instanceof PsiFile || scope instanceof PsiMethod || scope instanceof PsiClassInitializer){ + return TailType.SEMICOLON; + } + + if (scope instanceof PsiLabeledStatement){ + return TailType.NONE; + } + scope = scope.getParent(); + } + } + if(PsiKeyword.RETURN.equals(text)){ + PsiElement scope = position; + while(true){ + if (scope instanceof PsiFile || scope instanceof PsiClassInitializer){ + return TailType.NONE; + } + + if (scope instanceof PsiMethod){ + final PsiMethod method = (PsiMethod)scope; + if(method.isConstructor() || PsiType.VOID.equals(method.getReturnType())) { + return TailType.SEMICOLON; + } + + return TailType.SPACE; + } + scope = scope.getParent(); + } + } + } + return TailType.NONE; + } + protected void addLookupItem(Set set, TailType tailType, @NotNull Object completion, final PsiFile file, final CompletionVariant variant) { if (completion instanceof LookupElement && !(completion instanceof LookupItem)) { set.add((LookupElement)completion); @@ -44,18 +84,29 @@ public class JavaAwareCompletionData extends CompletionData{ LookupItem ret = (LookupItem)_ret; final InsertHandler insertHandler = variant.getInsertHandler(); if(insertHandler != null && ret.getInsertHandler() == null) { - ret.setInsertHandler(insertHandler); - ret.setTailType(TailType.UNKNOWN); - } - else if (tailType != TailType.NONE) { - ret.setTailType(tailType); } + ret.setInsertHandler(new InsertHandler() { + @Override + public void handleInsert(InsertionContext context, LookupElement item) { + final TailType type = analyzeItem(item.getObject(), context.getFile().findElementAt(context.getStartOffset())); + new DefaultInsertHandler().handleInsert(context, item); + if (type != TailType.NONE) { + context.setAddCompletionChar(false); + type.processTail(context.getEditor(), context.getTailOffset()); + } + } + }); final Map itemProperties = variant.getItemProperties(); for (final Object key : itemProperties.keySet()) { ret.setAttribute(key, itemProperties.get(key)); } - set.add(ret); + + if ((insertHandler == null || ret.getInsertHandler() != null) && tailType != TailType.NONE) { + set.add(TailTypeDecorator.withTail(ret, tailType)); + } else { + set.add(ret); + } } protected void addKeywords(final Set set, final PsiElement position, final PrefixMatcher matcher, final PsiFile file, diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java index 7a97465c0655..01a93aab9dca 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java @@ -16,7 +16,6 @@ package com.intellij.codeInsight.completion; import com.intellij.codeInsight.TailType; -import com.intellij.codeInsight.TailTypes; import com.intellij.codeInsight.daemon.impl.quickfix.ImportClassFix; import com.intellij.codeInsight.hint.ShowParameterInfoHandler; import com.intellij.codeInsight.lookup.LookupElement; @@ -250,15 +249,6 @@ public class JavaCompletionContributor extends CompletionContributor { completionData.fillCompletions(parameters, result); for (final LookupElement item : lookupSet) { - if (item instanceof LookupItem && ((LookupItem)item).getInsertHandler() == null) { - ((LookupItem)item).setInsertHandler(new InsertHandler() { - public void handleInsert(final InsertionContext context, final LookupElement item) { - analyzeItem((LookupItem)item, item.getObject(), parameters.getPosition()); - new DefaultInsertHandler().handleInsert(context, item); - } - }); - } - result.addElement(item); } @@ -469,54 +459,6 @@ public class JavaCompletionContributor extends CompletionContributor { return parent.getParent() instanceof PsiTypeElement || parent.getParent() instanceof PsiExpressionStatement || parent.getParent() instanceof PsiReferenceList; } - public static void analyzeItem(final LookupItem item, final Object completion, final PsiElement position) { - if(completion instanceof PsiKeyword){ - if(PsiKeyword.BREAK.equals(((PsiKeyword)completion).getText()) - || PsiKeyword.CONTINUE.equals(((PsiKeyword)completion).getText())){ - PsiElement scope = position; - while(true){ - if (scope instanceof PsiFile - || scope instanceof PsiMethod - || scope instanceof PsiClassInitializer){ - item.setTailType(TailType.SEMICOLON); - break; - } - else if (scope instanceof PsiLabeledStatement){ - item.setTailType(TailType.NONE); - break; - } - scope = scope.getParent(); - } - } - if(PsiKeyword.RETURN.equals(((PsiKeyword)completion).getText())){ - PsiElement scope = position; - while(true){ - if (scope instanceof PsiFile - || scope instanceof PsiClassInitializer){ - item.setTailType(TailType.NONE); - break; - } - else if (scope instanceof PsiMethod){ - final PsiMethod method = (PsiMethod)scope; - if(method.isConstructor() || PsiType.VOID.equals(method.getReturnType())) { - item.setTailType(TailType.SEMICOLON); - } - else item.setTailType(TailType.SPACE); - - break; - } - scope = scope.getParent(); - } - } - if(PsiKeyword.SYNCHRONIZED.equals(((PsiKeyword)completion).getText())){ - if (PsiTreeUtil.getParentOfType(position, PsiMember.class, PsiCodeBlock.class) instanceof PsiCodeBlock){ - item.setTailType(TailTypes.SYNCHRONIZED_LPARENTH); - } - } - } - - } - public void beforeCompletion(@NotNull final CompletionInitializationContext context) { final PsiFile file = context.getFile(); diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionData.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionData.java index 45a7965df590..d1a8955f8fc4 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionData.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionData.java @@ -541,6 +541,7 @@ public class JavaCompletionData extends JavaAwareCompletionData{ variant.addCompletion(PsiKeyword.RETURN, TailType.SPACE); variant.addCompletion(PsiKeyword.NEW, TailType.SPACE); variant.addCompletion(PsiKeyword.ASSERT, TailType.SPACE); + variant.addCompletion(PsiKeyword.SYNCHRONIZED, TailTypes.SYNCHRONIZED_LPARENTH); } @Override diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/ModifierChooser.java b/java/java-impl/src/com/intellij/codeInsight/completion/ModifierChooser.java index 15a704e21bb4..4326012d0bb7 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/ModifierChooser.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/ModifierChooser.java @@ -68,7 +68,7 @@ public class ModifierChooser }); myMap.put(new OrFilter(new ClassFilter(PsiStatement.class), new ClassFilter(PsiCodeBlock.class)), new String[][]{ - new String[]{"final", "synchronized"} + new String[]{"final"} }); myMap.put(new ClassFilter(PsiParameterList.class), new String[][]{ diff --git a/java/java-tests/testData/codeInsight/completion/normal/PrimitiveTypesInForLoopSpace.java b/java/java-tests/testData/codeInsight/completion/normal/PrimitiveTypesInForLoopSpace.java new file mode 100644 index 000000000000..f1918d7ca687 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/PrimitiveTypesInForLoopSpace.java @@ -0,0 +1,8 @@ +public class Foooo { + + { + int intaaaa; + for (in) + } + +} diff --git a/java/java-tests/testData/codeInsight/completion/normal/PrimitiveTypesInForLoopSpace_after.java b/java/java-tests/testData/codeInsight/completion/normal/PrimitiveTypesInForLoopSpace_after.java new file mode 100644 index 000000000000..b5b04b7c477a --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/PrimitiveTypesInForLoopSpace_after.java @@ -0,0 +1,8 @@ +public class Foooo { + + { + int intaaaa; + for (int ) + } + +} 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 30f7cdb853d1..661ec57195c4 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy @@ -620,6 +620,12 @@ public class NormalCompletionTest extends LightFixtureCompletionTestCase { public void testPrimitiveTypesInForLoop5() throws Throwable { doPrimitiveTypeTest() } public void testPrimitiveTypesInForLoop6() throws Throwable { doPrimitiveTypeTest() } + public void testPrimitiveTypesInForLoopSpace() throws Throwable { + configure() + myFixture.type ' ' + checkResultByFile(getTestName(false) + "_after.java") + } + public void testSecondInvocationToFillCommonPrefix() throws Throwable { configure() type('a'); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/lookup/TailTypeDecorator.java b/platform/lang-impl/src/com/intellij/codeInsight/lookup/TailTypeDecorator.java index 34245381345c..264afef7d421 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/lookup/TailTypeDecorator.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/lookup/TailTypeDecorator.java @@ -48,7 +48,7 @@ public abstract class TailTypeDecorator extends LookupE final LookupItem lookupItem = delegate.as(LookupItem.class); if (lookupItem != null && tailType != null) { - lookupItem.setTailType(TailType.NONE); + lookupItem.setTailType(TailType.UNKNOWN); } delegate.handleInsert(context); if (tailType != null && tailType.isApplicable(context)) {