provide type parameter based type with site substitutor to be accepted during type arguments check

This commit is contained in:
Anna Kozlova
2014-02-26 13:06:44 +01:00
parent 2f69c1e1e2
commit 6033fa8670
2 changed files with 43 additions and 52 deletions

View File

@@ -29,7 +29,6 @@ import com.intellij.psi.infos.MethodCandidateInfo;
import com.intellij.psi.scope.PsiConflictResolver;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.*;
import com.intellij.util.ArrayUtilRt;
import com.intellij.util.containers.HashSet;
import gnu.trove.THashMap;
import gnu.trove.THashSet;
@@ -37,7 +36,10 @@ import gnu.trove.TIntArrayList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Created by IntelliJ IDEA.
@@ -644,60 +646,10 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
final PsiType[] types = PsiType.createArray(types1.length);
for (int i = 0; i < types1.length; i++) {
types[i] = siteSubstitutor1.substitute(types1[i]);
if (types[i] instanceof PsiClassType) {
final PsiClass aClass = ((PsiClassType)types[i]).resolve();
if (aClass instanceof PsiTypeParameter) {
final List<PsiType> resultBounds = new ArrayList<PsiType>();
for (PsiType bound : aClass.getExtendsListTypes()) {
bound = siteSubstitutor1.substitute(bound);
if (!dependsOnOtherTypeParams(bound, typeParameters1)) {
resultBounds.add(bound);
} else {
resultBounds.clear();
break;
}
}
if (!resultBounds.isEmpty()) {
types[i] = PsiIntersectionType.createIntersection(resultBounds);
}
}
}
}
return types;
}
private static boolean dependsOnOtherTypeParams(PsiType type, final PsiTypeParameter[] params) {
return type.accept(new PsiTypeVisitor<Boolean>(){
@Nullable
@Override
public Boolean visitClassType(PsiClassType classType) {
for (PsiType psiType : classType.getParameters()) {
if (psiType.accept(this)) return true;
}
return ArrayUtilRt.find(params, classType.resolve()) > -1;
}
@Nullable
@Override
public Boolean visitArrayType(PsiArrayType arrayType) {
return arrayType.getComponentType().accept(this);
}
@Nullable
@Override
public Boolean visitWildcardType(PsiWildcardType wildcardType) {
final PsiType bound = wildcardType.getBound();
return bound != null && bound.accept(this);
}
@Nullable
@Override
public Boolean visitType(PsiType type) {
return false;
}
});
}
private static PsiSubstitutor calculateMethodSubstitutor(final PsiTypeParameter[] typeParameters,
final PsiMethod method,
final PsiSubstitutor siteSubstitutor,
@@ -715,6 +667,14 @@ public class JavaMethodsConflictResolver implements PsiConflictResolver{
type = TypeConversionUtil.erasure(type, substitutor);
}
substitutor = substitutor.put(typeParameter, type);
} else {
final PsiType type = substitutor.substitute(typeParameter);
if (type instanceof PsiClassType) {
final PsiClass aClass = ((PsiClassType)type).resolve();
if (aClass instanceof PsiTypeParameter) {
substitutor = substitutor.put(typeParameter, JavaPsiFacade.getElementFactory(aClass.getProject()).createType(aClass, siteSubstitutor));
}
}
}
}
return substitutor;

View File

@@ -45,4 +45,35 @@ class Test {
}
}
class Test1 {
class ResolveResult {
}
class A {
}
class B extends A {
}
abstract class AbstractResolver<K, V> {
}
abstract class Resolver<K> extends AbstractResolver<K, ResolveResult[]> {
}
public <T extends B> ResolveResult[] resolveWithCaching(T ref, Resolver<T> resolver) {
return null;
}
public <TRef extends A, TResult> TResult resolveWithCaching(TRef ref, AbstractResolver<TRef, TResult> resolver) {
return null;
}
{
Resolver<B> resolver = null;
B b = null;
resolveWithCaching(b, resolver);
}
}