mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
new inference: non wildcard parametrization against the spec
This commit is contained in:
@@ -519,6 +519,14 @@ public class GenericsUtil {
|
||||
else if (type instanceof PsiArrayType) {
|
||||
return checkNotAssignable(bound, type, true);
|
||||
}
|
||||
else if (type instanceof PsiIntersectionType) {
|
||||
for (PsiType psiType : ((PsiIntersectionType)type).getConjuncts()) {
|
||||
if (!checkNotInBounds(psiType, bound, uncheckedConversionByDefault)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -78,7 +78,8 @@ public class PsiIntersectionType extends PsiType {
|
||||
for (PsiType existing : array) {
|
||||
if (type != existing) {
|
||||
final boolean allowUncheckedConversion = type instanceof PsiClassType && ((PsiClassType)type).isRaw();
|
||||
if (TypeConversionUtil.isAssignable(type, existing, allowUncheckedConversion)) {
|
||||
if (TypeConversionUtil.isAssignable(GenericsUtil.eliminateWildcards(type),
|
||||
GenericsUtil.eliminateWildcards(existing), allowUncheckedConversion)) {
|
||||
iterator.remove();
|
||||
break;
|
||||
}
|
||||
|
||||
+20
-16
@@ -18,7 +18,6 @@ package com.intellij.psi.impl.source.resolve.graphInference;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.source.resolve.graphInference.constraints.TypeEqualityConstraint;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.TypeConversionUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -169,27 +168,32 @@ public class FunctionalInterfaceParameterizationUtil {
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
PsiType paramType = parameters[i];
|
||||
if (paramType instanceof PsiWildcardType) {
|
||||
final PsiClassType[] extendsListTypes = typeParameters[i].getExtendsListTypes();
|
||||
final PsiClassType Bi = extendsListTypes.length > 0 ? extendsListTypes[0]
|
||||
: PsiType.getJavaLangObject(psiClass.getManager(),
|
||||
GlobalSearchScope.allScope(psiClass.getProject()));
|
||||
if (PsiPolyExpressionUtil.mentionsTypeParameters(Bi, typeParametersSet)) {
|
||||
return null;
|
||||
final PsiType bound = GenericsUtil.eliminateWildcards(((PsiWildcardType)paramType).getBound(), false);
|
||||
if (((PsiWildcardType)paramType).isSuper()) {
|
||||
newParameters[i] = bound;
|
||||
}
|
||||
|
||||
final PsiType bound = ((PsiWildcardType)paramType).getBound();
|
||||
if (bound == null) {
|
||||
newParameters[i] = Bi;
|
||||
} else if (((PsiWildcardType)paramType).isExtends()){
|
||||
newParameters[i] = GenericsUtil.getGreatestLowerBound(Bi, GenericsUtil.eliminateWildcards(bound, false));
|
||||
} else {
|
||||
newParameters[i] = GenericsUtil.eliminateWildcards(bound, false);
|
||||
else {
|
||||
newParameters[i] = bound != null ? bound : PsiType.getJavaLangObject(psiClass.getManager(), psiClassType.getResolveScope());
|
||||
for (PsiClassType paramBound : typeParameters[i].getExtendsListTypes()) {
|
||||
if (!PsiPolyExpressionUtil.mentionsTypeParameters(paramBound, typeParametersSet)) {
|
||||
newParameters[i] = GenericsUtil.getGreatestLowerBound(paramBound, newParameters[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
newParameters[i] = paramType;
|
||||
}
|
||||
}
|
||||
return JavaPsiFacade.getElementFactory(psiClass.getProject()).createType(psiClass, newParameters);
|
||||
|
||||
if (!isWellFormed(psiClass, typeParameters, newParameters)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
final PsiClassType parameterization = JavaPsiFacade.getElementFactory(psiClass.getProject()).createType(psiClass, newParameters);
|
||||
if (!psiClassType.isAssignableFrom(parameterization)) {
|
||||
return null;
|
||||
}
|
||||
return parameterization;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
import java.util.List;
|
||||
|
||||
class SimpleDependency {
|
||||
|
||||
interface I<R extends U, U> {
|
||||
R m();
|
||||
}
|
||||
|
||||
{
|
||||
I<? extends String, ? extends String> k = () -> null;
|
||||
I<? extends String, String> k1 = () -> null;
|
||||
I<? extends List<String>, List<String>> k2 = () -> null;
|
||||
I<? extends List<String>, ? extends List<String>> k3 = () -> null;
|
||||
I<? extends List<? extends String>, ? extends List<String>> k4 = <error descr="Cannot infer functional interface type">() -> null</error>;
|
||||
I<? extends List<? extends String>, List<? extends String>> k5 = () -> null;
|
||||
I<? extends List<? extends String>, ? extends List<? extends String>> k6 = () -> null;
|
||||
|
||||
I<? super String, String> s = () -> null;
|
||||
I<? super List<String>, List<? extends String>> s1 = () -> null;
|
||||
}
|
||||
}
|
||||
|
||||
class NoDependency {
|
||||
interface I<T, U> {
|
||||
T m();
|
||||
}
|
||||
|
||||
{
|
||||
I<? extends String, ? extends String> k = () -> null;
|
||||
}
|
||||
}
|
||||
|
||||
class ExtendsList {
|
||||
interface I<R extends List<T>, T> {
|
||||
R m();
|
||||
}
|
||||
|
||||
{
|
||||
I<?, ? extends String> n = <error descr="Cannot infer functional interface type">() -> null</error>;
|
||||
I<?, ?> n1 = <error descr="Cannot infer functional interface type">() -> null</error>;
|
||||
I<?, String> n2 = <error descr="Cannot infer functional interface type">() -> null</error>;
|
||||
|
||||
|
||||
I<? extends List<?>, String> e1 = <error descr="Cannot infer functional interface type">() -> null</error>;
|
||||
I<? extends List<?>, ?> e2 = <error descr="Cannot infer functional interface type">() -> null</error>;
|
||||
I<? extends List<String>, ? extends String> e3 = () -> null;
|
||||
I<? extends List<? extends String>, ? extends String> e4 = <error descr="Cannot infer functional interface type">() -> null</error>;
|
||||
|
||||
I<? super List<String>, ? extends String> s1 = () -> null;
|
||||
I<? super List<String>, String> s2 = () -> null;
|
||||
}
|
||||
}
|
||||
|
||||
class MultipleBounds {
|
||||
interface I<R extends List<T> & Comparable<T>, T> {
|
||||
R m();
|
||||
}
|
||||
|
||||
interface LC<K> extends List<K>, Comparable<K> {}
|
||||
|
||||
{
|
||||
I<?, String> n = <error descr="Cannot infer functional interface type">() -> null</error>;
|
||||
|
||||
I<? extends List<String>, ? extends String> e1 = <error descr="Cannot infer functional interface type">() -> null</error>;
|
||||
I<? extends Comparable<String>, ? extends String> e2 = <error descr="Cannot infer functional interface type">() -> null</error>;
|
||||
I<? extends LC<String>, ? extends String> e3 = () -> null;
|
||||
I<? extends LC<String>, String> e4 = () -> null;
|
||||
I<? extends LC<? extends String>, String> e5 = <error descr="Cannot infer functional interface type">() -> null</error>;
|
||||
}
|
||||
}
|
||||
|
||||
class FirstIndependentBound {
|
||||
interface I<R extends List<String> & Comparable<T>, T> {
|
||||
R m();
|
||||
}
|
||||
|
||||
interface LC<K> extends List<String>, Comparable<K> {}
|
||||
|
||||
{
|
||||
I<?, String> n = <error descr="Cannot infer functional interface type">() -> null</error>;
|
||||
|
||||
I<? extends List<String>, ? extends String> e1 = <error descr="Cannot infer functional interface type">() -> null</error>;
|
||||
I<? extends Comparable<String>, ? extends String> e2 = () -> null;
|
||||
I<? extends LC<String>, ? extends String> e3 = () -> null;
|
||||
I<? extends LC<String>, String> e4 = () -> null;
|
||||
I<? extends LC<? extends String>, String> e5 = <error descr="Cannot infer functional interface type">() -> null</error>;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class SecondIndependentBound {
|
||||
interface I<R extends List<T> & Comparable<String>, T> {
|
||||
R m();
|
||||
}
|
||||
|
||||
interface LC<K> extends List<String>, Comparable<K> {}
|
||||
|
||||
{
|
||||
I<?, String> n = <error descr="Cannot infer functional interface type">() -> null</error>;
|
||||
|
||||
I<? extends List<String>, ? extends String> e1 = () -> null;
|
||||
I<? extends Comparable<String>, ? extends String> e2 = <error descr="Cannot infer functional interface type">() -> null</error>;
|
||||
I<? extends LC<String>, ? extends String> e3 = () -> null;
|
||||
I<? extends LC<String>, String> e4 = () -> null;
|
||||
I<? extends LC<? extends String>, String> e5 = <error descr="Cannot infer functional interface type">() -> null</error>;
|
||||
I<? extends LC<? extends String>, ? extends String> e6 = <error descr="Cannot infer functional interface type">() -> null</error>;
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInsight.daemon.lambda;
|
||||
|
||||
import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase;
|
||||
import com.intellij.openapi.projectRoots.JavaSdkVersion;
|
||||
import com.intellij.openapi.projectRoots.Sdk;
|
||||
import com.intellij.testFramework.IdeaTestUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
public class FunctionalTypeWildcardParameterizationTest extends LightDaemonAnalyzerTestCase {
|
||||
@NonNls static final String BASE_PATH = "/codeInsight/daemonCodeAnalyzer/lambda/wildcardParametrization";
|
||||
|
||||
public void testNonWildcardParametrization() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
private void doTest() {
|
||||
IdeaTestUtil.setTestVersion(JavaSdkVersion.JDK_1_8, getModule(), getTestRootDisposable());
|
||||
doTestNewInference(BASE_PATH + "/" + getTestName(false) + ".java", false, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Sdk getProjectJDK() {
|
||||
return IdeaTestUtil.getMockJdk18();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user