[java-inspections] IDEA-360079 unused for main method modifiers

GitOrigin-RevId: 698a021a1c86d8365a113d2d1b47c085beec9489
This commit is contained in:
Mikhail Pyltsin
2025-05-09 11:55:52 +00:00
committed by intellij-monorepo-bot
parent c1fe9eb0fc
commit 037958feaf
7 changed files with 132 additions and 0 deletions
@@ -1271,6 +1271,7 @@ unnecessary.interface.inner.class.modifier.problem.descriptor=Modifier <code>#re
unnecessary.interface.field.modifier.problem.descriptor=Modifier <code>#ref</code> is redundant for interface fields #loc
unnecessary.transient.modifier.problem.descriptor=Modifier <code>#ref</code> is redundant for a 'static' field
unnecessary.strictfp.modifier.problem.descriptor=Modifier <code>#ref</code> is redundant on Java 17 and later
unnecessary.main.modifier.problem.descriptor=Modifier <code>#ref</code> is redundant for ''main'' method on Java {0} #loc
smth.unnecessary.remove.quickfix=Remove unnecessary ''{0}''
unqualified.static.usage.problem.descriptor=Unqualified static method call <code>#ref()</code> #loc
unqualified.static.usage.problem.descriptor1=Unqualified static field access <code>#ref</code> #loc
@@ -4,10 +4,15 @@ package com.siyeh.ig.style;
import com.intellij.codeInspection.CleanupLocalInspectionTool;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.pom.java.JavaFeature;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.search.PsiSearchHelper;
import com.intellij.psi.search.searches.ReferencesSearch;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiMethodUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.siyeh.HardcodedMethodConstants;
import com.siyeh.InspectionGadgetsBundle;
import com.siyeh.ig.BaseInspection;
import com.siyeh.ig.BaseInspectionVisitor;
@@ -146,6 +151,54 @@ public final class UnnecessaryModifierInspection extends BaseInspection implemen
}
}
}
processMainMethod(method);
}
private void processMainMethod(@NotNull PsiMethod method) {
if (PsiUtil.isAvailable(JavaFeature.IMPLICIT_CLASSES, method) &&
HardcodedMethodConstants.MAIN.equals(method.getName()) &&
PsiMethodUtil.isMainMethod(method)) {
boolean isImplicitClass = method.getParent() instanceof PsiImplicitClass;
final PsiModifierList modifierList = method.getModifierList();
final List<PsiKeyword> modifiers = PsiTreeUtil.getChildrenOfTypeAsList(modifierList, PsiKeyword.class);
LanguageLevel level = PsiUtil.getLanguageLevel(method);
for (PsiKeyword modifier : modifiers) {
if (modifier.getTokenType() == JavaTokenType.STATIC_KEYWORD && isImplicitClass) {
//static for implicit class
registerError(modifier, InspectionGadgetsBundle.message("unnecessary.main.modifier.problem.descriptor", level.getShortText()),
modifier.getText());
continue;
}
if (modifier.getTokenType() == JavaTokenType.PUBLIC_KEYWORD ||
modifier.getTokenType() == JavaTokenType.PROTECTED_KEYWORD) {
if (isImplicitClass) {
//public and protected for implicit class
registerError(modifier, InspectionGadgetsBundle.message("unnecessary.main.modifier.problem.descriptor", level.getShortText()),
modifier.getText());
continue;
}
if (isOnTheFly()) {
final PsiSearchHelper searchHelper = PsiSearchHelper.getInstance(method.getProject());
PsiClass containingClass = method.getContainingClass();
if (containingClass == null || containingClass.getName() == null) return;
final PsiSearchHelper.SearchCostResult cost =
searchHelper.isCheapEnoughToSearch(containingClass.getName(), containingClass.getResolveScope(), null);
if (cost == PsiSearchHelper.SearchCostResult.TOO_MANY_OCCURRENCES) {
continue;
}
}
PsiReference first = ReferencesSearch.search(method, method.getResolveScope()).findFirst();
if (first != null) {
continue;
}
//public and protected for normal class
registerError(modifier, InspectionGadgetsBundle.message("unnecessary.main.modifier.problem.descriptor", level.getShortText()),
modifier.getText());
}
}
}
}
@Override
@@ -0,0 +1,3 @@
<warning descr="Modifier 'public' is redundant for 'main' method on Java 23-preview">public</warning> <warning descr="Modifier 'static' is redundant for 'main' method on Java 23-preview">static</warning> void main(String[] args) {
System.out.println("Hello World!");
}
@@ -0,0 +1,13 @@
package test;
public class NormalClassWithModifiers {
<warning descr="Modifier 'public' is redundant for 'main' method on Java 23-preview">public</warning> static void main(String[] args) {
System.out.println("Hello World!");
}
public static int main() {
System.out.println("Hello World!");
return 1;
}
}
@@ -0,0 +1,7 @@
package test;
class NormalClassWithModifiersClassIsUsed {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
@@ -0,0 +1,7 @@
package test;
public class OldJavaWithModifiers{
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
@@ -0,0 +1,48 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.siyeh.ig.style;
import com.intellij.pom.java.JavaFeature;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.testFramework.IdeaTestUtil;
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase;
import com.siyeh.ig.LightJavaInspectionTestCase;
public class UnnecessaryPsvmModifierInspectionTest extends LightJavaCodeInsightFixtureTestCase {
@Override
protected String getBasePath() {
return LightJavaInspectionTestCase.INSPECTION_GADGETS_TEST_DATA_PATH + "com/siyeh/igtest/style/unnecessary_psvm_modifier";
}
private void doTest() {
myFixture.enableInspections(new UnnecessaryModifierInspection());
myFixture.testHighlighting(getTestName(false) + ".java");
}
public void testOldJavaWithModifiers() {
IdeaTestUtil.withLevel(getModule(), LanguageLevel.JDK_1_8, () -> doTest());
}
public void testImplicitClassWithModifiers() {
IdeaTestUtil.withLevel(getModule(), JavaFeature.IMPLICIT_IMPORT_IN_IMPLICIT_CLASSES.getMinimumLevel(), () -> doTest());
}
public void testNormalClassWithModifiers() {
IdeaTestUtil.withLevel(getModule(), JavaFeature.IMPLICIT_IMPORT_IN_IMPLICIT_CLASSES.getMinimumLevel(), () -> doTest());
}
public void testNormalClassWithModifiersClassIsUsed() {
IdeaTestUtil.withLevel(getModule(), JavaFeature.IMPLICIT_IMPORT_IN_IMPLICIT_CLASSES.getMinimumLevel(), () -> {
myFixture.addClass("""
import test.NormalClassWithModifiersClassIsUsed;
class Foo {
public static void main(String[] args){
NormalClassWithModifiersClassIsUsed.main(args);
}
}
""");
doTest();
});
}
}