mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-19 13:02:30 +07:00
check method signatures equality by erasure; do not check method names for constructors.
note that erasure of type parameter is erasure of its left bound (jls), so erasure (T extends A & B) != erasure (T extends B & A) e.g. IDEA-74409
This commit is contained in:
@@ -181,7 +181,7 @@ public class OverrideImplementUtil {
|
||||
for (final MethodImplementor implementor : getImplementors()) {
|
||||
for (final PsiMethod method : implementor.getMethodsToImplement(aClass)) {
|
||||
MethodSignature signature = MethodSignatureUtil.createMethodSignature(method.getName(), method.getParameterList(),
|
||||
method.getTypeParameterList(), PsiSubstitutor.EMPTY);
|
||||
method.getTypeParameterList(), PsiSubstitutor.EMPTY, method.isConstructor());
|
||||
CandidateInfo info = new CandidateInfo(method, PsiSubstitutor.EMPTY);
|
||||
result.put(signature, info);
|
||||
}
|
||||
@@ -679,7 +679,7 @@ public class OverrideImplementUtil {
|
||||
String name = prevBaseMethod.isConstructor() ? aClass.getName() : prevBaseMethod.getName();
|
||||
//Happens when aClass instanceof PsiAnonymousClass
|
||||
if (name != null) {
|
||||
MethodSignature signature = MethodSignatureUtil.createMethodSignature(name, prevBaseMethod.getParameterList(), prevBaseMethod.getTypeParameterList(), substitutor);
|
||||
MethodSignature signature = MethodSignatureUtil.createMethodSignature(name, prevBaseMethod.getParameterList(), prevBaseMethod.getTypeParameterList(), substitutor, prevBaseMethod.isConstructor());
|
||||
PsiMethod prevMethod = MethodSignatureUtil.findMethodBySignature(aClass, signature, false);
|
||||
if (prevMethod != null){
|
||||
return prevMethod.getNextSibling();
|
||||
@@ -692,7 +692,7 @@ public class OverrideImplementUtil {
|
||||
while(nextBaseMethod != null) {
|
||||
String name = nextBaseMethod.isConstructor() ? aClass.getName() : nextBaseMethod.getName();
|
||||
if (name != null) {
|
||||
MethodSignature signature = MethodSignatureUtil.createMethodSignature(name, nextBaseMethod.getParameterList(), nextBaseMethod.getTypeParameterList(), substitutor);
|
||||
MethodSignature signature = MethodSignatureUtil.createMethodSignature(name, nextBaseMethod.getParameterList(), nextBaseMethod.getTypeParameterList(), substitutor, nextBaseMethod.isConstructor());
|
||||
PsiMethod nextMethod = MethodSignatureUtil.findMethodBySignature(aClass, signature, false);
|
||||
if (nextMethod != null){
|
||||
return nextMethod;
|
||||
|
||||
@@ -62,28 +62,26 @@ public class PsiDocMethodOrFieldRef extends CompositePsiElement implements PsiDo
|
||||
}
|
||||
|
||||
public PsiReference getReference() {
|
||||
final PsiElement scope = getScope();
|
||||
final PsiClass scope = getScope();
|
||||
final PsiElement element = getNameElement();
|
||||
if (scope == null || element == null) return new MyReference(null);
|
||||
|
||||
PsiReference psiReference = getReferenceInScope(scope, element);
|
||||
if (psiReference != null) return psiReference;
|
||||
|
||||
if (scope instanceof PsiClass) {
|
||||
PsiClass classScope = ((PsiClass)scope);
|
||||
PsiClass containingClass = classScope.getContainingClass();
|
||||
while (containingClass != null) {
|
||||
classScope = containingClass;
|
||||
psiReference = getReferenceInScope(classScope, element);
|
||||
if (psiReference != null) return psiReference;
|
||||
containingClass = classScope.getContainingClass();
|
||||
}
|
||||
PsiClass classScope;
|
||||
PsiClass containingClass = scope.getContainingClass();
|
||||
while (containingClass != null) {
|
||||
classScope = containingClass;
|
||||
psiReference = getReferenceInScope(classScope, element);
|
||||
if (psiReference != null) return psiReference;
|
||||
containingClass = classScope.getContainingClass();
|
||||
}
|
||||
return new MyReference(null);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PsiReference getReferenceInScope(PsiElement scope, PsiElement element) {
|
||||
private PsiReference getReferenceInScope(PsiClass scope, PsiElement element) {
|
||||
final String name = element.getText();
|
||||
final String[] signature = getSignature();
|
||||
|
||||
@@ -108,7 +106,8 @@ public class PsiDocMethodOrFieldRef extends CompositePsiElement implements PsiDo
|
||||
}
|
||||
}
|
||||
methodSignature = MethodSignatureUtil.createMethodSignature(name, types.toArray(new PsiType[types.size()]),
|
||||
PsiTypeParameter.EMPTY_ARRAY, PsiSubstitutor.EMPTY);
|
||||
PsiTypeParameter.EMPTY_ARRAY, PsiSubstitutor.EMPTY,
|
||||
name.equals(scope.getName()));
|
||||
}
|
||||
else {
|
||||
methodSignature = null;
|
||||
@@ -187,13 +186,13 @@ public class PsiDocMethodOrFieldRef extends CompositePsiElement implements PsiDo
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PsiElement getScope(){
|
||||
private PsiClass getScope(){
|
||||
if (getFirstChildNode().getElementType() == ElementType.DOC_REFERENCE_HOLDER) {
|
||||
final PsiElement firstChildPsi = SourceTreeToPsiMap.treeElementToPsi(getFirstChildNode().getFirstChildNode());
|
||||
if (firstChildPsi instanceof PsiJavaCodeReferenceElement) {
|
||||
PsiJavaCodeReferenceElement referenceElement = (PsiJavaCodeReferenceElement)firstChildPsi;
|
||||
final PsiElement referencedElement = referenceElement.resolve();
|
||||
if (referencedElement instanceof PsiClass) return referencedElement;
|
||||
if (referencedElement instanceof PsiClass) return (PsiClass)referencedElement;
|
||||
return null;
|
||||
}
|
||||
else if (firstChildPsi instanceof PsiKeyword) {
|
||||
|
||||
@@ -243,7 +243,8 @@ public class RenameJavaMethodProcessor extends RenameJavaMemberProcessor {
|
||||
MethodSignature oldSignature = method.getSignature(PsiSubstitutor.EMPTY);
|
||||
MethodSignature newSignature = MethodSignatureUtil.createMethodSignature(newName, oldSignature.getParameterTypes(),
|
||||
oldSignature.getTypeParameters(),
|
||||
oldSignature.getSubstitutor());
|
||||
oldSignature.getSubstitutor(),
|
||||
method.isConstructor());
|
||||
for (PsiClass inheritor : inheritors) {
|
||||
PsiSubstitutor superSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(containingClass, inheritor, PsiSubstitutor.EMPTY);
|
||||
final PsiMethod[] methodsByName = inheritor.findMethodsByName(newName, false);
|
||||
|
||||
@@ -16,9 +16,20 @@
|
||||
import java.io.*;
|
||||
class Test {
|
||||
interface InterfA {
|
||||
<error descr="'foo(T)' is already defined in 'Test.InterfA'"><T extends Cloneable & Iterable> void foo(T x)</error>;
|
||||
<T extends Cloneable & Iterable> void foo(T x);
|
||||
|
||||
<error descr="'foo(T)' is already defined in 'Test.InterfA'"><T extends Iterable & Cloneable> void foo(T x)</error>;
|
||||
<T extends Iterable & Cloneable> void foo(T x);
|
||||
}
|
||||
|
||||
class ANotSame {
|
||||
<T extends Cloneable & Iterable> void foo(T x){}
|
||||
|
||||
<T extends Iterable & Cloneable> void foo(T x){}
|
||||
}
|
||||
|
||||
class BNotSame extends ANotSame {
|
||||
@Override
|
||||
<T extends Cloneable & Iterable> void foo(T x){}
|
||||
}
|
||||
|
||||
abstract class A<T extends Throwable> {
|
||||
|
||||
@@ -45,7 +45,7 @@ public class MethodSignatureUtil {
|
||||
public static final TObjectHashingStrategy<MethodSignature> METHOD_PARAMETERS_ERASURE_EQUALITY =
|
||||
new TObjectHashingStrategy<MethodSignature>() {
|
||||
public int computeHashCode(final MethodSignature signature) {
|
||||
int result = signature.getName().hashCode();
|
||||
int result = signature.isConstructor() ? 0 : signature.getName().hashCode();
|
||||
|
||||
PsiType[] parameterTypes = signature.getParameterTypes();
|
||||
result += 37 * parameterTypes.length;
|
||||
@@ -58,7 +58,8 @@ public class MethodSignatureUtil {
|
||||
}
|
||||
|
||||
public boolean equals(MethodSignature method1, MethodSignature method2) {
|
||||
if (!method1.getName().equals(method2.getName())) return false;
|
||||
if (method1.isConstructor() != method2.isConstructor()) return false;
|
||||
if (!method1.isConstructor() && !method1.getName().equals(method2.getName())) return false;
|
||||
final PsiType[] parameterTypes1 = method1.getParameterTypes();
|
||||
final PsiType[] parameterTypes2 = method2.getParameterTypes();
|
||||
if (parameterTypes1.length != parameterTypes2.length) return false;
|
||||
@@ -122,6 +123,7 @@ public class MethodSignatureUtil {
|
||||
final MethodSignature superSignature,
|
||||
final PsiSubstitutor unifyingSubstitutor) {
|
||||
if (unifyingSubstitutor == null) return false;
|
||||
if (!METHOD_PARAMETERS_ERASURE_EQUALITY.equals(subSignature, superSignature)) return false;
|
||||
|
||||
final PsiType[] subParameterTypes = subSignature.getParameterTypes();
|
||||
final PsiType[] superParameterTypes = superSignature.getParameterTypes();
|
||||
|
||||
@@ -62,7 +62,7 @@ public class PsiSuperMethodUtil {
|
||||
PsiClass superClass = containingClass.getSuperClass();
|
||||
if (superClass != null) {
|
||||
MethodSignature defConstructor = MethodSignatureUtil.createMethodSignature(superClass.getName(), PsiType.EMPTY_ARRAY,
|
||||
PsiTypeParameter.EMPTY_ARRAY, PsiSubstitutor.EMPTY);
|
||||
PsiTypeParameter.EMPTY_ARRAY, PsiSubstitutor.EMPTY, true);
|
||||
return MethodSignatureUtil.findMethodBySignature(superClass, defConstructor, false);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user