[java-run] IDEA-367503 and IDEA-365965 hide gutters for java 22 and higher when it is impossible to create class

GitOrigin-RevId: be53750f3f70e70fde24181912887a36a874ab35
This commit is contained in:
Mikhail Pyltsin
2025-02-13 20:06:20 +00:00
committed by intellij-monorepo-bot
parent bb55a1b4f0
commit add71cb7da
3 changed files with 99 additions and 29 deletions
@@ -95,11 +95,15 @@ public final class PsiMethodUtil {
*/
private static @Nullable PsiMethod findMainMethod(final PsiMethod[] mainMethods, PsiClass aClass, boolean first) {
List<@NotNull PsiMethod> candidates = new ArrayList<>();
//from java 22 main methods are chosen according to parameters
boolean chooseMainMethodByParametersEnabled = inheritedStaticMainEnabled(aClass);
for (final PsiMethod mainMethod : mainMethods) {
if (mainMethod.hasModifierProperty(PsiModifier.ABSTRACT)) {
continue;
}
if (aClass.hasModifierProperty(PsiModifier.ABSTRACT) && !mainMethod.hasModifierProperty(PsiModifier.STATIC)) {
if (aClass.hasModifierProperty(PsiModifier.ABSTRACT) &&
!mainMethod.hasModifierProperty(PsiModifier.STATIC) &&
!chooseMainMethodByParametersEnabled) {
continue;
}
PsiClass containingClass = mainMethod.getContainingClass();
@@ -109,12 +113,12 @@ public final class PsiMethodUtil {
}
if (containingClass.isInterface() &&
mainMethod.hasModifierProperty(PsiModifier.STATIC) &&
!inheritedStaticMainEnabled(containingClass)) {
!chooseMainMethodByParametersEnabled) {
continue;
}
}
if (isMainMethod(mainMethod)) {
if (first) {
if (first && !chooseMainMethodByParametersEnabled) {
//fast exit
return mainMethod;
}
@@ -125,7 +129,18 @@ public final class PsiMethodUtil {
return null;
}
candidates.sort(mainCandidateComparator);
return candidates.get(0);
PsiMethod method = candidates.get(0);
if (chooseMainMethodByParametersEnabled) {
if (!method.hasModifierProperty(PsiModifier.STATIC)) {
if (aClass.hasModifierProperty(PsiModifier.ABSTRACT)) {
return null;
}
if (!PsiUtil.hasDefaultConstructor(aClass, true, true)) {
return null;
}
}
}
return method;
}
private static boolean instanceMainMethodsEnabled(@NotNull PsiElement psiElement) {
@@ -209,8 +209,6 @@ public final class AppMainV2 {
Class<?> last = classesToVisit.removeLast();
Method[] declaredMethods = last.getDeclaredMethods();
for (Method method : declaredMethods) {
//it is impossible to call non-static method for abstract class
if (Modifier.isAbstract(aClass.getModifiers()) && !Modifier.isStatic(method.getModifiers())) continue;
MainMethodStatus status = getMainMethodStatus(method, java21Preview ? MainMethodSearchMode.NON_STATIC_METHOD : MainMethodSearchMode.ALL_METHOD);
if (status == MainMethodStatus.WithArgs) {
return method;
@@ -238,7 +238,7 @@ public class RunLineMarkerJava22Test extends LightJavaCodeInsightFixtureTestCase
public static void main(String[] args) {
System.out.println("main with parameters");
}
static void main() {
System.out.println("main without parameters");
}
@@ -272,12 +272,12 @@ public class RunLineMarkerJava22Test extends LightJavaCodeInsightFixtureTestCase
public void testInheritMain() {
IdeaTestUtil.withLevel(getModule(), getEnabledLevel(), () -> {
myFixture.addClass("""
public class AAAAAA {
public void main(String[] args) {
System.out.println("2");
}
}
""");
public class AAAAAA {
public void main(String[] args) {
System.out.println("2");
}
}
""");
myFixture.configureByText("BBBBBB.java", """
public class BBBBBB extends AAAAAA {
public static void <caret>main() {
@@ -293,14 +293,14 @@ public class RunLineMarkerJava22Test extends LightJavaCodeInsightFixtureTestCase
public void testImpossibleInheritStatic() {
IdeaTestUtil.withLevel(getModule(), getEnabledLevel(), () -> {
myFixture.addClass("""
public class AAAAAA {
public AAAAAA(int a){}
public void main(String[] args) {
System.out.println("2");
}
}
""");
public class AAAAAA {
public AAAAAA(int a){}
public void main(String[] args) {
System.out.println("2");
}
}
""");
myFixture.configureByText("BBBBBB.java", """
public class BBBBBB extends AAAAAA {
public static void <caret>main() {
@@ -311,14 +311,71 @@ public class RunLineMarkerJava22Test extends LightJavaCodeInsightFixtureTestCase
List<GutterMark> marks = myFixture.findGuttersAtCaret();
assertEquals(1, marks.size());
GutterMark mark = marks.get(0);
assertTrue(mark instanceof LineMarkerInfo.LineMarkerGutterIconRenderer);
LineMarkerInfo.LineMarkerGutterIconRenderer gutterIconRenderer = (LineMarkerInfo.LineMarkerGutterIconRenderer)mark;
PsiElement element = gutterIconRenderer.getLineMarkerInfo().getElement();
assertEquals(AllIcons.RunConfigurations.TestState.Run, gutterIconRenderer.getIcon());
assertTrue(element instanceof PsiIdentifier);
assertEquals("main", element.getText());
PsiClass psiClass = PsiTreeUtil.getParentOfType(element, PsiClass.class);
assertEquals("BBBBBB", psiClass.getName());
checkMark(mark, "BBBBBB");
});
}
public void testImpossibleCreateClassForNonStaticMethodWithSuperClass() {
IdeaTestUtil.withLevel(getModule(), getEnabledLevel(), () -> {
myFixture.configureByText("BBBBBB.java", """
class Parent {
void main(String[] args) {
System.out.println("non-static, args");
}
}
class Child extends Parent <caret> {
Child(int p) {
System.out.println("Child constructor");
}
}
""");
List<GutterMark> marks = myFixture.findGuttersAtCaret();
assertEquals(0, marks.size());
myFixture.getEditor().getCaretModel().moveToOffset(myFixture.getEditor().getDocument().getText().indexOf("void main"));
marks = myFixture.findGuttersAtCaret();
assertEquals(1, marks.size());
GutterMark mark = marks.get(0);
checkMark(mark, "Parent");
});
}
public void testImpossibleCreateClassForNonStaticMethod() {
IdeaTestUtil.withLevel(getModule(), getEnabledLevel(), () -> {
myFixture.configureByText("BBBBBB.java", """
public abstract class AbstractClass {
static void main() {
System.out.println("Hello, World!");
}
void main<caret>(String[] args) {
System.out.println("Hello, World! no constructor, non-static, args");
}
}
""");
List<GutterMark> marks = myFixture.findGuttersAtCaret();
assertEquals(0, marks.size());
myFixture.getEditor().getCaretModel().moveToOffset(myFixture.getEditor().getDocument().getText().indexOf("static void main"));
marks = myFixture.findGuttersAtCaret();
assertEquals(0, marks.size());
myFixture.getEditor().getCaretModel().moveToOffset(myFixture.getEditor().getDocument().getText().indexOf("class AbstractClass"));
marks = myFixture.findGuttersAtCaret();
assertEquals(0, marks.size());
});
}
private static void checkMark(@NotNull GutterMark mark2, @NotNull String className) {
assertTrue(mark2 instanceof LineMarkerInfo.LineMarkerGutterIconRenderer);
LineMarkerInfo.LineMarkerGutterIconRenderer gutterIconRenderer2 = (LineMarkerInfo.LineMarkerGutterIconRenderer)mark2;
PsiElement element2 = gutterIconRenderer2.getLineMarkerInfo().getElement();
assertEquals(AllIcons.RunConfigurations.TestState.Run, gutterIconRenderer2.getIcon());
assertTrue(element2 instanceof PsiIdentifier);
PsiClass psiClass = PsiTreeUtil.getParentOfType(element2, PsiClass.class);
assertEquals(className, psiClass.getName());
}
}