From 624fa25d385c20f45a8ffae22e803babbbf61136 Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Wed, 27 Aug 2014 20:58:13 +0400 Subject: [PATCH] capture conversion: add upper bound for ? super if corresponding type parameter has upper bounds( IDEA-128328; IDEA-128972) --- .../intellij/psi/PsiCapturedWildcardType.java | 31 +++++++++++++++++-- .../intellij/psi/impl/PsiSubstitutorImpl.java | 2 +- ...tutionWhenTypeParameterHasUpperBounds.java | 30 ++++++++++++++++++ .../genericsHighlighting8/IDEA110947.java | 2 +- .../SuperWildcardWithBoundPromotion.java | 4 +-- .../daemon/GenericsHighlightingTest.java | 1 + .../lambda/GenericsHighlighting8Test.java | 2 +- 7 files changed, 65 insertions(+), 7 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/SuperCaptureSubstitutionWhenTypeParameterHasUpperBounds.java diff --git a/java/java-psi-api/src/com/intellij/psi/PsiCapturedWildcardType.java b/java/java-psi-api/src/com/intellij/psi/PsiCapturedWildcardType.java index 8130b864ad9a..c94709ee164a 100644 --- a/java/java-psi-api/src/com/intellij/psi/PsiCapturedWildcardType.java +++ b/java/java-psi-api/src/com/intellij/psi/PsiCapturedWildcardType.java @@ -28,6 +28,8 @@ public class PsiCapturedWildcardType extends PsiType.Stub { @NotNull private final PsiElement myContext; @Nullable private final PsiTypeParameter myParameter; + private PsiType myUpperBound; + @NotNull public static PsiCapturedWildcardType create(@NotNull PsiWildcardType existential, @NotNull PsiElement context) { return create(existential, context, null); @@ -40,11 +42,28 @@ public class PsiCapturedWildcardType extends PsiType.Stub { return new PsiCapturedWildcardType(existential, context, parameter); } - private PsiCapturedWildcardType(@NotNull PsiWildcardType existential, @NotNull PsiElement context, @Nullable PsiTypeParameter parameter) { + private PsiCapturedWildcardType(@NotNull PsiWildcardType existential, + @NotNull PsiElement context, + @Nullable PsiTypeParameter parameter) { super(PsiAnnotation.EMPTY_ARRAY); myExistential = existential; myContext = context; myParameter = parameter; + if (parameter != null) { + final PsiClassType[] boundTypes = parameter.getExtendsListTypes(); + if (boundTypes.length > 0) { + PsiType result = null; + for (PsiType type : boundTypes) { + if (result == null) { + result = type; + } + else { + result = GenericsUtil.getGreatestLowerBound(result, type); + } + } + myUpperBound = result; + } + } } @Override @@ -128,10 +147,14 @@ public class PsiCapturedWildcardType extends PsiType.Stub { return PsiWildcardType.createSuper(myContext.getManager(), ((PsiCapturedWildcardType)bound).getUpperBound()); } else { - return PsiType.getJavaLangObject(myContext.getManager(), getResolveScope()); + return myUpperBound != null ? myUpperBound : PsiType.getJavaLangObject(myContext.getManager(), getResolveScope()); } } + public void setUpperBound(PsiType upperBound) { + myUpperBound = upperBound; + } + @NotNull public PsiWildcardType getWildcard() { return myExistential; @@ -141,4 +164,8 @@ public class PsiCapturedWildcardType extends PsiType.Stub { public PsiElement getContext() { return myContext; } + + public PsiTypeParameter getTypeParameter() { + return myParameter; + } } diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java index c4bd26f8c61d..9c9525aef859 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java @@ -394,7 +394,7 @@ public class PsiSubstitutorImpl implements PsiSubstitutor { } } } - } else if (substituted instanceof PsiWildcardType && ((PsiWildcardType)substituted).isSuper()) { + } else if (substituted instanceof PsiWildcardType && ((PsiWildcardType)substituted).isSuper() && !(oldSubstituted instanceof PsiCapturedWildcardType)) { final PsiType erasure = TypeConversionUtil.erasure(((PsiWildcardType)substituted).getBound()); if (erasure != null) { final PsiType[] boundTypes = typeParameter.getExtendsListTypes(); diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/SuperCaptureSubstitutionWhenTypeParameterHasUpperBounds.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/SuperCaptureSubstitutionWhenTypeParameterHasUpperBounds.java new file mode 100644 index 000000000000..4eaf810dad4f --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/SuperCaptureSubstitutionWhenTypeParameterHasUpperBounds.java @@ -0,0 +1,30 @@ +class Test { + interface Event{} + + interface EventListener { + void handleEvent(V event); + } + + public void addListener(EventListener listener) { + EventListener localListener = listener; + EventListener localListener1 = listener; + } +} + +class Test1 { + + public static class Entity> { + + public final > T handle(final V visitor) { + return visitor.handle(this); + } + + } + + public interface EntityVisitor, T> { + + T handle(Entity e); + + } + +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA110947.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA110947.java index 5f7ac80942a2..e895159a5762 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA110947.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/IDEA110947.java @@ -9,7 +9,7 @@ abstract class ProcedureService { abstract > Class>> getProcedure(Class cmd); public > void execute(Class aClass) { - Class>> procedureClass = getProcedure(aClass); + Class>> procedureClass = getProcedure(aClass); Class c = aClass; Class c1 = aClass; } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SuperWildcardWithBoundPromotion.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SuperWildcardWithBoundPromotion.java index f1a533020e34..33dd56b27183 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SuperWildcardWithBoundPromotion.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting8/SuperWildcardWithBoundPromotion.java @@ -20,7 +20,7 @@ class Bug2{ } void bug1(Parametrized param) { - foo(param); + foo(param); } @@ -35,7 +35,7 @@ class Test { } void bug1(Parametrized param) { - foo(param); + foo(param); } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java index 12e8d91cabdb..09225b64bc1d 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java @@ -372,6 +372,7 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase { public void testIDEA126633() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); } public void testIDEA124363() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); } public void testIDEA78402() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); } + public void testSuperCaptureSubstitutionWhenTypeParameterHasUpperBounds() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); } public void testParameterBoundsWithCapturedWildcard() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_7, false); } //jdk should propagate LL 1.4 but actually it provides LL 1.7?! public void testCastObjectToIntJdk14() { doTest(LanguageLevel.JDK_1_7, JavaSdkVersion.JDK_1_4, false); } diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GenericsHighlighting8Test.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GenericsHighlighting8Test.java index d23dfea6daf0..fb5acf654e19 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GenericsHighlighting8Test.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/GenericsHighlighting8Test.java @@ -688,7 +688,7 @@ public class GenericsHighlighting8Test extends LightDaemonAnalyzerTestCase { public void testIDEA110869() { doTest(); } - /*public void testIDEA110947() { doTest5(false); }*/ + public void testIDEA110947() { doTest(false); } public void testIDEA112122() { doTest(); }