mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
method references: exclude type parameter used in return types only (IDEA-171480)
This commit is contained in:
@@ -335,39 +335,47 @@ public class PsiTypesUtil {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static PsiTypeParameter[] filterUnusedTypeParameters(final PsiType superReturnTypeInBaseClassType,
|
||||
@NotNull PsiTypeParameter[] typeParameters) {
|
||||
if (typeParameters.length == 0) return typeParameters;
|
||||
public static PsiTypeParameter[] filterUnusedTypeParameters(@NotNull PsiTypeParameter[] typeParameters,
|
||||
final PsiType... types) {
|
||||
if (typeParameters.length == 0) return PsiTypeParameter.EMPTY_ARRAY;
|
||||
|
||||
final Set<PsiTypeParameter> usedParameters = new HashSet<>();
|
||||
superReturnTypeInBaseClassType.accept(new PsiTypeVisitor<Object>(){
|
||||
@Nullable
|
||||
@Override
|
||||
public Object visitClassType(PsiClassType classType) {
|
||||
final PsiClass aClass = classType.resolve();
|
||||
if (aClass instanceof PsiTypeParameter && ArrayUtil.find(typeParameters, aClass) > -1) {
|
||||
usedParameters.add((PsiTypeParameter)aClass);
|
||||
for (PsiType type : types) {
|
||||
type.accept(new PsiTypeVisitor<Object>() {
|
||||
@Nullable
|
||||
@Override
|
||||
public Object visitClassType(PsiClassType classType) {
|
||||
final PsiClass aClass = classType.resolve();
|
||||
if (aClass instanceof PsiTypeParameter && ArrayUtil.find(typeParameters, aClass) > -1) {
|
||||
usedParameters.add((PsiTypeParameter)aClass);
|
||||
return null;
|
||||
}
|
||||
for (PsiType type : classType.getParameters()) {
|
||||
type.accept(this);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
for (PsiType type : classType.getParameters()) {
|
||||
type.accept(this);
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Object visitWildcardType(PsiWildcardType wildcardType) {
|
||||
final PsiType bound = wildcardType.getBound();
|
||||
return bound != null ? bound.accept(this) : null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Object visitWildcardType(PsiWildcardType wildcardType) {
|
||||
final PsiType bound = wildcardType.getBound();
|
||||
return bound != null ? bound.accept(this) : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public Object visitArrayType(PsiArrayType arrayType) {
|
||||
return arrayType.getComponentType().accept(this);
|
||||
}
|
||||
});
|
||||
@Nullable
|
||||
@Override
|
||||
public Object visitArrayType(PsiArrayType arrayType) {
|
||||
return arrayType.getComponentType().accept(this);
|
||||
}
|
||||
});
|
||||
}
|
||||
return usedParameters.toArray(new PsiTypeParameter[usedParameters.size()]);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static PsiTypeParameter[] filterUnusedTypeParameters(final PsiType superReturnTypeInBaseClassType,
|
||||
@NotNull PsiTypeParameter[] typeParameters) {
|
||||
return filterUnusedTypeParameters(typeParameters, superReturnTypeInBaseClassType);
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -237,7 +237,7 @@ public class PsiMethodReferenceCompatibilityConstraint implements ConstraintForm
|
||||
psiSubstitutor = getParameterizedTypeSubstitutor(qContainingClass, pType);
|
||||
}
|
||||
else if (member instanceof PsiMethod && ((PsiMethod)member).isConstructor() || member instanceof PsiClass) {
|
||||
//15.13.1
|
||||
//15.13.1
|
||||
//If ClassType is a raw type, but is not a non-static member type of a raw type,
|
||||
//the candidate notional member methods are those specified in §15.9.3 for a class instance creation expression that uses <>
|
||||
//to elide the type arguments to a class.
|
||||
@@ -247,7 +247,7 @@ public class PsiMethodReferenceCompatibilityConstraint implements ConstraintForm
|
||||
LOG.assertTrue(paramTypes.length == signature.getParameterTypes().length, "expr: " + methodReferenceExpression + "; " +
|
||||
paramTypes.length + "; " +
|
||||
Arrays.toString(signature.getParameterTypes()));
|
||||
psiSubstitutor = helper.inferTypeArguments(qContainingClass.getTypeParameters(),
|
||||
psiSubstitutor = helper.inferTypeArguments(PsiTypesUtil.filterUnusedTypeParameters(qContainingClass.getTypeParameters(), paramTypes),
|
||||
paramTypes,
|
||||
signature.getParameterTypes(),
|
||||
PsiUtil.getLanguageLevel(methodReferenceExpression));
|
||||
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
|
||||
import java.util.function.Function;
|
||||
|
||||
abstract class View<Tv, Av, Bv> {
|
||||
|
||||
public Const<Av, Tv> apply(final Fixed<Tv, Av, Bv, Const<Av, Tv>, Const<Av, Bv>> fix) {
|
||||
return fix.apply(Const::new);
|
||||
}
|
||||
}
|
||||
|
||||
@FunctionalInterface
|
||||
interface Fixed< T, A, B,
|
||||
FT extends Functor<T>,
|
||||
FB extends Functor<B>> {
|
||||
FT apply(Function< A, FB> function);
|
||||
}
|
||||
|
||||
interface Functor<A> {
|
||||
}
|
||||
|
||||
final class Const<A, B> implements Functor<B> {
|
||||
A a;
|
||||
|
||||
public Const(A a) {
|
||||
this.a = a;
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -167,6 +167,7 @@ public class NewMethodRefHighlightingTest extends LightDaemonAnalyzerTestCase {
|
||||
public void testReturnTypeCompatibilityConstraintForSecondSearchCase() { doTest(); }
|
||||
public void testMethodInInheritorFoundBySecondSearch() { doTest(); }
|
||||
public void testNonExactMethodReferenceOnRawClassType() { doTest(); }
|
||||
public void testIncludeOnlyTypeParametersUsedInParameterTypesExcludeThoseUsedInReturnOnly() { doTest(); }
|
||||
public void testMethodREfToContainingMethodWithGenericParam() { doTest(); }
|
||||
public void testDistinguishCapturedWildcardsByDifferentParameters() throws Exception { doTest(); }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user