IDEA-90883 (do not insert super call to implemented extension method)

This commit is contained in:
Roman Shevchenko
2012-09-13 19:02:20 +04:00
parent 7f310f8565
commit edd939be23
6 changed files with 83 additions and 71 deletions

View File

@@ -45,7 +45,7 @@ import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.keymap.Keymap;
import com.intellij.openapi.keymap.KeymapManager;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtil;
import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
@@ -80,8 +80,7 @@ public class OverrideImplementUtil {
@NonNls private static final String PROP_COMBINED_OVERRIDE_IMPLEMENT = "OverrideImplement.combined";
private OverrideImplementUtil() {
}
private OverrideImplementUtil() { }
@NotNull
public static Collection<CandidateInfo> getMethodsToOverrideImplement(PsiClass aClass, boolean toImplement) {
@@ -218,7 +217,8 @@ public class OverrideImplementUtil {
PsiSubstitutor substitutor = aClass.isInheritor(containingClass, true)
? TypeConversionUtil.getSuperClassSubstitutor(containingClass, aClass, PsiSubstitutor.EMPTY)
: PsiSubstitutor.EMPTY;
return overrideOrImplementMethod(aClass, method, substitutor, toCopyJavaDoc, CodeStyleSettingsManager.getSettings(aClass.getProject()).INSERT_OVERRIDE_ANNOTATION);
return overrideOrImplementMethod(aClass, method, substitutor, toCopyJavaDoc,
CodeStyleSettingsManager.getSettings(aClass.getProject()).INSERT_OVERRIDE_ANNOTATION);
}
public static boolean isInsertOverride(PsiMethod superMethod, PsiClass targetClass) {
@@ -325,11 +325,11 @@ public class OverrideImplementUtil {
}
final PsiCodeBlock body = JavaPsiFacade.getInstance(method.getProject()).getElementFactory().createCodeBlockFromText("{}", null);
PsiCodeBlock oldbody = result.getBody();
if (oldbody != null){
oldbody.replace(body);
PsiCodeBlock oldBody = result.getBody();
if (oldBody != null) {
oldBody.replace(body);
}
else{
else {
result.add(body);
}
@@ -356,7 +356,7 @@ public class OverrideImplementUtil {
if (insertOverride && canInsertOverride(overridden, targetClass)) {
annotate(method, Override.class.getName());
}
final Module module = ModuleUtil.findModuleForPsiElement(targetClass);
final Module module = ModuleUtilCore.findModuleForPsiElement(targetClass);
final GlobalSearchScope moduleScope = module != null ? GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module) : null;
final Project project = targetClass.getProject();
final JavaPsiFacade facade = JavaPsiFacade.getInstance(project);
@@ -378,13 +378,6 @@ public class OverrideImplementUtil {
}
}
public static boolean isOverridable(PsiMethod method) {
return !method.isConstructor()
&& !method.hasModifierProperty(PsiModifier.STATIC)
&& !method.hasModifierProperty(PsiModifier.FINAL)
&& !method.hasModifierProperty(PsiModifier.PRIVATE);
}
@NotNull
public static List<PsiGenerationInfo<PsiMethod>> overrideOrImplementMethods(PsiClass aClass,
Collection<PsiMethodMember> candidates,
@@ -437,20 +430,20 @@ public class OverrideImplementUtil {
}
@NotNull
public static String callSuper (PsiMethod superMethod, PsiMethod overriding) {
public static String callSuper(PsiMethod superMethod, PsiMethod overriding) {
@NonNls StringBuilder buffer = new StringBuilder();
if (!superMethod.isConstructor() && superMethod.getReturnType() != PsiType.VOID) {
buffer.append("return ");
}
buffer.append("super");
PsiParameter[] parms = overriding.getParameterList().getParameters();
if (!superMethod.isConstructor()){
PsiParameter[] parameters = overriding.getParameterList().getParameters();
if (!superMethod.isConstructor()) {
buffer.append(".");
buffer.append(superMethod.getName());
}
buffer.append("(");
for (int i = 0; i < parms.length; i++) {
String name = parms[i].getName();
for (int i = 0; i < parameters.length; i++) {
String name = parameters[i].getName();
if (i > 0) buffer.append(",");
buffer.append(name);
}
@@ -459,13 +452,15 @@ public class OverrideImplementUtil {
}
public static void setupMethodBody(PsiMethod result, PsiMethod originalMethod, PsiClass targetClass) throws IncorrectOperationException {
String templName = originalMethod.hasModifierProperty(PsiModifier.ABSTRACT) ?
JavaTemplateUtil.TEMPLATE_IMPLEMENTED_METHOD_BODY : JavaTemplateUtil.TEMPLATE_OVERRIDDEN_METHOD_BODY;
FileTemplate template = FileTemplateManager.getInstance().getCodeTemplate(templName);
boolean isAbstract = originalMethod.hasModifierProperty(PsiModifier.ABSTRACT) || PsiUtil.isExtensionMethod(originalMethod);
String templateName = isAbstract ? JavaTemplateUtil.TEMPLATE_IMPLEMENTED_METHOD_BODY : JavaTemplateUtil.TEMPLATE_OVERRIDDEN_METHOD_BODY;
FileTemplate template = FileTemplateManager.getInstance().getCodeTemplate(templateName);
setupMethodBody(result, originalMethod, targetClass, template);
}
public static void setupMethodBody(final PsiMethod result, final PsiMethod originalMethod, final PsiClass targetClass,
public static void setupMethodBody(final PsiMethod result,
final PsiMethod originalMethod,
final PsiClass targetClass,
final FileTemplate template) throws IncorrectOperationException {
if (targetClass.isInterface()) {
final PsiCodeBlock body = result.getBody();
@@ -613,7 +608,7 @@ public class OverrideImplementUtil {
}
if (ApplicationManager.getApplication().isUnitTestMode()) {
if (!toImplement) {
if (!toImplement || onlyPrimary.length == 0) {
chooser.selectElements(all);
}
chooser.close(DialogWrapper.OK_EXIT_CODE);

View File

@@ -0,0 +1,15 @@
interface A<T> {
void m1(T t);
void m2();
}
interface B<T> extends A<T> {
void m1(T t) default { }
}
class MyClass<T> implements B<T> {
@Override
public void m2() {
<selection>//To change body of implemented methods use File | Settings | File Templates.</selection>
}
}

View File

@@ -1,17 +1,10 @@
class Test {
interface A<T> {
void m1(T t);
void m2();
}
interface A<T> {
void m(T t) default { }
}
interface B<T> extends A<T> {
void m1(T t) default { }
}
class MyClass<T> implements B<T> {
class MyClass<T> implements A<T> {
@Override
public void m2() {
public void m(T t) {
<selection>//To change body of implemented methods use File | Settings | File Templates.</selection>
}
}
}

View File

@@ -0,0 +1,12 @@
interface A<T> {
void m1(T t);
void m2();
}
interface B<T> extends A<T> {
void m1(T t) default { }
}
class MyClass<T> implements B<T> {
<caret>
}

View File

@@ -1,14 +1,7 @@
class Test {
interface A<T> {
void m1(T t);
void m2();
}
interface B<T> extends A<T> {
void m1(T t) default { }
}
class MyClass<T> implements B<T> {
<caret>
}
interface A<T> {
void m(T t) default { }
}
class MyClass<T> implements A<T> {
<caret>
}

View File

@@ -30,6 +30,7 @@ import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.testFramework.LightCodeInsightTestCase;
import com.intellij.util.FunctionUtil;
import com.intellij.util.containers.ContainerUtil;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.Collections;
@@ -60,6 +61,9 @@ public class OverrideImplementTest extends LightCodeInsightTestCase {
public void testClone() { doTest(false); }
public void testOnTheLineWithExistingExpression() { doTest(false); }
public void testImplementExtensionMethods() { doTest8(false, true); }
public void testDoNotImplementExtensionMethods() { doTest8(false, true); }
public void testLongFinalParameterList() {
CodeStyleSettings codeStyleSettings = CodeStyleSettingsManager.getSettings(getProject()).clone();
try {
@@ -120,25 +124,21 @@ public class OverrideImplementTest extends LightCodeInsightTestCase {
checkResultByFile(BASE_DIR + "after" + name + ".java");
}
public void testImplementExtensionMethods() {
private void doTest(boolean copyJavadoc) { doTest(copyJavadoc, null); }
private void doTest8(boolean copyJavadoc, @Nullable Boolean toImplement) {
setLanguageLevel(LanguageLevel.JDK_1_8);
String name = getTestName(false);
configureByFile(BASE_DIR + "before" + name + ".java");
int offset = getEditor().getCaretModel().getOffset();
PsiElement context = getFile().findElementAt(offset);
PsiClass psiClass = PsiTreeUtil.getParentOfType(context, PsiClass.class);
assert psiClass != null;
OverrideImplementUtil.chooseAndOverrideOrImplementMethods(getProject(), getEditor(), psiClass, true);
checkResultByFile(BASE_DIR + "after" + name + ".java");
doTest(copyJavadoc, toImplement);
}
private void doTest(boolean copyJavadoc) {
private void doTest(boolean copyJavadoc, @Nullable Boolean toImplement) {
String name = getTestName(false);
configureByFile(BASE_DIR + "before" + name + ".java");
int offset = getEditor().getCaretModel().getOffset();
PsiElement context = getFile().findElementAt(offset);
PsiClass psiClass = PsiTreeUtil.getParentOfType(context, PsiClass.class);
assert psiClass != null;
if (toImplement == null) {
PsiClassType[] implement = psiClass.getImplementsListTypes();
final PsiClass superClass = implement.length == 0 ? psiClass.getSuperClass() : implement[0].resolve();
assert superClass != null;
@@ -146,6 +146,10 @@ public class OverrideImplementTest extends LightCodeInsightTestCase {
final PsiSubstitutor substitutor = TypeConversionUtil.getSuperClassSubstitutor(superClass, psiClass, PsiSubstitutor.EMPTY);
final List<PsiMethodMember> candidates = Collections.singletonList(new PsiMethodMember(method, substitutor));
OverrideImplementUtil.overrideOrImplementMethodsInRightPlace(getEditor(), psiClass, candidates, copyJavadoc, true);
}
else {
OverrideImplementUtil.chooseAndOverrideOrImplementMethods(getProject(), getEditor(), psiClass, toImplement);
}
checkResultByFile(BASE_DIR + "after" + name + ".java");
}
}