diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java b/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java index 28fad0f44302..604722a50a77 100644 --- a/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java @@ -789,13 +789,13 @@ public final class OverrideImplementUtil extends OverrideImplementExploreUtil { try { int offset = editor.getCaretModel().getOffset(); PsiElement brace = aClass.getLBrace(); - if (brace == null) { + if (brace == null && !(aClass instanceof PsiImplicitClass)) { PsiClass psiClass = JavaPsiFacade.getElementFactory(aClass.getProject()).createClass("X"); brace = aClass.addRangeAfter(psiClass.getLBrace(), psiClass.getRBrace(), aClass.getLastChild()); LOG.assertTrue(brace != null, aClass.getLastChild()); } - int lbraceOffset = brace.getTextOffset(); + int lbraceOffset = brace == null ? 0 : brace.getTextOffset(); List> resultMembers; if (offset <= lbraceOffset || aClass.isEnum()) { resultMembers = new ArrayList<>(); @@ -904,6 +904,13 @@ public final class OverrideImplementUtil extends OverrideImplementExploreUtil { final PsiClass aClass = (PsiClass)element; if (aClass instanceof PsiSyntheticClass) return null; + if (file instanceof PsiJavaFile javaFile) { + PsiClass[] classes = javaFile.getClasses(); + if (classes.length == 1 && classes[0] instanceof PsiImplicitClass implicitClass && + implicitClass.getFirstChild() != null && PsiMethodUtil.hasMainMethod(implicitClass)) { + return classes[0]; + } + } return aClass == null || !allowInterface && aClass.isInterface() ? null : aClass; } diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/generation/OverrideImplementExploreUtil.java b/java/java-psi-impl/src/com/intellij/codeInsight/generation/OverrideImplementExploreUtil.java index 108b8581fa08..aedb0316ecce 100644 --- a/java/java-psi-impl/src/com/intellij/codeInsight/generation/OverrideImplementExploreUtil.java +++ b/java/java-psi-impl/src/com/intellij/codeInsight/generation/OverrideImplementExploreUtil.java @@ -65,7 +65,9 @@ public class OverrideImplementExploreUtil { PsiClass hisClass = method.getContainingClass(); if (hisClass == null) continue; // filter non-immediate super constructors - if (method.isConstructor() && (!aClass.isInheritor(hisClass, false) || aClass instanceof PsiAnonymousClass || aClass.isEnum())) { + if (method.isConstructor() && + (!aClass.isInheritor(hisClass, false) || aClass instanceof PsiAnonymousClass || + aClass.isEnum() || aClass instanceof PsiImplicitClass)) { continue; } // filter already implemented diff --git a/java/java-tests/testData/codeInsight/overrideImplement/afterOverrideForImplicitClass.java b/java/java-tests/testData/codeInsight/overrideImplement/afterOverrideForImplicitClass.java new file mode 100644 index 000000000000..01cf2699e02c --- /dev/null +++ b/java/java-tests/testData/codeInsight/overrideImplement/afterOverrideForImplicitClass.java @@ -0,0 +1,29 @@ +public static void main(String[] args) { + +} + +@Override +public int hashCode() { + return super.hashCode(); +} + +@Override +public boolean equals(Object obj) { + return super.equals(obj); +} + +@Override +protected Object clone() throws CloneNotSupportedException { + return super.clone(); +} + +@Override +public String toString() { + return super.toString(); +} + +@Override +protected void finalize() throws Throwable { + super.finalize(); +} + diff --git a/java/java-tests/testData/codeInsight/overrideImplement/beforeOverrideForImplicitClass.java b/java/java-tests/testData/codeInsight/overrideImplement/beforeOverrideForImplicitClass.java new file mode 100644 index 000000000000..f3f4cc7c7db6 --- /dev/null +++ b/java/java-tests/testData/codeInsight/overrideImplement/beforeOverrideForImplicitClass.java @@ -0,0 +1,5 @@ +public static void main(String[] args) { + +} + + \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/OverrideImplementTest.java b/java/java-tests/testSrc/com/intellij/java/codeInsight/OverrideImplementTest.java index 45c669582a14..a92224652495 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/OverrideImplementTest.java +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/OverrideImplementTest.java @@ -12,6 +12,8 @@ import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiImplicitClass; +import com.intellij.psi.PsiJavaFile; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.testFramework.LightProjectDescriptor; import com.intellij.testFramework.PsiTestUtil; @@ -53,6 +55,10 @@ public class OverrideImplementTest extends LightJavaCodeInsightFixtureTestCase { doTest(false); } + public void testOverrideForImplicitClass() { + doTest(false); + } + public void testImplementExtensionMethods() { doTest(true); } public void testOverrideExtensionMethods() { doTest(false); } @@ -528,7 +534,12 @@ public class OverrideImplementTest extends LightJavaCodeInsightFixtureTestCase { private void invokeAction(boolean toImplement) { int offset = myFixture.getEditor().getCaretModel().getOffset(); - PsiClass psiClass = PsiTreeUtil.findElementOfClassAtOffset(myFixture.getFile(), offset, PsiClass.class, false); + PsiFile psiFile = myFixture.getFile(); + PsiClass psiClass = PsiTreeUtil.findElementOfClassAtOffset(psiFile, offset, PsiClass.class, false); + if (psiFile instanceof PsiJavaFile javaFile && javaFile.getClasses().length == 1 && + javaFile.getClasses()[0] instanceof PsiImplicitClass implicitClass) { + psiClass = implicitClass; + } assertNotNull(psiClass); OverrideImplementUtil.chooseAndOverrideOrImplementMethods(getProject(), myFixture.getEditor(), psiClass, toImplement); NonBlockingReadActionImpl.waitForAsyncTaskCompletion();