override default methods in interfaces with default methods (IDEA-155381)

This commit is contained in:
Anna.Kozlova
2016-04-29 11:17:36 +02:00
parent 041c09cc17
commit ce9556a909
7 changed files with 62 additions and 10 deletions

View File

@@ -28,10 +28,8 @@ import com.intellij.ide.fileTemplates.FileTemplateManager;
import com.intellij.ide.fileTemplates.FileTemplateUtil;
import com.intellij.ide.fileTemplates.JavaTemplateUtil;
import com.intellij.ide.util.MemberChooser;
import com.intellij.idea.ActionsBundle;
import com.intellij.lang.java.JavaLanguage;
import com.intellij.openapi.actionSystem.KeyboardShortcut;
import com.intellij.openapi.actionSystem.Presentation;
import com.intellij.openapi.actionSystem.Shortcut;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.Result;
@@ -52,6 +50,7 @@ import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
@@ -184,7 +183,7 @@ public class OverrideImplementUtil extends OverrideImplementExploreUtil {
boolean toCopyJavaDoc,
boolean insertOverrideIfPossible,
PsiMethod result) {
PsiUtil.setModifierProperty(result, PsiModifier.ABSTRACT, aClass.isInterface());
PsiUtil.setModifierProperty(result, PsiModifier.ABSTRACT, aClass.isInterface() && method.hasModifierProperty(PsiModifier.ABSTRACT));
PsiUtil.setModifierProperty(result, PsiModifier.NATIVE, false);
if (!toCopyJavaDoc){
@@ -368,7 +367,7 @@ public class OverrideImplementUtil extends OverrideImplementExploreUtil {
final PsiClass targetClass,
final FileTemplate template) throws IncorrectOperationException {
if (targetClass.isInterface()) {
if (isImplementInterfaceInJava8Interface(targetClass)) {
if (isImplementInterfaceInJava8Interface(targetClass) || originalMethod.hasModifierProperty(PsiModifier.DEFAULT)) {
PsiUtil.setModifierProperty(result, PsiModifier.DEFAULT, true);
}
else {
@@ -424,10 +423,8 @@ public class OverrideImplementUtil extends OverrideImplementExploreUtil {
if (!PsiUtil.isLanguageLevel8OrHigher(targetClass)){
return false;
}
final String implementMethodsName = ActionsBundle.message("action.ImplementMethods.text");
final Presentation presentation = new Presentation();
presentation.setText(implementMethodsName);
return presentation.getText().equals(CommandProcessor.getInstance().getCurrentCommandName());
String commandName = CommandProcessor.getInstance().getCurrentCommandName();
return commandName != null && StringUtil.containsIgnoreCase(commandName, "implement");
}
public static void chooseAndOverrideMethods(Project project, Editor editor, PsiClass aClass){

View File

@@ -33,6 +33,7 @@ import com.intellij.psi.search.PsiElementProcessor;
import com.intellij.psi.search.PsiElementProcessorAdapter;
import com.intellij.psi.search.searches.ClassInheritorsSearch;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -120,7 +121,7 @@ public class ImplementAbstractMethodAction extends BaseIntentionAction {
public boolean execute(@NotNull PsiElement element) {
if (element instanceof PsiClass) {
PsiClass aClass = (PsiClass) element;
if (aClass.isInterface()) return true;
if (aClass.isInterface() && !PsiUtil.isLanguageLevel8OrHigher(aClass)) return true;
final PsiMethod existingImplementation = findExistingImplementation(aClass, myMethod);
if (existingImplementation != null && !existingImplementation.hasModifierProperty(PsiModifier.ABSTRACT)) {
myHasExistingImplementations = true;

View File

@@ -41,6 +41,7 @@ import com.intellij.openapi.util.Computable;
import com.intellij.psi.*;
import com.intellij.psi.search.searches.ClassInheritorsSearch;
import com.intellij.psi.util.MethodSignatureUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.ui.components.JBList;
@@ -181,7 +182,7 @@ public class ImplementAbstractMethodHandler {
private PsiClass[] getClassImplementations(final PsiClass psiClass) {
ArrayList<PsiClass> list = new ArrayList<PsiClass>();
for (PsiClass inheritor : ClassInheritorsSearch.search(psiClass)) {
if (!inheritor.isInterface()) {
if (!inheritor.isInterface() || PsiUtil.isLanguageLevel8OrHigher(inheritor)) {
final PsiSubstitutor classSubstitutor = TypeConversionUtil.getClassSubstitutor(psiClass, inheritor, PsiSubstitutor.EMPTY);
PsiMethod method = classSubstitutor != null ? MethodSignatureUtil.findMethodBySignature(inheritor, myMethod.getSignature(classSubstitutor), true)
: inheritor.findMethodBySignature(myMethod, true);;

View File

@@ -0,0 +1,11 @@
// "Override method 'm'" "true"
interface A {
default void m(){}
}
interface B extends A {
@Override
default void m() {
}
}

View File

@@ -0,0 +1,6 @@
// "Override method 'm'" "true"
interface A {
default void <caret>m(){}
}
interface B extends A {}

View File

@@ -1,6 +1,7 @@
package com.intellij.codeInsight.intention;
import com.intellij.codeInsight.daemon.LightIntentionActionTestCase;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
@@ -30,4 +31,9 @@ public class CopyAbstractMethodImplementationTest extends LightIntentionActionTe
public void test() throws Exception {
doAllTests();
}
@Override
protected LanguageLevel getLanguageLevel() {
return LanguageLevel.JDK_1_6;
}
}

View File

@@ -0,0 +1,30 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.codeInsight.intention;
import com.intellij.codeInsight.daemon.LightIntentionActionTestCase;
public class ImplementAbstractMethodActionTest extends LightIntentionActionTestCase {
@Override
protected String getBasePath() {
return "/codeInsight/daemonCodeAnalyzer/quickFix/implementAbstractMethod";
}
public void test() throws Exception {
doAllTests();
}
}