From 3068fceeea6d139e4166f93b06215bdf14e4d1bd Mon Sep 17 00:00:00 2001 From: Roman Shevchenko Date: Tue, 8 Nov 2016 17:04:11 +0100 Subject: [PATCH] [platform] decompiler calls in hierarchy browser (IDEA-163673) --- .../ide/hierarchy/HierarchyBrowserBaseEx.java | 18 ++--- .../fileEditor/PsiElementNavigatable.java | 68 +++++++++++++++++++ .../src/messages/EditorBundle.properties | 4 +- 3 files changed, 80 insertions(+), 10 deletions(-) create mode 100644 platform/platform-api/src/com/intellij/openapi/fileEditor/PsiElementNavigatable.java diff --git a/platform/lang-impl/src/com/intellij/ide/hierarchy/HierarchyBrowserBaseEx.java b/platform/lang-impl/src/com/intellij/ide/hierarchy/HierarchyBrowserBaseEx.java index 07eefa63f449..574a01ccfa6d 100644 --- a/platform/lang-impl/src/com/intellij/ide/hierarchy/HierarchyBrowserBaseEx.java +++ b/platform/lang-impl/src/com/intellij/ide/hierarchy/HierarchyBrowserBaseEx.java @@ -31,12 +31,11 @@ import com.intellij.openapi.actionSystem.*; import com.intellij.openapi.actionSystem.ex.ComboBoxAction; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.diagnostic.Logger; -import com.intellij.openapi.fileEditor.OpenFileDescriptor; +import com.intellij.openapi.fileEditor.PsiElementNavigatable; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Ref; -import com.intellij.openapi.vfs.VirtualFile; import com.intellij.pom.Navigatable; import com.intellij.psi.*; import com.intellij.psi.search.scope.packageSet.NamedScope; @@ -140,13 +139,14 @@ public abstract class HierarchyBrowserBaseEx extends HierarchyBrowserBase implem @Override @Nullable protected Navigatable createDescriptorForNode(DefaultMutableTreeNode node) { - final HierarchyNodeDescriptor descriptor = getDescriptor(node); - if (descriptor == null) return null; - PsiElement psiElement = getOpenFileElementFromDescriptor(descriptor); - if (psiElement == null || !psiElement.isValid()) return null; - final VirtualFile virtualFile = psiElement.getContainingFile().getVirtualFile(); - if (virtualFile == null) return null; - return new OpenFileDescriptor(psiElement.getProject(), virtualFile, psiElement.getTextOffset()); + HierarchyNodeDescriptor descriptor = getDescriptor(node); + if (descriptor != null) { + PsiElement psiElement = getOpenFileElementFromDescriptor(descriptor); + if (psiElement != null && psiElement.isValid()) { + return new PsiElementNavigatable(psiElement); + } + } + return null; } @Override diff --git a/platform/platform-api/src/com/intellij/openapi/fileEditor/PsiElementNavigatable.java b/platform/platform-api/src/com/intellij/openapi/fileEditor/PsiElementNavigatable.java new file mode 100644 index 000000000000..4f5a0c533c22 --- /dev/null +++ b/platform/platform-api/src/com/intellij/openapi/fileEditor/PsiElementNavigatable.java @@ -0,0 +1,68 @@ +/* + * Copyright 2000-2016 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.intellij.openapi.fileEditor; + +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.ReadAction; +import com.intellij.openapi.editor.EditorBundle; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.progress.Task; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.pom.Navigatable; +import com.intellij.psi.PsiElement; +import com.intellij.psi.SmartPointerManager; +import com.intellij.psi.SmartPsiElementPointer; +import org.jetbrains.annotations.NotNull; + +public class PsiElementNavigatable implements Navigatable { + private final SmartPsiElementPointer myPointer; + + public PsiElementNavigatable(@NotNull PsiElement element) { + myPointer = SmartPointerManager.getInstance(element.getProject()).createSmartPsiElementPointer(element); + } + + @Override + public final void navigate(boolean requestFocus) { + PsiElement element = myPointer.getElement(); + if (element != null && element.isValid()) { + VirtualFile file = element.getContainingFile().getVirtualFile(); + if (file != null) { + new Task.Backgroundable(element.getProject(), EditorBundle.message("editor.open.file.progress", file.getName())) { + @Override + public void run(@NotNull ProgressIndicator indicator) { + if (element.isValid() && !myProject.isDisposed()) { + int offset = ReadAction.compute(() -> element.getTextOffset()); // may trigger decompilation + indicator.checkCanceled(); + OpenFileDescriptor descriptor = new OpenFileDescriptor(myProject, file, offset); + ApplicationManager.getApplication().invokeLater(() -> descriptor.navigate(requestFocus), myProject.getDisposed()); + } + } + }.queue(); + } + } + } + + @Override + public boolean canNavigate() { + PsiElement element = myPointer.getElement(); + return element != null && element.isValid() && element.getContainingFile().getVirtualFile() != null; + } + + @Override + public boolean canNavigateToSource() { + return canNavigate(); + } +} \ No newline at end of file diff --git a/platform/platform-resources-en/src/messages/EditorBundle.properties b/platform/platform-resources-en/src/messages/EditorBundle.properties index 87c7ec599eb1..0e2d7e1c87bc 100644 --- a/platform/platform-resources-en/src/messages/EditorBundle.properties +++ b/platform/platform-resources-en/src/messages/EditorBundle.properties @@ -27,4 +27,6 @@ forced.soft.wrap.message=This document contains very long lines. Soft wraps were forced.soft.wrap.hide.message=Hide notification forced.soft.wrap.dont.show.again.message=Don't show again editor.notification.default.action.name=Notification actions -editor.notification.settings.option.name=Settings... \ No newline at end of file +editor.notification.settings.option.name=Settings... + +editor.open.file.progress=Opening {0} \ No newline at end of file