mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-13 21:55:01 +07:00
type equality constraint: accept unbounded/extends wildcards pair; reject unbounded/super
This commit is contained in:
+16
-13
@@ -55,11 +55,12 @@ public class TypeEqualityConstraint implements ConstraintFormula {
|
||||
if (myT instanceof PsiClassType && myS instanceof PsiClassType) {
|
||||
final PsiClassType.ClassResolveResult tResult = ((PsiClassType)myT).resolveGenerics();
|
||||
final PsiClassType.ClassResolveResult sResult = ((PsiClassType)myS).resolveGenerics();
|
||||
final PsiClass C = tResult.getElement();
|
||||
if (C == sResult.getElement() && C != null) {
|
||||
final PsiClass tClass = tResult.getElement();
|
||||
//equal erasure
|
||||
if (tClass != null && tClass.equals(sResult.getElement())) {
|
||||
final PsiSubstitutor tSubstitutor = tResult.getSubstitutor();
|
||||
final PsiSubstitutor sSubstitutor = sResult.getSubstitutor();
|
||||
for (PsiTypeParameter typeParameter : C.getTypeParameters()) {
|
||||
for (PsiTypeParameter typeParameter : tClass.getTypeParameters()) {
|
||||
final PsiType tSubstituted = tSubstitutor.substitute(typeParameter);
|
||||
final PsiType sSubstituted = sSubstitutor.substitute(typeParameter);
|
||||
if (tSubstituted != null && sSubstituted != null) {
|
||||
@@ -73,16 +74,6 @@ public class TypeEqualityConstraint implements ConstraintFormula {
|
||||
constraints.add(new TypeEqualityConstraint(((PsiArrayType)myT).getComponentType(), ((PsiArrayType)myS).getComponentType()));
|
||||
return true;
|
||||
}
|
||||
if (myT instanceof PsiIntersectionType && myS instanceof PsiIntersectionType) {
|
||||
final PsiType[] tConjuncts = ((PsiIntersectionType)myT).getConjuncts();
|
||||
final PsiType[] sConjuncts = ((PsiIntersectionType)myS).getConjuncts();
|
||||
if (sConjuncts.length == tConjuncts.length) {
|
||||
for (int i = 0; i < sConjuncts.length; i++) {
|
||||
constraints.add(new TypeEqualityConstraint(tConjuncts[i], sConjuncts[i]));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (myT instanceof PsiWildcardType && myS instanceof PsiWildcardType) {
|
||||
final PsiType tBound = ((PsiWildcardType)myT).getBound();
|
||||
@@ -90,6 +81,18 @@ public class TypeEqualityConstraint implements ConstraintFormula {
|
||||
|
||||
if (tBound == null && sBound == null) return true;
|
||||
|
||||
if (sBound == null && ((PsiWildcardType)myT).isExtends()) {
|
||||
//extends bound of "?" (Object)
|
||||
constraints.add(new TypeEqualityConstraint(((PsiWildcardType)myS).getExtendsBound(), tBound));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (tBound == null && ((PsiWildcardType)myS).isExtends()) {
|
||||
//extends bound of "?" (Object)
|
||||
constraints.add(new TypeEqualityConstraint(((PsiWildcardType)myT).getExtendsBound(), sBound));
|
||||
return true;
|
||||
}
|
||||
|
||||
if (((PsiWildcardType)myT).isExtends() && ((PsiWildcardType)myS).isExtends() ||
|
||||
((PsiWildcardType)myT).isSuper() && ((PsiWildcardType)myS).isSuper()) {
|
||||
|
||||
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
public class SampleExtendsWildcard {
|
||||
public void highlightsTheBug(Stream<String> stream) {
|
||||
stream.flatMap((Block<?> sink, String element) -> {});
|
||||
}
|
||||
|
||||
public interface Block<B> {
|
||||
void apply(B t);
|
||||
}
|
||||
|
||||
public interface Stream<S> {
|
||||
<R> Stream<R> flatMap(FlatMapper<? super S, R> mapper);
|
||||
|
||||
}
|
||||
|
||||
public interface FlatMapper<F, R> {
|
||||
void flatMapInto(Block<? extends R> sink, F element);
|
||||
}
|
||||
}
|
||||
|
||||
class SampleSuperWildcard {
|
||||
public void highlightsTheBug(Stream<String> stream) {
|
||||
stream.flatMap((<error descr="Incompatible parameter types in lambda expression">Block<?> sink</error>, String element) -> {});
|
||||
}
|
||||
|
||||
public interface Block<B> {
|
||||
void apply(B t);
|
||||
}
|
||||
|
||||
public interface Stream<S> {
|
||||
<R> Stream<R> flatMap(FlatMapper<? super S, R> mapper);
|
||||
|
||||
}
|
||||
|
||||
public interface FlatMapper<F, R> {
|
||||
void flatMapInto(Block<? super R> sink, F element);
|
||||
}
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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.Sdk;
|
||||
import com.intellij.testFramework.IdeaTestUtil;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
/**
|
||||
* Created by anna on 1/31/14.
|
||||
*/
|
||||
public class ConstraintsInferenceMiscTest extends LightDaemonAnalyzerTestCase {
|
||||
@NonNls static final String BASE_PATH = "/codeInsight/daemonCodeAnalyzer/lambda/constraints";
|
||||
|
||||
public void testEqualityUnboundWildcard() throws Exception {
|
||||
doTest(false);
|
||||
}
|
||||
|
||||
private void doTest(final boolean checkWarnings) {
|
||||
doTestNewInference(BASE_PATH + "/" + getTestName(false) + ".java", checkWarnings, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Sdk getProjectJDK() {
|
||||
return IdeaTestUtil.getMockJdk18();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user