mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-01-06 03:21:12 +07:00
[java] IDEA-373841 Backward compatibility regression for java copy-paste
GitOrigin-RevId: 55b8b55ae5105e95530e7b727f5aed2f87e5638a
This commit is contained in:
committed by
intellij-monorepo-bot
parent
93b987c157
commit
f66a437ec8
@@ -0,0 +1,304 @@
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.codeInsight.editorActions;
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightSettings;
|
||||
import com.intellij.codeInsight.daemon.impl.CollectHighlightsUtil;
|
||||
import com.intellij.codeInsight.hint.HintManager;
|
||||
import com.intellij.codeInsight.hint.HintManagerImpl;
|
||||
import com.intellij.codeInsight.hint.HintUtil;
|
||||
import com.intellij.java.JavaBundle;
|
||||
import com.intellij.modcommand.ActionContext;
|
||||
import com.intellij.modcommand.ModCommand;
|
||||
import com.intellij.modcommand.ModCommandExecutor;
|
||||
import com.intellij.modcommand.ModPsiUpdater;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.application.ReadAction;
|
||||
import com.intellij.openapi.application.ex.ApplicationEx;
|
||||
import com.intellij.openapi.application.ex.ApplicationManagerEx;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.RangeMarker;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.*;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.intellij.ui.LightweightHint;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.event.HyperlinkEvent;
|
||||
import javax.swing.event.HyperlinkListener;
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
import java.awt.datatransfer.Transferable;
|
||||
import java.awt.datatransfer.UnsupportedFlavorException;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public abstract class AbstractJavaCopyPasteReferenceProcessor<TRef extends PsiElement> extends CopyPastePostProcessor<ReferenceTransferableData>
|
||||
implements ReferenceCopyPasteProcessor {
|
||||
private static final Logger LOG = Logger.getInstance(AbstractJavaCopyPasteReferenceProcessor.class);
|
||||
|
||||
@Override
|
||||
public @NotNull List<ReferenceTransferableData> collectTransferableData(@NotNull PsiFile file,
|
||||
@NotNull Editor editor,
|
||||
int @NotNull [] startOffsets,
|
||||
int @NotNull [] endOffsets) {
|
||||
if (CodeInsightSettings.getInstance().ADD_IMPORTS_ON_PASTE == CodeInsightSettings.NO) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
if (!(file instanceof PsiClassOwner)) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
ArrayList<ReferenceData> array = new ArrayList<>();
|
||||
int refOffset = 0; // this is an offset delta for conversion from absolute offset to an offset inside clipboard contents
|
||||
for (int j = 0; j < startOffsets.length; j++) {
|
||||
refOffset += startOffsets[j];
|
||||
for (PsiElement element : CollectHighlightsUtil.getElementsInRange(file, startOffsets[j], endOffsets[j])) {
|
||||
addReferenceData(file, refOffset, element, array);
|
||||
}
|
||||
refOffset -= endOffsets[j] + 1; // 1 accounts for line break inserted between contents corresponding to different carets
|
||||
}
|
||||
|
||||
if (array.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
return Collections.singletonList(new ReferenceTransferableData(array.toArray(new ReferenceData[0])));
|
||||
}
|
||||
|
||||
protected abstract void addReferenceData(PsiFile file, int startOffset, PsiElement element, ArrayList<ReferenceData> to);
|
||||
|
||||
@Override
|
||||
public @NotNull List<ReferenceTransferableData> extractTransferableData(@NotNull Transferable content) {
|
||||
ReferenceTransferableData referenceData = null;
|
||||
if (CodeInsightSettings.getInstance().ADD_IMPORTS_ON_PASTE != CodeInsightSettings.NO) {
|
||||
try {
|
||||
DataFlavor flavor = ReferenceData.getDataFlavor();
|
||||
if (flavor != null) {
|
||||
referenceData = (ReferenceTransferableData)content.getTransferData(flavor);
|
||||
}
|
||||
}
|
||||
catch (UnsupportedFlavorException | IOException ignored) {
|
||||
}
|
||||
}
|
||||
|
||||
if (referenceData != null) { // copy to prevent changing of original by convertLineSeparators
|
||||
return Collections.singletonList(referenceData.clone());
|
||||
}
|
||||
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processTransferableData(@NotNull Project project,
|
||||
@NotNull Editor editor,
|
||||
@NotNull RangeMarker bounds,
|
||||
int caretOffset,
|
||||
@NotNull Ref<? super Boolean> indented, @NotNull List<? extends ReferenceTransferableData> values) {
|
||||
if (DumbService.getInstance(project).isDumb()) {
|
||||
return;
|
||||
}
|
||||
Document document = editor.getDocument();
|
||||
PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(document);
|
||||
|
||||
if (!(file instanceof PsiClassOwner)) {
|
||||
return;
|
||||
}
|
||||
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments();
|
||||
assert values.size() == 1;
|
||||
ReferenceData[] referenceData = values.get(0).getData();
|
||||
TRef[] refs;
|
||||
refs = ProgressManager.getInstance().runProcessWithProgressSynchronously(
|
||||
() -> ReadAction.compute(
|
||||
() -> findReferencesToRestore(file, bounds, referenceData)
|
||||
), JavaBundle.message("progress.title.searching.references"), true, project);
|
||||
if (refs == null) return;
|
||||
if (CodeInsightSettings.getInstance().ADD_IMPORTS_ON_PASTE == CodeInsightSettings.ASK) {
|
||||
askReferencesToRestore(project, refs, referenceData);
|
||||
}
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments();
|
||||
ApplicationEx app = ApplicationManagerEx.getApplicationEx();
|
||||
Consumer<ProgressIndicator> consumer = indicator -> {
|
||||
Set<String> imported = new TreeSet<>();
|
||||
createAndApplyRestoreReferencesFixWithModCommand(referenceData, refs, imported, editor, file);
|
||||
if (CodeInsightSettings.getInstance().ADD_IMPORTS_ON_PASTE == CodeInsightSettings.YES && !imported.isEmpty()) {
|
||||
Integer size = imported.size();
|
||||
String notificationText = JavaBundle.message("copy.paste.reference.notification", size);
|
||||
app.invokeLater(
|
||||
() -> showHint(editor, notificationText, e -> {
|
||||
if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
|
||||
reviewImports(project, file, imported);
|
||||
}
|
||||
}), ModalityState.nonModal(), __ -> editor.isDisposed());
|
||||
}
|
||||
};
|
||||
consumer.accept(null);
|
||||
}
|
||||
|
||||
private void createAndApplyRestoreReferencesFixWithModCommand(ReferenceData[] data,
|
||||
TRef[] refs,
|
||||
@NotNull Set<String> imported,
|
||||
@NotNull Editor editor,
|
||||
@NotNull PsiFile file) {
|
||||
if (refs.length == 0) return;
|
||||
Optional<TRef> ref1 = Arrays.stream(refs).filter(Objects::nonNull).findAny();
|
||||
if (ref1.isEmpty()) return;
|
||||
ActionContext context = ActionContext.from(editor, file).withOffset(ref1.get().getTextRange().getStartOffset());
|
||||
ModCommandExecutor.executeInteractively(context,
|
||||
JavaBundle.message("progress.title.searching.references"),
|
||||
editor,
|
||||
() -> {
|
||||
return ModCommand.psiUpdate(context.file(), (e, updater) -> {
|
||||
List<TRef> copies = ContainerUtil.map(refs, el -> updater.getWritable(el));
|
||||
restoreReferences(data, copies, imported, updater);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
protected abstract void removeImports(@NotNull PsiFile file, @NotNull Set<String> imports);
|
||||
|
||||
private void reviewImports(@NotNull Project project, @NotNull PsiFile file, @NotNull Set<String> importedClasses) {
|
||||
RestoreReferencesDialog dialog = new RestoreReferencesDialog(project, ArrayUtil.toObjectArray(importedClasses), false);
|
||||
dialog.setTitle(JavaBundle.message("dialog.import.on.paste.title3"));
|
||||
dialog.setExplanation(JavaBundle.message("dialog.paste.on.import.text3"));
|
||||
if (dialog.showAndGet()) {
|
||||
Object[] selectedElements = dialog.getSelectedElements();
|
||||
if (selectedElements.length > 0) {
|
||||
WriteCommandAction.runWriteCommandAction(project, "", null, () ->
|
||||
removeImports(file, Arrays.stream(selectedElements).map(o -> (String)o).collect(Collectors.toSet())));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected static void addReferenceData(@NotNull PsiElement element,
|
||||
@NotNull List<? super ReferenceData> array,
|
||||
int startOffset,
|
||||
@NotNull String qClassName,
|
||||
@Nullable String staticMemberName) {
|
||||
TextRange range = element.getTextRange();
|
||||
array.add(
|
||||
new ReferenceData(
|
||||
range.getStartOffset() - startOffset,
|
||||
range.getEndOffset() - startOffset,
|
||||
qClassName, staticMemberName));
|
||||
}
|
||||
|
||||
protected abstract TRef @NotNull [] findReferencesToRestore(@NotNull PsiFile file,
|
||||
@NotNull RangeMarker bounds,
|
||||
ReferenceData @NotNull [] referenceData);
|
||||
|
||||
protected static PsiElement resolveReferenceIgnoreOverriding(@NotNull PsiPolyVariantReference reference) {
|
||||
PsiElement referent = reference.resolve();
|
||||
if (referent == null) {
|
||||
ResolveResult[] results = reference.multiResolve(true);
|
||||
if (results.length > 0) {
|
||||
referent = results[0].getElement();
|
||||
}
|
||||
}
|
||||
return referent;
|
||||
}
|
||||
|
||||
protected abstract void restoreReferences(ReferenceData @NotNull [] referenceData,
|
||||
List<TRef> refs,
|
||||
@NotNull Set<? super String> imported);
|
||||
|
||||
protected void restoreReferences(ReferenceData @NotNull [] referenceData,
|
||||
List<TRef> refs,
|
||||
@NotNull Set<? super String> imported,
|
||||
@NotNull ModPsiUpdater updater) {
|
||||
restoreReferences(referenceData, refs, imported);
|
||||
}
|
||||
|
||||
private static void askReferencesToRestore(@NotNull Project project, PsiElement @NotNull [] refs,
|
||||
ReferenceData @NotNull [] referenceData) {
|
||||
PsiManager manager = PsiManager.getInstance(project);
|
||||
|
||||
ThrowableComputable<Pair<ArrayList<Object>, Object[]>, RuntimeException> computable = () -> {
|
||||
ArrayList<Object> array = new ArrayList<>();
|
||||
Object[] refObjects = new Object[refs.length];
|
||||
|
||||
for (int i = 0; i < referenceData.length; i++) {
|
||||
PsiElement ref = refs[i];
|
||||
if (ref != null) {
|
||||
LOG.assertTrue(ref.isValid());
|
||||
ReferenceData data = referenceData[i];
|
||||
PsiClass refClass = JavaPsiFacade.getInstance(manager.getProject()).findClass(data.qClassName, ref.getResolveScope());
|
||||
if (refClass == null) continue;
|
||||
|
||||
Object refObject = refClass;
|
||||
if (data.staticMemberName != null) {
|
||||
//Show static members as Strings
|
||||
refObject = refClass.getQualifiedName() + "." + data.staticMemberName;
|
||||
}
|
||||
refObjects[i] = refObject;
|
||||
|
||||
if (!array.contains(refObject)) {
|
||||
array.add(refObject);
|
||||
}
|
||||
}
|
||||
}
|
||||
return new Pair<>(array, refObjects);
|
||||
};
|
||||
Pair<ArrayList<Object>, Object[]> context;
|
||||
context = ProgressManager.getInstance().runProcessWithProgressSynchronously(
|
||||
() -> ReadAction.compute(
|
||||
computable
|
||||
), JavaBundle.message("progress.title.searching.references"), true, project);
|
||||
if (context == null) return;
|
||||
ArrayList<Object> array = context.getFirst();
|
||||
Object[] refObjects = context.getSecond();
|
||||
if (array.isEmpty()) return;
|
||||
|
||||
Object[] selectedObjects = ArrayUtil.toObjectArray(array);
|
||||
Arrays.sort(selectedObjects, (o1, o2) -> getFQName(o1).compareToIgnoreCase(getFQName(o2)));
|
||||
|
||||
RestoreReferencesDialog dialog = new RestoreReferencesDialog(project, selectedObjects);
|
||||
dialog.show();
|
||||
selectedObjects = dialog.getSelectedElements();
|
||||
|
||||
for (int i = 0; i < referenceData.length; i++) {
|
||||
PsiElement ref = refs[i];
|
||||
if (ref != null) {
|
||||
PsiUtilCore.ensureValid(ref);
|
||||
Object refObject = refObjects[i];
|
||||
boolean found = false;
|
||||
for (Object selected : selectedObjects) {
|
||||
if (Comparing.equal(refObject, selected)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
refs[i] = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void showHint(@NotNull Editor editor,
|
||||
@NotNull @NlsContexts.HintText String info,
|
||||
@Nullable HyperlinkListener hyperlinkListener) {
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) return;
|
||||
LightweightHint hint = new LightweightHint(HintUtil.createInformationLabel(info, hyperlinkListener, null, null));
|
||||
|
||||
int flags = HintManager.HIDE_BY_ANY_KEY | HintManager.HIDE_BY_TEXT_CHANGE;
|
||||
HintManagerImpl.getInstanceImpl().showEditorHint(hint, editor, HintManager.UNDER, flags, 0, false);
|
||||
}
|
||||
|
||||
private static String getFQName(@NotNull Object element) {
|
||||
return element instanceof PsiClass ? ((PsiClass)element).getQualifiedName() : (String)element;
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.codeInsight.editorActions;
|
||||
|
||||
import com.intellij.codeInsight.CodeInsightSettings;
|
||||
@@ -7,13 +7,8 @@ import com.intellij.codeInsight.hint.HintManager;
|
||||
import com.intellij.codeInsight.hint.HintManagerImpl;
|
||||
import com.intellij.codeInsight.hint.HintUtil;
|
||||
import com.intellij.java.JavaBundle;
|
||||
import com.intellij.modcommand.ActionContext;
|
||||
import com.intellij.modcommand.ModCommand;
|
||||
import com.intellij.modcommand.ModCommandExecutor;
|
||||
import com.intellij.modcommand.ModPsiUpdater;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ModalityState;
|
||||
import com.intellij.openapi.application.ReadAction;
|
||||
import com.intellij.openapi.application.ex.ApplicationEx;
|
||||
import com.intellij.openapi.application.ex.ApplicationManagerEx;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
@@ -22,15 +17,16 @@ import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.RangeMarker;
|
||||
import com.intellij.openapi.progress.ProgressIndicator;
|
||||
import com.intellij.openapi.progress.ProgressManager;
|
||||
import com.intellij.openapi.project.DumbService;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.*;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.NlsContexts;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.intellij.ui.LightweightHint;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -44,15 +40,17 @@ import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* @deprecated use {@link AbstractJavaCopyPasteReferenceProcessor}
|
||||
*/
|
||||
@SuppressWarnings("DuplicatedCode")
|
||||
@Deprecated(forRemoval = true)
|
||||
public abstract class CopyPasteReferenceProcessor<TRef extends PsiElement> extends CopyPastePostProcessor<ReferenceTransferableData>
|
||||
implements ReferenceCopyPasteProcessor {
|
||||
private static final Logger LOG = Logger.getInstance(CopyPasteReferenceProcessor.class);
|
||||
|
||||
|
||||
@Override
|
||||
public @NotNull List<ReferenceTransferableData> collectTransferableData(@NotNull PsiFile file,
|
||||
@NotNull Editor editor,
|
||||
int @NotNull [] startOffsets,
|
||||
int @NotNull [] endOffsets) {
|
||||
public @NotNull List<ReferenceTransferableData> collectTransferableData(@NotNull PsiFile file, @NotNull Editor editor, int @NotNull [] startOffsets, int @NotNull [] endOffsets) {
|
||||
if (CodeInsightSettings.getInstance().ADD_IMPORTS_ON_PASTE == CodeInsightSettings.NO) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
@@ -120,12 +118,7 @@ public abstract class CopyPasteReferenceProcessor<TRef extends PsiElement> exten
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments();
|
||||
assert values.size() == 1;
|
||||
ReferenceData[] referenceData = values.get(0).getData();
|
||||
TRef[] refs;
|
||||
refs = ProgressManager.getInstance().runProcessWithProgressSynchronously(
|
||||
() -> ReadAction.compute(
|
||||
() -> findReferencesToRestore(file, bounds, referenceData)
|
||||
), JavaBundle.message("progress.title.searching.references"), true, project);
|
||||
if (refs == null) return;
|
||||
TRef[] refs = findReferencesToRestore(file, bounds, referenceData);
|
||||
if (CodeInsightSettings.getInstance().ADD_IMPORTS_ON_PASTE == CodeInsightSettings.ASK) {
|
||||
askReferencesToRestore(project, refs, referenceData);
|
||||
}
|
||||
@@ -133,10 +126,9 @@ public abstract class CopyPasteReferenceProcessor<TRef extends PsiElement> exten
|
||||
ApplicationEx app = ApplicationManagerEx.getApplicationEx();
|
||||
Consumer<ProgressIndicator> consumer = indicator -> {
|
||||
Set<String> imported = new TreeSet<>();
|
||||
createAndApplyRestoreReferencesFixWithModCommand(referenceData, refs, imported, editor, file);
|
||||
restoreReferences(referenceData, refs, imported);
|
||||
if (CodeInsightSettings.getInstance().ADD_IMPORTS_ON_PASTE == CodeInsightSettings.YES && !imported.isEmpty()) {
|
||||
Integer size = imported.size();
|
||||
String notificationText = JavaBundle.message("copy.paste.reference.notification", size);
|
||||
String notificationText = JavaBundle.message("copy.paste.reference.notification", imported.size());
|
||||
app.invokeLater(
|
||||
() -> showHint(editor, notificationText, e -> {
|
||||
if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
|
||||
@@ -145,27 +137,8 @@ public abstract class CopyPasteReferenceProcessor<TRef extends PsiElement> exten
|
||||
}), ModalityState.nonModal(), __ -> editor.isDisposed());
|
||||
}
|
||||
};
|
||||
consumer.accept(null);
|
||||
}
|
||||
|
||||
private void createAndApplyRestoreReferencesFixWithModCommand(ReferenceData[] data,
|
||||
TRef[] refs,
|
||||
@NotNull Set<String> imported,
|
||||
@NotNull Editor editor,
|
||||
@NotNull PsiFile file) {
|
||||
if (refs.length == 0) return;
|
||||
Optional<TRef> ref1 = Arrays.stream(refs).filter(Objects::nonNull).findAny();
|
||||
if (ref1.isEmpty()) return;
|
||||
ActionContext context = ActionContext.from(editor, file).withOffset(ref1.get().getTextRange().getStartOffset());
|
||||
ModCommandExecutor.executeInteractively(context,
|
||||
JavaBundle.message("progress.title.searching.references"),
|
||||
editor,
|
||||
() -> {
|
||||
return ModCommand.psiUpdate(context.file(), (e, updater) -> {
|
||||
List<TRef> copies = ContainerUtil.map(refs, el -> updater.getWritable(el));
|
||||
restoreReferences(data, copies, imported, updater);
|
||||
});
|
||||
});
|
||||
app.runWriteActionWithCancellableProgressInDispatchThread(JavaBundle.message("progress.title.restore.references"), project, null, consumer);
|
||||
}
|
||||
|
||||
protected abstract void removeImports(@NotNull PsiFile file, @NotNull Set<String> imports);
|
||||
@@ -190,10 +163,10 @@ public abstract class CopyPasteReferenceProcessor<TRef extends PsiElement> exten
|
||||
@Nullable String staticMemberName) {
|
||||
TextRange range = element.getTextRange();
|
||||
array.add(
|
||||
new ReferenceData(
|
||||
range.getStartOffset() - startOffset,
|
||||
range.getEndOffset() - startOffset,
|
||||
qClassName, staticMemberName));
|
||||
new ReferenceData(
|
||||
range.getStartOffset() - startOffset,
|
||||
range.getEndOffset() - startOffset,
|
||||
qClassName, staticMemberName));
|
||||
}
|
||||
|
||||
protected abstract TRef @NotNull [] findReferencesToRestore(@NotNull PsiFile file,
|
||||
@@ -212,54 +185,35 @@ public abstract class CopyPasteReferenceProcessor<TRef extends PsiElement> exten
|
||||
}
|
||||
|
||||
protected abstract void restoreReferences(ReferenceData @NotNull [] referenceData,
|
||||
List<TRef> refs,
|
||||
TRef @NotNull [] refs,
|
||||
@NotNull Set<? super String> imported);
|
||||
|
||||
protected void restoreReferences(ReferenceData @NotNull [] referenceData,
|
||||
List<TRef> refs,
|
||||
@NotNull Set<? super String> imported,
|
||||
@NotNull ModPsiUpdater updater) {
|
||||
restoreReferences(referenceData, refs, imported);
|
||||
}
|
||||
|
||||
private static void askReferencesToRestore(@NotNull Project project, PsiElement @NotNull [] refs,
|
||||
ReferenceData @NotNull [] referenceData) {
|
||||
PsiManager manager = PsiManager.getInstance(project);
|
||||
|
||||
ThrowableComputable<Pair<ArrayList<Object>, Object[]>, RuntimeException> computable = () -> {
|
||||
ArrayList<Object> array = new ArrayList<>();
|
||||
Object[] refObjects = new Object[refs.length];
|
||||
ArrayList<Object> array = new ArrayList<>();
|
||||
Object[] refObjects = new Object[refs.length];
|
||||
for (int i = 0; i < referenceData.length; i++) {
|
||||
PsiElement ref = refs[i];
|
||||
if (ref != null) {
|
||||
LOG.assertTrue(ref.isValid());
|
||||
ReferenceData data = referenceData[i];
|
||||
PsiClass refClass = JavaPsiFacade.getInstance(manager.getProject()).findClass(data.qClassName, ref.getResolveScope());
|
||||
if (refClass == null) continue;
|
||||
|
||||
for (int i = 0; i < referenceData.length; i++) {
|
||||
PsiElement ref = refs[i];
|
||||
if (ref != null) {
|
||||
LOG.assertTrue(ref.isValid());
|
||||
ReferenceData data = referenceData[i];
|
||||
PsiClass refClass = JavaPsiFacade.getInstance(manager.getProject()).findClass(data.qClassName, ref.getResolveScope());
|
||||
if (refClass == null) continue;
|
||||
Object refObject = refClass;
|
||||
if (data.staticMemberName != null) {
|
||||
//Show static members as Strings
|
||||
refObject = refClass.getQualifiedName() + "." + data.staticMemberName;
|
||||
}
|
||||
refObjects[i] = refObject;
|
||||
|
||||
Object refObject = refClass;
|
||||
if (data.staticMemberName != null) {
|
||||
//Show static members as Strings
|
||||
refObject = refClass.getQualifiedName() + "." + data.staticMemberName;
|
||||
}
|
||||
refObjects[i] = refObject;
|
||||
|
||||
if (!array.contains(refObject)) {
|
||||
array.add(refObject);
|
||||
}
|
||||
if (!array.contains(refObject)) {
|
||||
array.add(refObject);
|
||||
}
|
||||
}
|
||||
return new Pair<>(array, refObjects);
|
||||
};
|
||||
Pair<ArrayList<Object>, Object[]> context;
|
||||
context = ProgressManager.getInstance().runProcessWithProgressSynchronously(
|
||||
() -> ReadAction.compute(
|
||||
computable
|
||||
), JavaBundle.message("progress.title.searching.references"), true, project);
|
||||
if (context == null) return;
|
||||
ArrayList<Object> array = context.getFirst();
|
||||
Object[] refObjects = context.getSecond();
|
||||
}
|
||||
if (array.isEmpty()) return;
|
||||
|
||||
Object[] selectedObjects = ArrayUtil.toObjectArray(array);
|
||||
@@ -288,17 +242,15 @@ public abstract class CopyPasteReferenceProcessor<TRef extends PsiElement> exten
|
||||
}
|
||||
}
|
||||
|
||||
private static void showHint(@NotNull Editor editor,
|
||||
@NotNull @NlsContexts.HintText String info,
|
||||
@Nullable HyperlinkListener hyperlinkListener) {
|
||||
private static void showHint(@NotNull Editor editor, @NotNull @NlsContexts.HintText String info, @Nullable HyperlinkListener hyperlinkListener) {
|
||||
if (ApplicationManager.getApplication().isUnitTestMode()) return;
|
||||
LightweightHint hint = new LightweightHint(HintUtil.createInformationLabel(info, hyperlinkListener, null, null));
|
||||
|
||||
int flags = HintManager.HIDE_BY_ANY_KEY | HintManager.HIDE_BY_TEXT_CHANGE;
|
||||
HintManagerImpl.getInstanceImpl().showEditorHint(hint, editor, HintManager.UNDER, flags, 0, false);
|
||||
}
|
||||
|
||||
|
||||
private static String getFQName(@NotNull Object element) {
|
||||
return element instanceof PsiClass ? ((PsiClass)element).getQualifiedName() : (String)element;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package com.intellij.codeInsight.editorActions;
|
||||
|
||||
import com.intellij.codeInsight.daemon.impl.analysis.JavaModuleGraphUtil;
|
||||
@@ -25,7 +25,7 @@ import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
public final class JavaCopyPasteReferenceProcessor extends CopyPasteReferenceProcessor<PsiJavaCodeReferenceElement> {
|
||||
public final class JavaCopyPasteReferenceProcessor extends AbstractJavaCopyPasteReferenceProcessor<PsiJavaCodeReferenceElement> {
|
||||
private static final Logger LOG = Logger.getInstance(JavaCopyPasteReferenceProcessor.class);
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
// Copyright 2000-2025 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
|
||||
package org.jetbrains.plugins.groovy.editor;
|
||||
|
||||
import com.intellij.codeInsight.editorActions.CopyPasteReferenceProcessor;
|
||||
import com.intellij.codeInsight.editorActions.AbstractJavaCopyPasteReferenceProcessor;
|
||||
import com.intellij.codeInsight.editorActions.ReferenceData;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.RangeMarker;
|
||||
@@ -23,7 +23,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public final class GroovyReferenceCopyPasteProcessor extends CopyPasteReferenceProcessor<GrReferenceElement> {
|
||||
public final class GroovyReferenceCopyPasteProcessor extends AbstractJavaCopyPasteReferenceProcessor<GrReferenceElement> {
|
||||
private static final Logger LOG = Logger.getInstance(GroovyReferenceCopyPasteProcessor.class);
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user