From c65ff63395b493ddbfb614920d0b91b4d4fda725 Mon Sep 17 00:00:00 2001 From: peter Date: Thu, 7 Apr 2011 13:29:01 +0200 Subject: [PATCH] java-specific parts of MembersGetter go to JavaMembersGetter --- .../BasicExpressionCompletionContributor.java | 6 +- .../completion/JavaCompletionData.java | 4 +- .../JavaSmartCompletionContributor.java | 8 +- .../completion/SmartCompletionDecorator.java | 5 +- .../filters/getters/JavaMembersGetter.java | 124 ++++++++++++++++++ .../psi/filters/getters/MembersGetter.java | 103 +++------------ 6 files changed, 152 insertions(+), 98 deletions(-) create mode 100644 java/java-impl/src/com/intellij/psi/filters/getters/JavaMembersGetter.java diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/BasicExpressionCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/BasicExpressionCompletionContributor.java index 15028e8e538c..19fbe8b95441 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/BasicExpressionCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/BasicExpressionCompletionContributor.java @@ -24,7 +24,7 @@ import com.intellij.patterns.ElementPattern; import com.intellij.patterns.PsiJavaPatterns; import com.intellij.psi.*; import com.intellij.psi.filters.getters.ClassLiteralGetter; -import com.intellij.psi.filters.getters.MembersGetter; +import com.intellij.psi.filters.getters.JavaMembersGetter; import com.intellij.psi.filters.getters.ThisGetter; import com.intellij.psi.scope.BaseScopeProcessor; import com.intellij.psi.scope.util.PsiScopesUtil; @@ -90,9 +90,9 @@ public class BasicExpressionCompletionContributor { final PsiElement parent = position.getParent(); if (parent != null && !(parent.getParent() instanceof PsiSwitchLabelStatement)) { - MembersGetter.addMembers(parameters.getPosition(), expectedType, result); + new JavaMembersGetter(expectedType).addMembers(parameters.getPosition(), result); if (!parameters.getDefaultType().equals(expectedType)) { - MembersGetter.addMembers(parameters.getPosition(), parameters.getDefaultType(), result); + new JavaMembersGetter(parameters.getDefaultType()).addMembers(parameters.getPosition(), result); } for (final PsiExpression expression : ThisGetter.getThisExpressionVariants(position)) { 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 3460698ebda6..164aa4f884bd 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionData.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionData.java @@ -31,7 +31,7 @@ import com.intellij.psi.filters.*; import com.intellij.psi.filters.classes.EnumOrAnnotationTypeFilter; import com.intellij.psi.filters.classes.InterfaceFilter; import com.intellij.psi.filters.element.ReferenceOnFilter; -import com.intellij.psi.filters.getters.MembersGetter; +import com.intellij.psi.filters.getters.JavaMembersGetter; import com.intellij.psi.filters.position.*; import com.intellij.psi.filters.types.TypeCodeFragmentIsVoidEnabledFilter; import com.intellij.psi.impl.source.jsp.jspJava.JspClassLevelDeclarationStatement; @@ -616,7 +616,7 @@ public class JavaCompletionData extends JavaAwareCompletionData{ !(position.getParent() instanceof PsiLiteralExpression) && !(position.getParent().getParent() instanceof PsiSwitchLabelStatement)) { for (final ExpectedTypeInfo info : JavaSmartCompletionContributor.getExpectedTypes(parameters)) { - MembersGetter.addMembers(position, info.getDefaultType(), new Consumer() { + new JavaMembersGetter(info.getDefaultType()).addMembers(position, new Consumer() { @Override public void consume(LookupElement element) { result.addElement(element); diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java index 2379251a7fdd..fd64b6780a54 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaSmartCompletionContributor.java @@ -341,11 +341,9 @@ public class JavaSmartCompletionContributor extends CompletionContributor { } public static SmartCompletionDecorator decorate(LookupElement lookupElement, Collection infos) { - if (lookupElement instanceof LookupItem) { - final LookupItem lookupItem = (LookupItem)lookupElement; - if (lookupItem.getInsertHandler() == null) { - lookupItem.setInsertHandler(DefaultInsertHandler.NO_TAIL_HANDLER); - } + LookupItem item = lookupElement.as(LookupItem.CLASS_CONDITION_KEY); + if (item != null && item.getInsertHandler() == null) { + item.setInsertHandler(DefaultInsertHandler.NO_TAIL_HANDLER); } return new SmartCompletionDecorator(lookupElement, infos); diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/SmartCompletionDecorator.java b/java/java-impl/src/com/intellij/codeInsight/completion/SmartCompletionDecorator.java index 9bd06caa047a..271fd394403d 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/SmartCompletionDecorator.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/SmartCompletionDecorator.java @@ -115,8 +115,9 @@ public class SmartCompletionDecorator extends TailTypeDecorator { @Override public void handleInsert(InsertionContext context) { myPosition = getPosition(context, this); - if (getDelegate() instanceof LookupItem) { - analyzeItem(context, (LookupItem)getDelegate(), getObject(), myPosition, myExpectedTypeInfos); + LookupItem item = getDelegate().as(LookupItem.CLASS_CONDITION_KEY); + if (item != null) { + analyzeItem(context, item, getObject(), myPosition, myExpectedTypeInfos); } super.handleInsert(context); } diff --git a/java/java-impl/src/com/intellij/psi/filters/getters/JavaMembersGetter.java b/java/java-impl/src/com/intellij/psi/filters/getters/JavaMembersGetter.java new file mode 100644 index 000000000000..9963cc3ac968 --- /dev/null +++ b/java/java-impl/src/com/intellij/psi/filters/getters/JavaMembersGetter.java @@ -0,0 +1,124 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.psi.filters.getters; + +import com.intellij.codeInsight.completion.JavaCompletionUtil; +import com.intellij.codeInsight.completion.JavaMethodCallElement; +import com.intellij.codeInsight.completion.SmartCompletionDecorator; +import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.codeInsight.lookup.VariableLookupItem; +import com.intellij.psi.*; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; +import com.intellij.util.Consumer; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author peter + */ +public class JavaMembersGetter extends MembersGetter { + private final PsiType myExpectedType; + + public JavaMembersGetter(@NotNull PsiType expectedType) { + myExpectedType = expectedType; + } + + public void addMembers(PsiElement position, Consumer results) { + final PsiClass psiClass = PsiUtil.resolveClassInType(myExpectedType); + processMembers(position, results, psiClass, PsiTreeUtil.getParentOfType(position, PsiAnnotation.class) != null); + + if (myExpectedType instanceof PsiPrimitiveType && PsiType.DOUBLE.isAssignableFrom(myExpectedType)) { + addConstantsFromTargetClass(position, results); + } + } + + private void addConstantsFromTargetClass(PsiElement position, Consumer results) { + PsiElement parent = position.getParent(); + if (!(parent instanceof PsiReferenceExpression)) { + return; + } + + PsiElement prev = parent; + parent = parent.getParent(); + while (parent instanceof PsiBinaryExpression) { + final PsiBinaryExpression binaryExpression = (PsiBinaryExpression)parent; + final IElementType op = binaryExpression.getOperationSign().getTokenType(); + if (JavaTokenType.EQEQ == op || JavaTokenType.NE == op) { + if (prev == binaryExpression.getROperand()) { + processMembers(position, results, getCalledClass(binaryExpression.getLOperand()), false); + } + return; + } + prev = parent; + parent = parent.getParent(); + } + if (parent instanceof PsiExpressionList) { + processMembers(position, results, getCalledClass(parent.getParent()), false); + } + } + + @Nullable + private static PsiClass getCalledClass(@Nullable PsiElement call) { + if (call instanceof PsiMethodCallExpression) { + for (final JavaResolveResult result : ((PsiMethodCallExpression)call).getMethodExpression().multiResolve(true)) { + final PsiElement element = result.getElement(); + if (element instanceof PsiMethod) { + final PsiClass aClass = ((PsiMethod)element).getContainingClass(); + if (aClass != null) { + return aClass; + } + } + } + } + if (call instanceof PsiNewExpression) { + final PsiJavaCodeReferenceElement reference = ((PsiNewExpression)call).getClassReference(); + if (reference != null) { + for (final JavaResolveResult result : reference.multiResolve(true)) { + final PsiElement element = result.getElement(); + if (element instanceof PsiClass) { + return (PsiClass)element; + } + } + } + } + return null; + } + + @Nullable + protected LookupElement createFieldElement(PsiField field) { + if (!myExpectedType.isAssignableFrom(field.getType())) { + return null; + } + + return JavaCompletionUtil.qualify(new VariableLookupItem(field)); + } + + @Nullable + protected LookupElement createMethodElement(PsiMethod method) { + PsiSubstitutor substitutor = SmartCompletionDecorator.calculateMethodReturnTypeSubstitutor(method, myExpectedType); + PsiType type = substitutor.substitute(method.getReturnType()); + if (type == null || !myExpectedType.isAssignableFrom(type)) { + return null; + } + + + JavaMethodCallElement item = new JavaMethodCallElement(method); + item.setInferenceSubstitutor(substitutor); + return JavaCompletionUtil.qualify(item); + } +} diff --git a/java/java-impl/src/com/intellij/psi/filters/getters/MembersGetter.java b/java/java-impl/src/com/intellij/psi/filters/getters/MembersGetter.java index fc0b4d1ac854..50829b1b1bca 100644 --- a/java/java-impl/src/com/intellij/psi/filters/getters/MembersGetter.java +++ b/java/java-impl/src/com/intellij/psi/filters/getters/MembersGetter.java @@ -1,5 +1,5 @@ /* - * Copyright 2000-2009 JetBrains s.r.o. + * Copyright 2000-2011 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,91 +16,24 @@ package com.intellij.psi.filters.getters; import com.intellij.codeInsight.completion.JavaCompletionUtil; -import com.intellij.codeInsight.completion.JavaMethodCallElement; -import com.intellij.codeInsight.completion.SmartCompletionDecorator; -import com.intellij.codeInsight.lookup.*; +import com.intellij.codeInsight.lookup.AutoCompletionPolicy; +import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.psi.*; import com.intellij.psi.filters.TrueFilter; import com.intellij.psi.scope.processor.FilterScopeProcessor; -import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.InheritanceUtil; import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.psi.util.PsiUtil; import com.intellij.util.Consumer; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** - * Created by IntelliJ IDEA. - * User: ik - * Date: 15.04.2003 - * Time: 17:07:09 - * To change this template use Options | File Templates. + * @author ik + * @author peter */ -public class MembersGetter { +public abstract class MembersGetter { - public static void addMembers(PsiElement position, PsiType expectedType, Consumer results) { - final PsiClass psiClass = PsiUtil.resolveClassInType(expectedType); - processMembers(position, results, psiClass, PsiTreeUtil.getParentOfType(position, PsiAnnotation.class) != null, expectedType); - - if (expectedType instanceof PsiPrimitiveType && PsiType.DOUBLE.isAssignableFrom(expectedType)) { - addConstantsFromTargetClass(position, expectedType, results); - } - } - - private static void addConstantsFromTargetClass(PsiElement position, PsiType expectedType, Consumer results) { - PsiElement parent = position.getParent(); - if (!(parent instanceof PsiReferenceExpression)) { - return; - } - - PsiElement prev = parent; - parent = parent.getParent(); - while (parent instanceof PsiBinaryExpression) { - final PsiBinaryExpression binaryExpression = (PsiBinaryExpression)parent; - final IElementType op = binaryExpression.getOperationSign().getTokenType(); - if (JavaTokenType.EQEQ == op || JavaTokenType.NE == op) { - if (prev == binaryExpression.getROperand()) { - processMembers(position, results, getCalledClass(binaryExpression.getLOperand()), false, expectedType); - } - return; - } - prev = parent; - parent = parent.getParent(); - } - if (parent instanceof PsiExpressionList) { - processMembers(position, results, getCalledClass(parent.getParent()), false, expectedType); - } - } - - @Nullable - private static PsiClass getCalledClass(@Nullable PsiElement call) { - if (call instanceof PsiMethodCallExpression) { - for (final JavaResolveResult result : ((PsiMethodCallExpression)call).getMethodExpression().multiResolve(true)) { - final PsiElement element = result.getElement(); - if (element instanceof PsiMethod) { - final PsiClass aClass = ((PsiMethod)element).getContainingClass(); - if (aClass != null) { - return aClass; - } - } - } - } - if (call instanceof PsiNewExpression) { - final PsiJavaCodeReferenceElement reference = ((PsiNewExpression)call).getClassReference(); - if (reference != null) { - for (final JavaResolveResult result : reference.multiResolve(true)) { - final PsiElement element = result.getElement(); - if (element instanceof PsiClass) { - return (PsiClass)element; - } - } - } - } - return null; - } - - private static void processMembers(final PsiElement context, final Consumer results, @Nullable final PsiClass where, - final boolean acceptMethods, PsiType expectedType) { + public void processMembers(@NotNull final PsiElement context, final Consumer results, @Nullable final PsiClass where, final boolean acceptMethods) { if (where == null) return; PsiClass current = PsiTreeUtil.getContextOfType(context, PsiClass.class); @@ -122,20 +55,18 @@ public class MembersGetter { if (member.hasModifierProperty(PsiModifier.STATIC) && resolveHelper.isAccessible(member, context, null)) { if (result instanceof PsiField && !member.hasModifierProperty(PsiModifier.FINAL)) continue; if (result instanceof PsiMethod && acceptMethods) continue; - final LookupItem item = result instanceof PsiMethod ? new JavaMethodCallElement((PsiMethod)result) : new VariableLookupItem((PsiVariable)result); - item.setAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE); - JavaCompletionUtil.qualify(item); - if (member instanceof PsiMethod) { - final PsiMethod method = (PsiMethod)member; - final PsiSubstitutor substitutor = SmartCompletionDecorator.calculateMethodReturnTypeSubstitutor(method, expectedType); - ((JavaMethodCallElement) item).setInferenceSubstitutor(substitutor); - } - final PsiType itemType = ((TypedLookupItem)item).getType(); - if (itemType != null && expectedType.isAssignableFrom(itemType)) { - results.consume(item); + final LookupElement item = result instanceof PsiMethod ? createMethodElement((PsiMethod)result) : createFieldElement((PsiField)result); + if (item != null) { + results.consume(AutoCompletionPolicy.NEVER_AUTOCOMPLETE.applyPolicy(item)); } } } } } + + @Nullable + protected abstract LookupElement createFieldElement(PsiField field); + + @Nullable + protected abstract LookupElement createMethodElement(PsiMethod method); }