java: move javac bug workaround to the suppressable inspection (IDEA-258347)

GitOrigin-RevId: 131d9adc783927a143393a59f98efe2afb414c68
This commit is contained in:
Anna Kozlova
2020-12-28 16:51:31 +01:00
committed by intellij-monorepo-bot
parent bb4683f8b4
commit 454edfca70
13 changed files with 95 additions and 92 deletions

View File

@@ -1355,61 +1355,6 @@ public final class GenericsHighlightUtil {
return null;
}
static HighlightInfo checkCannotPassInner(@NotNull PsiJavaCodeReferenceElement ref) {
if (ref.getParent() instanceof PsiTypeElement) {
final PsiClass psiClass = PsiTreeUtil.getParentOfType(ref, PsiClass.class);
if (psiClass == null) return null;
if (PsiTreeUtil.isAncestor(psiClass.getExtendsList(), ref, false) ||
PsiTreeUtil.isAncestor(psiClass.getImplementsList(), ref, false)) {
final PsiElement qualifier = ref.getQualifier();
if (qualifier instanceof PsiJavaCodeReferenceElement && ((PsiJavaCodeReferenceElement)qualifier).resolve() == psiClass) {
final PsiJavaCodeReferenceElement referenceElement = PsiTreeUtil.getParentOfType(ref, PsiJavaCodeReferenceElement.class);
if (referenceElement == null) return null;
final PsiElement typeClass = referenceElement.resolve();
if (!(typeClass instanceof PsiClass)) return null;
final PsiElement resolve = ref.resolve();
final PsiClass containingClass = resolve != null ? ((PsiClass)resolve).getContainingClass() : null;
if (containingClass == null) return null;
PsiClass hiddenClass;
if (psiClass.isInheritor(containingClass, true)) {
hiddenClass = (PsiClass)resolve;
}
else {
hiddenClass = unqualifiedNestedClassReferenceAccessedViaContainingClassInheritance((PsiClass)typeClass, ((PsiClass)resolve).getExtendsList());
if (hiddenClass == null) {
hiddenClass = unqualifiedNestedClassReferenceAccessedViaContainingClassInheritance((PsiClass)typeClass, ((PsiClass)resolve).getImplementsList());
}
}
if (hiddenClass != null) {
final String message = JavaErrorBundle.message("text.class.is.not.accessible", hiddenClass.getName());
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).description(message).range(ref).create();
}
}
}
}
return null;
}
private static PsiClass unqualifiedNestedClassReferenceAccessedViaContainingClassInheritance(@NotNull PsiClass containingClass,
@Nullable PsiReferenceList referenceList) {
if (referenceList != null) {
for (PsiJavaCodeReferenceElement referenceElement : referenceList.getReferenceElements()) {
if (!referenceElement.isQualified()) {
final PsiElement superClass = referenceElement.resolve();
if (superClass instanceof PsiClass) {
final PsiClass superContainingClass = ((PsiClass)superClass).getContainingClass();
if (superContainingClass != null &&
InheritanceUtil.isInheritorOrSelf(containingClass, superContainingClass, true) &&
!PsiTreeUtil.isAncestor(superContainingClass, containingClass, true)) {
return (PsiClass)superClass;
}
}
}
}
}
return null;
}
private static void registerVariableParameterizedTypeFixes(@Nullable HighlightInfo highlightInfo,
@NotNull PsiVariable variable,
@NotNull PsiReferenceParameterList parameterList,

View File

@@ -1227,7 +1227,6 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
if (!myHolder.hasErrorResults()) {
myHolder.add(GenericsHighlightUtil.checkParameterizedReferenceTypeArguments(resolved, ref, result.getSubstitutor(), myJavaSdkVersion));
}
if (!myHolder.hasErrorResults()) myHolder.add(GenericsHighlightUtil.checkCannotPassInner(ref));
if (resolved != null && parent instanceof PsiReferenceList) {
if (!myHolder.hasErrorResults()) {

View File

@@ -24,10 +24,7 @@ import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.impl.source.resolve.graphInference.PsiPolyExpressionUtil;
import com.intellij.psi.infos.MethodCandidateInfo;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiTypesUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.psi.util.*;
import com.siyeh.ig.PsiReplacementUtil;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
@@ -182,6 +179,62 @@ public class JavacQuirksInspectionVisitor extends JavaElementVisitor {
}
}
@Override
public void visitReferenceElement(PsiJavaCodeReferenceElement ref) {
if (myLanguageLevel.isAtLeast(LanguageLevel.JDK_1_9)) return;//javac 9 has no such bug
if (ref.getParent() instanceof PsiTypeElement) {
final PsiClass psiClass = PsiTreeUtil.getParentOfType(ref, PsiClass.class);
if (psiClass == null) return;
if (PsiTreeUtil.isAncestor(psiClass.getExtendsList(), ref, false) ||
PsiTreeUtil.isAncestor(psiClass.getImplementsList(), ref, false)) {
final PsiElement qualifier = ref.getQualifier();
if (qualifier instanceof PsiJavaCodeReferenceElement && ((PsiJavaCodeReferenceElement)qualifier).resolve() == psiClass) {
final PsiJavaCodeReferenceElement referenceElement = PsiTreeUtil.getParentOfType(ref, PsiJavaCodeReferenceElement.class);
if (referenceElement == null) return;
final PsiElement typeClass = referenceElement.resolve();
if (!(typeClass instanceof PsiClass)) return;
final PsiElement resolve = ref.resolve();
final PsiClass containingClass = resolve != null ? ((PsiClass)resolve).getContainingClass() : null;
if (containingClass == null) return;
PsiClass hiddenClass;
if (psiClass.isInheritor(containingClass, true)) {
hiddenClass = (PsiClass)resolve;
}
else {
hiddenClass = unqualifiedNestedClassReferenceAccessedViaContainingClassInheritance((PsiClass)typeClass, ((PsiClass)resolve).getExtendsList());
if (hiddenClass == null) {
hiddenClass = unqualifiedNestedClassReferenceAccessedViaContainingClassInheritance((PsiClass)typeClass, ((PsiClass)resolve).getImplementsList());
}
}
if (hiddenClass != null) {
myHolder.registerProblem(ref, JavaErrorBundle.message("text.class.is.not.accessible", hiddenClass.getName()));
}
}
}
}
}
private static PsiClass unqualifiedNestedClassReferenceAccessedViaContainingClassInheritance(@NotNull PsiClass containingClass,
@Nullable PsiReferenceList referenceList) {
if (referenceList != null) {
for (PsiJavaCodeReferenceElement referenceElement : referenceList.getReferenceElements()) {
if (!referenceElement.isQualified()) {
final PsiElement superClass = referenceElement.resolve();
if (superClass instanceof PsiClass) {
final PsiClass superContainingClass = ((PsiClass)superClass).getContainingClass();
if (superContainingClass != null &&
InheritanceUtil.isInheritorOrSelf(containingClass, superContainingClass, true) &&
!PsiTreeUtil.isAncestor(superContainingClass, containingClass, true)) {
return (PsiClass)superClass;
}
}
}
}
}
return null;
}
private static class ReplaceAssignmentOperatorWithAssignmentFix implements LocalQuickFix {
private final String myOperationSign;

View File

@@ -1,9 +1,9 @@
class Foo<T> {
class Foo<<warning descr="Type parameter 'T' is never used">T</warning>> {
static class Nested {};
}
class Bar extends Foo<<error descr="Nested is not accessible in current context">Bar.Nested</error>> {}
class Bar extends Foo<<warning descr="Nested is not accessible in current context">Bar.Nested</warning>> {}
interface FooI<T> {
interface FooI<<warning descr="Type parameter 'T' is never used">T</warning>> {
interface Nested {};
}
interface BarI extends FooI<<error descr="Nested is not accessible in current context">BarI.Nested</error>> {}
interface BarI extends FooI<<warning descr="Nested is not accessible in current context">BarI.Nested</warning>> {}

View File

@@ -1,9 +1,9 @@
abstract class IdeaBugTest<M extends IdeaBugTest.Mapping>
abstract class IdeaBugTest<<warning descr="Type parameter 'M' is never used">M</warning> extends IdeaBugTest.Mapping>
{
static class Mapping {}
}
class BugTestSub extends IdeaBugTest<<error descr="Mapping is not accessible in current context">BugTestSub.SubMapping</error>>
class BugTestSub extends IdeaBugTest<<warning descr="Mapping is not accessible in current context">BugTestSub.SubMapping</warning>>
{
public abstract static class SubMapping extends Mapping {}
}
@@ -16,7 +16,7 @@ class BugTestSub1 extends IdeaBugTest<BugTestSub1.SubMapping>
class AbstractSettings {
interface State {}
}
interface SomeInterface<T> {}
interface SomeInterface<<warning descr="Type parameter 'T' is never used">T</warning>> {}
class Settings extends AbstractSettings implements SomeInterface<Settings.MyState> {
static class MyState implements State {}
}
@@ -26,7 +26,7 @@ class Records {
interface RecordCategory {
}
static abstract class Record<CATEGORY_TYPE extends RecordCategory> extends Records {}
static abstract class Record<<warning descr="Type parameter 'CATEGORY_TYPE' is never used">CATEGORY_TYPE</warning> extends RecordCategory> extends Records {}
static class ResultRecord extends Record<ResultRecord.Category> {
public enum Category implements RecordCategory {
@@ -35,7 +35,7 @@ class Records {
}
}
//---------------------------------------------
class Parent<T extends Parent.NestedParent>
class Parent<<warning descr="Type parameter 'T' is never used">T</warning> extends Parent.NestedParent>
{
protected static interface NestedParent
{
@@ -44,7 +44,7 @@ class Parent<T extends Parent.NestedParent>
class Test
{
public final static class Child extends Parent<<error descr="NestedParent is not accessible in current context">Child.NestedChild</error>>
public final static class Child extends Parent<<warning descr="NestedParent is not accessible in current context">Child.NestedChild</warning>>
{
private static interface NestedChild extends NestedParent
{

View File

@@ -1,3 +1,3 @@
class A<T> {
class B extends A<<error descr="B is not accessible in current context">B.B</error>>{}
class A<<warning descr="Type parameter 'T' is never used">T</warning>> {
class B extends A<<warning descr="B is not accessible in current context">B.B</warning>>{}
}

View File

@@ -1,6 +1,6 @@
class A<T extends B.C>
class A<<warning descr="Type parameter 'T' is never used">T</warning> extends B.C>
{
interface C {}
}
class B extends A<<error descr="C is not accessible in current context">B.C</error>>{}
class B extends A<<warning descr="C is not accessible in current context">B.C</warning>>{}

View File

@@ -3,6 +3,6 @@ interface A
interface B { }
}
interface C extends A, D<<error descr="B is not accessible in current context">C.B</error>> {}
interface C extends A, D<<warning descr="B is not accessible in current context">C.B</warning>> {}
interface D<T> {}
interface D<<warning descr="Type parameter 'T' is never used">T</warning>> {}

View File

@@ -1,9 +1,9 @@
class Foo<T> {
class Foo<<warning descr="Type parameter 'T' is never used">T</warning>> {
static class Nested {};
}
class Bar extends Foo<<error descr="Nested is not accessible in current context">Bar.Nested</error>> {}
class Bar extends Foo<<warning descr="Nested is not accessible in current context">Bar.Nested</warning>> {}
interface FooI<T> {
interface FooI<<warning descr="Type parameter 'T' is never used">T</warning>> {
interface Nested {};
}
interface BarI extends FooI<<error descr="Nested is not accessible in current context">BarI.Nested</error>> {}
interface BarI extends FooI<<warning descr="Nested is not accessible in current context">BarI.Nested</warning>> {}

View File

@@ -1,9 +1,9 @@
abstract class IdeaBugTest<M extends IdeaBugTest.Mapping>
abstract class IdeaBugTest<<warning descr="Type parameter 'M' is never used">M</warning> extends IdeaBugTest.Mapping>
{
static class Mapping {}
}
class BugTestSub extends IdeaBugTest<<error descr="Mapping is not accessible in current context">BugTestSub.SubMapping</error>>
class BugTestSub extends IdeaBugTest<<warning descr="Mapping is not accessible in current context">BugTestSub.SubMapping</warning>>
{
public abstract static class SubMapping extends Mapping {}
}
@@ -16,7 +16,7 @@ class BugTestSub1 extends IdeaBugTest<BugTestSub1.SubMapping>
class AbstractSettings {
interface State {}
}
interface SomeInterface<T> {}
interface SomeInterface<<warning descr="Type parameter 'T' is never used">T</warning>> {}
class Settings extends AbstractSettings implements SomeInterface<Settings.MyState> {
static class MyState implements State {}
}

View File

@@ -160,7 +160,7 @@ Boolean.class, Boolean.TYPE /*,String[].class */ /*,BigDecimal.class*/);
///////////////////////
class Axx {
<T extends Runnable> T a() {
String s = a();
String s <warning descr="Though assignment is formal correct, it could lead to ClassCastException at runtime. Expected: 'String', actual: 'Runnable & String'">=</warning> a();
s.hashCode();
return null;
}

View File

@@ -17,6 +17,7 @@ package com.intellij.java.codeInsight.daemon;
import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase;
import com.intellij.codeInspection.LocalInspectionTool;
import com.intellij.codeInspection.compiler.JavacQuirksInspection;
import com.intellij.codeInspection.deadCode.UnusedDeclarationInspection;
import com.intellij.codeInspection.uncheckedWarnings.UncheckedWarningLocalInspection;
import com.intellij.codeInspection.unusedImport.UnusedImportInspection;
@@ -25,7 +26,9 @@ import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.LanguageLevelProjectExtension;
import com.intellij.openapi.util.RecursionManager;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.GenericsUtil;
import com.intellij.psi.PsiManager;
import com.intellij.psi.PsiType;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.testFramework.IdeaTestUtil;
import org.jetbrains.annotations.NotNull;
@@ -38,6 +41,7 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase {
super.setUp();
enableInspectionTool(new UnusedDeclarationInspection());
enableInspectionTool(new UnusedImportInspection());
enableInspectionTool(new JavacQuirksInspection());
}
@Override
@@ -257,14 +261,14 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase {
public void testCaptureTopLevelWildcardsForConditionalExpression() { doTest5(false);}
public void testGenericsOverrideMethodInRawInheritor() { doTest5(false);}
public void testIDEA107654() { doTest5(false); }
public void testIDEA55510() { doTest5(false); }
public void testIDEA55510() { doTest5(true); }
public void testIDEA27185(){ doTest6(false); }
public void testIDEA67571(){ doTest7(false); }
public void testTypeArgumentsOnRawType(){ doTest6(false); }
public void testTypeArgumentsOnRawType17(){ doTest7(false); }
public void testWildcardsOnRawTypes() { doTest5(false); }
public void testDisableWithinBoundsCheckForSuperWildcards() { doTest7(false); }
public void testIDEA108287() { doTest5(false); }
public void testIDEA108287() { doTest5(true); }
public void testIDEA77128() { doTest7(false); }
public void testDisableCastingToNestedWildcards() { doTest5(false); }
public void testBooleanInferenceFromIfCondition() { doTest7(false); }
@@ -297,15 +301,15 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase {
public void testIDEA87860() { doTest5(false); }
public void testIDEA67584() { doTest5(false); }
public void testIDEA113225() { doTest5(false); }
public void testIDEA67518() { doTest5(false); }
public void testIDEA67518() { doTest5(true); }
public void testIDEA57252() {
RecursionManager.disableMissedCacheAssertions(getTestRootDisposable());
doTest5(false);
doTest5(true);
}
public void testIDEA57274() { doTest7(false); }
public void testIDEA67591() { doTest5(false); }
public void testIDEA67591() { doTest5(true); }
public void testIDEA114894() { doTest5(false); }
public void testIDEA60818() { doTest5(false); }
public void testIDEA63331() { doTest5(false); }

View File

@@ -18,6 +18,7 @@ package com.intellij.java.codeInsight.daemon.lambda;
import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase;
import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
import com.intellij.codeInspection.LocalInspectionTool;
import com.intellij.codeInspection.compiler.JavacQuirksInspection;
import com.intellij.codeInspection.deadCode.UnusedDeclarationInspection;
import com.intellij.codeInspection.uncheckedWarnings.UncheckedWarningLocalInspection;
import com.intellij.codeInspection.unusedImport.UnusedImportInspection;
@@ -45,6 +46,7 @@ public class GenericsHighlighting8Test extends LightDaemonAnalyzerTestCase {
super.setUp();
enableInspectionTool(new UnusedDeclarationInspection());
enableInspectionTool(new UnusedImportInspection());
enableInspectionTool(new JavacQuirksInspection());
}
@Override
@@ -619,7 +621,7 @@ public class GenericsHighlighting8Test extends LightDaemonAnalyzerTestCase {
}
public void testIDEA55510() {
doTest();
doTest(true);
}
public void testIDEA27185(){
@@ -644,7 +646,7 @@ public class GenericsHighlighting8Test extends LightDaemonAnalyzerTestCase {
}
public void testIDEA108287() {
doTest();
doTest(true);
}
public void testIDEA77128() {