mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
re-fix "comparator breaks contract" error (e.g. in ea.jetbrains.com/browser/ea_reports/9957034): introduce Usage.getNavigationOffset() and use it to sort children nodes
GitOrigin-RevId: 830f5693452c6a2b4ac5c33bd94d06280fdce1a3
This commit is contained in:
committed by
intellij-monorepo-bot
parent
ea1533a948
commit
a19bab9414
@@ -28,6 +28,7 @@ import com.intellij.openapi.util.*;
|
||||
import com.intellij.openapi.vcs.FileStatusListener;
|
||||
import com.intellij.openapi.vcs.FileStatusManager;
|
||||
import com.intellij.openapi.vfs.ReadonlyStatusHandler;
|
||||
import com.intellij.openapi.vfs.VfsUtilCore;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.pom.Navigatable;
|
||||
import com.intellij.psi.*;
|
||||
@@ -125,29 +126,23 @@ public class UsageViewImpl implements UsageViewEx {
|
||||
|
||||
public static final Comparator<Usage> USAGE_COMPARATOR_BY_FILE_AND_OFFSET = (o1, o2) -> {
|
||||
if (o1 == o2) return 0;
|
||||
if (o1 == NullUsage.INSTANCE) return -1;
|
||||
if (o2 == NullUsage.INSTANCE) return 1;
|
||||
if (o1 instanceof Comparable && o2 instanceof Comparable && o1.getClass() == o2.getClass()) {
|
||||
//noinspection unchecked
|
||||
int selfcompared = ((Comparable<Usage>)o1).compareTo(o2);
|
||||
if (selfcompared != 0) return selfcompared;
|
||||
|
||||
if (o1 instanceof UsageInFile && o2 instanceof UsageInFile) {
|
||||
UsageInFile u1 = (UsageInFile)o1;
|
||||
UsageInFile u2 = (UsageInFile)o2;
|
||||
|
||||
VirtualFile f1 = u1.getFile();
|
||||
VirtualFile f2 = u2.getFile();
|
||||
|
||||
if (f1 != null && f1.isValid() && f2 != null && f2.isValid()) {
|
||||
return f1.getPresentableUrl().compareTo(f2.getPresentableUrl());
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
if (o1 == NullUsage.INSTANCE || o1 == null) return -1;
|
||||
if (o2 == NullUsage.INSTANCE || o2 == null) return 1;
|
||||
int c = compareByFileAndOffset(o1, o2);
|
||||
if (c != 0) return c;
|
||||
return o1.toString().compareTo(o2.toString());
|
||||
};
|
||||
|
||||
private static int compareByFileAndOffset(@NotNull Usage o1, @NotNull Usage o2) {
|
||||
VirtualFile file1 = o1 instanceof UsageInFile ? ((UsageInFile)o1).getFile() : null;
|
||||
VirtualFile file2 = o2 instanceof UsageInFile ? ((UsageInFile)o2).getFile() : null;
|
||||
if (file1 == null || file2 == null) return 0;
|
||||
if (file1.equals(file2)) {
|
||||
return Integer.compare(o1.getNavigationOffset(), o2.getNavigationOffset());
|
||||
}
|
||||
return VfsUtilCore.compareByPath(file1, file2);
|
||||
}
|
||||
|
||||
@NonNls public static final String HELP_ID = "ideaInterface.find";
|
||||
private UsageContextPanel myCurrentUsageContextPanel; // accessed in EDT only
|
||||
private final List<UsageContextPanel> myAllUsageContextPanels = new ArrayList<>(); // accessed in EDT only
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
|
||||
package com.intellij.usages;
|
||||
|
||||
import com.intellij.openapi.editor.LogicalPosition;
|
||||
import com.intellij.openapi.fileEditor.FileEditorLocation;
|
||||
import com.intellij.openapi.fileEditor.TextEditor;
|
||||
import com.intellij.openapi.fileEditor.TextEditorLocation;
|
||||
import com.intellij.pom.Navigatable;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -23,4 +26,21 @@ public interface Usage extends Navigatable {
|
||||
void selectInEditor();
|
||||
|
||||
void highlightInEditor();
|
||||
|
||||
/**
|
||||
* @return offset of this usage in its containing file to which the corresponding "Go to Source" action should navigate,
|
||||
* or {@code -1} if the offset can't be computed for some reason.
|
||||
* This offset is used in "Find Usages" tool window tree to group usages by containing file and then by their offsets.
|
||||
* Please consider overriding this method if you implement {@link Usage} from scratch and can compute its offset efficiently.
|
||||
* The already existing implementations in the core, like {@link UsageInfo2UsageAdapter} implement this method efficiently enough, so there's no need to override them.
|
||||
* Also, please make your {@link Usage} implementation extend {@link com.intellij.usages.rules.UsageInFile} to be able to group usages in "Find Usages" tool window.
|
||||
*/
|
||||
default int getNavigationOffset() {
|
||||
FileEditorLocation location = getLocation();
|
||||
if (location instanceof TextEditorLocation) {
|
||||
LogicalPosition position = ((TextEditorLocation)location).getPosition();
|
||||
return ((TextEditor)location.getEditor()).getEditor().logicalPositionToOffset(position);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class UsageInfo2UsageAdapter implements UsageInModule, UsageInfoAdapter,
|
||||
UsageInLibrary, UsageInFile, PsiElementUsage,
|
||||
MergeableUsage, Comparable<UsageInfo2UsageAdapter>,
|
||||
MergeableUsage,
|
||||
RenameableUsage, DataProvider, UsagePresentation {
|
||||
public static final NotNullFunction<UsageInfo, Usage> CONVERTER = UsageInfo2UsageAdapter::new;
|
||||
private static final Comparator<UsageInfo> BY_NAVIGATION_OFFSET = Comparator.comparingInt(UsageInfo::getNavigationOffset);
|
||||
|
||||
Reference in New Issue
Block a user