[mod-command] ModCreateFile; used in MoveAnnotationToPackageInfoFileFix; tests

GitOrigin-RevId: c894f03c5fdb035fda9662337563368d380cb5fe
This commit is contained in:
Tagir Valeev
2023-06-19 19:35:27 +02:00
committed by intellij-monorepo-bot
parent 451019313c
commit e58fae06c9
13 changed files with 220 additions and 75 deletions

View File

@@ -7,6 +7,7 @@ import com.intellij.codeInsight.daemon.JavaErrorBundle;
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
import com.intellij.codeInsight.daemon.impl.quickfix.MoveAnnotationOnStaticMemberQualifyingTypeFix;
import com.intellij.codeInsight.daemon.impl.quickfix.MoveAnnotationToPackageInfoFileFix;
import com.intellij.codeInsight.daemon.impl.quickfix.ReplaceVarWithExplicitTypeFix;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInsight.intention.QuickFixFactory;
@@ -623,7 +624,7 @@ public final class AnnotationsHighlightUtil {
QUICK_FIX_FACTORY.createDeleteFix(annotationList, JavaAnalysisBundle.message("intention.text.remove.annotation"));
HighlightInfo.Builder builder =
HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(annotationList).descriptionAndTooltip(message);
IntentionAction moveAnnotationToPackageInfoFileFix = new MoveAnnotationToPackageInfoFileFix(statement);
var moveAnnotationToPackageInfoFileFix = new MoveAnnotationToPackageInfoFileFix(statement);
return builder.registerFix(deleteFix, null, null, null, null)
.registerFix(moveAnnotationToPackageInfoFileFix, null, null, null, null);
}

View File

@@ -1,63 +1,60 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInsight.daemon.impl.analysis;
package com.intellij.codeInsight.daemon.impl.quickfix;
import com.intellij.codeInsight.intention.preview.IntentionPreviewInfo;
import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement;
import com.intellij.codeInspection.EditorUpdater;
import com.intellij.codeInspection.PsiUpdateModCommandAction;
import com.intellij.ide.highlighter.JavaFileType;
import com.intellij.java.analysis.JavaAnalysisBundle;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleManager;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.ObjectUtils;
import one.util.streamex.StreamEx;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class MoveAnnotationToPackageInfoFileFix extends LocalQuickFixAndIntentionActionOnPsiElement {
public class MoveAnnotationToPackageInfoFileFix extends PsiUpdateModCommandAction<PsiPackageStatement> {
protected MoveAnnotationToPackageInfoFileFix(@NotNull PsiPackageStatement pkgStatement) {
public MoveAnnotationToPackageInfoFileFix(@NotNull PsiPackageStatement pkgStatement) {
super(pkgStatement);
}
@Override
public boolean isAvailable(@NotNull Project project,
@NotNull PsiFile file,
@NotNull PsiElement startElement,
@NotNull PsiElement endElement) {
PsiPackageStatement packageStatement = (PsiPackageStatement)startElement;
protected @Nullable Presentation getPresentation(@NotNull ActionContext context, @NotNull PsiPackageStatement packageStatement) {
PsiPackage aPackage = getPackage(packageStatement);
if (aPackage == null) return false;
if (aPackage == null) return null;
PsiFile packageInfoFile = getPackageInfoFile(aPackage);
if (packageInfoFile == null) return true;
if (!PsiPackage.PACKAGE_INFO_FILE.equals(packageInfoFile.getName())) return false;
if (packageInfoFile == null) return Presentation.of(getFamilyName());
if (!PsiPackage.PACKAGE_INFO_FILE.equals(packageInfoFile.getName())) return null;
PsiPackageStatement packageStatementInPackageInfoFile = PsiTreeUtil.findChildOfType(packageInfoFile, PsiPackageStatement.class);
if (packageStatementInPackageInfoFile == null) return false;
if (packageStatementInPackageInfoFile == null) return null;
PsiModifierList missingAnnotations = findMissingAnnotations(packageStatement, packageStatementInPackageInfoFile);
return missingAnnotations != null && missingAnnotations.getAnnotations().length != 0;
if (missingAnnotations == null || missingAnnotations.getAnnotations().length == 0) return null;
return Presentation.of(getFamilyName());
}
@Override
public void invoke(@NotNull Project project,
@NotNull PsiFile file,
@Nullable Editor editor,
@NotNull PsiElement startElement,
@NotNull PsiElement endElement) {
PsiPackageStatement packageStatement = (PsiPackageStatement)startElement;
protected void invoke(@NotNull ActionContext context, @NotNull PsiPackageStatement packageStatement, @NotNull EditorUpdater updater) {
PsiPackage aPackage = getPackage(packageStatement);
if (aPackage == null) return;
PsiFile packageInfoFile = getPackageInfoFile(aPackage);
if (packageInfoFile == null) {
PsiFile createdFile = file.getContainingDirectory().createFile(PsiPackage.PACKAGE_INFO_FILE);
createdFile.add(packageStatement);
createdFile.navigate(true);
packageInfoFile = updater.createFile(packageStatement.getContainingFile().getOriginalFile().getContainingDirectory(),
PsiPackage.PACKAGE_INFO_FILE, JavaFileType.INSTANCE, "");
}
else if (PsiPackage.PACKAGE_INFO_FILE.equals(packageInfoFile.getName())) {
PsiFile modifiedPackageInfoFile = moveAnnotationsAndGetFile(packageStatement, packageInfoFile);
if (PsiPackage.PACKAGE_INFO_FILE.equals(packageInfoFile.getName())) {
PsiFile modifiedPackageInfoFile = moveAnnotationsAndGetFile(packageStatement, updater.getWritable(packageInfoFile));
if (modifiedPackageInfoFile != null) {
modifiedPackageInfoFile.navigate(true);
updater.moveTo(modifiedPackageInfoFile);
}
}
deleteAnnotations(packageStatement);
}
private static void deleteAnnotations(@NotNull PsiPackageStatement packageStatement) {
for (PsiAnnotation annotation : packageStatement.getAnnotationList().getAnnotations()) {
annotation.delete();
}
}
private static @Nullable PsiPackage getPackage(@NotNull PsiPackageStatement packageStatement) {
@@ -68,7 +65,11 @@ public class MoveAnnotationToPackageInfoFileFix extends LocalQuickFixAndIntentio
private static @Nullable PsiFile moveAnnotationsAndGetFile(@NotNull PsiPackageStatement packageStatement,
@NotNull PsiFile packageInfoFile) {
PsiPackageStatement packageStatementInPackageInfoFile = PsiTreeUtil.findChildOfType(packageInfoFile, PsiPackageStatement.class);
if (packageStatementInPackageInfoFile == null) return null;
if (packageStatementInPackageInfoFile == null) {
PsiPackageStatement copy = (PsiPackageStatement)packageStatement.copy();
deleteAnnotations(copy);
packageStatementInPackageInfoFile = (PsiPackageStatement)packageInfoFile.addBefore(copy, packageInfoFile.getFirstChild());
}
PsiModifierList missingAnnotations = findMissingAnnotations(packageStatement, packageStatementInPackageInfoFile);
if (missingAnnotations == null) return null;
PsiModifierList annotationList = packageStatementInPackageInfoFile.getAnnotationList();
@@ -78,6 +79,7 @@ public class MoveAnnotationToPackageInfoFileFix extends LocalQuickFixAndIntentio
else {
packageStatementInPackageInfoFile.addBefore(missingAnnotations, packageStatementInPackageInfoFile.getFirstChild());
}
CodeStyleManager.getInstance(packageInfoFile.getProject()).reformat(packageInfoFile);
return packageInfoFile;
}
@@ -96,30 +98,6 @@ public class MoveAnnotationToPackageInfoFileFix extends LocalQuickFixAndIntentio
return copy.getAnnotationList();
}
@Override
public @NotNull IntentionPreviewInfo generatePreview(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) {
PsiPackageStatement packageStatement = (PsiPackageStatement)myStartElement.getElement();
assert packageStatement != null;
PsiPackage aPackage = getPackage(packageStatement);
if (aPackage == null) return IntentionPreviewInfo.EMPTY;
PsiFile packageInfoFile = getPackageInfoFile(aPackage);
if (packageInfoFile == null) {
return new IntentionPreviewInfo.CustomDiff(JavaFileType.INSTANCE, PsiPackage.PACKAGE_INFO_FILE, "", packageStatement.getText());
}
else if (PsiPackage.PACKAGE_INFO_FILE.equals(packageInfoFile.getName())) {
PsiFile modifiedPackageInfoFile = moveAnnotationsAndGetFile(packageStatement, (PsiFile)packageInfoFile.copy());
if (modifiedPackageInfoFile == null) return IntentionPreviewInfo.EMPTY;
return new IntentionPreviewInfo.CustomDiff(JavaFileType.INSTANCE, PsiPackage.PACKAGE_INFO_FILE, packageInfoFile.getText(),
modifiedPackageInfoFile.getText());
}
return IntentionPreviewInfo.EMPTY;
}
@Override
public @NotNull String getText() {
return getFamilyName();
}
@Override
public @NotNull String getFamilyName() {
return JavaAnalysisBundle.message("move.annotations.to.package.info.file.family.name");

View File

@@ -0,0 +1,6 @@
@<caret>Deprecated @Anno
package com.example;
import com.example.anno.Anno;
class Imports {}

View File

@@ -0,0 +1,2 @@
@<caret>Deprecated
package com.example;

View File

@@ -0,0 +1,42 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.codeInsight.daemon.impl.quickfix;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.java.analysis.JavaAnalysisBundle;
import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase;
public class MoveAnnotationToPackageInfoFileFixTest extends LightJavaCodeInsightFixtureTestCase {
public void testSimple() {
myFixture.configureByFile("com/example/Simple.java");
IntentionAction action = myFixture.findSingleIntention(JavaAnalysisBundle.message("move.annotations.to.package.info.file.family.name"));
String text = myFixture.getIntentionPreviewText(action);
assertEquals("""
package com.example;
----------
@Deprecated
package com.example;""", text);
}
public void testImports() {
myFixture.addClass("package com.example.anno; @interface Anno {}");
myFixture.configureByFile("com/example/Imports.java");
IntentionAction action = myFixture.findSingleIntention(JavaAnalysisBundle.message("move.annotations.to.package.info.file.family.name"));
String text = myFixture.getIntentionPreviewText(action);
assertEquals("""
package com.example;
import com.example.anno.Anno;
class Imports {}
----------
@Deprecated @Anno
package com.example;
import com.example.anno.Anno;""", text);
}
@Override
protected String getBasePath() {
return "/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/moveAnnotationToPackage";
}
}

View File

@@ -4,10 +4,7 @@ package com.intellij.codeInsight.intention.preview;
import com.intellij.codeInsight.FileModificationService;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.lang.injection.InjectedLanguageManager;
import com.intellij.modcommand.ModChooseTarget;
import com.intellij.modcommand.ModCommand;
import com.intellij.modcommand.ModNavigate;
import com.intellij.modcommand.ModUpdateFileText;
import com.intellij.modcommand.*;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
@@ -167,6 +164,10 @@ public final class IntentionPreviewUtils {
customDiffList.add(new IntentionPreviewInfo.CustomDiff(vFile.getFileType(),
currentFile ? null : vFile.getName(), modFile.oldText(), modFile.newText(), true));
}
else if (command instanceof ModCreateFile createFile) {
VirtualFile vFile = createFile.file();
customDiffList.add(new IntentionPreviewInfo.CustomDiff(vFile.getFileType(), vFile.getName(), "", createFile.text(), true));
}
else if (command instanceof ModNavigate navigate && navigate.caret() != -1) {
PsiFile target = PsiManager.getInstance(project).findFile(navigate.file());
if (target != null) {

View File

@@ -0,0 +1,26 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.modcommand;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.testFramework.LightVirtualFile;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
/**
* Virtual file that doesn't exist yet
*/
@ApiStatus.Experimental
public class FutureVirtualFile extends LightVirtualFile {
private final VirtualFile myParent;
public FutureVirtualFile(@NotNull VirtualFile parent, @NotNull String name, @NotNull FileType fileType, @NotNull CharSequence text) {
super(name, fileType, text);
myParent = parent;
}
@Override
public VirtualFile getParent() {
return myParent;
}
}

View File

@@ -15,7 +15,8 @@ import java.util.Set;
* All inheritors are records, so the whole state is declarative and readable.
*/
public sealed interface ModCommand
permits ModChooseTarget, ModCompositeCommand, ModDisplayError, ModHighlight, ModNavigate, ModNothing, ModRenameSymbol, ModUpdateFileText {
permits ModChooseTarget, ModCompositeCommand, ModCreateFile, ModDisplayError, ModHighlight, ModNavigate, ModNothing, ModRenameSymbol,
ModUpdateFileText {
/**
* @return true if the command does nothing

View File

@@ -0,0 +1,11 @@
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.modcommand;
import org.jetbrains.annotations.NotNull;
/**
* @param file file to create
* @param text file content
*/
public record ModCreateFile(@NotNull FutureVirtualFile file, @NotNull String text) implements ModCommand {
}

View File

@@ -3,8 +3,11 @@ package com.intellij.codeInspection;
import com.intellij.openapi.editor.colors.EditorColors;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiDirectory;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiNameIdentifierOwner;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Contract;
@@ -27,6 +30,15 @@ public interface EditorUpdater {
*/
@Contract(value = "null -> null; !null -> !null")
<E extends PsiElement> E getWritable(E e);
/**
* @param directory parent directory
* @param name file name
* @param type file type
* @param content initial file content
* @return a newly created editable non-physical file, whose changes will be added to the final command
*/
@NotNull PsiFile createFile(@NotNull PsiDirectory directory, @NotNull String name, @NotNull FileType type, @NotNull String content);
/**
* Selects given element

View File

@@ -13,6 +13,7 @@ import com.intellij.openapi.editor.Document;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.editor.event.DocumentEvent;
import com.intellij.openapi.editor.event.DocumentListener;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.NlsContexts;
@@ -279,20 +280,35 @@ public final class ModCommands {
private static class EditorUpdaterImpl implements EditorUpdater, DocumentListener, Disposable {
private final @NotNull FileTracker myTracker;
private final @NotNull Map<PsiFile, FileTracker> myChangedFiles = new LinkedHashMap<>();
private final @NotNull VirtualFile myOrigVirtualFile;
private final @NotNull Map<PsiFile, NewFileInfo> myNewFiles = new LinkedHashMap<>();
private @NotNull VirtualFile myNavigationFile;
private int myCaretOffset;
private @NotNull TextRange mySelection;
private final List<ModHighlight.HighlightInfo> myHighlightInfos = new ArrayList<>();
private @Nullable ModRenameSymbol myRenameSymbol;
private boolean myPositionUpdated = false;
private static final class NewFileInfo {
private final @NotNull PsiFile file;
private final @NotNull FutureVirtualFile futureFile;
private NewFileInfo(@NotNull VirtualFile directory, @NotNull PsiFile file) {
this.file = file;
futureFile = new FutureVirtualFile(directory, file.getName(), file.getFileType(), "");
}
private @NotNull ModCommand getCommand() {
return new ModCreateFile(futureFile, file.getText());
}
}
private EditorUpdaterImpl(@NotNull ModCommandAction.ActionContext actionContext) {
myCaretOffset = actionContext.offset();
mySelection = actionContext.selection();
// TODO: lazily get the tracker for the current file
myTracker = tracker(actionContext.file());
myTracker.myPositionDocument.addDocumentListener(this, this);
myOrigVirtualFile = Objects.requireNonNull(myTracker.myOrigFile.getOriginalFile().getVirtualFile());
myNavigationFile = Objects.requireNonNull(myTracker.myOrigFile.getOriginalFile().getVirtualFile());
}
private @NotNull FileTracker tracker(@NotNull PsiFile file) {
@@ -307,6 +323,9 @@ public final class ModCommands {
public <E extends PsiElement> E getWritable(E e) {
if (e == null) return null;
PsiFile file = e.getContainingFile();
if (myNewFiles.containsKey(file)) {
return e;
}
PsiFile originalFile = file.getOriginalFile();
if (originalFile != file) {
FileTracker tracker = tracker(originalFile);
@@ -317,6 +336,17 @@ public final class ModCommands {
return tracker(file).getCopy(e);
}
@Override
public @NotNull PsiFile createFile(@NotNull PsiDirectory directory,
@NotNull String name,
@NotNull FileType type,
@NotNull String content) {
VirtualFile parent = directory.getVirtualFile();
PsiFile psiFile = PsiFileFactory.getInstance(myTracker.myProject).createFileFromText(name, type, content);
myNewFiles.put(psiFile, new NewFileInfo(parent, psiFile));
return psiFile;
}
@Override
public void dispose() {
}
@@ -330,7 +360,16 @@ public final class ModCommands {
}
private @Nullable TextRange getRange(@NotNull PsiElement element) {
validate(element);
if (!element.isValid()) throw new IllegalArgumentException();
if (!PsiTreeUtil.isAncestor(myTracker.myCopyFile, element, false)) {
if (element instanceof PsiFile file) {
// allow navigating to the beginning of files
NewFileInfo info = myNewFiles.get(file);
myNavigationFile = info != null ? info.futureFile : file.getOriginalFile().getVirtualFile();
return TextRange.create(0, 0);
}
throw new IllegalArgumentException();
}
SmartPsiElementPointer<PsiElement> pointer = SmartPointerManager.createPointer(element);
myTracker.unblock();
Segment range = pointer.getRange();
@@ -395,7 +434,7 @@ public final class ModCommands {
if (myRenameSymbol != null) {
throw new IllegalStateException("One element is already registered for rename");
}
myRenameSymbol = new ModRenameSymbol(myOrigVirtualFile, element.getTextRange(), suggestedNames);
myRenameSymbol = new ModRenameSymbol(myNavigationFile, element.getTextRange(), suggestedNames);
}
private TextRange mapRange(@NotNull TextRange range) {
@@ -426,11 +465,6 @@ public final class ModCommands {
return Objects.requireNonNull(visitor.myFile);
}
private void validate(@NotNull PsiElement element) {
if (!element.isValid()) throw new IllegalArgumentException();
if (!PsiTreeUtil.isAncestor(myTracker.myCopyFile, element, false)) throw new IllegalArgumentException();
}
@Override
public void documentChanged(@NotNull DocumentEvent event) {
myCaretOffset = updateOffset(event, myCaretOffset);
@@ -459,6 +493,7 @@ public final class ModCommands {
private @NotNull ModCommand getCommand() {
return myChangedFiles.values().stream().map(FileTracker::getUpdateCommand).reduce(nop(), ModCommand::andThen)
.andThen(myNewFiles.values().stream().map(NewFileInfo::getCommand).reduce(nop(), ModCommand::andThen))
.andThen(getNavigateCommand()).andThen(getHighlightCommand()).andThen(myRenameSymbol == null ? nop() : myRenameSymbol);
}
@@ -475,13 +510,13 @@ public final class ModCommands {
caret = this.myCaretOffset;
}
if (start == -1 && end == -1 && caret == -1) return nop();
return new ModNavigate(myOrigVirtualFile, start, end, caret);
return new ModNavigate(myNavigationFile, start, end, caret);
}
@NotNull
private ModCommand getHighlightCommand() {
if (myHighlightInfos.isEmpty()) return nop();
return new ModHighlight(myOrigVirtualFile, myHighlightInfos);
return new ModHighlight(myNavigationFile, myHighlightInfos);
}
}
}

View File

@@ -46,6 +46,7 @@ import one.util.streamex.StreamEx;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Set;
@@ -127,11 +128,33 @@ public class ModCommandServiceImpl implements ModCommandService {
if (!onTheFly) return true;
return executeRename(project, rename);
}
if (command instanceof ModCreateFile create) {
return executeCreate(project, create);
}
throw new IllegalArgumentException("Unknown command: " + command);
}
private boolean executeCreate(@NotNull Project project, @NotNull ModCreateFile create) {
FutureVirtualFile file = create.file();
VirtualFile parent = actualize(file.getParent());
try {
return WriteAction.compute(() -> {
VirtualFile newFile = parent.createChildData(this, file.getName());
PsiFile psiFile = PsiManager.getInstance(project).findFile(newFile);
if (psiFile == null) return false;
psiFile.getViewProvider().getDocument().setText(create.text());
return true;
});
}
catch (IOException e) {
executeError(project, new ModDisplayError(e.getMessage()));
return false;
}
}
private static boolean executeRename(Project project, ModRenameSymbol rename) {
VirtualFile file = rename.file();
VirtualFile file = actualize(rename.file());
if (file == null) return false;
PsiFile psiFile = PsiManagerEx.getInstanceEx(project).findFile(file);
if (psiFile == null) return false;
PsiNameIdentifierOwner element =
@@ -265,8 +288,13 @@ public class ModCommandServiceImpl implements ModCommandService {
.submit(AppExecutorUtil.getAppExecutorService());
}
private static VirtualFile actualize(@NotNull VirtualFile file) {
return file instanceof FutureVirtualFile future ? actualize(future.getParent()).findChild(future.getName()) : file;
}
private static boolean executeNavigate(@NotNull Project project, ModNavigate nav) {
VirtualFile file = nav.file();
VirtualFile file = actualize(nav.file());
if (file == null) return false;
int selectionStart = nav.selectionStart();
int selectionEnd = nav.selectionEnd();
int caret = nav.caret();
@@ -283,7 +311,9 @@ public class ModCommandServiceImpl implements ModCommandService {
}
private static boolean executeHighlight(Project project, ModHighlight highlight) {
FileEditor fileEditor = FileEditorManager.getInstance(project).getSelectedEditor(highlight.virtualFile());
VirtualFile file = actualize(highlight.virtualFile());
if (file == null) return false;
FileEditor fileEditor = FileEditorManager.getInstance(project).getSelectedEditor(file);
if (!(fileEditor instanceof TextEditor textEditor)) return false;
Editor editor = textEditor.getEditor();
HighlightManager manager = HighlightManager.getInstance(project);

View File

@@ -2,7 +2,7 @@
package com.siyeh.ig.javadoc;
import com.intellij.analysis.AnalysisScope;
import com.intellij.codeInsight.daemon.impl.analysis.MoveAnnotationToPackageInfoFileFix;
import com.intellij.codeInsight.daemon.impl.quickfix.MoveAnnotationToPackageInfoFileFix;
import com.intellij.codeInsight.intention.preview.IntentionPreviewInfo;
import com.intellij.codeInspection.*;
import com.intellij.codeInspection.reference.RefPackage;