mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
fix for changing parameter types for method which used to extend the generic-parameter-method which was refactored to bounded wildcards and "both method signatures have same erasure" error appeared as a result
This commit is contained in:
@@ -455,4 +455,9 @@ public abstract class QuickFixFactory {
|
||||
|
||||
@NotNull
|
||||
public abstract IntentionAction createPushDownMethodFix();
|
||||
|
||||
@NotNull
|
||||
public IntentionAction createSameErasureButDifferentMethodsFix(@NotNull PsiMethod method, @NotNull PsiMethod superMethod) {
|
||||
throw new AbstractMethodError();
|
||||
}
|
||||
}
|
||||
+5
-1
@@ -689,7 +689,11 @@ public class GenericsHighlightUtil {
|
||||
"generics.methods.have.same.erasure.hide" :
|
||||
"generics.methods.have.same.erasure.override";
|
||||
String description = JavaErrorMessages.message(key, HighlightMethodUtil.createClashMethodMessage(method, superMethod, !sameClass));
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(textRange).descriptionAndTooltip(description).create();
|
||||
HighlightInfo info =
|
||||
HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(textRange).descriptionAndTooltip(description).create();
|
||||
QuickFixAction.registerQuickFixAction(info, QUICK_FIX_FACTORY.createSameErasureButDifferentMethodsFix(method, superMethod));
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
static HighlightInfo checkTypeParameterInstantiation(@NotNull PsiNewExpression expression) {
|
||||
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.codeInsight.intention.impl;
|
||||
|
||||
import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement;
|
||||
import com.intellij.openapi.application.TransactionGuard;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.JavaClassSupers;
|
||||
import com.intellij.psi.util.MethodSignature;
|
||||
import com.intellij.psi.util.MethodSignatureUtil;
|
||||
import com.intellij.refactoring.changeSignature.ChangeSignatureProcessor;
|
||||
import com.intellij.refactoring.changeSignature.ParameterInfoImpl;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
// @Override void f(List<String> p); -> @Override void f(List<? super String> p);
|
||||
public class SameErasureButDifferentMethodsFix extends LocalQuickFixAndIntentionActionOnPsiElement {
|
||||
private final SmartPsiElementPointer<PsiMethod> methodPtr;
|
||||
|
||||
public SameErasureButDifferentMethodsFix(@NotNull PsiMethod method, @NotNull PsiMethod superMethod) {
|
||||
super(superMethod);
|
||||
methodPtr = SmartPointerManager.getInstance(method.getProject()).createSmartPsiElementPointer(method);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project,
|
||||
@NotNull PsiFile file,
|
||||
@Nullable Editor editor,
|
||||
@NotNull PsiElement startElement,
|
||||
@NotNull PsiElement endElement) {
|
||||
if (!isAvailable(project, file, startElement, endElement)) return;
|
||||
PsiMethod superMethod = (PsiMethod)startElement;
|
||||
PsiMethod method = methodPtr.getElement();
|
||||
if (method == null || !method.isValid()) return;
|
||||
PsiClass containingClass = method.getContainingClass();
|
||||
PsiClass superContainingClass = superMethod.getContainingClass();
|
||||
if (containingClass == null || superContainingClass == null) return;
|
||||
PsiSubstitutor superSubstitutor = JavaClassSupers.getInstance()
|
||||
.getSuperClassSubstitutor(superContainingClass, containingClass, containingClass.getResolveScope(), PsiSubstitutor.EMPTY);
|
||||
if (superSubstitutor == null) return;
|
||||
|
||||
PsiParameter[] parameters = method.getParameterList().getParameters();
|
||||
PsiParameter[] superParameters = superMethod.getParameterList().getParameters();
|
||||
if (parameters.length != superParameters.length) return;
|
||||
ParameterInfoImpl[] infos = new ParameterInfoImpl[parameters.length];
|
||||
for (int i = 0; i < parameters.length; i++) {
|
||||
PsiParameter parameter = parameters[i];
|
||||
PsiParameter superParameter = superParameters[i];
|
||||
PsiType parameterType = parameter.getType();
|
||||
PsiType superParameterType = superSubstitutor.substitute(superParameter.getType());
|
||||
infos[i] = new ParameterInfoImpl(i, parameter.getName(), superParameterType);
|
||||
}
|
||||
|
||||
ChangeSignatureProcessor processor =
|
||||
new ChangeSignatureProcessor(project, method, false, null, method.getName(), method.getReturnType(), infos);
|
||||
|
||||
TransactionGuard.submitTransaction(project, processor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project,
|
||||
@NotNull PsiFile file,
|
||||
@NotNull PsiElement startElement,
|
||||
@NotNull PsiElement endElement) {
|
||||
PsiMethod superMethod = (PsiMethod)startElement;
|
||||
PsiMethod method = methodPtr.getElement();
|
||||
if (method == null || !method.isValid()) return false;
|
||||
JavaPsiFacade facade = JavaPsiFacade.getInstance(project);
|
||||
PsiClass containingClass = method.getContainingClass();
|
||||
PsiClass superContainingClass = superMethod.getContainingClass();
|
||||
if (containingClass == null || superContainingClass == null) return false;
|
||||
if (!facade.getResolveHelper().isAccessible(superMethod, containingClass, null)) return false;
|
||||
|
||||
MethodSignature signature = method.getSignature(PsiSubstitutor.EMPTY);
|
||||
PsiSubstitutor superSubstitutor = JavaClassSupers.getInstance()
|
||||
.getSuperClassSubstitutor(superContainingClass, containingClass, containingClass.getResolveScope(), PsiSubstitutor.EMPTY);
|
||||
if (superSubstitutor == null) return false;
|
||||
MethodSignature superSignature = superMethod.getSignature(superSubstitutor);
|
||||
if (method.getParameterList().getParametersCount() != superMethod.getParameterList().getParametersCount()) return false;
|
||||
return !signature.equals(superSignature) && MethodSignatureUtil.areSignaturesErasureEqual(signature, superSignature);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
PsiMethod method = methodPtr.getElement();
|
||||
if (method == null || !method.isValid()) return getFamilyName();
|
||||
return "Fix method '"+method.getName()+"' parameters with bounded wildcards";
|
||||
}
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return "Fix bounded wildcards";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startInWriteAction() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
+7
@@ -16,6 +16,7 @@ import com.intellij.codeInsight.intention.QuickFixFactory;
|
||||
import com.intellij.codeInsight.intention.impl.CreateClassInPackageInModuleFix;
|
||||
import com.intellij.codeInsight.intention.impl.ReplaceAssignmentWithComparisonFix;
|
||||
import com.intellij.codeInsight.intention.impl.RunRefactoringAction;
|
||||
import com.intellij.codeInsight.intention.impl.SameErasureButDifferentMethodsFix;
|
||||
import com.intellij.codeInspection.*;
|
||||
import com.intellij.codeInspection.deadCode.UnusedDeclarationInspectionBase;
|
||||
import com.intellij.codeInspection.ex.EntryPointsManagerBase;
|
||||
@@ -926,4 +927,10 @@ public class QuickFixFactoryImpl extends QuickFixFactory {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public IntentionAction createSameErasureButDifferentMethodsFix(@NotNull PsiMethod method, @NotNull PsiMethod superMethod) {
|
||||
return new SameErasureButDifferentMethodsFix(method, superMethod);
|
||||
}
|
||||
}
|
||||
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
// "Fix method 'foo' parameters with bounded wildcards" "true"
|
||||
import java.util.List;
|
||||
|
||||
interface Xo {
|
||||
void foo(List<? super String> s);
|
||||
}
|
||||
public class ErrWarn implements Xo {
|
||||
public void <caret>foo(List<? super String> s) {
|
||||
|
||||
}
|
||||
}
|
||||
class D extends ErrWarn {
|
||||
@Override
|
||||
public void foo(List<? super String> s) {
|
||||
super.foo(s);
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
// "Fix method 'foo' parameters with bounded wildcards" "true"
|
||||
import java.util.List;
|
||||
|
||||
interface Xo {
|
||||
void foo(List<? super String> s);
|
||||
}
|
||||
public class ErrWarn implements Xo {
|
||||
public void <caret>foo(List<String> s) {
|
||||
|
||||
}
|
||||
}
|
||||
class D extends ErrWarn {
|
||||
@Override
|
||||
public void foo(List<String> s) {
|
||||
super.foo(s);
|
||||
}
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.java.codeInsight.intention;
|
||||
|
||||
import com.intellij.codeInsight.daemon.LightIntentionActionTestCase;
|
||||
import com.intellij.refactoring.BaseRefactoringProcessor;
|
||||
|
||||
public class BoundedWildcardFixTest extends LightIntentionActionTestCase {
|
||||
@Override
|
||||
protected String getBasePath() {
|
||||
return "/codeInsight/daemonCodeAnalyzer/quickFix/boundedWildcard";
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doSingleTest(String fileSuffix, String testDataPath) {
|
||||
BaseRefactoringProcessor.ConflictsInTestsException.withIgnoredConflicts(()-> super.doSingleTest(fileSuffix, testDataPath));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user