mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-05-06 05:10:22 +07:00
[java-highlighting] Provide fixes for the "Duplicate attribute" error (IDEA-216119)
GitOrigin-RevId: ae3db3461abcfa2578b50657ec99dc51b0bbd699
This commit is contained in:
committed by
intellij-monorepo-bot
parent
1a10d8214d
commit
7815b148f2
@@ -547,4 +547,7 @@ public abstract class QuickFixFactory {
|
||||
public abstract IntentionAction createDeleteDefaultFix(@NotNull PsiFile file, @Nullable Object highlightInfo);
|
||||
|
||||
public abstract @NotNull IntentionAction createAddAnnotationTargetFix(@NotNull PsiAnnotation annotation, PsiAnnotation.TargetType target);
|
||||
|
||||
@Nullable
|
||||
public abstract IntentionAction createMergeDuplicateAttributesFix(@NotNull PsiNameValuePair pair);
|
||||
}
|
||||
@@ -104,7 +104,11 @@ public final class AnnotationsHighlightUtil {
|
||||
if (Objects.equals(attribute.getName(), name)) {
|
||||
String description = JavaErrorBundle.message("annotation.duplicate.attribute",
|
||||
name == null ? PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME : name);
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(pair).descriptionAndTooltip(description).create();
|
||||
HighlightInfo info =
|
||||
HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(pair).descriptionAndTooltip(description).create();
|
||||
QuickFixAction.registerQuickFixAction(info, QUICK_FIX_FACTORY.createDeleteFix(pair));
|
||||
QuickFixAction.registerQuickFixAction(info, QUICK_FIX_FACTORY.createMergeDuplicateAttributesFix(pair));
|
||||
return info;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -680,7 +684,7 @@ public final class AnnotationsHighlightUtil {
|
||||
PsiClass container = getRepeatableContainer(annotation);
|
||||
if (container == null) return null;
|
||||
|
||||
PsiMethod[] methods = !container.isAnnotationType() ? PsiMethod.EMPTY_ARRAY
|
||||
PsiMethod[] methods = !container.isAnnotationType() ? PsiMethod.EMPTY_ARRAY
|
||||
: container.findMethodsByName("value", false);
|
||||
if (methods.length == 0) {
|
||||
return JavaErrorBundle.message("annotation.container.no.value", container.getQualifiedName());
|
||||
@@ -709,11 +713,11 @@ public final class AnnotationsHighlightUtil {
|
||||
if (repeatableTargets.contains(containerTarget)) {
|
||||
continue;
|
||||
}
|
||||
if (containerTarget == PsiAnnotation.TargetType.ANNOTATION_TYPE &&
|
||||
if (containerTarget == PsiAnnotation.TargetType.ANNOTATION_TYPE &&
|
||||
(repeatableTargets.contains(PsiAnnotation.TargetType.TYPE) || repeatableTargets.contains(PsiAnnotation.TargetType.TYPE_USE))) {
|
||||
continue;
|
||||
}
|
||||
if ((containerTarget == PsiAnnotation.TargetType.TYPE || containerTarget == PsiAnnotation.TargetType.TYPE_PARAMETER) &&
|
||||
if ((containerTarget == PsiAnnotation.TargetType.TYPE || containerTarget == PsiAnnotation.TargetType.TYPE_PARAMETER) &&
|
||||
repeatableTargets.contains(PsiAnnotation.TargetType.TYPE_USE)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -413,4 +413,6 @@ unwrap.array.initializer.fix=Replace array initializer with its element
|
||||
replace.with.type.pattern.fix=Replace with type pattern
|
||||
|
||||
add.annotation.target.fix=Add the ''{0}'' target
|
||||
add.annotation.target.family=Add annotation target
|
||||
add.annotation.target.family=Add annotation target
|
||||
|
||||
merge.duplicate.attributes.family=Merge duplicate attributes
|
||||
@@ -0,0 +1,78 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. and contributors. 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.daemon.impl.quickfix;
|
||||
|
||||
import com.intellij.codeInsight.daemon.QuickFixBundle;
|
||||
import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtil;
|
||||
import com.siyeh.ig.psiutils.CommentTracker;
|
||||
import one.util.streamex.StreamEx;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
public class MergeDuplicateAttributesFix extends LocalQuickFixAndIntentionActionOnPsiElement {
|
||||
public MergeDuplicateAttributesFix(PsiElement element) {
|
||||
super(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project,
|
||||
@NotNull PsiFile file,
|
||||
@Nullable Editor editor,
|
||||
@NotNull PsiElement startElement,
|
||||
@NotNull PsiElement endElement) {
|
||||
final PsiNameValuePair pair = (PsiNameValuePair)startElement;
|
||||
final PsiAnnotationParameterList parameterList = (PsiAnnotationParameterList)pair.getParent();
|
||||
final PsiNameValuePair[] attributes = parameterList.getAttributes();
|
||||
final StringJoiner joiner = new StringJoiner(", ");
|
||||
final String name = pair.getName();
|
||||
final boolean[] isFirstValue = {true};
|
||||
StreamEx.of(attributes).filterBy(PsiNameValuePair::getName, name).map(attribute -> attribute.getValue()).filter(Objects::nonNull)
|
||||
.forEach(value -> {
|
||||
CommentTracker ct = new CommentTracker();
|
||||
if (value instanceof PsiArrayInitializerMemberValue) {
|
||||
if (((PsiArrayInitializerMemberValue)value).getInitializers().length == 0 && !isFirstValue[0]) {
|
||||
new CommentTracker().deleteAndRestoreComments(value.getParent());
|
||||
return;
|
||||
}
|
||||
else {
|
||||
final PsiElement lBrace = value.getFirstChild();
|
||||
final PsiElement lastChild = value.getLastChild();
|
||||
PsiElement maybeTrailingComma = PsiTreeUtil.skipWhitespacesAndCommentsBackward(lastChild);
|
||||
if (PsiUtil.isJavaToken(maybeTrailingComma, JavaTokenType.COMMA)) {
|
||||
maybeTrailingComma = maybeTrailingComma.getPrevSibling();
|
||||
}
|
||||
if (maybeTrailingComma == null) return;
|
||||
joiner.add(ct.rangeText(lBrace.getNextSibling(), maybeTrailingComma));
|
||||
}
|
||||
}
|
||||
else {
|
||||
joiner.add(value.getText());
|
||||
}
|
||||
if (!isFirstValue[0]) {
|
||||
ct.deleteAndRestoreComments(value.getParent());
|
||||
}
|
||||
isFirstValue[0] = false;
|
||||
});
|
||||
final PsiAnnotation dummyAnnotation = JavaPsiFacade.getElementFactory(project).createAnnotationFromText("@A({" + joiner + "})", null);
|
||||
final PsiAnnotationMemberValue mergedValue = dummyAnnotation.getParameterList().getAttributes()[0].getValue();
|
||||
final PsiAnnotation annotation = (PsiAnnotation)parameterList.getParent();
|
||||
annotation.setDeclaredAttributeValue(pair.getName(), mergedValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getText() {
|
||||
return getFamilyName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull String getFamilyName() {
|
||||
return QuickFixBundle.message("merge.duplicate.attributes.family");
|
||||
}
|
||||
}
|
||||
@@ -48,6 +48,7 @@ import com.intellij.psi.util.PropertyMemberType;
|
||||
import com.intellij.refactoring.memberPushDown.JavaPushDownHandler;
|
||||
import com.intellij.util.DocumentUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.ObjectUtils;
|
||||
import com.siyeh.ig.controlflow.UnnecessaryDefaultInspection;
|
||||
import com.siyeh.ig.fixes.CreateDefaultBranchFix;
|
||||
import com.siyeh.ig.fixes.CreateEnumMissingSwitchBranchesFix;
|
||||
@@ -1112,4 +1113,16 @@ public final class QuickFixFactoryImpl extends QuickFixFactory {
|
||||
@NotNull PsiAnnotation.TargetType target) {
|
||||
return new AddAnnotationTargetFix(annotation, target);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public IntentionAction createMergeDuplicateAttributesFix(@NotNull PsiNameValuePair pair) {
|
||||
final PsiReference reference = pair.getReference();
|
||||
if (reference == null) return null;
|
||||
final PsiMethod resolved = ObjectUtils.tryCast(reference.resolve(), PsiMethod.class);
|
||||
if (resolved == null) return null;
|
||||
final PsiType returnType = resolved.getReturnType();
|
||||
if (!(returnType instanceof PsiArrayType)) return null;
|
||||
return new MergeDuplicateAttributesFix(pair);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
// "Merge duplicate attributes" "true"
|
||||
@SuppressWarnings(value= {"a", "b", "c"})
|
||||
class Main { }
|
||||
@@ -0,0 +1,3 @@
|
||||
// "Merge duplicate attributes" "true"
|
||||
@SuppressWarnings(/*1*/value/*2*/=/*3*/{"a", "b", /*12*/"c"/*13*/, /*14*/"d"/*15*/}/*4*/ /*5*//*6*//*7*//*8*/ /*9*//*10*//*11*//*16*//*17*/)
|
||||
class Main { }
|
||||
@@ -0,0 +1,3 @@
|
||||
// "Merge duplicate attributes" "true"
|
||||
@SuppressWarnings(value= {"a", "b", "c"})
|
||||
class Main { }
|
||||
@@ -0,0 +1,3 @@
|
||||
// "Merge duplicate attributes" "true"
|
||||
@SuppressWarnings(value= {"a", "b", "c"})
|
||||
class Main { }
|
||||
@@ -0,0 +1,3 @@
|
||||
// "Merge duplicate attributes" "true"
|
||||
@SuppressWarnings(value= {"a", "b", "c"})
|
||||
class Main { }
|
||||
@@ -0,0 +1,3 @@
|
||||
// "Merge duplicate attributes" "true"
|
||||
@SuppressWarnings(value= {"a", "b", "c"})
|
||||
class Main { }
|
||||
@@ -0,0 +1,3 @@
|
||||
// "Merge duplicate attributes" "true"
|
||||
@SuppressWarnings(value={"a"}, value={"b"}<caret>, value={"c"})
|
||||
class Main { }
|
||||
@@ -0,0 +1,3 @@
|
||||
// "Merge duplicate attributes" "true"
|
||||
@SuppressWarnings(/*1*/value/*2*/=/*3*/"a"/*4*/, /*5*/value/*6*/=/*7*/"b"/*8*/, /*9*/value/*10*/=/*11*/{/*12*/"c"/*13*/, /*14*/"d"/*15*/, /*16*/<caret>}/*17*/)
|
||||
class Main { }
|
||||
@@ -0,0 +1,3 @@
|
||||
// "Merge duplicate attributes" "true"
|
||||
@SuppressWarnings(value={"a"}, value="b"<caret>, value={"c"})
|
||||
class Main { }
|
||||
@@ -0,0 +1,3 @@
|
||||
// "Merge duplicate attributes" "true"
|
||||
@SuppressWarnings(value="a", value={"b"}<caret>, value="c")
|
||||
class Main { }
|
||||
@@ -0,0 +1,3 @@
|
||||
// "Merge duplicate attributes" "false"
|
||||
@Deprecated(since = "1.2", since = "1.2"<caret>)
|
||||
class Main { }
|
||||
@@ -0,0 +1,3 @@
|
||||
// "Merge duplicate attributes" "true"
|
||||
@SuppressWarnings(value="a", value="b"<caret>, value="c")
|
||||
class Main { }
|
||||
@@ -0,0 +1,3 @@
|
||||
// "Merge duplicate attributes" "true"
|
||||
@SuppressWarnings(value={"a",}, value={"b", }<caret>, value={"c", })
|
||||
class Main { }
|
||||
@@ -0,0 +1,3 @@
|
||||
// "Remove element" "true"
|
||||
@SuppressWarnings(value = "1")
|
||||
class Main { }
|
||||
@@ -0,0 +1,3 @@
|
||||
// "Remove element" "true"
|
||||
@SuppressWarnings(value = "1", value = "2"<caret>)
|
||||
class Main { }
|
||||
@@ -0,0 +1,12 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. and contributors. 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.daemon.quickFix;
|
||||
|
||||
import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase;
|
||||
|
||||
public class MergeDuplicateAttributesFixTest extends LightQuickFixParameterizedTestCase {
|
||||
|
||||
@Override
|
||||
protected String getBasePath() {
|
||||
return "/codeInsight/daemonCodeAnalyzer/quickFix/mergeDuplicates";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user