[java-highlighting] Fixes after review (IJ-CR-14615)

GitOrigin-RevId: 16f2532fa7f7ed391da553022c3dce685b823571
This commit is contained in:
Andrey.Cherkasov
2021-10-19 23:43:32 +03:00
committed by intellij-monorepo-bot
parent b66443e58e
commit 1922f00a54
13 changed files with 60 additions and 35 deletions

View File

@@ -412,8 +412,7 @@ seal.class.from.permits.list.fix=Seal inheritor
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
make.annotation.applicable.to.0.fix=Make annotation applicable to {0}
merge.duplicate.attributes.family=Merge duplicate attributes

View File

@@ -3,58 +3,65 @@ package com.intellij.codeInsight.daemon.impl.quickfix;
import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.codeInsight.daemon.QuickFixBundle;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInsight.intention.AddAnnotationPsiFix;
import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class AddAnnotationTargetFix implements IntentionAction {
@NotNull private final PsiAnnotation myAnnotation;
public class AddAnnotationTargetFix extends LocalQuickFixAndIntentionActionOnPsiElement {
@NotNull private final PsiAnnotation.TargetType myTarget;
public AddAnnotationTargetFix(@NotNull PsiAnnotation annotation, @NotNull PsiAnnotation.TargetType target) {
myAnnotation = annotation;
super(annotation);
myTarget = target;
}
@Override
public @NotNull String getText() {
return QuickFixBundle.message("add.annotation.target.fix", myTarget);
return QuickFixBundle.message("make.annotation.applicable.to.0.fix",
StringUtil.toLowerCase(myTarget.toString()).replace('_', ' ') + 's');
}
@Override
public @NotNull String getFamilyName() {
return QuickFixBundle.message("add.annotation.target.family");
return getText();
}
@Override
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
return true;
}
@Override
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
final PsiClass annotationType = myAnnotation.resolveAnnotationType();
public void invoke(@NotNull Project project,
@NotNull PsiFile file,
@Nullable Editor editor,
@NotNull PsiElement startElement,
@NotNull PsiElement endElement) {
PsiClass annotationType = ((PsiAnnotation)startElement).resolveAnnotationType();
if (annotationType == null) return;
final PsiModifierList modifierList = annotationType.getModifierList();
PsiModifierList modifierList = annotationType.getModifierList();
if (modifierList == null) return;
final PsiAnnotation annotation = modifierList.findAnnotation(CommonClassNames.JAVA_LANG_ANNOTATION_TARGET);
if (annotation == null) return;
final PsiNameValuePair attribute = AnnotationUtil.findDeclaredAttribute(annotation, null);
PsiAnnotation targetAnnotation = modifierList.findAnnotation(CommonClassNames.JAVA_LANG_ANNOTATION_TARGET);
String targetText = "java.lang.annotation.ElementType." + myTarget;
PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
if (targetAnnotation == null) {
final PsiAnnotation newAnnotation = factory.createAnnotationFromText("@Target(" + targetText + ")", annotationType);
AddAnnotationPsiFix fix = new AddAnnotationPsiFix(CommonClassNames.JAVA_LANG_ANNOTATION_TARGET, annotationType,
newAnnotation.getParameterList().getAttributes());
fix.invoke(project, file, annotationType, annotationType);
return;
}
PsiNameValuePair attribute = AnnotationUtil.findDeclaredAttribute(targetAnnotation, null);
if (attribute == null) return;
PsiAnnotationMemberValue value = attribute.getValue();
if (value == null) return;
if (!(value instanceof PsiArrayInitializerMemberValue)) {
PsiAnnotation dummyAnnotation =
JavaPsiFacade.getElementFactory(project).createAnnotationFromText("@A({" + value.getText() + "})", null);
final PsiAnnotationMemberValue wrappedValue = dummyAnnotation.getParameterList().getAttributes()[0].getValue();
value = annotation.setDeclaredAttributeValue("value", wrappedValue);
PsiAnnotation dummyAnnotation = factory.createAnnotationFromText("@A({" + value.getText() + "})", null);
PsiAnnotationMemberValue dummyValue = dummyAnnotation.getParameterList().getAttributes()[0].getValue();
value = targetAnnotation.setDeclaredAttributeValue(PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME, dummyValue);
}
final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
final PsiExpression expression = factory.createExpressionFromText("java.lang.annotation.ElementType." + myTarget, value);
PsiExpression expression = factory.createExpressionFromText(targetText, value);
JavaCodeStyleManager.getInstance(project).shortenClassReferences(expression);
value.addAfter(expression, value.getFirstChild());
}

View File

@@ -1,4 +1,4 @@
// "Add the 'FIELD' target" "true"
// "Make annotation applicable to fields" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;

View File

@@ -1,4 +1,4 @@
// "Add the 'FIELD' target" "true"
// "Make annotation applicable to fields" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;

View File

@@ -1,4 +1,4 @@
// "Add the 'FIELD' target" "true"
// "Make annotation applicable to fields" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;

View File

@@ -1,4 +1,4 @@
// "Add the 'FIELD' target" "true"
// "Make annotation applicable to fields" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;

View File

@@ -0,0 +1,11 @@
// "Make annotation applicable to type uses" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
import java.util.List;
@Target(ElementType.TYPE_USE)
@interface Foo {}
class Main {
List<@Foo Integer> answers = List.of(42);
}

View File

@@ -1,4 +1,4 @@
// "Add the 'FIELD' target" "false"
// "Make annotation applicable to fields" "false"
class Main {
@Override<caret> int x = 42;
}

View File

@@ -1,4 +1,4 @@
// "Add the 'FIELD' target" "true"
// "Make annotation applicable to fields" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;

View File

@@ -1,4 +1,4 @@
// "Add the 'FIELD' target" "true"
// "Make annotation applicable to fields" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;

View File

@@ -1,4 +1,4 @@
// "Add the 'FIELD' target" "true"
// "Make annotation applicable to fields" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;

View File

@@ -1,4 +1,4 @@
// "Add the 'FIELD' target" "true"
// "Make annotation applicable to fields" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;

View File

@@ -0,0 +1,8 @@
// "Make annotation applicable to type uses" "true"
import java.util.List;
@interface Foo {}
class Main {
List<@Foo<caret> Integer> answers = List.of(42);
}