mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
fix annotation matching in duplicates finder
This commit is contained in:
+2
-19
@@ -15,6 +15,7 @@
|
||||
*/
|
||||
package com.intellij.refactoring.util.duplicates;
|
||||
|
||||
import com.intellij.codeInsight.AnnotationUtil;
|
||||
import com.intellij.codeInsight.PsiEquivalenceUtil;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
@@ -30,7 +31,6 @@ import com.intellij.refactoring.extractMethod.InputVariables;
|
||||
import com.intellij.refactoring.util.RefactoringChangeUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.IntArrayList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -556,24 +556,7 @@ public class DuplicatesFinder {
|
||||
}
|
||||
}
|
||||
}
|
||||
final List<PsiAnnotation> annotations1 = ContainerUtil.newArrayList(modifierList1.getAnnotations());
|
||||
final List<PsiAnnotation> annotations2 = ContainerUtil.newArrayList(modifierList2.getAnnotations());
|
||||
annotations1.removeIf(a -> CommonClassNames.JAVA_LANG_OVERRIDE.equals(a.getQualifiedName()));
|
||||
annotations2.removeIf(a -> CommonClassNames.JAVA_LANG_OVERRIDE.equals(a.getQualifiedName()));
|
||||
if (annotations1.size() != annotations2.size()) {
|
||||
return false;
|
||||
}
|
||||
for (final Iterator<PsiAnnotation> iterator = annotations1.iterator(); iterator.hasNext(); ) {
|
||||
final PsiAnnotation annotation1 = iterator.next();
|
||||
for (final Iterator<PsiAnnotation> iterator2 = annotations2.iterator(); iterator2.hasNext(); ) {
|
||||
final PsiAnnotation annotation2 = iterator2.next();
|
||||
if (PsiEquivalenceUtil.areElementsEquivalent(annotation1, annotation2)) {
|
||||
iterator.remove();
|
||||
iterator2.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
return AnnotationUtil.equal(modifierList1.getAnnotations(), modifierList2.getAnnotations());
|
||||
}
|
||||
|
||||
private static boolean checkParameterModification(PsiExpression expression,
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.intellij.util.Processor;
|
||||
import com.intellij.util.Processors;
|
||||
import com.intellij.util.containers.ConcurrentFactoryMap;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import gnu.trove.THashMap;
|
||||
import gnu.trove.THashSet;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
@@ -573,4 +574,99 @@ public class AnnotationUtil {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static boolean equal(@Nullable PsiAnnotation a, @Nullable PsiAnnotation b) {
|
||||
if (a == null) {
|
||||
return b == null;
|
||||
}
|
||||
else if (b == null) {
|
||||
return false;
|
||||
}
|
||||
final String name = a.getQualifiedName();
|
||||
if (name == null || !name.equals(b.getQualifiedName())) {
|
||||
return false;
|
||||
}
|
||||
final Map<String, PsiAnnotationMemberValue> valueMap1 = new THashMap<String, PsiAnnotationMemberValue>(2);
|
||||
final Map<String, PsiAnnotationMemberValue> valueMap2 = new THashMap<String, PsiAnnotationMemberValue>(2);
|
||||
if (!fillValueMap(a.getParameterList(), valueMap1) || !fillValueMap(b.getParameterList(), valueMap2) ||
|
||||
valueMap1.size() != valueMap2.size()) {
|
||||
return false;
|
||||
}
|
||||
for (Map.Entry<String, PsiAnnotationMemberValue> entry : valueMap1.entrySet()) {
|
||||
if (!equal(entry.getValue(), valueMap2.get(entry.getKey()))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean fillValueMap(PsiAnnotationParameterList parameterList, Map<String, PsiAnnotationMemberValue> valueMap) {
|
||||
final PsiNameValuePair[] attributes1 = parameterList.getAttributes();
|
||||
for (PsiNameValuePair attribute : attributes1) {
|
||||
final PsiReference reference = attribute.getReference();
|
||||
if (reference == null) {
|
||||
return false;
|
||||
}
|
||||
final PsiElement target = reference.resolve();
|
||||
if (!(target instanceof PsiAnnotationMethod)) {
|
||||
return false;
|
||||
}
|
||||
final PsiAnnotationMethod annotationMethod = (PsiAnnotationMethod)target;
|
||||
final PsiAnnotationMemberValue defaultValue = annotationMethod.getDefaultValue();
|
||||
final PsiAnnotationMemberValue value = attribute.getValue();
|
||||
if (equal(value, defaultValue)) {
|
||||
continue;
|
||||
}
|
||||
final String name1 = attribute.getName();
|
||||
valueMap.put(name1 == null ? PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME : name1, value);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public static boolean equal(PsiAnnotationMemberValue value1, PsiAnnotationMemberValue value2) {
|
||||
if (value1 instanceof PsiArrayInitializerMemberValue && value2 instanceof PsiArrayInitializerMemberValue) {
|
||||
final PsiAnnotationMemberValue[] initializers1 = ((PsiArrayInitializerMemberValue)value1).getInitializers();
|
||||
final PsiAnnotationMemberValue[] initializers2 = ((PsiArrayInitializerMemberValue)value2).getInitializers();
|
||||
if (initializers1.length != initializers2.length) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < initializers1.length; i++) {
|
||||
if (!equal(initializers1[i], initializers2[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (value1 != null && value2 != null) {
|
||||
final PsiConstantEvaluationHelper constantEvaluationHelper =
|
||||
JavaPsiFacade.getInstance(value1.getProject()).getConstantEvaluationHelper();
|
||||
final Object const1 = constantEvaluationHelper.computeConstantExpression(value1);
|
||||
final Object const2 = constantEvaluationHelper.computeConstantExpression(value2);
|
||||
return const1 != null && const1.equals(const2);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean equal(PsiAnnotation[] annotations1, PsiAnnotation[] annotations2) {
|
||||
final Map<String, PsiAnnotation> map1 = buildAnnotationMap(annotations1);
|
||||
final Map<String, PsiAnnotation> map2 = buildAnnotationMap(annotations2);
|
||||
if (map1.size() != map2.size()) {
|
||||
return false;
|
||||
}
|
||||
for (Map.Entry<String, PsiAnnotation> entry : map1.entrySet()) {
|
||||
if (!equal(entry.getValue(), map2.get(entry.getKey()))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static Map<String, PsiAnnotation> buildAnnotationMap(PsiAnnotation[] annotations) {
|
||||
final Map<String, PsiAnnotation> map = new HashMap<String, PsiAnnotation>();
|
||||
for (PsiAnnotation annotation : annotations) {
|
||||
map.put(annotation.getQualifiedName(), annotation);
|
||||
}
|
||||
map.remove(CommonClassNames.JAVA_LANG_OVERRIDE);
|
||||
return map;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
class C {
|
||||
{
|
||||
@A int i = 0;
|
||||
System.out.println(i);
|
||||
}
|
||||
|
||||
void f() {
|
||||
<selection>@B int j = 0;
|
||||
System.out.println(j);</selection>
|
||||
}
|
||||
}
|
||||
@interface A {}
|
||||
@interface B {}
|
||||
@@ -0,0 +1,17 @@
|
||||
class C {
|
||||
{
|
||||
@A int i = 0;
|
||||
System.out.println(i);
|
||||
}
|
||||
|
||||
void f() {
|
||||
newMethod();
|
||||
}
|
||||
|
||||
private void newMethod() {
|
||||
@B int j = 0;
|
||||
System.out.println(j);
|
||||
}
|
||||
}
|
||||
@interface A {}
|
||||
@interface B {}
|
||||
@@ -0,0 +1,19 @@
|
||||
class C {
|
||||
{
|
||||
@A(value="asdf") int i = 0;
|
||||
System.out.println(i);
|
||||
}
|
||||
|
||||
void f() {
|
||||
<selection>@A int j = 0;
|
||||
System.out.println(j);</selection>
|
||||
}
|
||||
|
||||
void g() {
|
||||
@A("asdf") int k = 0;
|
||||
System.out.println(k);
|
||||
}
|
||||
}
|
||||
@interface A {
|
||||
String value() default "asdf";
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
class C {
|
||||
{
|
||||
newMethod();
|
||||
}
|
||||
|
||||
void f() {
|
||||
newMethod();
|
||||
}
|
||||
|
||||
private void newMethod() {
|
||||
@A int j = 0;
|
||||
System.out.println(j);
|
||||
}
|
||||
|
||||
void g() {
|
||||
newMethod();
|
||||
}
|
||||
}
|
||||
@interface A {
|
||||
String value() default "asdf";
|
||||
}
|
||||
@@ -864,7 +864,15 @@ public class ExtractMethodTest extends LightCodeInsightTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testLocalVariableAnnotationsOrder() throws Exception {
|
||||
public void testLocalVariableAnnotationsOrder() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testDifferentAnnotations() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testSameAnnotations() throws Exception {
|
||||
doTest();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user