From a815811dbae7d0f714845c2aae7eea029888d9ab Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Wed, 6 Nov 2019 16:10:00 +0700 Subject: [PATCH] IDEA-226296 Forward compatibility inspection GitOrigin-RevId: eadb0e5ec707311f802879dd347fa7a72a67d0af --- .../JavacQuirksInspectionVisitor.java | 65 ----------- .../ForwardCompatibility.html | 13 +++ .../src/messages/JavaErrorMessages.properties | 12 +- .../advHighlighting8/VarClassesWarning.java | 1 - .../daemon/LightAdvHighlightingJdk8Test.java | 3 - .../quickFix/QualifyYieldCallFixTest.java | 4 +- .../src/messages/InspectionsBundle.properties | 2 + .../src/META-INF/InspectionGadgets.xml | 12 +- .../siyeh/ig/jdk/AssertAsNameInspection.java | 109 ------------------ .../siyeh/ig/jdk/EnumAsNameInspection.java | 109 ------------------ .../jdk/ForwardCompatibilityInspection.java | 101 ++++++++++++++++ .../ForwardCompatibilityInspectionMerger.java | 30 +++++ .../inspectionDescriptions/AssertAsName.html | 10 -- .../inspectionDescriptions/EnumAsName.html | 10 -- .../jdk/forward_compatibility/Assert.java | 12 ++ .../jdk/forward_compatibility/Enum.java | 12 ++ .../forward_compatibility}/Underscore.java | 0 .../UnqualifiedYield.java | 0 .../VarClassesWarning.java | 1 + .../forward_compatibility/module-info.java | 3 + .../ForwardCompatibilityInspectionTest.java | 50 ++++++++ 21 files changed, 237 insertions(+), 322 deletions(-) create mode 100644 java/java-impl/src/inspectionDescriptions/ForwardCompatibility.html delete mode 100644 java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting8/VarClassesWarning.java delete mode 100644 plugins/InspectionGadgets/src/com/siyeh/ig/jdk/AssertAsNameInspection.java delete mode 100644 plugins/InspectionGadgets/src/com/siyeh/ig/jdk/EnumAsNameInspection.java create mode 100644 plugins/InspectionGadgets/src/com/siyeh/ig/jdk/ForwardCompatibilityInspection.java create mode 100644 plugins/InspectionGadgets/src/com/siyeh/ig/jdk/ForwardCompatibilityInspectionMerger.java delete mode 100644 plugins/InspectionGadgets/src/inspectionDescriptions/AssertAsName.html delete mode 100644 plugins/InspectionGadgets/src/inspectionDescriptions/EnumAsName.html create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igtest/jdk/forward_compatibility/Assert.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igtest/jdk/forward_compatibility/Enum.java rename {java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting8 => plugins/InspectionGadgets/test/com/siyeh/igtest/jdk/forward_compatibility}/Underscore.java (100%) rename {java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting8 => plugins/InspectionGadgets/test/com/siyeh/igtest/jdk/forward_compatibility}/UnqualifiedYield.java (100%) create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igtest/jdk/forward_compatibility/VarClassesWarning.java create mode 100644 plugins/InspectionGadgets/test/com/siyeh/igtest/jdk/forward_compatibility/module-info.java create mode 100644 plugins/InspectionGadgets/testsrc/com/siyeh/ig/jdk/ForwardCompatibilityInspectionTest.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/compiler/JavacQuirksInspectionVisitor.java b/java/java-analysis-impl/src/com/intellij/codeInspection/compiler/JavacQuirksInspectionVisitor.java index 5d776c4f342e..a8a85741b4e3 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/compiler/JavacQuirksInspectionVisitor.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/compiler/JavacQuirksInspectionVisitor.java @@ -25,7 +25,6 @@ import com.intellij.psi.util.PsiTypesUtil; import com.intellij.psi.util.PsiUtil; import com.intellij.psi.util.TypeConversionUtil; import com.siyeh.ig.PsiReplacementUtil; -import com.siyeh.ig.psiutils.ExpressionUtils; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -38,11 +37,9 @@ public class JavacQuirksInspectionVisitor extends JavaElementVisitor { private final ProblemsHolder myHolder; private final LanguageLevel myLanguageLevel; - private final JavaSdkVersion mySdkVersion; public JavacQuirksInspectionVisitor(ProblemsHolder holder) { myHolder = holder; - mySdkVersion = JavaVersionService.getInstance().getJavaSdkVersion(myHolder.getFile()); myLanguageLevel = PsiUtil.getLanguageLevel(myHolder.getFile()); } @@ -158,50 +155,6 @@ public class JavacQuirksInspectionVisitor extends JavaElementVisitor { } } } - PsiReferenceExpression ref = expression.getMethodExpression(); - PsiElement nameElement = ref.getReferenceNameElement(); - if (nameElement != null && PsiKeyword.YIELD.equals(nameElement.getText()) && ref.getQualifierExpression() == null) { - PsiExpression qualifier = ExpressionUtils.getEffectiveQualifier(expression.getMethodExpression()); - myHolder.registerProblem(nameElement, JavaErrorMessages.message("yield.unqualified.method.warn"), - qualifier == null ? null : new QualifyCallFix()); - } - } - - @Override - public void visitIdentifier(PsiIdentifier identifier) { - super.visitIdentifier(identifier); - if ("_".equals(identifier.getText()) && - mySdkVersion != null && - mySdkVersion.isAtLeast(JavaSdkVersion.JDK_1_8) && - myLanguageLevel.isLessThan(LanguageLevel.JDK_1_9)) { - String message = JavaErrorMessages.message("underscore.identifier.warn"); - myHolder.registerProblem(identifier, message, ProblemHighlightType.GENERIC_ERROR_OR_WARNING); - } - if (PsiKeyword.VAR.equals(identifier.getText()) && - identifier.getParent() instanceof PsiClass && - myLanguageLevel.isLessThan(LanguageLevel.JDK_10)) { - String message = JavaErrorMessages.message("var.identifier.warn"); - myHolder.registerProblem(identifier, message); - } - } - - @Override - public void visitKeyword(PsiKeyword keyword) { - super.visitKeyword(keyword); - if (myLanguageLevel.isAtLeast(LanguageLevel.JDK_1_9) && !myLanguageLevel.isAtLeast(LanguageLevel.JDK_10)) { - @PsiModifier.ModifierConstant String modifier = keyword.getText(); - if (PsiKeyword.STATIC.equals(modifier) || PsiKeyword.TRANSITIVE.equals(modifier)) { - PsiElement parent = keyword.getParent(); - if (parent instanceof PsiModifierList) { - PsiElement grand = parent.getParent(); - if (grand instanceof PsiRequiresStatement && PsiJavaModule.JAVA_BASE.equals(((PsiRequiresStatement)grand).getModuleName())) { - String message = JavaErrorMessages.message("module.unwanted.modifier"); - LocalQuickFix fix = QuickFixFactory.getInstance().createModifierListFix((PsiModifierList)parent, modifier, false, false); - myHolder.registerProblem(keyword, message, fix); - } - } - } - } } @Override @@ -281,22 +234,4 @@ public class JavacQuirksInspectionVisitor extends JavaElementVisitor { return false; } } - - private static class QualifyCallFix implements LocalQuickFix { - @Nls(capitalization = Nls.Capitalization.Sentence) - @NotNull - @Override - public String getFamilyName() { - return "Qualify call"; - } - - @Override - public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { - PsiMethodCallExpression call = PsiTreeUtil.getParentOfType(descriptor.getStartElement(), PsiMethodCallExpression.class); - if (call == null) return; - PsiExpression qualifier = ExpressionUtils.getEffectiveQualifier(call.getMethodExpression()); - if (qualifier == null) return; - call.getMethodExpression().setQualifierExpression(qualifier); - } - } } diff --git a/java/java-impl/src/inspectionDescriptions/ForwardCompatibility.html b/java/java-impl/src/inspectionDescriptions/ForwardCompatibility.html new file mode 100644 index 000000000000..45fea3c44207 --- /dev/null +++ b/java/java-impl/src/inspectionDescriptions/ForwardCompatibility.html @@ -0,0 +1,13 @@ + + +Reports the Java code constructs that may fail to compile in future Java versions. The following problems are reported: + + +

New in 2020.1

+ + \ No newline at end of file diff --git a/java/java-psi-impl/src/messages/JavaErrorMessages.properties b/java/java-psi-impl/src/messages/JavaErrorMessages.properties index 33419c161f6c..3593026463b4 100644 --- a/java/java-psi-impl/src/messages/JavaErrorMessages.properties +++ b/java/java-psi-impl/src/messages/JavaErrorMessages.properties @@ -407,11 +407,15 @@ wildcard.not.expected=Unexpected wildcard bound.not.expected=Unexpected bound declaration.not.allowed=Declaration not allowed here -underscore.identifier.warn=Use of '_' as an identifier is not supported in releases after Java 8 underscore.identifier.error=As of Java 9, '_' is a keyword, and may not be used as an identifier underscore.lambda.identifier=Use of '_' as a lambda parameter name is not allowed -var.identifier.warn=Usage of 'var' as class name is not supported in releases after Java 9 -yield.unqualified.method.warn=Unqualified call of 'yield' method might not be supported in releases after Java 13 + +underscore.identifier.warn=Use of '_' as an identifier is not supported in releases after Java 8 +assert.identifier.warn=Use of 'assert' as an identifier is not supported in releases after Java 1.3 +enum.identifier.warn=Use of 'enum' as an identifier is not supported in releases after Java 1.4 +var.identifier.warn=Use of 'var' as class name is not supported in releases after Java 9 +yield.unqualified.method.warn=Unqualified call to 'yield' method might not be supported in releases after Java 13 +module.unwanted.modifier.warn=Modifiers on 'requires java.base' are prohibited in releases after Java 9 module.no.package=A module file should not have 'package' statement module.file.wrong.name=Module declaration should be in a file named 'module-info.java' @@ -450,8 +454,6 @@ module.access.does.not.read=Package ''{0}'' is declared in module ''{1}'', but m module.access.not.in.graph=Package ''{0}'' is declared in module ''{1}'', which is not in the module graph module.access.bad.name=Package ''{0}'' is declared in module with an invalid name (''{1}'') -module.unwanted.modifier=Since Java 10, modifiers on 'requires java.base' are prohibited - lvti.illegal=Illegal reference to restricted type 'var' lvti.no.initializer=Cannot infer type: 'var' on variable without initializer lvti.lambda=Cannot infer type: lambda expression requires an explicit target type diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting8/VarClassesWarning.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting8/VarClassesWarning.java deleted file mode 100644 index a3e6e418088f..000000000000 --- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting8/VarClassesWarning.java +++ /dev/null @@ -1 +0,0 @@ -class var {} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/LightAdvHighlightingJdk8Test.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/LightAdvHighlightingJdk8Test.java index c37887e40c5d..b4fa93815300 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/LightAdvHighlightingJdk8Test.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/LightAdvHighlightingJdk8Test.java @@ -38,7 +38,6 @@ public class LightAdvHighlightingJdk8Test extends LightDaemonAnalyzerTestCase { doTest(BASE_PATH + "/" + getTestName(false) + ".java", warnings, weakWarnings, false); } - public void testUnderscore() { doTest(true, false); } public void testFinalVariableMightNotHaveBeenInitializedInsideLambda() { doTest(true, false); } public void testStrictfpInsideInterface() { doTest(true, false); } public void testMethodReferences() { doTest(false, true); } @@ -48,11 +47,9 @@ public class LightAdvHighlightingJdk8Test extends LightDaemonAnalyzerTestCase { public void testLambdaExpressions() { doTest(false, true); } public void testUnsupportedFeatures() { doTest(false, false); } public void testModulesNotSupported() { doTest(false, false); } - public void testVarClassesWarning() { doTest(true, false); } public void testTooManyVarargsPolyArguments() { doTest(true, false); } public void testNoArraySuperType() { doTest(true, true);} - public void testUnqualifiedYield() { doTest(true, false); } } \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/quickFix/QualifyYieldCallFixTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/quickFix/QualifyYieldCallFixTest.java index 1095fb551dbc..a9245d0c965c 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/quickFix/QualifyYieldCallFixTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/daemon/quickFix/QualifyYieldCallFixTest.java @@ -3,14 +3,14 @@ package com.intellij.java.codeInsight.daemon.quickFix; import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase; import com.intellij.codeInspection.LocalInspectionTool; -import com.intellij.codeInspection.compiler.JavacQuirksInspection; +import com.siyeh.ig.jdk.ForwardCompatibilityInspection; import org.jetbrains.annotations.NotNull; public class QualifyYieldCallFixTest extends LightQuickFixParameterizedTestCase { @NotNull @Override protected LocalInspectionTool[] configureLocalInspectionTools() { - return new LocalInspectionTool[]{new JavacQuirksInspection()}; + return new LocalInspectionTool[]{new ForwardCompatibilityInspection()}; } @Override diff --git a/platform/platform-resources-en/src/messages/InspectionsBundle.properties b/platform/platform-resources-en/src/messages/InspectionsBundle.properties index c2d7ebb15fd8..c568d820f295 100644 --- a/platform/platform-resources-en/src/messages/InspectionsBundle.properties +++ b/platform/platform-resources-en/src/messages/InspectionsBundle.properties @@ -534,6 +534,8 @@ inspection.redundant.requires.statement.description=Redundant directive ''requir inspection.redundant.requires.statement.fix.family=Delete redundant 'requires' directive inspection.redundant.requires.statement.fix.name=Delete directive ''requires {0}'' +inspection.forward.compatibility.name=Forward compatibility + inspection.root.node.title=Inspections # inspection tools list actions: diff --git a/plugins/InspectionGadgets/src/META-INF/InspectionGadgets.xml b/plugins/InspectionGadgets/src/META-INF/InspectionGadgets.xml index af586ad8e393..97578a5f8a5a 100644 --- a/plugins/InspectionGadgets/src/META-INF/InspectionGadgets.xml +++ b/plugins/InspectionGadgets/src/META-INF/InspectionGadgets.xml @@ -17,6 +17,7 @@ + - + @@ -1352,10 +1352,6 @@ - diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/jdk/AssertAsNameInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/jdk/AssertAsNameInspection.java deleted file mode 100644 index 87f59f3c41d4..000000000000 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/jdk/AssertAsNameInspection.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2003-2009 Dave Griffith, Bas Leijdekkers - * - * 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.siyeh.ig.jdk; - -import com.intellij.psi.*; -import com.siyeh.InspectionGadgetsBundle; -import com.siyeh.ig.BaseInspection; -import com.siyeh.ig.BaseInspectionVisitor; -import com.siyeh.ig.InspectionGadgetsFix; -import com.siyeh.ig.fixes.RenameFix; -import org.jetbrains.annotations.NotNull; - -public class AssertAsNameInspection extends BaseInspection { - - @Override - protected InspectionGadgetsFix buildFix(Object... infos) { - return new RenameFix(); - } - - @Override - @NotNull - public String getID() { - return "AssertAsIdentifier"; - } - - @Override - @NotNull - public String getDisplayName() { - return InspectionGadgetsBundle.message( - "use.assert.as.identifier.display.name"); - } - - @Override - @NotNull - public String buildErrorString(Object... infos) { - return InspectionGadgetsBundle.message( - "use.assert.as.identifier.problem.descriptor"); - } - - @Override - protected boolean buildQuickFixesOnlyForOnTheFlyErrors() { - return true; - } - - @Override - public BaseInspectionVisitor buildVisitor() { - return new AssertAsNameVisitor(); - } - - private static class AssertAsNameVisitor extends BaseInspectionVisitor { - - @Override - public void visitVariable(@NotNull PsiVariable variable) { - super.visitVariable(variable); - final String variableName = variable.getName(); - if (!PsiKeyword.ASSERT.equals(variableName)) { - return; - } - registerVariableError(variable); - } - - @Override - public void visitMethod(@NotNull PsiMethod method) { - super.visitMethod(method); - final String name = method.getName(); - if (!PsiKeyword.ASSERT.equals(name)) { - return; - } - registerMethodError(method); - } - - @Override - public void visitClass(@NotNull PsiClass aClass) { - //note: no call to super, to avoid drill-down - final String name = aClass.getName(); - if (!PsiKeyword.ASSERT.equals(name)) { - return; - } - final PsiTypeParameterList params = aClass.getTypeParameterList(); - if (params != null) { - params.accept(this); - } - registerClassError(aClass); - } - - @Override - public void visitTypeParameter(PsiTypeParameter parameter) { - super.visitTypeParameter(parameter); - final String name = parameter.getName(); - if (!PsiKeyword.ASSERT.equals(name)) { - return; - } - registerTypeParameterError(parameter); - } - } -} \ No newline at end of file diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/jdk/EnumAsNameInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/jdk/EnumAsNameInspection.java deleted file mode 100644 index ccc3707afc51..000000000000 --- a/plugins/InspectionGadgets/src/com/siyeh/ig/jdk/EnumAsNameInspection.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2003-2009 Dave Griffith, Bas Leijdekkers - * - * 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.siyeh.ig.jdk; - -import com.intellij.psi.*; -import com.siyeh.InspectionGadgetsBundle; -import com.siyeh.ig.BaseInspection; -import com.siyeh.ig.BaseInspectionVisitor; -import com.siyeh.ig.InspectionGadgetsFix; -import com.siyeh.ig.fixes.RenameFix; -import org.jetbrains.annotations.NotNull; - -public class EnumAsNameInspection extends BaseInspection { - - @Override - protected InspectionGadgetsFix buildFix(Object... infos) { - return new RenameFix(); - } - - @Override - @NotNull - public String getID() { - return "EnumAsIdentifier"; - } - - @Override - @NotNull - public String getDisplayName() { - return InspectionGadgetsBundle.message( - "use.enum.as.identifier.display.name"); - } - - @Override - @NotNull - public String buildErrorString(Object... infos) { - return InspectionGadgetsBundle.message( - "use.enum.as.identifier.problem.descriptor"); - } - - @Override - protected boolean buildQuickFixesOnlyForOnTheFlyErrors() { - return true; - } - - @Override - public BaseInspectionVisitor buildVisitor() { - return new EnumAsNameVisitor(); - } - - private static class EnumAsNameVisitor extends BaseInspectionVisitor { - - @Override - public void visitVariable(@NotNull PsiVariable variable) { - super.visitVariable(variable); - final String variableName = variable.getName(); - if (!PsiKeyword.ENUM.equals(variableName)) { - return; - } - registerVariableError(variable); - } - - @Override - public void visitMethod(@NotNull PsiMethod method) { - super.visitMethod(method); - final String name = method.getName(); - if (!PsiKeyword.ENUM.equals(name)) { - return; - } - registerMethodError(method); - } - - @Override - public void visitClass(@NotNull PsiClass aClass) { - //note: no call to super, to avoid drill-down - final String name = aClass.getName(); - if (!PsiKeyword.ENUM.equals(name)) { - return; - } - final PsiTypeParameterList params = aClass.getTypeParameterList(); - if (params != null) { - params.accept(this); - } - registerClassError(aClass); - } - - @Override - public void visitTypeParameter(PsiTypeParameter parameter) { - super.visitTypeParameter(parameter); - final String name = parameter.getName(); - if (!PsiKeyword.ENUM.equals(name)) { - return; - } - registerTypeParameterError(parameter); - } - } -} \ No newline at end of file diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/jdk/ForwardCompatibilityInspection.java b/plugins/InspectionGadgets/src/com/siyeh/ig/jdk/ForwardCompatibilityInspection.java new file mode 100644 index 000000000000..0989a78153b8 --- /dev/null +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/jdk/ForwardCompatibilityInspection.java @@ -0,0 +1,101 @@ +// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.siyeh.ig.jdk; + +import com.intellij.codeInsight.daemon.JavaErrorMessages; +import com.intellij.codeInsight.intention.QuickFixFactory; +import com.intellij.codeInspection.*; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.projectRoots.JavaSdkVersion; +import com.intellij.openapi.projectRoots.JavaVersionService; +import com.intellij.pom.java.LanguageLevel; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.psi.util.PsiUtil; +import com.siyeh.ig.fixes.RenameFix; +import com.siyeh.ig.psiutils.ExpressionUtils; +import org.jetbrains.annotations.Nls; +import org.jetbrains.annotations.NotNull; + +public class ForwardCompatibilityInspection extends AbstractBaseJavaLocalInspectionTool { + @NotNull + @Override + public PsiElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) { + LanguageLevel languageLevel = PsiUtil.getLanguageLevel(holder.getFile()); + JavaSdkVersion sdkVersion = JavaVersionService.getInstance().getJavaSdkVersion(holder.getFile()); + return new JavaElementVisitor() { + @Override + public void visitIdentifier(PsiIdentifier identifier) { + String name = identifier.getText(); + if ("_".equals(name) && sdkVersion != null && + sdkVersion.isAtLeast(JavaSdkVersion.JDK_1_8) && languageLevel.isLessThan(LanguageLevel.JDK_1_9)) { + String message = JavaErrorMessages.message("underscore.identifier.warn"); + holder.registerProblem(identifier, message, ProblemHighlightType.GENERIC_ERROR_OR_WARNING); + } + PsiElement parent = identifier.getParent(); + if (PsiKeyword.VAR.equals(name) && parent instanceof PsiClass && + languageLevel.isLessThan(LanguageLevel.JDK_10)) { + String message = JavaErrorMessages.message("var.identifier.warn"); + holder.registerProblem(identifier, message, new RenameFix()); + } + if (PsiKeyword.ASSERT.equals(name) && languageLevel.isLessThan(LanguageLevel.JDK_1_4) && + (parent instanceof PsiClass || parent instanceof PsiMethod || parent instanceof PsiVariable)) { + String message = JavaErrorMessages.message("assert.identifier.warn"); + holder.registerProblem(identifier, message, new RenameFix()); + } + if (PsiKeyword.ENUM.equals(name) && languageLevel.isLessThan(LanguageLevel.JDK_1_5) && + (parent instanceof PsiClass || parent instanceof PsiMethod || parent instanceof PsiVariable)) { + String message = JavaErrorMessages.message("enum.identifier.warn"); + holder.registerProblem(identifier, message, new RenameFix()); + } + } + + @Override + public void visitMethodCallExpression(PsiMethodCallExpression expression) { + PsiReferenceExpression ref = expression.getMethodExpression(); + PsiElement nameElement = ref.getReferenceNameElement(); + if (nameElement != null && PsiKeyword.YIELD.equals(nameElement.getText()) && ref.getQualifierExpression() == null) { + PsiExpression qualifier = ExpressionUtils.getEffectiveQualifier(expression.getMethodExpression()); + holder.registerProblem(nameElement, JavaErrorMessages.message("yield.unqualified.method.warn"), + qualifier == null ? null : new QualifyCallFix(), new RenameFix()); + } + } + + @Override + public void visitKeyword(PsiKeyword keyword) { + super.visitKeyword(keyword); + if (languageLevel.isAtLeast(LanguageLevel.JDK_1_9) && !languageLevel.isAtLeast(LanguageLevel.JDK_10)) { + @PsiModifier.ModifierConstant String modifier = keyword.getText(); + if (PsiKeyword.STATIC.equals(modifier) || PsiKeyword.TRANSITIVE.equals(modifier)) { + PsiElement parent = keyword.getParent(); + if (parent instanceof PsiModifierList) { + PsiElement grand = parent.getParent(); + if (grand instanceof PsiRequiresStatement && PsiJavaModule.JAVA_BASE.equals(((PsiRequiresStatement)grand).getModuleName())) { + String message = JavaErrorMessages.message("module.unwanted.modifier.warn"); + LocalQuickFix fix = QuickFixFactory.getInstance().createModifierListFix((PsiModifierList)parent, modifier, false, false); + holder.registerProblem(keyword, message, fix); + } + } + } + } + } + }; + } + + private static class QualifyCallFix implements LocalQuickFix { + @Nls(capitalization = Nls.Capitalization.Sentence) + @NotNull + @Override + public String getFamilyName() { + return "Qualify call"; + } + + @Override + public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) { + PsiMethodCallExpression call = PsiTreeUtil.getParentOfType(descriptor.getStartElement(), PsiMethodCallExpression.class); + if (call == null) return; + PsiExpression qualifier = ExpressionUtils.getEffectiveQualifier(call.getMethodExpression()); + if (qualifier == null) return; + call.getMethodExpression().setQualifierExpression(qualifier); + } + } +} diff --git a/plugins/InspectionGadgets/src/com/siyeh/ig/jdk/ForwardCompatibilityInspectionMerger.java b/plugins/InspectionGadgets/src/com/siyeh/ig/jdk/ForwardCompatibilityInspectionMerger.java new file mode 100644 index 000000000000..35cfcf84abc0 --- /dev/null +++ b/plugins/InspectionGadgets/src/com/siyeh/ig/jdk/ForwardCompatibilityInspectionMerger.java @@ -0,0 +1,30 @@ +// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.siyeh.ig.jdk; + +import com.intellij.codeInspection.ex.InspectionElementsMergerBase; +import org.jetbrains.annotations.NotNull; + +public class ForwardCompatibilityInspectionMerger extends InspectionElementsMergerBase { + + @NotNull + @Override + public String getMergedToolName() { + return "ForwardCompatibility"; + } + + @NotNull + @Override + public String[] getSourceToolNames() { + return new String[] { + "AssertAsName", "EnumAsName" + }; + } + + @NotNull + @Override + public String[] getSuppressIds() { + return new String[] { + "AssertAsIdentifier", "EnumAsIdentifier" + }; + } +} diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/AssertAsName.html b/plugins/InspectionGadgets/src/inspectionDescriptions/AssertAsName.html deleted file mode 100644 index f8147a603d8d..000000000000 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/AssertAsName.html +++ /dev/null @@ -1,10 +0,0 @@ - - -Reports variables, methods, or classes named -assert. Such names are legal under Java 1.3 or -earlier JVMs, but will cause problems under Java 1.4 or later. - -

- - - diff --git a/plugins/InspectionGadgets/src/inspectionDescriptions/EnumAsName.html b/plugins/InspectionGadgets/src/inspectionDescriptions/EnumAsName.html deleted file mode 100644 index ceda4a07bef8..000000000000 --- a/plugins/InspectionGadgets/src/inspectionDescriptions/EnumAsName.html +++ /dev/null @@ -1,10 +0,0 @@ - - -Reports variables, methods, or classes named -enum. Such names are legal under Java 1.4 or -earlier JVMs, but will cause problems under Java 5.0 or later. - -

- - - \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/jdk/forward_compatibility/Assert.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/jdk/forward_compatibility/Assert.java new file mode 100644 index 000000000000..8807cb71fcc6 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/jdk/forward_compatibility/Assert.java @@ -0,0 +1,12 @@ +class Test { + void assert() {} + + void test() { + int assert = 1; + assert = 2; + assert(); + new assert(); + } + + class assert {} +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/jdk/forward_compatibility/Enum.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/jdk/forward_compatibility/Enum.java new file mode 100644 index 000000000000..73056ab2c24f --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/jdk/forward_compatibility/Enum.java @@ -0,0 +1,12 @@ +class Test { + void enum() {} + + void test() { + int enum = 1; + enum = 2; + enum(); + new enum(); + } + + class enum {} +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting8/Underscore.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/jdk/forward_compatibility/Underscore.java similarity index 100% rename from java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting8/Underscore.java rename to plugins/InspectionGadgets/test/com/siyeh/igtest/jdk/forward_compatibility/Underscore.java diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting8/UnqualifiedYield.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/jdk/forward_compatibility/UnqualifiedYield.java similarity index 100% rename from java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting8/UnqualifiedYield.java rename to plugins/InspectionGadgets/test/com/siyeh/igtest/jdk/forward_compatibility/UnqualifiedYield.java diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/jdk/forward_compatibility/VarClassesWarning.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/jdk/forward_compatibility/VarClassesWarning.java new file mode 100644 index 000000000000..7b259e8bb65b --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/jdk/forward_compatibility/VarClassesWarning.java @@ -0,0 +1 @@ +class var {} \ No newline at end of file diff --git a/plugins/InspectionGadgets/test/com/siyeh/igtest/jdk/forward_compatibility/module-info.java b/plugins/InspectionGadgets/test/com/siyeh/igtest/jdk/forward_compatibility/module-info.java new file mode 100644 index 000000000000..3d5555a53176 --- /dev/null +++ b/plugins/InspectionGadgets/test/com/siyeh/igtest/jdk/forward_compatibility/module-info.java @@ -0,0 +1,3 @@ +module M { + requires static transitive java.base; +} \ No newline at end of file diff --git a/plugins/InspectionGadgets/testsrc/com/siyeh/ig/jdk/ForwardCompatibilityInspectionTest.java b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/jdk/ForwardCompatibilityInspectionTest.java new file mode 100644 index 000000000000..116688bd7b38 --- /dev/null +++ b/plugins/InspectionGadgets/testsrc/com/siyeh/ig/jdk/ForwardCompatibilityInspectionTest.java @@ -0,0 +1,50 @@ +// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.siyeh.ig.jdk; + +import com.intellij.codeInspection.InspectionProfileEntry; +import com.intellij.pom.java.LanguageLevel; +import com.intellij.testFramework.IdeaTestUtil; +import com.intellij.testFramework.LightProjectDescriptor; +import com.siyeh.ig.LightJavaInspectionTestCase; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class ForwardCompatibilityInspectionTest extends LightJavaInspectionTestCase { + @Override + protected String getBasePath() { + return LightJavaInspectionTestCase.INSPECTION_GADGETS_TEST_DATA_PATH + "com/siyeh/igtest/jdk/forward_compatibility"; + } + + @Nullable + @Override + protected InspectionProfileEntry getInspection() { + return new ForwardCompatibilityInspection(); + } + + @NotNull + @Override + protected LightProjectDescriptor getProjectDescriptor() { + return JAVA_8; + } + + public void testAssert() { doTestWithLevel(LanguageLevel.JDK_1_3); } + + public void testEnum() { doTestWithLevel(LanguageLevel.JDK_1_3); } + + public void testUnqualifiedYield() { doTest(); } + + public void testUnderscore() { doTest(); } + + public void testVarClassesWarning() { doTest(); } + + public void testModuleInfoWarning() { + IdeaTestUtil.setModuleLanguageLevel(getModule(), LanguageLevel.JDK_1_9, getTestRootDisposable()); + myFixture.configureByFile("module-info.java"); + myFixture.testHighlighting(true, false, false); + } + + public void doTestWithLevel(LanguageLevel languageLevel) { + IdeaTestUtil.setModuleLanguageLevel(getModule(), languageLevel, getTestRootDisposable()); + doTest(); + } +}