mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-21 05:51:25 +07:00
[java inference] treat intersection type in one more place (IDEA-274350)
GitOrigin-RevId: d31b30aab900748010f28b02c483c56982d26040
This commit is contained in:
committed by
intellij-monorepo-bot
parent
41f79ea01a
commit
07fe5de1ce
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.psi;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationTargetUtil;
|
||||
@@ -33,7 +33,7 @@ public final class LambdaUtil {
|
||||
}
|
||||
|
||||
public static @Nullable PsiType getFunctionalInterfaceReturnType(@Nullable PsiType functionalInterfaceType) {
|
||||
final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(functionalInterfaceType);
|
||||
final PsiClassType.ClassResolveResult resolveResult = PsiUtil.resolveGenericsClassInType(normalizeFunctionalType(functionalInterfaceType));
|
||||
final PsiClass psiClass = resolveResult.getElement();
|
||||
if (psiClass != null) {
|
||||
final MethodSignature methodSignature = getFunction(psiClass);
|
||||
@@ -47,7 +47,21 @@ public final class LambdaUtil {
|
||||
|
||||
@Contract("null -> null")
|
||||
public static @Nullable PsiMethod getFunctionalInterfaceMethod(@Nullable PsiType functionalInterfaceType) {
|
||||
return getFunctionalInterfaceMethod(PsiUtil.resolveGenericsClassInType(functionalInterfaceType));
|
||||
return getFunctionalInterfaceMethod(PsiUtil.resolveGenericsClassInType(normalizeFunctionalType(functionalInterfaceType)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract functional interface from intersection
|
||||
*/
|
||||
@Nullable
|
||||
public static PsiType normalizeFunctionalType(@Nullable PsiType functionalInterfaceType) {
|
||||
if (functionalInterfaceType instanceof PsiIntersectionType) {
|
||||
PsiType functionalConjunct = extractFunctionalConjunct((PsiIntersectionType)functionalInterfaceType);
|
||||
if (functionalConjunct != null) {
|
||||
functionalInterfaceType = functionalConjunct;
|
||||
}
|
||||
}
|
||||
return functionalInterfaceType;
|
||||
}
|
||||
|
||||
public static PsiMethod getFunctionalInterfaceMethod(@Nullable PsiElement element) {
|
||||
@@ -87,10 +101,7 @@ public final class LambdaUtil {
|
||||
}
|
||||
|
||||
public static boolean isFunctionalType(PsiType type) {
|
||||
if (type instanceof PsiIntersectionType) {
|
||||
return extractFunctionalConjunct((PsiIntersectionType)type) != null;
|
||||
}
|
||||
return isFunctionalClass(PsiUtil.resolveClassInClassTypeOnly(type));
|
||||
return isFunctionalClass(PsiUtil.resolveClassInClassTypeOnly(normalizeFunctionalType(type)));
|
||||
}
|
||||
|
||||
@Contract("null -> false")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.psi.impl.source.resolve.graphInference;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -15,12 +15,8 @@ public final class FunctionalInterfaceParameterizationUtil {
|
||||
private static final Logger LOG = Logger.getInstance(FunctionalInterfaceParameterizationUtil.class);
|
||||
|
||||
public static boolean isWildcardParameterized(@Nullable PsiType classType) {
|
||||
classType = LambdaUtil.normalizeFunctionalType(classType);
|
||||
if (classType == null) return false;
|
||||
if (classType instanceof PsiIntersectionType) {
|
||||
for (PsiType type : ((PsiIntersectionType)classType).getConjuncts()) {
|
||||
if (!isWildcardParameterized(type)) return false;
|
||||
}
|
||||
}
|
||||
if (classType instanceof PsiClassType) {
|
||||
final PsiClassType.ClassResolveResult result = ((PsiClassType)classType).resolveGenerics();
|
||||
final PsiClass aClass = result.getElement();
|
||||
@@ -49,6 +45,7 @@ public final class FunctionalInterfaceParameterizationUtil {
|
||||
|
||||
@Nullable
|
||||
public static PsiType getGroundTargetType(@Nullable PsiType psiClassType, @Nullable PsiLambdaExpression expr, boolean performFinalCheck) {
|
||||
psiClassType = LambdaUtil.normalizeFunctionalType(psiClassType);
|
||||
if (!isWildcardParameterized(psiClassType)) {
|
||||
return psiClassType;
|
||||
}
|
||||
@@ -63,14 +60,6 @@ public final class FunctionalInterfaceParameterizationUtil {
|
||||
*/
|
||||
private static PsiType getFunctionalTypeExplicit(PsiType psiClassType, PsiLambdaExpression expr, boolean performFinalCheck) {
|
||||
final PsiParameter[] lambdaParams = expr.getParameterList().getParameters();
|
||||
if (psiClassType instanceof PsiIntersectionType) {
|
||||
for (PsiType psiType : ((PsiIntersectionType)psiClassType).getConjuncts()) {
|
||||
final PsiType functionalType = getFunctionalTypeExplicit(psiType, expr, performFinalCheck);
|
||||
if (functionalType != null) return functionalType;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
LOG.assertTrue(psiClassType instanceof PsiClassType, "Unexpected type: " + psiClassType);
|
||||
final PsiType[] parameters = ((PsiClassType)psiClassType).getParameters();
|
||||
final PsiClassType.ClassResolveResult resolveResult = ((PsiClassType)psiClassType).resolveGenerics();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import java.io.Serializable;
|
||||
import java.util.function.Function;
|
||||
|
||||
class Test {
|
||||
|
||||
@@ -33,3 +34,17 @@ class Test1 {
|
||||
Object c0 = (A & B) ()->{};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class Test2 {
|
||||
{
|
||||
foo(i -> i);
|
||||
foo1(i -> i);
|
||||
foo2(i -> i);
|
||||
}
|
||||
|
||||
private static <T extends Function<?, ?> & A<?>> void foo(T t) { }
|
||||
private static <T extends Function<?, ?> & Serializable> void foo1(T t) { }
|
||||
private static <T extends Function<Integer, Integer> & Serializable> void foo2(T t) { }
|
||||
interface A<K> {}
|
||||
}
|
||||
Reference in New Issue
Block a user