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 16d3ddf20063..0de7a293d26c 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java @@ -883,7 +883,7 @@ public class JavaCompletionUtil { } } - JavaGlobalMemberNameCompletionContributor.completeStaticMembers(element).processMethodsOfRegisteredClasses(matcher, new Consumer() { + JavaGlobalMemberNameCompletionContributor.completeStaticMembers(element).processMembersOfRegisteredClasses(matcher, new Consumer() { @Override public void consume(LookupElement element) { set.add(element); diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaGlobalMemberNameCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaGlobalMemberNameCompletionContributor.java index 3b62d8d9ec37..c0a2e66f5dab 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaGlobalMemberNameCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaGlobalMemberNameCompletionContributor.java @@ -1,8 +1,10 @@ package com.intellij.codeInsight.completion; import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.codeInsight.lookup.VariableLookupItem; import com.intellij.openapi.application.ApplicationManager; import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; /** @@ -39,11 +41,25 @@ public class JavaGlobalMemberNameCompletionContributor extends CompletionContrib final StaticMemberProcessor processor = new StaticMemberProcessor(position) { @NotNull @Override - protected LookupElement createLookupElement(@NotNull PsiMethod method, @NotNull PsiClass containingClass, boolean shouldImport) { - final JavaMethodCallElement element = new JavaMethodCallElement(method, true); - element.setShouldBeImported(shouldImport); - return element; + protected LookupElement createLookupElement(@NotNull PsiMember member, @NotNull final PsiClass containingClass, boolean shouldImport) { + if (member instanceof PsiMethod) { + final JavaMethodCallElement element = new JavaMethodCallElement((PsiMethod)member, true); + element.setShouldBeImported(shouldImport); + return element; + } + return new VariableLookupItem((PsiVariable)member) { + @Override + public void handleInsert(InsertionContext context) { + context.commitDocument(); + final PsiReferenceExpression ref = PsiTreeUtil.findElementOfClassAtOffset(context.getFile(), context.getStartOffset(), PsiReferenceExpression.class, false); + if (ref != null) { + ref.bindToElementViaStaticImport(containingClass); + } + super.handleInsert(context); + } + }; } + }; ApplicationManager.getApplication().runReadAction(new Runnable() { public void run() { diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/StaticMemberProcessor.java b/java/java-impl/src/com/intellij/codeInsight/completion/StaticMemberProcessor.java index 19236cf93232..baeb6a25d2c9 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/StaticMemberProcessor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/StaticMemberProcessor.java @@ -64,7 +64,7 @@ public abstract class StaticMemberProcessor { for (final PsiMethod method : methods) { ApplicationManager.getApplication().runReadAction(new Runnable() { public void run() { - processMethod(method, consumer); + processMember(method, consumer); } }); @@ -73,7 +73,7 @@ public abstract class StaticMemberProcessor { } } - public void processMethodsOfRegisteredClasses(@Nullable final PrefixMatcher matcher, final Consumer consumer) { + public void processMembersOfRegisteredClasses(@Nullable final PrefixMatcher matcher, final Consumer consumer) { for (final PsiClass psiClass : myStaticImportedClasses) { final PsiMethod[] classMethods = ApplicationManager.getApplication().runReadAction(new Computable() { public PsiMethod[] compute() { @@ -84,7 +84,21 @@ public abstract class StaticMemberProcessor { ApplicationManager.getApplication().runReadAction(new Runnable() { public void run() { if (matcher == null || matcher.prefixMatches(method.getName())) { - processMethod(method, consumer); + processMember(method, consumer); + } + } + }); + } + final PsiField[] fields = ApplicationManager.getApplication().runReadAction(new Computable() { + public PsiField[] compute() { + return psiClass.getAllFields(); + } + }); + for (final PsiField field : fields) { + ApplicationManager.getApplication().runReadAction(new Runnable() { + public void run() { + if (matcher == null || matcher.prefixMatches(field.getName())) { + processMember(field, consumer); } } }); @@ -93,11 +107,12 @@ public abstract class StaticMemberProcessor { } - private void processMethod(final PsiMethod method, final Consumer consumer) { - if (method.hasModifierProperty(PsiModifier.STATIC) && myResolveHelper.isAccessible(method, myPosition, null)) { - final PsiClass containingClass = method.getContainingClass(); + private void processMember(final PsiMember member, final Consumer consumer) { + if (member.hasModifierProperty(PsiModifier.STATIC) && myResolveHelper.isAccessible(member, myPosition, null)) { + final PsiClass containingClass = member.getContainingClass(); if (containingClass != null) { - if (!JavaCompletionUtil.isInExcludedPackage(containingClass) && !StaticImportMethodFix.isExcluded(method)) { + if (!JavaCompletionUtil.isInExcludedPackage(containingClass) && + (!(member instanceof PsiMethod) || !StaticImportMethodFix.isExcluded((PsiMethod)member))) { final boolean shouldImport = myStaticImportedClasses.contains(containingClass); if (!myHintShown && !shouldImport && @@ -110,7 +125,7 @@ public abstract class StaticMemberProcessor { myHintShown = true; } - consumer.consume(createLookupElement(method, containingClass, shouldImport)); + consumer.consume(createLookupElement(member, containingClass, shouldImport)); } } @@ -118,5 +133,5 @@ public abstract class StaticMemberProcessor { } @NotNull - protected abstract LookupElement createLookupElement(@NotNull PsiMethod method, @NotNull PsiClass containingClass, boolean shouldImport); + protected abstract LookupElement createLookupElement(@NotNull PsiMember member, @NotNull PsiClass containingClass, boolean shouldImport); } diff --git a/java/java-tests/testData/codeInsight/completion/smartType/SiblingOfAStaticallyImportedField-out.java b/java/java-tests/testData/codeInsight/completion/smartType/SiblingOfAStaticallyImportedField-out.java new file mode 100644 index 000000000000..84b336de9245 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/smartType/SiblingOfAStaticallyImportedField-out.java @@ -0,0 +1,15 @@ +import static Bar.BAR; +import static Bar.FOO; + +class Bar { + static String FOO; + static String BAR; +} + +class Foo { + + Object[] foo() { + String a = FOO; + String b = BAR; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/smartType/SiblingOfAStaticallyImportedField.java b/java/java-tests/testData/codeInsight/completion/smartType/SiblingOfAStaticallyImportedField.java new file mode 100644 index 000000000000..87041bee1f28 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/smartType/SiblingOfAStaticallyImportedField.java @@ -0,0 +1,14 @@ +import static Bar.FOO; + +class Bar { + static String FOO; + static String BAR; +} + +class Foo { + + Object[] foo() { + String a = FOO; + String b = BA + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/smartType/StaticallyImportedField-out.java b/java/java-tests/testData/codeInsight/completion/smartType/StaticallyImportedField-out.java new file mode 100644 index 000000000000..883dfd465f09 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/smartType/StaticallyImportedField-out.java @@ -0,0 +1,13 @@ +import static Bar.FOO + +class Bar { + static String FOO; + static String BAR; +} + +class Foo { + + Object[] foo() { + String b = FOO; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/completion/smartType/StaticallyImportedField.java b/java/java-tests/testData/codeInsight/completion/smartType/StaticallyImportedField.java new file mode 100644 index 000000000000..301e1e051d81 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/smartType/StaticallyImportedField.java @@ -0,0 +1,13 @@ +import static Bar.FOO + +class Bar { + static String FOO; + static String BAR; +} + +class Foo { + + Object[] foo() { + String b = FO + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java index edc7aedbe4cb..6abecd9398e0 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java @@ -936,6 +936,9 @@ public class SmartTypeCompletionTest extends LightCompletionTestCase { doTest(); } + public void testStaticallyImportedField() throws Throwable { doTest(); } + public void testSiblingOfAStaticallyImportedField() throws Throwable { doTest(); } + public void testInferFromCall() throws Throwable { doTest(); } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java index f3618c56a3fa..2eee16fa6348 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/completion/GroovyCompletionContributor.java @@ -160,7 +160,7 @@ public class GroovyCompletionContributor extends CompletionContributor { } }); - completeStaticMembers(position).processMethodsOfRegisteredClasses(result.getPrefixMatcher(), new Consumer() { + completeStaticMembers(position).processMembersOfRegisteredClasses(result.getPrefixMatcher(), new Consumer() { @Override public void consume(LookupElement element) { result.addElement(element); @@ -389,8 +389,11 @@ public class GroovyCompletionContributor extends CompletionContributor { final StaticMemberProcessor processor = new StaticMemberProcessor(position) { @NotNull @Override - protected LookupElement createLookupElement(@NotNull PsiMethod method, @NotNull PsiClass containingClass, boolean shouldImport) { - return new JavaGlobalMemberLookupElement(method, containingClass, QUALIFIED_METHOD_INSERT_HANDLER, STATIC_IMPORT_INSERT_HANDLER, shouldImport); + protected LookupElement createLookupElement(@NotNull PsiMember member, @NotNull PsiClass containingClass, boolean shouldImport) { + if (member instanceof PsiMethod) { + return new JavaGlobalMemberLookupElement((PsiMethod)member, containingClass, QUALIFIED_METHOD_INSERT_HANDLER, STATIC_IMPORT_INSERT_HANDLER, shouldImport); + } + return GroovyCompletionUtil.getLookupElement(member); //todo; } }; final PsiFile file = position.getContainingFile();