[analysis] IDEA-241656 Provide a fix for "static member qualifying type may not be annotated"

This patch adds a quickfix for errors of the "static member qualifying type may not be annotated" type

Signed-off-by: Nikita Eshkeev <nikita.eshkeev@jetbrains.com>

GitOrigin-RevId: 9046c0c45d6a9d04058aae458f04b3f9fc0a5ad1
This commit is contained in:
Nikita Eshkeev
2020-06-08 09:05:53 +00:00
committed by intellij-monorepo-bot
parent 1ad538f097
commit 397638666d
53 changed files with 851 additions and 14 deletions
@@ -10,8 +10,12 @@ import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInsight.intention.QuickFixFactory;
import com.intellij.codeInsight.intention.impl.BaseIntentionAction;
import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement;
import com.intellij.codeInspection.util.IntentionFamilyName;
import com.intellij.codeInspection.util.IntentionName;
import com.intellij.java.analysis.JavaAnalysisBundle;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.patterns.ElementPattern;
import com.intellij.pom.java.LanguageLevel;
@@ -25,6 +29,7 @@ import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.ObjectUtils;
import com.siyeh.ig.psiutils.CommentTracker;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -395,34 +400,45 @@ public class AnnotationsHighlightUtil {
return null;
}
@Nullable
private static HighlightInfo annotationError(@NotNull PsiAnnotation annotation, @NotNull String message) {
HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(annotation).descriptionAndTooltip(message).create();
LocalQuickFixAndIntentionActionOnPsiElement fix =
QuickFixFactory.getInstance().createDeleteFix(annotation, JavaAnalysisBundle.message("intention.text.remove.annotation"));
return annotationError(annotation, message, fix);
}
@Nullable
private static HighlightInfo annotationError(@NotNull final PsiAnnotation annotation,
@NotNull final String message,
@NotNull final IntentionAction fix) {
final HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
.range(annotation)
.descriptionAndTooltip(message)
.create();
QuickFixAction.registerQuickFixAction(info, fix);
return info;
}
@Nullable
private static HighlightInfo checkReferenceTarget(@NotNull PsiAnnotation annotation, @Nullable PsiJavaCodeReferenceElement ref) {
if (ref == null) return null;
PsiElement refTarget = ref.resolve();
final PsiElement refTarget = ref.resolve();
if (refTarget == null) return null;
String message = null;
if (!(refTarget instanceof PsiClass)) {
message = JavaErrorBundle.message("annotation.not.allowed.ref");
}
else {
PsiElement parent = ref.getParent();
if (parent instanceof PsiJavaCodeReferenceElement) {
PsiElement qualified = ((PsiJavaCodeReferenceElement)parent).resolve();
if (qualified instanceof PsiMember && ((PsiMember)qualified).hasModifierProperty(PsiModifier.STATIC)) {
message = JavaErrorBundle.message("annotation.not.allowed.static");
}
}
return annotationError(annotation, JavaErrorBundle.message("annotation.not.allowed.ref"));
}
return message != null ? annotationError(annotation, message) : null;
final PsiElement parent = ref.getParent();
if (parent instanceof PsiJavaCodeReferenceElement) {
final PsiElement qualified = ((PsiJavaCodeReferenceElement)parent).resolve();
if (qualified instanceof PsiMember && ((PsiMember)qualified).hasModifierProperty(PsiModifier.STATIC)) {
return annotationError(annotation,
JavaErrorBundle.message("annotation.not.allowed.static"),
new MoveAnnotationOnStaticMemberQualifyingTypeFix(annotation));
}
}
return null;
}
@Contract("null->null; !null->!null")
@@ -755,4 +771,69 @@ public class AnnotationsHighlightUtil {
return classType.equalsToText(CommonClassNames.JAVA_LANG_CLASS) || classType.equalsToText(CommonClassNames.JAVA_LANG_STRING);
}
}
private static final class MoveAnnotationOnStaticMemberQualifyingTypeFix extends LocalQuickFixAndIntentionActionOnPsiElement {
private MoveAnnotationOnStaticMemberQualifyingTypeFix(@NotNull final PsiAnnotation annotation) {
super(annotation);
}
@Override
public @IntentionFamilyName @NotNull String getFamilyName() {
return JavaErrorBundle.message("annotation.on.static.member.qualifying.type.family.name");
}
@Override
public @IntentionName @NotNull String getText() {
return JavaErrorBundle.message("annotation.on.static.member.qualifying.type.family.name");
}
@Override
public void invoke(@NotNull final Project project,
@NotNull final PsiFile file,
@Nullable final Editor editor,
@NotNull final PsiElement startElement,
@NotNull final PsiElement endElement) {
final PsiTypeElement psiTypeElement = getTypeElement(startElement);
if (psiTypeElement == null) return;
final PsiJavaCodeReferenceElement innermostParent = psiTypeElement.getInnermostComponentReferenceElement();
if (innermostParent == null) return;
final PsiElement rightmostDot = getRightmostDot(innermostParent.getLastChild());
if (rightmostDot == null) return;
innermostParent.addAfter(startElement, rightmostDot);
final CommentTracker ct = new CommentTracker();
ct.markUnchanged(startElement);
ct.deleteAndRestoreComments(startElement);
}
@Nullable("The type does not have DOT tokens")
@Contract(value = "null -> null", pure = true)
private static PsiElement getRightmostDot(@Nullable final PsiElement element) {
if (element == null) return null;
if (element.getNode().getElementType().equals(JavaTokenType.DOT)) return element;
return getRightmostDot(element.getPrevSibling());
}
/**
* Returns the type element either from a type parameter or a variable declaration
*
* @param startElement element to find the type for
* @return the type element either from a type parameter or a variable declaration
*/
@Nullable("No type element found")
@Contract(pure = true)
private static PsiTypeElement getTypeElement(@NotNull final PsiElement startElement) {
final PsiTypeElement psiTypeElement = PsiTreeUtil.getParentOfType(startElement, PsiTypeElement.class);
if (psiTypeElement != null) return psiTypeElement;
final PsiVariable variable = PsiTreeUtil.getParentOfType(startElement, PsiVariable.class);
if (variable == null) return null;
return variable.getTypeElement();
}
}
}
@@ -463,3 +463,4 @@ repeated.interface=Repeated interface
class.cannot.be.inherited.with.different.arguments={0} cannot be inherited with different arguments: {1}
bad.type.in.switch.expression=Bad type in switch expression: {0} cannot be converted to {1}
switch.expression.cannot.be.void=Target type for switch expression cannot be void
annotation.on.static.member.qualifying.type.family.name=Move type annotation
@@ -0,0 +1,12 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface Meta { }
class Main {
public static class Data { }
static final /*1 */ /*2*/ /*5 *//*6 */ transient Main.@/* 3 */ /* 4*/ Meta Data var = null;
}
@@ -0,0 +1,14 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface Meta { }
class Main {
public static class Data { }
static {
final /*1 */ /*2*/ /*5 *//*6 */ synchronized transient Main.@/* 3 */ /* 4*/ Meta Data var = null;
}
}
@@ -0,0 +1,12 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface Meta { }
class Main {
public static class Data { }
void func(final /*1 */ /*2*/ /*5 *//*6 */ synchronized transient Main.@/* 3 */ /* 4*/ Meta Data var) { }
}
@@ -0,0 +1,12 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface Meta { }
class Generic<T> {}
class Main extends Generic</*1 */ /*2*/ /*5 *//*6 */ Main.@/* 3 */ /* 4*/ Meta Data> {
public static class Data { }
}
@@ -0,0 +1,14 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface First { }
@Target(ElementType.TYPE_USE)
@interface Second { }
class Main {
public static class Data { }
static final /*1 */ /*2*//*one*/ @/*two*/Second /*5 *//*6 */ transient Main.@/* 3 */ /* 4*/ First Data var = null;
}
@@ -0,0 +1,14 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface First { }
@Target(ElementType.TYPE_USE)
@interface Second { }
class Main {
public static class Data { }
static final /*1 */ /*2*/@/* 3 */ /* 4*/ First/*one*/ /*5 *//*6 */ transient Main.@/*two*/Second Data var = null;
}
@@ -0,0 +1,16 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface First { }
@Target(ElementType.TYPE_USE)
@interface Second { }
class Main {
public static class Data { }
static {
final /*1 */ /*2*//*one*/ @/*two*/Second /*5 *//*6 */ synchronized transient Main.@/* 3 */ /* 4*/ First Data var = null;
}
}
@@ -0,0 +1,16 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface First { }
@Target(ElementType.TYPE_USE)
@interface Second { }
class Main {
public static class Data { }
static {
final /*1 */ /*2*/@/* 3 */ /* 4*/ First/*one*/ /*5 *//*6 */ synchronized transient Main.@/*two*/Second Data var = null;
}
}
@@ -0,0 +1,14 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface First { }
@Target(ElementType.TYPE_USE)
@interface Second { }
class Main {
public static class Data { }
void func(final /*1 */ /*2*//*one*/ @/*two*/Second /*5 *//*6 */ synchronized transient Main.@/* 3 */ /* 4*/ First Data var) { }
}
@@ -0,0 +1,14 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface First { }
@Target(ElementType.TYPE_USE)
@interface Second { }
class Main {
public static class Data { }
void func(final /*1 */ /*2*/@/* 3 */ /* 4*/ First/*one*/ /*5 *//*6 */ synchronized transient Main.@/*two*/Second Data var) { }
}
@@ -0,0 +1,14 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface First { }
@Target(ElementType.TYPE_USE)
@interface Second { }
class Generic<T> {}
class Main extends Generic</*1 */ /*2*//*one*/ @/*two*/Second /*5 *//*6 */ Main.@/* 3 */ /* 4*/ First Data> {
public static class Data { }
}
@@ -0,0 +1,14 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface First { }
@Target(ElementType.TYPE_USE)
@interface Second { }
class Generic<T> {}
class Main extends Generic</*1 */ /*2*/@/* 3 */ /* 4*/ First/*one*/ /*5 *//*6 */ Main.@/*two*/Second Data> {
public static class Data { }
}
@@ -0,0 +1,14 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface Meta { }
class Main {
public static class Data {
public static class Nested { }
}
static final /*1 */ /*2*/ /*5 *//*6 */ transient Main.Data.@/* 3 */ /* 4*/ Meta Nested var = null;
}
@@ -0,0 +1,16 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface Meta { }
class Main {
public static class Data {
public static class Nested { }
}
static {
final /*1 */ /*2*/ /*5 *//*6 */ synchronized transient Main.Data.@/* 3 */ /* 4*/ Meta Nested var = null;
}
}
@@ -0,0 +1,14 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface Meta { }
class Main {
public static class Data {
public static class Nested { }
}
void func(final /*1 */ /*2*/ /*5 *//*6 */ synchronized transient Main.Data.@/* 3 */ /* 4*/ Meta Nested var) { }
}
@@ -0,0 +1,14 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface Meta { }
class Generic<T> {}
class Main extends Generic</*1 */ /*2*/ /*5 *//*6 */ Main.Data.@/* 3 */ /* 4*/ Meta Nested> {
public static class Data {
public static class Nested { }
}
}
@@ -0,0 +1,16 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface First { }
@Target(ElementType.TYPE_USE)
@interface Second { }
class Main {
public static class Data {
public static class Nested { }
}
static final /*1 */ /*2*//*one*/ @/*two*/Second /*5 *//*6 */ transient Main.Data.@/* 3 */ /* 4*/ First Nested var = null;
}
@@ -0,0 +1,16 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface First { }
@Target(ElementType.TYPE_USE)
@interface Second { }
class Main {
public static class Data {
public static class Nested { }
}
static final /*1 */ /*2*/@/* 3 */ /* 4*/ First/*one*/ /*5 *//*6 */ transient Main.Data.@/*two*/Second Nested var = null;
}
@@ -0,0 +1,18 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface First { }
@Target(ElementType.TYPE_USE)
@interface Second { }
class Main {
public static class Data {
public static class Nested { }
}
static {
final /*1 */ /*2*//*one*/ @/*two*/Second /*5 *//*6 */ synchronized transient Main.Data.@/* 3 */ /* 4*/ First Nested var = null;
}
}
@@ -0,0 +1,18 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface First { }
@Target(ElementType.TYPE_USE)
@interface Second { }
class Main {
public static class Data {
public static class Nested { }
}
static {
final /*1 */ /*2*/@/* 3 */ /* 4*/ First/*one*/ /*5 *//*6 */ synchronized transient Main.Data.@/*two*/Second Nested var = null;
}
}
@@ -0,0 +1,16 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface First { }
@Target(ElementType.TYPE_USE)
@interface Second { }
class Main {
public static class Data {
public static class Nested { }
}
void func(final /*1 */ /*2*//*one*/ @/*two*/Second /*5 *//*6 */ synchronized transient Main.Data.@/* 3 */ /* 4*/ First Nested var) { }
}
@@ -0,0 +1,16 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface First { }
@Target(ElementType.TYPE_USE)
@interface Second { }
class Main {
public static class Data {
public static class Nested { }
}
void func(final /*1 */ /*2*/@/* 3 */ /* 4*/ First/*one*/ /*5 *//*6 */ synchronized transient Main.Data.@/*two*/Second Nested var) { }
}
@@ -0,0 +1,16 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface First { }
@Target(ElementType.TYPE_USE)
@interface Second { }
class Generic<T> {}
class Main extends Generic</*1 */ /*2*//*one*/ @/*two*/Second /*5 *//*6 */ Main.Data.@/* 3 */ /* 4*/ First Nested> {
public static class Data {
public static class Nested { }
}
}
@@ -0,0 +1,16 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface First { }
@Target(ElementType.TYPE_USE)
@interface Second { }
class Generic<T> {}
class Main extends Generic</*1 */ /*2*/@/* 3 */ /* 4*/ First/*one*/ /*5 *//*6 */ Main.Data.@/*two*/Second Nested> {
public static class Data {
public static class Nested { }
}
}
@@ -0,0 +1,16 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface Meta { }
class Generic<T> {}
class Main extends Generic</*1 */ /*2*/ /*5 *//*6 */ Main.Data.Nested.@/* 3 */ /* 4*/ Meta Inner> {
public static class Data {
public static class Nested {
public static class Inner { }
}
}
}
@@ -0,0 +1,12 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface Meta { }
class Main {
public static class Data { }
static final /*1 */ /*2*/@<caret>/* 3 */ /* 4*/ Meta /*5 *//*6 */ transient Main.Data var = null;
}
@@ -0,0 +1,14 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface Meta { }
class Main {
public static class Data { }
static {
final /*1 */ /*2*/@<caret>/* 3 */ /* 4*/ Meta /*5 *//*6 */ synchronized transient Main.Data var = null;
}
}
@@ -0,0 +1,12 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface Meta { }
class Main {
public static class Data { }
void func(final /*1 */ /*2*/@<caret>/* 3 */ /* 4*/ Meta /*5 *//*6 */ synchronized transient Main.Data var) { }
}
@@ -0,0 +1,12 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface Meta { }
class Generic<T> {}
class Main extends Generic</*1 */ /*2*/@<caret>/* 3 */ /* 4*/ Meta /*5 *//*6 */ Main.Data> {
public static class Data { }
}
@@ -0,0 +1,14 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface First { }
@Target(ElementType.TYPE_USE)
@interface Second { }
class Main {
public static class Data { }
static final /*1 */ /*2*/@<caret>/* 3 */ /* 4*/ First/*one*/ @/*two*/Second /*5 *//*6 */ transient Main.Data var = null;
}
@@ -0,0 +1,14 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface First { }
@Target(ElementType.TYPE_USE)
@interface Second { }
class Main {
public static class Data { }
static final /*1 */ /*2*/@/* 3 */ /* 4*/ First/*one*/ @/*two*/<caret>Second /*5 *//*6 */ transient Main.Data var = null;
}
@@ -0,0 +1,16 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface First { }
@Target(ElementType.TYPE_USE)
@interface Second { }
class Main {
public static class Data { }
static {
final /*1 */ /*2*/@<caret>/* 3 */ /* 4*/ First/*one*/ @/*two*/Second /*5 *//*6 */ synchronized transient Main.Data var = null;
}
}
@@ -0,0 +1,16 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface First { }
@Target(ElementType.TYPE_USE)
@interface Second { }
class Main {
public static class Data { }
static {
final /*1 */ /*2*/@/* 3 */ /* 4*/ First/*one*/ @/*two*/<caret>Second /*5 *//*6 */ synchronized transient Main.Data var = null;
}
}
@@ -0,0 +1,14 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface First { }
@Target(ElementType.TYPE_USE)
@interface Second { }
class Main {
public static class Data { }
void func(final /*1 */ /*2*/@<caret>/* 3 */ /* 4*/ First/*one*/ @/*two*/Second /*5 *//*6 */ synchronized transient Main.Data var) { }
}
@@ -0,0 +1,14 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface First { }
@Target(ElementType.TYPE_USE)
@interface Second { }
class Main {
public static class Data { }
void func(final /*1 */ /*2*/@/* 3 */ /* 4*/ First/*one*/ @/*two*/<caret>Second /*5 *//*6 */ synchronized transient Main.Data var) { }
}
@@ -0,0 +1,14 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface First { }
@Target(ElementType.TYPE_USE)
@interface Second { }
class Generic<T> {}
class Main extends Generic</*1 */ /*2*/@<caret>/* 3 */ /* 4*/ First/*one*/ @/*two*/Second /*5 *//*6 */ Main.Data> {
public static class Data { }
}
@@ -0,0 +1,14 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface First { }
@Target(ElementType.TYPE_USE)
@interface Second { }
class Generic<T> {}
class Main extends Generic</*1 */ /*2*/@/* 3 */ /* 4*/ First/*one*/ @/*two*/<caret>Second /*5 *//*6 */ Main.Data> {
public static class Data { }
}
@@ -0,0 +1,14 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface Meta { }
class Main {
public static class Data {
public static class Nested { }
}
static final /*1 */ /*2*/@<caret>/* 3 */ /* 4*/ Meta /*5 *//*6 */ transient Main.Data.Nested var = null;
}
@@ -0,0 +1,16 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface Meta { }
class Main {
public static class Data {
public static class Nested { }
}
static {
final /*1 */ /*2*/@<caret>/* 3 */ /* 4*/ Meta /*5 *//*6 */ synchronized transient Main.Data.Nested var = null;
}
}
@@ -0,0 +1,14 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface Meta { }
class Main {
public static class Data {
public static class Nested { }
}
void func(final /*1 */ /*2*/@<caret>/* 3 */ /* 4*/ Meta /*5 *//*6 */ synchronized transient Main.Data.Nested var) { }
}
@@ -0,0 +1,14 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface Meta { }
class Generic<T> {}
class Main extends Generic</*1 */ /*2*/@<caret>/* 3 */ /* 4*/ Meta /*5 *//*6 */ Main.Data.Nested> {
public static class Data {
public static class Nested { }
}
}
@@ -0,0 +1,16 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface First { }
@Target(ElementType.TYPE_USE)
@interface Second { }
class Main {
public static class Data {
public static class Nested { }
}
static final /*1 */ /*2*/@<caret>/* 3 */ /* 4*/ First/*one*/ @/*two*/Second /*5 *//*6 */ transient Main.Data.Nested var = null;
}
@@ -0,0 +1,16 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface First { }
@Target(ElementType.TYPE_USE)
@interface Second { }
class Main {
public static class Data {
public static class Nested { }
}
static final /*1 */ /*2*/@/* 3 */ /* 4*/ First/*one*/ @/*two*/<caret>Second /*5 *//*6 */ transient Main.Data.Nested var = null;
}
@@ -0,0 +1,18 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface First { }
@Target(ElementType.TYPE_USE)
@interface Second { }
class Main {
public static class Data {
public static class Nested { }
}
static {
final /*1 */ /*2*/@<caret>/* 3 */ /* 4*/ First/*one*/ @/*two*/Second /*5 *//*6 */ synchronized transient Main.Data.Nested var = null;
}
}
@@ -0,0 +1,18 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface First { }
@Target(ElementType.TYPE_USE)
@interface Second { }
class Main {
public static class Data {
public static class Nested { }
}
static {
final /*1 */ /*2*/@/* 3 */ /* 4*/ First/*one*/ @/*two*/<caret>Second /*5 *//*6 */ synchronized transient Main.Data.Nested var = null;
}
}
@@ -0,0 +1,16 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface First { }
@Target(ElementType.TYPE_USE)
@interface Second { }
class Main {
public static class Data {
public static class Nested { }
}
void func(final /*1 */ /*2*/@<caret>/* 3 */ /* 4*/ First/*one*/ @/*two*/Second /*5 *//*6 */ synchronized transient Main.Data.Nested var) { }
}
@@ -0,0 +1,16 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface First { }
@Target(ElementType.TYPE_USE)
@interface Second { }
class Main {
public static class Data {
public static class Nested { }
}
void func(final /*1 */ /*2*/@/* 3 */ /* 4*/ First/*one*/ @/*two*/<caret>Second /*5 *//*6 */ synchronized transient Main.Data.Nested var) { }
}
@@ -0,0 +1,16 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface First { }
@Target(ElementType.TYPE_USE)
@interface Second { }
class Generic<T> {}
class Main extends Generic</*1 */ /*2*/@<caret>/* 3 */ /* 4*/ First/*one*/ @/*two*/Second /*5 *//*6 */ Main.Data.Nested> {
public static class Data {
public static class Nested { }
}
}
@@ -0,0 +1,16 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface First { }
@Target(ElementType.TYPE_USE)
@interface Second { }
class Generic<T> {}
class Main extends Generic</*1 */ /*2*/@/* 3 */ /* 4*/ First/*one*/ @/*two*/<caret>Second /*5 *//*6 */ Main.Data.Nested> {
public static class Data {
public static class Nested { }
}
}
@@ -0,0 +1,16 @@
// "Move type annotation" "true"
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.TYPE_USE)
@interface Meta { }
class Generic<T> {}
class Main extends Generic</*1 */ /*2*/@<caret>/* 3 */ /* 4*/ Meta /*5 *//*6 */ Main.Data.Nested.Inner> {
public static class Data {
public static class Nested {
public static class Inner { }
}
}
}
@@ -0,0 +1,11 @@
// Copyright 2000-2020 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.daemon.quickFix;
import com.intellij.codeInsight.daemon.quickFix.LightQuickFixParameterizedTestCase;
public class MoveAnnotationOnStaticMemberQualifyingTypeTest extends LightQuickFixParameterizedTestCase {
@Override
protected String getBasePath() {
return "/codeInsight/daemonCodeAnalyzer/quickFix/annotatedStaticMemberQualifyingType";
}
}