mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-04-19 04:51:24 +07:00
[mod-command] ModCreateFile; used in MoveAnnotationToPackageInfoFileFix; tests
GitOrigin-RevId: c894f03c5fdb035fda9662337563368d380cb5fe
This commit is contained in:
committed by
intellij-monorepo-bot
parent
451019313c
commit
e58fae06c9
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
@@ -0,0 +1,6 @@
|
||||
@<caret>Deprecated @Anno
|
||||
package com.example;
|
||||
|
||||
import com.example.anno.Anno;
|
||||
|
||||
class Imports {}
|
||||
@@ -0,0 +1,2 @@
|
||||
@<caret>Deprecated
|
||||
package com.example;
|
||||
@@ -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";
|
||||
}
|
||||
}
|
||||
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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 {
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user