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 71c2db4065b9..544838da81c2 100644 --- a/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java +++ b/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java @@ -300,19 +300,22 @@ public final class OverrideImplementUtil extends OverrideImplementExploreUtil { } @NotNull - private static String callSuper(@NotNull PsiMethod superMethod, @NotNull PsiMethod overriding) { - return callSuper(superMethod, overriding, true); + private static String callSuper(@NotNull PsiMethod superMethod, @NotNull PsiMethod overriding, PsiClass targetClass) { + return callSuper(superMethod, overriding, targetClass, true); } @NotNull - private static String callSuper(@NotNull PsiMethod superMethod, @NotNull PsiMethod overriding, boolean prependReturn) { + private static String callSuper(@NotNull PsiMethod superMethod, @NotNull PsiMethod overriding, PsiClass targetClass, boolean prependReturn) { @NonNls StringBuilder buffer = new StringBuilder(); if (prependReturn && !superMethod.isConstructor() && !PsiType.VOID.equals(superMethod.getReturnType())) { buffer.append("return "); } PsiClass aClass = superMethod.getContainingClass(); if (aClass != null && aClass.isInterface()) { - buffer.append(aClass.getName()).append("."); + PsiClass superQualifier = getSuperQualifier(aClass, targetClass); + if (superQualifier != null) { + buffer.append(superQualifier.getName()).append("."); + } } buffer.append("super"); PsiParameter[] parameters = overriding.getParameterList().getParameters(); @@ -330,6 +333,22 @@ public final class OverrideImplementUtil extends OverrideImplementExploreUtil { return buffer.toString(); } + private static PsiClass getSuperQualifier(PsiClass aClass, PsiClass targetClass) { + if (targetClass != null) { + if (targetClass.isInheritor(aClass, false)) { + return aClass; + } + + for (PsiClassType type : targetClass.getSuperTypes()) { + PsiClass superClass = type.resolve(); + if (InheritanceUtil.isInheritorOrSelf(superClass, aClass, true)) { + return superClass; + } + } + } + return null; + } + public static void setupMethodBody(@NotNull PsiMethod result, @NotNull PsiMethod originalMethod, @NotNull PsiClass targetClass) throws IncorrectOperationException { boolean isAbstract = originalMethod.hasModifierProperty(PsiModifier.ABSTRACT); String templateName = isAbstract ? JavaTemplateUtil.TEMPLATE_IMPLEMENTED_METHOD_BODY : JavaTemplateUtil.TEMPLATE_OVERRIDDEN_METHOD_BODY; @@ -358,8 +377,8 @@ public final class OverrideImplementUtil extends OverrideImplementExploreUtil { Properties properties = FileTemplateManager.getInstance(targetClass.getProject()).getDefaultProperties(); properties.setProperty(FileTemplate.ATTRIBUTE_RETURN_TYPE, returnType.getPresentableText()); properties.setProperty(FileTemplate.ATTRIBUTE_DEFAULT_RETURN_VALUE, PsiTypesUtil.getDefaultValueOfType(returnType, true)); - properties.setProperty(FileTemplate.ATTRIBUTE_CALL_SUPER, callSuper(originalMethod, result)); - properties.setProperty(FileTemplate.ATTRIBUTE_PLAIN_CALL_SUPER, callSuper(originalMethod, result, false)); + properties.setProperty(FileTemplate.ATTRIBUTE_CALL_SUPER, callSuper(originalMethod, result, targetClass)); + properties.setProperty(FileTemplate.ATTRIBUTE_PLAIN_CALL_SUPER, callSuper(originalMethod, result, targetClass, false)); JavaTemplateUtil.setClassAndMethodNameProperties(properties, targetClass, result); JVMElementFactory factory = JVMElementFactories.getFactory(targetClass.getLanguage(), originalMethod.getProject()); diff --git a/java/java-tests/testData/codeInsight/overrideImplement/afterExtensionMethods1.java b/java/java-tests/testData/codeInsight/overrideImplement/afterExtensionMethods1.java new file mode 100644 index 000000000000..003e912d00e6 --- /dev/null +++ b/java/java-tests/testData/codeInsight/overrideImplement/afterExtensionMethods1.java @@ -0,0 +1,14 @@ +interface A { + default void m1(T t) { } +} + +interface B extends A { + +} + +class MyClass implements B { + @Override + public void m1(T t) { + B.super.m1(t); + } +} diff --git a/java/java-tests/testData/codeInsight/overrideImplement/beforeExtensionMethods1.java b/java/java-tests/testData/codeInsight/overrideImplement/beforeExtensionMethods1.java new file mode 100644 index 000000000000..bad208e29dce --- /dev/null +++ b/java/java-tests/testData/codeInsight/overrideImplement/beforeExtensionMethods1.java @@ -0,0 +1,11 @@ +interface A { + default void m1(T t) { } +} + +interface B extends A { + +} + +class MyClass implements B { + +} diff --git a/java/java-tests/testSrc/com/intellij/java/codeInsight/OverrideImplementTest.groovy b/java/java-tests/testSrc/com/intellij/java/codeInsight/OverrideImplementTest.groovy index b3e2e2cbec21..c5c5b2566a77 100644 --- a/java/java-tests/testSrc/com/intellij/java/codeInsight/OverrideImplementTest.groovy +++ b/java/java-tests/testSrc/com/intellij/java/codeInsight/OverrideImplementTest.groovy @@ -50,6 +50,8 @@ class OverrideImplementTest extends LightJavaCodeInsightFixtureTestCase { void testMultipleSuperMethodsThroughGenerics() { doTest(true) } void testDoNotImplementExtensionMethods() { doTest(true) } + + void testExtensionMethods1() { doTest(true) } void testSkipUnknownAnnotations() { doTest(true) }