mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-19 13:02:30 +07:00
java: move javac bug workaround to the suppressable inspection (IDEA-258347)
GitOrigin-RevId: 131d9adc783927a143393a59f98efe2afb414c68
This commit is contained in:
committed by
intellij-monorepo-bot
parent
bb4683f8b4
commit
454edfca70
@@ -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,
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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>> {}
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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>>{}
|
||||
}
|
||||
@@ -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>>{}
|
||||
@@ -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>> {}
|
||||
@@ -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>> {}
|
||||
|
||||
@@ -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 {}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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); }
|
||||
|
||||
@@ -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() {
|
||||
|
||||
Reference in New Issue
Block a user