From bc7e569fa1af3ac975f1fe77727dd03b6ba2a58c Mon Sep 17 00:00:00 2001 From: anna Date: Wed, 28 Mar 2012 13:25:11 +0200 Subject: [PATCH] covariant return types: difference between java7 & java6 (IDEA-83599) --- .../impl/analysis/GenericsHighlightUtil.java | 13 ++++- .../SameErasureDifferentReturnTypes.java | 4 +- .../SameErasureDifferentReturnTypesJdk14.java | 48 +++++++++++++++++++ .../daemon/GenericsHighlightingTest.java | 8 ++++ .../openapi/projectRoots/JavaSdkVersion.java | 16 +++++++ 5 files changed, 86 insertions(+), 3 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/SameErasureDifferentReturnTypesJdk14.java diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java index 4a0ed7347583..4b7f8ce86cda 100644 --- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java @@ -26,6 +26,7 @@ import com.intellij.codeInsight.intention.QuickFixFactory; import com.intellij.openapi.diagnostic.Logger; import com.intellij.openapi.project.IndexNotReadyException; import com.intellij.openapi.project.Project; +import com.intellij.openapi.projectRoots.JavaSdkVersion; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.TextRange; import com.intellij.pom.java.LanguageLevel; @@ -505,7 +506,17 @@ public class GenericsHighlightUtil { final PsiType retErasure1 = TypeConversionUtil.erasure(checkMethod.getReturnType()); final PsiType retErasure2 = TypeConversionUtil.erasure(superMethod.getReturnType()); - if (!Comparing.equal(retErasure1, retErasure2) && + + boolean differentReturnTypeErasure = !Comparing.equal(retErasure1, retErasure2); + if (checkEqualsSuper && JavaSdkVersion.isAtLeast(checkMethod, JavaSdkVersion.JDK_1_7)) { + if (retErasure1 != null && retErasure2 != null) { + differentReturnTypeErasure = !TypeConversionUtil.isAssignable(retErasure1, retErasure2); + } else { + differentReturnTypeErasure = !(retErasure1 == null && retErasure2 == null); + } + } + + if (differentReturnTypeErasure && !TypeConversionUtil.isVoidType(retErasure1) && !TypeConversionUtil.isVoidType(retErasure2) && !(checkEqualsSuper && Arrays.equals(superSignature.getParameterTypes(), signatureToCheck.getParameterTypes()))) { diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/SameErasureDifferentReturnTypes.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/SameErasureDifferentReturnTypes.java index f203f95c25de..8bbd7b65154a 100644 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/SameErasureDifferentReturnTypes.java +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/SameErasureDifferentReturnTypes.java @@ -7,7 +7,7 @@ interface Matcher { } interface ArgumentConstraintPhrases { - T with(Matcher matcher); + T with(Matcher matcher); boolean with(Matcher matcher); byte with(Matcher matcher); short with(Matcher matcher); @@ -19,7 +19,7 @@ interface ArgumentConstraintPhrases { class ExpectationGroupBuilder implements ArgumentConstraintPhrases { - public T with(final Matcher matcher) { + public T with(final Matcher matcher) { return null; } diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/SameErasureDifferentReturnTypesJdk14.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/SameErasureDifferentReturnTypesJdk14.java new file mode 100644 index 000000000000..b046069c784a --- /dev/null +++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/SameErasureDifferentReturnTypesJdk14.java @@ -0,0 +1,48 @@ +/** @noinspection UnusedDeclaration*/ +interface Matcher { + + boolean matches(Object object); + + void _dont_implement_Matcher___instead_extend_BaseMatcher_(); +} + +interface ArgumentConstraintPhrases { + T with(Matcher matcher); + boolean with(Matcher matcher); + byte with(Matcher matcher); + int with(Matcher matcher); + long with(Matcher matcher); + float with(Matcher matcher); + double with(Matcher matcher); +} + +class ExpectationGroupBuilder implements ArgumentConstraintPhrases { + + public T with(final Matcher matcher) { + return null; + } + + public boolean with(final Matcher matcher) { + return false; + } + + public byte with(final Matcher matcher) { + return 0; + } + + public int with(final Matcher matcher) { + return 0; + } + + public long with(final Matcher matcher) { + return 0; + } + + public float with(final Matcher matcher) { + return 0; + } + + public double with(final Matcher matcher) { + return 0; + } +} 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 d33381ec1e2e..c8ed0105e79a 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java @@ -4,6 +4,8 @@ import com.intellij.codeInspection.LocalInspectionTool; import com.intellij.codeInspection.uncheckedWarnings.UncheckedWarningLocalInspection; import com.intellij.codeInspection.unusedImport.UnusedImportLocalInspection; import com.intellij.codeInspection.unusedSymbol.UnusedSymbolLocalInspection; +import com.intellij.openapi.projectRoots.Sdk; +import com.intellij.openapi.projectRoots.impl.JavaSdkImpl; import com.intellij.openapi.roots.LanguageLevelProjectExtension; import com.intellij.pom.java.LanguageLevel; import com.intellij.psi.PsiClass; @@ -34,6 +36,11 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase { LanguageLevelProjectExtension.getInstance(getJavaFacade().getProject()).setLanguageLevel(level); } + @Override + protected Sdk getProjectJDK() { + return getTestName(false).contains("Jdk14") ? JavaSdkImpl.getMockJdk14() : super.getProjectJDK(); + } + public void testReferenceTypeParams() throws Exception { doTest(false); } public void testOverridingMethods() throws Exception { doTest(false); } public void testTypeParameterBoundsList() throws Exception { doTest(false); } @@ -85,6 +92,7 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase { public void testGenericExtendException() throws Exception { doTest(false); } public void testSameErasureDifferentReturnTypes() throws Exception { doTest(false); } + public void testSameErasureDifferentReturnTypesJdk14() throws Exception { doTest(false); } public void testDeepConflictingReturnTypes() throws Exception { doTest(false); } public void testInheritFromTypeParameter() throws Exception { doTest(false); } public void testAnnotationsAsPartOfModifierList() throws Exception { doTest(false); } diff --git a/java/openapi/src/com/intellij/openapi/projectRoots/JavaSdkVersion.java b/java/openapi/src/com/intellij/openapi/projectRoots/JavaSdkVersion.java index 57a56966449f..2d7e6629ad3b 100644 --- a/java/openapi/src/com/intellij/openapi/projectRoots/JavaSdkVersion.java +++ b/java/openapi/src/com/intellij/openapi/projectRoots/JavaSdkVersion.java @@ -15,7 +15,11 @@ */ package com.intellij.openapi.projectRoots; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleUtil; +import com.intellij.openapi.roots.ModuleRootManager; import com.intellij.pom.java.LanguageLevel; +import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import java.util.Arrays; @@ -70,4 +74,16 @@ public enum JavaSdkVersion { String.format("Can't map Java SDK by description (%s). Available values: %s", description, Arrays.toString(values())) ); } + + public static boolean isAtLeast(PsiElement element, JavaSdkVersion minVersion) { + final Module module = ModuleUtil.findModuleForPsiElement(element); + if (module != null) { + final Sdk sdk = ModuleRootManager.getInstance(module).getSdk(); + if (sdk != null && sdk.getSdkType() instanceof JavaSdk) { + final JavaSdkVersion version = JavaSdk.getInstance().getVersion(sdk); + return version != null && version.isAtLeast(minVersion); + } + } + return false; + } }