From a9a9d2dd108bcfcb5c2332911bd9de363ad5779e Mon Sep 17 00:00:00 2001 From: Anna Kozlova Date: Fri, 29 Jan 2021 21:33:35 +0100 Subject: [PATCH] java: override default: fix super qualifier for default method (IDEA-260570) GitOrigin-RevId: 7ad2c736b94867a067137f39e0eabf454ed8d5aa --- .../generation/OverrideImplementUtil.java | 31 +++++++++++++++---- .../afterExtensionMethods1.java | 14 +++++++++ .../beforeExtensionMethods1.java | 11 +++++++ .../codeInsight/OverrideImplementTest.groovy | 2 ++ 4 files changed, 52 insertions(+), 6 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/overrideImplement/afterExtensionMethods1.java create mode 100644 java/java-tests/testData/codeInsight/overrideImplement/beforeExtensionMethods1.java 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) }