From 792940cf8e1296ede687be7d99430d0b7ea2cfde Mon Sep 17 00:00:00 2001 From: peter Date: Wed, 26 Jul 2017 12:32:33 +0200 Subject: [PATCH] java completion: fix shadowed type parameter duplication --- .../completion/JavaKeywordCompletion.java | 22 --------------- .../PsiJavaCodeReferenceElementImpl.java | 28 +++++++++++++++++++ .../normal/ShadowedTypeParameter.java | 5 ++++ .../completion/NormalCompletionTest.groovy | 5 ++++ 4 files changed, 38 insertions(+), 22 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/completion/normal/ShadowedTypeParameter.java diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaKeywordCompletion.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaKeywordCompletion.java index 62da46d0a493..889549d66e3d 100644 --- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaKeywordCompletion.java +++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaKeywordCompletion.java @@ -38,7 +38,6 @@ import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.util.Consumer; import com.intellij.util.ObjectUtils; -import com.intellij.util.ProcessingContext; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.JBIterable; import org.jetbrains.annotations.NotNull; @@ -311,8 +310,6 @@ public class JavaKeywordCompletion { addClassLiteral(); - addUnfinishedMethodTypeParameters(); - addExtendsImplements(); } @@ -618,25 +615,6 @@ public class JavaKeywordCompletion { return END_OF_BLOCK.getValue().isAcceptable(position, position); } - private void addUnfinishedMethodTypeParameters() { - final ProcessingContext context = new ProcessingContext(); - if (psiElement().inside( - psiElement(PsiTypeElement.class).afterLeaf( - psiElement().withText(">").withParent( - psiElement(PsiTypeParameterList.class).withParent(PsiErrorElement.class).save("typeParameterList")))).accepts(myPosition, context)) { - final PsiTypeParameterList list = (PsiTypeParameterList)context.get("typeParameterList"); - PsiElement current = list.getParent().getParent(); - if (current instanceof PsiField) { - current = current.getParent(); - } - if (current instanceof PsiClass) { - for (PsiTypeParameter typeParameter : list.getTypeParameters()) { - addKeyword(new JavaPsiClassReferenceElement(typeParameter)); - } - } - } - } - static boolean isAfterPrimitiveOrArrayType(PsiElement element) { return psiElement().withParent( psiReferenceExpression().withFirstChild( diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java index cbfc20bd4f97..4b73582e1992 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaCodeReferenceElementImpl.java @@ -47,6 +47,7 @@ import com.intellij.psi.util.PsiTreeUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.psi.util.PsiUtilCore; import com.intellij.util.IncorrectOperationException; +import com.intellij.util.ProcessingContext; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -54,6 +55,8 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import static com.intellij.patterns.PsiJavaPatterns.psiElement; + public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement implements PsiAnnotatedJavaCodeReferenceElement, SourceJavaCodeReference { private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.source.PsiJavaCodeReferenceElementImpl"); @@ -863,9 +866,34 @@ public class PsiJavaCodeReferenceElementImpl extends CompositePsiElement impleme OrFilter filter = new OrFilter(filters.toArray(ElementFilter.EMPTY_ARRAY)); FilterScopeProcessor proc = new FilterScopeProcessor(filter, processor); + + for (PsiTypeParameter typeParameter : getUnfinishedMethodTypeParameters()) { + if (!proc.execute(typeParameter, ResolveState.initial())) { + return; + } + } + PsiScopesUtil.resolveAndWalk(proc, this, null, true); } + private PsiTypeParameter[] getUnfinishedMethodTypeParameters() { + ProcessingContext context = new ProcessingContext(); + if (psiElement().inside( + psiElement(PsiTypeElement.class).afterLeaf( + psiElement().withText(">").withParent( + psiElement(PsiTypeParameterList.class).withParent(PsiErrorElement.class).save("typeParameterList")))).accepts(this, context)) { + PsiTypeParameterList list = (PsiTypeParameterList)context.get("typeParameterList"); + PsiElement current = list.getParent().getParent(); + if (current instanceof PsiField) { + current = current.getParent(); + } + if (current instanceof PsiClass) { + return list.getTypeParameters(); + } + } + return PsiTypeParameter.EMPTY_ARRAY; + } + private boolean isInCode() { if (isCodeFragmentType(getTreeParent().getElementType()) || getParent() instanceof PsiAnnotation) { return false; diff --git a/java/java-tests/testData/codeInsight/completion/normal/ShadowedTypeParameter.java b/java/java-tests/testData/codeInsight/completion/normal/ShadowedTypeParameter.java new file mode 100644 index 000000000000..77feb9e92c42 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/ShadowedTypeParameter.java @@ -0,0 +1,5 @@ +class Foo { + MyParam foo(MyParam p) { + return p; + } +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/NormalCompletionTest.groovy b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/NormalCompletionTest.groovy index 7e93cd00941a..2e83d48bcd4c 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/NormalCompletionTest.groovy +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/completion/NormalCompletionTest.groovy @@ -688,6 +688,11 @@ public class ListUtils { assert myFixture.lookupElementStrings == ['char'] } + void testShadowedTypeParameter() { + configure() + assert myFixture.lookupElementStrings == ['MyParam'] + } + void testMethodReturnType() throws Throwable { doTest() }