java completion: fix shadowed type parameter duplication

This commit is contained in:
peter
2017-07-26 12:34:10 +02:00
parent 81da6d4ecf
commit 792940cf8e
4 changed files with 38 additions and 22 deletions
@@ -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(
@@ -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;
@@ -0,0 +1,5 @@
class Foo<MyParam> {
<MyParam> MyPara<caret>m foo(MyParam p) {
return p;
}
}
@@ -688,6 +688,11 @@ public class ListUtils {
assert myFixture.lookupElementStrings == ['char']
}
void testShadowedTypeParameter() {
configure()
assert myFixture.lookupElementStrings == ['MyParam']
}
void testMethodReturnType() throws Throwable {
doTest()
}