IDEA-176014: improve migration of AbstractUrlFavoriteAdapter

GitOrigin-RevId: d2645b2bdec700b5afb16c384e36fb7665a16c8d
This commit is contained in:
Sergey Malenkov
2021-10-05 10:22:08 +00:00
committed by intellij-monorepo-bot
parent 01cbf345e1
commit a2d9d88aa0
16 changed files with 213 additions and 46 deletions
@@ -1062,6 +1062,7 @@
<exceptionFilter implementation="com.intellij.openapi.vcs.contentAnnotation.VcsContentAnnotationExceptionFilterFactory"/>
<packageDependencies.visitor language="JAVA" implementationClass="com.intellij.packageDependencies.JavaDependencyVisitorFactory"/>
<pathMacroFilter implementation="com.intellij.execution.configuration.JavaRunConfigurationPathMacroFilter"/>
<bookmarkProvider implementation="com.intellij.ide.bookmark.providers.PackageBookmarkProvider"/>
<favoriteNodeProvider implementation="com.intellij.ide.favoritesTreeView.PsiPackageFavoriteNodeProvider"/>
<favoriteNodeProvider implementation="com.intellij.ide.favoritesTreeView.PsiMethodFavoriteNodeProvider"/>
<favoriteNodeProvider implementation="com.intellij.ide.favoritesTreeView.PsiFieldFavoriteNodeProvider"/>
@@ -0,0 +1,35 @@
// 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.ide.bookmark.providers
import com.intellij.ide.bookmark.Bookmark
import com.intellij.ide.projectView.impl.nodes.PackageElement
import java.util.Objects
internal class PackageBookmark(override val provider: PackageBookmarkProvider, val element: PackageElement) : Bookmark {
internal val name
get() = element.`package`.qualifiedName
internal val module
get() = element.module?.name
internal val library
get() = element.isLibraryElement
override val attributes: Map<String, String>
get() = module?.let { mapOf("package" to name, "module" to it, "library" to library.toString()) }
?: mapOf("package" to name, "library" to library.toString())
override fun createNode() = PackageNode(provider.project, this)
override fun canNavigate() = element.`package`.canNavigate()
override fun canNavigateToSource() = element.`package`.canNavigateToSource()
override fun navigate(requestFocus: Boolean) = element.`package`.navigate(requestFocus)
override fun hashCode() = Objects.hash(provider, element)
override fun equals(other: Any?) = other === this || other is PackageBookmark
&& other.provider == provider
&& other.element == element
override fun toString() = "PackageBookmark(package=$name,module=$module,library=$library,provider=$provider)"
}
@@ -0,0 +1,47 @@
// 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.ide.bookmark.providers
import com.intellij.ide.bookmark.Bookmark
import com.intellij.ide.bookmark.BookmarkProvider
import com.intellij.ide.projectView.impl.nodes.PackageElement
import com.intellij.ide.util.treeView.AbstractTreeNode
import com.intellij.ide.util.treeView.NodeDescriptor
import com.intellij.openapi.module.ModuleManager
import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.ui.configuration.ProjectSettingsService
import com.intellij.openapi.util.text.StringUtil
import com.intellij.psi.JavaPsiFacade
internal class PackageBookmarkProvider(private val project: Project) : BookmarkProvider {
override fun getWeight() = 100
override fun getProject() = project
internal val moduleManager
get() = if (project.isDisposed) null else ModuleManager.getInstance(project)
internal val projectSettingsService
get() = if (project.isDisposed) null else ProjectSettingsService.getInstance(project)
override fun compare(bookmark1: Bookmark, bookmark2: Bookmark): Int {
bookmark1 as PackageBookmark
bookmark2 as PackageBookmark
StringUtil.naturalCompare(bookmark1.name, bookmark2.name).let { if (it != 0) return it }
StringUtil.naturalCompare(bookmark1.module, bookmark2.module).let { if (it != 0) return it }
if (bookmark1.library && !bookmark2.library) return +1
if (!bookmark1.library && bookmark2.library) return -1
return 0
}
override fun createBookmark(map: MutableMap<String, String>): PackageBookmark? {
val psi = map["package"]?.let { JavaPsiFacade.getInstance(project).findPackage(it) } ?: return null
val module = map["module"]?.let { ModuleManager.getInstance(project).findModuleByName(it) }
return PackageBookmark(this, PackageElement(module, psi, map["library"].toBoolean()))
}
override fun createBookmark(context: Any?): PackageBookmark? = when (context) {
is AbstractTreeNode<*> -> createBookmark(context.value)
is NodeDescriptor<*> -> createBookmark(context.element)
is PackageElement -> PackageBookmark(this, context)
else -> null
}
}
@@ -0,0 +1,20 @@
// 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.ide.bookmark.providers
import com.intellij.ide.bookmark.ui.tree.BookmarkNode
import com.intellij.ide.projectView.PresentationData
import com.intellij.ide.projectView.impl.CompoundIconProvider
import com.intellij.ide.util.treeView.AbstractTreeNode
import com.intellij.openapi.project.Project
internal class PackageNode(project: Project, bookmark: PackageBookmark) : BookmarkNode<PackageBookmark>(project, bookmark) {
override fun getChildren() = emptyList<AbstractTreeNode<*>>()
override fun update(presentation: PresentationData) {
presentation.setIcon(wrapIcon(CompoundIconProvider.findIcon(value?.element?.`package`, 0)))
presentation.tooltip = bookmarkDescription
presentation.presentableText = value?.name
presentation.locationString = value?.module
}
}
@@ -1,4 +1,4 @@
// 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.
// 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.ide.favoritesTreeView;
@@ -24,11 +24,12 @@ import com.intellij.psi.PsiFile;
import com.intellij.psi.presentation.java.ClassPresentationUtil;
import com.intellij.psi.search.GlobalSearchScope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collection;
public class PsiClassFavoriteNodeProvider extends FavoriteNodeProvider {
public class PsiClassFavoriteNodeProvider extends FavoriteNodeProvider implements AbstractUrlFavoriteConverter {
@Override
public Collection<AbstractTreeNode<?>> getFavoriteNodes(final DataContext context, @NotNull final ViewSettings viewSettings) {
final Project project = CommonDataKeys.PROJECT.getData(context);
@@ -131,7 +132,12 @@ public class PsiClassFavoriteNodeProvider extends FavoriteNodeProvider {
if (DumbService.isDumb(project)) {
return null;
}
var context = createBookmarkContext(project, url, moduleName);
return context == null ? null : new Object[]{context};
}
@Override
public @Nullable Object createBookmarkContext(@NotNull Project project, @NotNull String url, @Nullable String moduleName) {
GlobalSearchScope scope = null;
if (moduleName != null) {
final Module module = ModuleManager.getInstance(project).findModuleByName(moduleName);
@@ -142,8 +148,6 @@ public class PsiClassFavoriteNodeProvider extends FavoriteNodeProvider {
if (scope == null) {
scope = GlobalSearchScope.allScope(project);
}
final PsiClass aClass = JavaPsiFacade.getInstance(project).findClass(url, scope);
if (aClass == null) return null;
return new Object[]{aClass};
return JavaPsiFacade.getInstance(project).findClass(url, scope);
}
}
@@ -1,4 +1,4 @@
// 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.
// 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.ide.favoritesTreeView;
@@ -21,11 +21,12 @@ import com.intellij.psi.PsiField;
import com.intellij.psi.presentation.java.ClassPresentationUtil;
import com.intellij.psi.search.GlobalSearchScope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collection;
public class PsiFieldFavoriteNodeProvider extends FavoriteNodeProvider {
public class PsiFieldFavoriteNodeProvider extends FavoriteNodeProvider implements AbstractUrlFavoriteConverter {
@Override
public Collection<AbstractTreeNode<?>> getFavoriteNodes(final DataContext context, @NotNull final ViewSettings viewSettings) {
final Project project = CommonDataKeys.PROJECT.getData(context);
@@ -113,14 +114,19 @@ public class PsiFieldFavoriteNodeProvider extends FavoriteNodeProvider {
@Override
public Object[] createPathFromUrl(final Project project, final String url, final String moduleName) {
if (DumbService.isDumb(project)) return null;
var context = createBookmarkContext(project, url, moduleName);
return context == null ? null : new Object[]{context};
}
@Override
public @Nullable Object createBookmarkContext(@NotNull Project project, @NotNull String url, @Nullable String moduleName) {
final Module module = moduleName != null ? ModuleManager.getInstance(project).findModuleByName(moduleName) : null;
final GlobalSearchScope scope = module != null ? GlobalSearchScope.moduleScope(module) : GlobalSearchScope.allScope(project);
final String[] paths = url.split(";");
if (paths.length != 2) return null;
final PsiClass aClass = JavaPsiFacade.getInstance(project).findClass(paths[0], scope);
if (aClass == null) return null;
final PsiField aField = aClass.findFieldByName(paths[1], false);
return new Object[]{aField};
return aClass.findFieldByName(paths[1], false);
}
@@ -1,4 +1,4 @@
// 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.
// 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.ide.favoritesTreeView;
@@ -21,11 +21,12 @@ import com.intellij.psi.PsiMethod;
import com.intellij.psi.presentation.java.ClassPresentationUtil;
import com.intellij.psi.util.PsiFormatUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collection;
public class PsiMethodFavoriteNodeProvider extends FavoriteNodeProvider {
public class PsiMethodFavoriteNodeProvider extends FavoriteNodeProvider implements AbstractUrlFavoriteConverter {
@Override
public Collection<AbstractTreeNode<?>> getFavoriteNodes(final DataContext context, @NotNull final ViewSettings viewSettings) {
final Project project = CommonDataKeys.PROJECT.getData(context);
@@ -115,8 +116,12 @@ public class PsiMethodFavoriteNodeProvider extends FavoriteNodeProvider {
@Override
public Object[] createPathFromUrl(final Project project, final String url, final String moduleName) {
if (DumbService.isDumb(project)) return null;
final PsiMethod method = RefMethodImpl.findPsiMethod(PsiManager.getInstance(project), url);
if (method == null) return null;
return new Object[]{method};
var context = createBookmarkContext(project, url, moduleName);
return context == null ? null : new Object[]{context};
}
@Override
public @Nullable Object createBookmarkContext(@NotNull Project project, @NotNull String url, @Nullable String moduleName) {
return RefMethodImpl.findPsiMethod(PsiManager.getInstance(project), url);
}
}
@@ -1,4 +1,4 @@
// 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.
// 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.ide.favoritesTreeView;
@@ -26,13 +26,14 @@ import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiPackage;
import com.intellij.psi.search.GlobalSearchScope;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
public class PsiPackageFavoriteNodeProvider extends FavoriteNodeProvider {
public class PsiPackageFavoriteNodeProvider extends FavoriteNodeProvider implements AbstractUrlFavoriteConverter {
@Override
public Collection<AbstractTreeNode<?>> getFavoriteNodes(final DataContext context, @NotNull final ViewSettings viewSettings) {
final Project project = CommonDataKeys.PROJECT.getData(context);
@@ -170,12 +171,17 @@ public class PsiPackageFavoriteNodeProvider extends FavoriteNodeProvider {
@Override
public Object[] createPathFromUrl(final Project project, final String url, final String moduleName) {
var context = createBookmarkContext(project, url, moduleName);
return context == null ? null : new Object[]{context};
}
@Override
public @Nullable Object createBookmarkContext(@NotNull Project project, @NotNull String url, @Nullable String moduleName) {
final Module module = moduleName != null ? ModuleManager.getInstance(project).findModuleByName(moduleName) : null;
// module can be null if 'show module' turned off
final PsiPackage aPackage = JavaPsiFacade.getInstance(project).findPackage(url);
if (aPackage == null) return null;
PackageElement packageElement = new PackageElement(module, aPackage, false);
return new Object[]{packageElement};
return new PackageElement(module, aPackage, false);
}
@Override
@@ -2,7 +2,6 @@
package com.intellij.ide.bookmark.providers
import com.intellij.ide.bookmark.*
import com.intellij.ide.favoritesTreeView.AbstractUrlFavoriteAdapter
import com.intellij.ide.projectView.impl.DirectoryUrl
import com.intellij.ide.projectView.impl.PsiFileUrl
import com.intellij.ide.util.treeView.AbstractTreeNode
@@ -15,8 +14,6 @@ import com.intellij.openapi.editor.event.EditorMouseEvent
import com.intellij.openapi.editor.event.EditorMouseEventArea
import com.intellij.openapi.editor.event.EditorMouseListener
import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.openapi.progress.ProcessCanceledException
import com.intellij.openapi.project.DumbService
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.SystemInfo
import com.intellij.openapi.util.TextRange
@@ -61,8 +58,7 @@ class LineBookmarkProvider(private val project: Project) : BookmarkProvider, Edi
is AbstractTreeNode<*> -> createBookmark(context.value)
is NodeDescriptor<*> -> createBookmark(context.element)
// below // migrate old bookmarks and favorites
is com.intellij.ide.bookmarks.Bookmark -> createBookmark(context.file, context.line) //
is AbstractUrlFavoriteAdapter -> createBookmark(context)
is com.intellij.ide.bookmarks.Bookmark -> createBookmark(context.file, context.line)
is DirectoryUrl -> createBookmark(context.url)
is PsiFileUrl -> createBookmark(context.url)
// above // migrate old bookmarks and favorites
@@ -87,12 +83,6 @@ class LineBookmarkProvider(private val project: Project) : BookmarkProvider, Edi
?.let { VirtualFileManager.getInstance().findFileByUrl(it) }
?.let { createBookmark(it, line) }
private fun createBookmark(adapter: AbstractUrlFavoriteAdapter) = when {
!adapter.nodeProvider::class.java.name.startsWith("com.intellij.ide.favoritesTreeView.Psi") -> null
DumbService.isDumb(project) -> throw ProcessCanceledException() // wait for the end of indexing
else -> adapter.createPath(project)?.singleOrNull()?.let { createBookmark(it) }
}
private fun createBookmark(element: PsiElement): FileBookmark? {
if (element is PsiFileSystemItem) return element.virtualFile?.let { createBookmark(it) }
if (element is PsiCompiledElement) return null
@@ -2,11 +2,10 @@
package com.intellij.ide.bookmark.providers
import com.intellij.ide.bookmark.Bookmark
import com.intellij.ide.bookmark.ui.tree.ModuleNode
import org.jetbrains.annotations.Nls
import java.util.*
import java.util.Objects
class ModuleBookmark(override val provider: ModuleBookmarkProvider, val name: @Nls String, val isGroup: Boolean) : Bookmark {
internal class ModuleBookmark(override val provider: ModuleBookmarkProvider, val name: @Nls String, val isGroup: Boolean) : Bookmark {
override val attributes: Map<String, String>
get() = when (isGroup) {
@@ -12,8 +12,8 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.roots.ui.configuration.ProjectSettingsService
import com.intellij.openapi.util.text.StringUtil
class ModuleBookmarkProvider(private val project: Project) : BookmarkProvider {
override fun getWeight() = 10
internal class ModuleBookmarkProvider(private val project: Project) : BookmarkProvider {
override fun getWeight() = 200
override fun getProject() = project
internal val moduleManager
@@ -23,14 +23,11 @@ class ModuleBookmarkProvider(private val project: Project) : BookmarkProvider {
get() = if (project.isDisposed) null else ProjectSettingsService.getInstance(project)
override fun compare(bookmark1: Bookmark, bookmark2: Bookmark): Int {
val moduleBookmark1 = bookmark1 as? ModuleBookmark
val moduleBookmark2 = bookmark2 as? ModuleBookmark
if (moduleBookmark1 == null && moduleBookmark2 == null) return 0
if (moduleBookmark1 == null) return -1
if (moduleBookmark2 == null) return 1
if (moduleBookmark1.isGroup && !moduleBookmark2.isGroup) return -1
if (!moduleBookmark1.isGroup && moduleBookmark2.isGroup) return 1
return StringUtil.naturalCompare(moduleBookmark1.name, moduleBookmark2.name)
bookmark1 as ModuleBookmark
bookmark2 as ModuleBookmark
if (bookmark1.isGroup && !bookmark2.isGroup) return -1
if (!bookmark1.isGroup && bookmark2.isGroup) return +1
return StringUtil.naturalCompare(bookmark1.name, bookmark2.name)
}
override fun createBookmark(map: MutableMap<String, String>) =
@@ -1,14 +1,14 @@
// 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.ide.bookmark.ui.tree
package com.intellij.ide.bookmark.providers
import com.intellij.icons.AllIcons.Nodes
import com.intellij.ide.bookmark.providers.ModuleBookmark
import com.intellij.ide.bookmark.ui.tree.BookmarkNode
import com.intellij.ide.projectView.PresentationData
import com.intellij.ide.util.treeView.AbstractTreeNode
import com.intellij.openapi.project.Project
import com.intellij.ui.SimpleTextAttributes
class ModuleNode(project: Project, bookmark: ModuleBookmark) : BookmarkNode<ModuleBookmark>(project, bookmark) {
internal class ModuleNode(project: Project, bookmark: ModuleBookmark) : BookmarkNode<ModuleBookmark>(project, bookmark) {
override fun getChildren() = emptyList<AbstractTreeNode<*>>()
@@ -0,0 +1,20 @@
// 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.ide.favoritesTreeView
import com.intellij.ide.bookmark.Bookmark
import com.intellij.ide.bookmark.BookmarkProvider
import com.intellij.openapi.project.Project
internal class AbstractUrlBookmarkProvider(private val project: Project) : BookmarkProvider {
override fun getWeight() = Int.MAX_VALUE
override fun getProject() = project
override fun compare(bookmark1: Bookmark?, bookmark2: Bookmark?) = 0
override fun createBookmark(map: Map<String, String>): Bookmark? = null
override fun createBookmark(context: Any?) = when (context) {
is AbstractUrlFavoriteAdapter -> context.createBookmark(project)
else -> null
}
}
@@ -1,13 +1,18 @@
// Copyright 2000-2021 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.
// 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.ide.favoritesTreeView;
import com.intellij.ide.bookmark.Bookmark;
import com.intellij.ide.projectView.impl.AbstractUrl;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class AbstractUrlFavoriteAdapter extends AbstractUrl {
private static final Logger LOG = Logger.getInstance(AbstractUrlFavoriteAdapter.class);
@NotNull
private final FavoriteNodeProvider myNodeProvider;
@@ -21,6 +26,17 @@ public class AbstractUrlFavoriteAdapter extends AbstractUrl {
return myNodeProvider.createPathFromUrl(project, url, moduleName);
}
@Nullable Bookmark createBookmark(@NotNull Project project) {
if (myNodeProvider instanceof AbstractUrlFavoriteConverter) {
var converter = (AbstractUrlFavoriteConverter)myNodeProvider;
var bookmark = converter.createBookmark(project, url, moduleName);
if (bookmark != null) return bookmark;
var id = myNodeProvider.getFavoriteTypeId();
LOG.warn("cannot convert favorite: id=" + id + "; module=" + moduleName + "; url: " + url);
}
return null;
}
@Override
protected AbstractUrl createUrl(String moduleName, String url) {
return null;
@@ -0,0 +1,20 @@
// 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.ide.favoritesTreeView;
import com.intellij.ide.bookmark.Bookmark;
import com.intellij.ide.bookmark.BookmarksManager;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public interface AbstractUrlFavoriteConverter {
@Nullable Object createBookmarkContext(@NotNull Project project, @NotNull String url, @Nullable String moduleName);
default @Nullable Bookmark createBookmark(@NotNull Project project, @NotNull String url, @Nullable String moduleName) {
BookmarksManager manager = BookmarksManager.getInstance(project);
if (manager == null) return null;
Object context = createBookmarkContext(project, url, moduleName);
if (context == null) return null;
return manager.createBookmark(context);
}
}
@@ -75,6 +75,7 @@
<projectService serviceImplementation="com.intellij.ide.bookmarks.BookmarkManager"/>
<projectService serviceInterface="com.intellij.ide.bookmark.BookmarksManager"
serviceImplementation="com.intellij.ide.bookmark.BookmarksManagerImpl"/>
<bookmarkProvider implementation="com.intellij.ide.favoritesTreeView.AbstractUrlBookmarkProvider" order="first"/>
<bookmarkProvider implementation="com.intellij.ide.bookmark.providers.LineBookmarkProvider" order="last"/>
<bookmarkProvider implementation="com.intellij.ide.bookmark.providers.ModuleBookmarkProvider"/>
<bookmarksListProvider implementation="com.intellij.ide.bookmark.ui.tree.BookmarkListProvider"/>