implement interface inside java 8+ interface should create default methods (IDEA-135105)

This commit is contained in:
Anna Kozlova
2015-01-13 20:55:45 +01:00
parent 532b21f088
commit 495b152d2c
3 changed files with 62 additions and 5 deletions
@@ -23,6 +23,7 @@ import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiCodeFragment;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiJavaFile;
import com.intellij.psi.util.PsiUtil;
import org.jetbrains.annotations.NotNull;
/**
@@ -35,13 +36,13 @@ public class JavaImplementMethodsHandler implements LanguageCodeInsightActionHan
return false;
}
PsiClass aClass = OverrideImplementUtil.getContextClass(file.getProject(), editor, file, false);
PsiClass aClass = OverrideImplementUtil.getContextClass(file.getProject(), editor, file, PsiUtil.isLanguageLevel8OrHigher(file));
return aClass != null && !OverrideImplementUtil.getMethodSignaturesToImplement(aClass).isEmpty();
}
@Override
public void invoke(@NotNull final Project project, @NotNull final Editor editor, @NotNull final PsiFile file) {
PsiClass aClass = OverrideImplementUtil.getContextClass(project, editor, file, false);
PsiClass aClass = OverrideImplementUtil.getContextClass(project, editor, file, PsiUtil.isLanguageLevel8OrHigher(file));
if (aClass == null) {
return;
}
@@ -25,11 +25,14 @@ 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;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
@@ -363,8 +366,13 @@ public class OverrideImplementUtil extends OverrideImplementExploreUtil {
final PsiClass targetClass,
final FileTemplate template) throws IncorrectOperationException {
if (targetClass.isInterface()) {
final PsiCodeBlock body = result.getBody();
if (body != null) body.delete();
if (isImplementInterfaceInJava8Interface(targetClass)) {
PsiUtil.setModifierProperty(result, PsiModifier.DEFAULT, true);
}
else {
final PsiCodeBlock body = result.getBody();
if (body != null) body.delete();
}
}
FileType fileType = FileTypeManager.getInstance().getFileTypeByExtension(template.getExtension());
PsiType returnType = result.getReturnType();
@@ -410,6 +418,16 @@ public class OverrideImplementUtil extends OverrideImplementExploreUtil {
}
}
private static boolean isImplementInterfaceInJava8Interface(PsiClass targetClass) {
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());
}
public static void chooseAndOverrideMethods(Project project, Editor editor, PsiClass aClass){
FeatureUsageTracker.getInstance().triggerFeatureUsed(ProductivityFeatureNames.CODEASSISTS_OVERRIDE_IMPLEMENT);
chooseAndOverrideOrImplementMethods(project, editor, aClass, false);
@@ -16,7 +16,10 @@
package com.intellij.codeInsight;
import com.intellij.JavaTestUtil;
import com.intellij.codeInsight.generation.OverrideImplementUtil;
import com.intellij.codeInsight.generation.OverrideImplementUtil
import com.intellij.idea.ActionsBundle
import com.intellij.openapi.actionSystem.Presentation
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.psi.PsiClass;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
@@ -38,6 +41,41 @@ public class OverrideImplementTest extends LightCodeInsightFixtureTestCase {
public void testSkipUnknownAnnotations() { doTest(true); }
public void testOverrideInInterface() { doTest(false); }
public void testImplementInInterface() {
myFixture.addClass """
interface A {
void foo();
}
"""
def file = myFixture.addClass("""
interface B extends A {
<caret>
}
""").containingFile.virtualFile
myFixture.configureFromExistingVirtualFile(file)
def implementMethodsName = ActionsBundle.message("action.ImplementMethods.text")
final Presentation presentation = new Presentation();
presentation.setText(implementMethodsName);
CommandProcessor.instance.executeCommand(project, new Runnable() {
@Override
void run() {
invokeAction(true)
}
}, presentation.getText(), null)
myFixture.checkResult """
interface B extends A {
@Override
default void foo() {
<caret>
}
}
"""
}
public void testMultipleInheritedThrows() {doTest(false);}
public void "test overriding overloaded method"() {