do posponed formatting after processing each file in batch quick fix application (IDEA-185248)

This commit is contained in:
Dmitry Batkovich
2018-01-23 17:37:20 +03:00
parent 9e31253649
commit 580ddbcfd1
9 changed files with 118 additions and 200 deletions
@@ -1,4 +1,4 @@
// Copyright 2000-2017 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-2018 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.
package com.intellij.codeInsight.daemon.impl;
import com.intellij.codeHighlighting.HighlightDisplayLevel;
@@ -158,9 +158,9 @@ public class LocalInspectionsPass extends ProgressableTextEditorHighlightingPass
@NotNull ProblemDescriptor descriptor,
@NotNull GlobalInspectionContextImpl context) {
InspectionToolPresentation toolPresentation = context.getPresentation(toolWrapper);
LocalDescriptorsUtil.addProblemDescriptors(Collections.singletonList(descriptor), toolPresentation, myIgnoreSuppressed,
context,
toolWrapper.getTool());
BatchModeDescriptorsUtil.addProblemDescriptors(Collections.singletonList(descriptor), toolPresentation, myIgnoreSuppressed,
context,
toolWrapper.getTool());
}
private void addDescriptorsFromInjectedResults(@NotNull InspectionManager iManager, @NotNull GlobalInspectionContextImpl context) {
@@ -1,4 +1,4 @@
// Copyright 2000-2017 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-2018 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.
package com.intellij.codeInspection.ex;
import com.intellij.codeInspection.*;
@@ -12,12 +12,9 @@ import com.intellij.util.TripleFunction;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.*;
public class LocalDescriptorsUtil {
public class BatchModeDescriptorsUtil {
private static final TripleFunction<LocalInspectionTool, PsiElement, GlobalInspectionContext,RefElement> CONVERT =
(tool, element, context) -> {
final PsiNamedElement problemElement = getContainerElement(element, tool, context);
@@ -93,4 +90,9 @@ public class LocalDescriptorsUtil {
PsiNamedElement container = context.getRefManager().getContainerElement(element);
return container != null ? container : containerFromTool;
}
@NotNull
public static CommonProblemDescriptor[] flattenDescriptors(@NotNull List<CommonProblemDescriptor[]> descriptors) {
return descriptors.stream().flatMap(ds -> Arrays.stream(ds)).toArray(CommonProblemDescriptor.ARRAY_FACTORY::create);
}
}
@@ -1,6 +1,4 @@
/*
* Copyright 2000-2017 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-2018 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.
package com.intellij.codeInspection.ex;
@@ -434,7 +432,8 @@ public class GlobalInspectionContextImpl extends GlobalInspectionContextBase imp
.forEach(wrapper -> {
ProblemDescriptor[] descriptors = ((ExternalAnnotatorBatchInspection)wrapper.getTool()).checkFile(file, this, inspectionManager);
InspectionToolPresentation toolPresentation = getPresentation(wrapper);
ReadAction.run(() -> LocalDescriptorsUtil.addProblemDescriptors(Arrays.asList(descriptors), false, this, null, CONVERT, toolPresentation));
ReadAction.run(() -> BatchModeDescriptorsUtil
.addProblemDescriptors(Arrays.asList(descriptors), false, this, null, CONVERT, toolPresentation));
});
return true;
@@ -548,7 +547,7 @@ public class GlobalInspectionContextImpl extends GlobalInspectionContextBase imp
ProblemDescriptionsProcessor problemDescriptionProcessor = getProblemDescriptionProcessor(toolWrapper, wrappersMap);
tool.checkFile(file, inspectionManager, holder, this, problemDescriptionProcessor);
InspectionToolPresentation toolPresentation = getPresentation(toolWrapper);
LocalDescriptorsUtil.addProblemDescriptors(holder.getResults(), false, this, null, CONVERT, toolPresentation);
BatchModeDescriptorsUtil.addProblemDescriptors(holder.getResults(), false, this, null, CONVERT, toolPresentation);
return true;
});
}
@@ -1,18 +1,4 @@
/*
* Copyright 2000-2017 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.
*/
// Copyright 2000-2018 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.
package com.intellij.codeInspection.ex;
@@ -129,11 +115,11 @@ public class LocalQuickFixWrapper extends QuickFixAction {
@Override
protected void performFixesInBatch(@NotNull Project project,
@NotNull CommonProblemDescriptor[] descriptors,
@NotNull List<CommonProblemDescriptor[]> descriptors,
@NotNull GlobalInspectionContextImpl context,
Set<PsiElement> ignoredElements) {
if (myFix instanceof BatchQuickFix) {
applyFix(project, context, descriptors, ignoredElements);
applyFix(project, context, BatchModeDescriptorsUtil.flattenDescriptors(descriptors), ignoredElements);
}
else {
super.performFixesInBatch(project, descriptors, context, ignoredElements);
@@ -1,18 +1,4 @@
/*
* Copyright 2000-2015 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.
*/
// Copyright 2000-2018 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.
package com.intellij.codeInspection.ex;
import com.intellij.codeInspection.CommonProblemDescriptor;
@@ -21,24 +7,41 @@ import com.intellij.codeInspection.QuickFix;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Pair;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.impl.source.PostprocessReformattingAspect;
import com.intellij.psi.presentation.java.SymbolPresentationUtil;
import com.intellij.util.SequentialTask;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
import java.util.List;
public abstract class PerformFixesModalTask implements SequentialTask {
@NotNull
protected final Project myProject;
private final CommonProblemDescriptor[] myDescriptors;
private final List<CommonProblemDescriptor[]> myDescriptorPacks;
private final PsiDocumentManager myDocumentManager;
private int myCount = 0;
private final PostprocessReformattingAspect myReformattingAspect;
private final int myLength;
public PerformFixesModalTask(@NotNull Project project,
@NotNull CommonProblemDescriptor[] descriptors) {
private int myProcessed = 0;
private int myPackIdx = 0;
private int myDescriptorIdx = 0;
protected PerformFixesModalTask(@NotNull Project project,
@NotNull CommonProblemDescriptor[] descriptors) {
this(project, Collections.singletonList(descriptors));
}
protected PerformFixesModalTask(@NotNull Project project,
@NotNull List<CommonProblemDescriptor[]> descriptorPacks) {
myProject = project;
myDescriptors = descriptors;
myDescriptorPacks = descriptorPacks;
myLength = descriptorPacks.stream().mapToInt(ds -> ds.length).sum();
myDocumentManager = PsiDocumentManager.getInstance(myProject);
myReformattingAspect = PostprocessReformattingAspect.getInstance(myProject);
}
@Override
@@ -47,7 +50,7 @@ public abstract class PerformFixesModalTask implements SequentialTask {
@Override
public boolean isDone() {
return myCount > myDescriptors.length - 1;
return myPackIdx > myDescriptorPacks.size() - 1;
}
@Override
@@ -66,9 +69,12 @@ public abstract class PerformFixesModalTask implements SequentialTask {
}
public boolean iteration(ProgressIndicator indicator) {
final CommonProblemDescriptor descriptor = myDescriptors[myCount++];
final Pair<CommonProblemDescriptor, Boolean> pair = nextDescriptor();
CommonProblemDescriptor descriptor = pair.getFirst();
boolean shouldDoPostponedOperations = pair.getSecond();
if (indicator != null) {
indicator.setFraction((double)myCount / myDescriptors.length);
indicator.setFraction((double)myProcessed++ / myLength);
String presentableText = "usages";
if (descriptor instanceof ProblemDescriptor) {
final PsiElement psiElement = ((ProblemDescriptor)descriptor).getPsiElement();
@@ -96,6 +102,9 @@ public abstract class PerformFixesModalTask implements SequentialTask {
myDocumentManager.commitAllDocuments();
if (!runInReadAction[0]) {
applyFix(myProject, descriptor);
if (shouldDoPostponedOperations) {
myReformattingAspect.doPostponedFormatting();
}
}
});
if (runInReadAction[0]) {
@@ -108,4 +117,16 @@ public abstract class PerformFixesModalTask implements SequentialTask {
public void stop() {}
protected abstract void applyFix(Project project, CommonProblemDescriptor descriptor);
private Pair<CommonProblemDescriptor, Boolean> nextDescriptor() {
CommonProblemDescriptor[] descriptors = myDescriptorPacks.get(myPackIdx);
CommonProblemDescriptor descriptor = descriptors[myDescriptorIdx++];
boolean shouldDoPostponedOperations = false;
if (myDescriptorIdx == descriptors.length) {
shouldDoPostponedOperations = true;
myPackIdx++;
myDescriptorIdx = 0;
}
return Pair.create(descriptor, shouldDoPostponedOperations);
}
}
@@ -108,16 +108,16 @@ public class QuickFixAction extends AnAction implements CustomComponentAction {
final InspectionResultsView view = getInvoker(e);
final InspectionTree tree = view.getTree();
try {
Ref<CommonProblemDescriptor[]> descriptors = Ref.create();
Ref<List<CommonProblemDescriptor[]>> descriptors = Ref.create();
Set<VirtualFile> readOnlyFiles = new THashSet<>();
if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(() -> ReadAction.run(() -> {
final ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
indicator.setText("Checking problem descriptors...");
descriptors.set(tree.getSelectedDescriptors(true, readOnlyFiles, false, false));
descriptors.set(tree.getSelectedDescriptorPacks(true, readOnlyFiles, false));
}), InspectionsBundle.message("preparing.for.apply.fix"), true, e.getProject())) {
return;
}
if (isProblemDescriptorsAcceptable() && descriptors.get().length > 0) {
if (isProblemDescriptorsAcceptable() && descriptors.get().size() > 0) {
doApplyFix(view.getProject(), descriptors.get(), readOnlyFiles, tree.getContext());
} else {
doApplyFix(getSelectedElements(view), view);
@@ -136,10 +136,10 @@ public class QuickFixAction extends AnAction implements CustomComponentAction {
@NotNull Set<PsiElement> ignoredElements) {
}
private void doApplyFix(@NotNull final Project project,
@NotNull final CommonProblemDescriptor[] descriptors,
private void doApplyFix(@NotNull Project project,
@NotNull List<CommonProblemDescriptor[]> descriptors,
@NotNull Set<VirtualFile> readOnlyFiles,
@NotNull final GlobalInspectionContextImpl context) {
@NotNull GlobalInspectionContextImpl context) {
if (!FileModificationService.getInstance().prepareVirtualFilesForWrite(project, readOnlyFiles)) return;
final RefManagerImpl refManager = (RefManagerImpl)context.getRefManager();
@@ -163,7 +163,7 @@ public class QuickFixAction extends AnAction implements CustomComponentAction {
}
protected void performFixesInBatch(@NotNull Project project,
@NotNull CommonProblemDescriptor[] descriptors,
@NotNull List<CommonProblemDescriptor[]> descriptors,
@NotNull GlobalInspectionContextImpl context,
Set<PsiElement> ignoredElements) {
final String templatePresentationText = getTemplatePresentation().getText();
@@ -310,7 +310,7 @@ public class QuickFixAction extends AnAction implements CustomComponentAction {
private final Set<PsiElement> myIgnoredElements;
PerformFixesTask(@NotNull Project project,
@NotNull CommonProblemDescriptor[] descriptors,
@NotNull List<CommonProblemDescriptor[]> descriptors,
@NotNull Set<PsiElement> ignoredElements,
@NotNull GlobalInspectionContextImpl context) {
super(project, descriptors);
@@ -1,6 +1,4 @@
/*
* Copyright 2000-2018 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-2018 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.
package com.intellij.codeInspection.offlineViewer;
import com.intellij.codeInsight.daemon.impl.CollectHighlightsUtil;
@@ -164,7 +162,7 @@ class OfflineDescriptorResolveResult {
final int idx = offlineProblemDescriptor.getProblemIndex();
int curIdx = 0;
for (ProblemDescriptor descriptor : list) {
final PsiNamedElement member = LocalDescriptorsUtil.getContainerElement(descriptor.getPsiElement(), localTool, context);
final PsiNamedElement member = BatchModeDescriptorsUtil.getContainerElement(descriptor.getPsiElement(), localTool, context);
if (psiElement instanceof PsiFile || member != null && member.equals(psiElement)) {
if (curIdx == idx) {
return descriptor;
@@ -4,9 +4,9 @@ package com.intellij.codeInspection.ui;
import com.intellij.codeHighlighting.HighlightDisplayLevel;
import com.intellij.codeInspection.CommonProblemDescriptor;
import com.intellij.codeInspection.ProblemDescriptor;
import com.intellij.codeInspection.ex.GlobalInspectionContextImpl;
import com.intellij.codeInspection.ex.InspectionToolWrapper;
import com.intellij.codeInspection.ex.BatchModeDescriptorsUtil;
import com.intellij.codeInspection.reference.RefElement;
import com.intellij.codeInspection.reference.RefEntity;
import com.intellij.concurrency.ConcurrentCollectionFactory;
@@ -15,13 +15,11 @@ import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.profile.codeInspection.ui.inspectionsTree.InspectionsConfigTreeComparator;
import com.intellij.psi.PsiElement;
import com.intellij.psi.SmartPsiElementPointer;
import com.intellij.ui.TreeSpeedSearch;
import com.intellij.ui.treeStructure.Tree;
import com.intellij.util.ArrayUtil;
import com.intellij.util.ConcurrencyUtil;
import com.intellij.util.SmartList;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.MultiMap;
import com.intellij.util.ui.UIUtil;
@@ -38,6 +36,7 @@ import javax.swing.tree.TreePath;
import java.awt.event.MouseEvent;
import java.util.*;
import java.util.concurrent.ConcurrentMap;
import java.util.stream.Stream;
import static com.intellij.codeInspection.CommonProblemDescriptor.DESCRIPTOR_COMPARATOR;
@@ -214,79 +213,50 @@ public class InspectionTree extends Tree {
@NotNull
public CommonProblemDescriptor[] getAllValidSelectedDescriptors() {
return getSelectedDescriptors(false, null, true, false);
return BatchModeDescriptorsUtil.flattenDescriptors(getSelectedDescriptorPacks(false, null, true));
}
@NotNull
public CommonProblemDescriptor[] getSelectedDescriptors() {
return getSelectedDescriptors(false, null, false, false);
return BatchModeDescriptorsUtil.flattenDescriptors(getSelectedDescriptorPacks(false, null, false));
}
@NotNull
public CommonProblemDescriptor[] getSelectedDescriptors(boolean sortedByPosition,
@Nullable Set<VirtualFile> readOnlyFilesSink,
boolean allowResolved,
boolean allowSuppressed) {
public List<CommonProblemDescriptor[]> getSelectedDescriptorPacks(boolean sortedByPosition,
@Nullable Set<VirtualFile> readOnlyFilesSink,
boolean allowResolved) {
final TreePath[] paths = getSelectionPaths();
if (paths == null) return CommonProblemDescriptor.EMPTY_ARRAY;
final TreePath[] selectionPaths = TreeUtil.selectMaximals(paths);
final List<CommonProblemDescriptor> descriptors = new ArrayList<>();
if (paths == null) return Collections.emptyList();
// key can be node or VirtualFile (if problem descriptor node parent is a file/member RefElementNode).
MultiMap<Object, ProblemDescriptionNode> parentToChildNode = new MultiMap<>();
final List<InspectionTreeNode> nonDescriptorNodes = new SmartList<>();
for (TreePath path : selectionPaths) {
final Object[] pathAsArray = path.getPath();
final int length = pathAsArray.length;
final Object node = pathAsArray[length - 1];
if (node instanceof ProblemDescriptionNode) {
if (isNodeValidAndIncluded((ProblemDescriptionNode)node, allowResolved, allowSuppressed)) {
if (length >= 2) {
parentToChildNode.putValue(getVirtualFileFromNode(pathAsArray[length - 2]), (ProblemDescriptionNode)node);
} else {
parentToChildNode.putValue(node, (ProblemDescriptionNode)node);
}
}
} else {
nonDescriptorNodes.add((InspectionTreeNode)node);
MultiMap<Object, CommonProblemDescriptor> parentToChildNode = new MultiMap<>();
TreeUtil
.treePathTraverser(this)
.withRoots(Arrays.asList(paths))
.traverse()
.map(p -> p.getLastPathComponent())
.filter(ProblemDescriptionNode.class)
.filter(node -> node.getDescriptor() != null && isNodeValidAndIncluded(node, allowResolved))
.consumeEach(node -> {
Object key = getVirtualFileOrEntity(node.getElement());
parentToChildNode.putValue(key, node.getDescriptor());
});
final List<CommonProblemDescriptor[]> descriptors = new ArrayList<>();
for (Map.Entry<Object, Collection<CommonProblemDescriptor>> entry : parentToChildNode.entrySet()) {
Object key = entry.getKey();
if (readOnlyFilesSink != null && key instanceof VirtualFile && !((VirtualFile)key).isWritable()) {
readOnlyFilesSink.add((VirtualFile)key);
}
}
for (InspectionTreeNode node : nonDescriptorNodes) {
processChildDescriptorsDeep(node, descriptors, sortedByPosition, allowResolved, allowSuppressed, readOnlyFilesSink);
}
for (Map.Entry<Object, Collection<ProblemDescriptionNode>> entry : parentToChildNode.entrySet()) {
final Collection<ProblemDescriptionNode> siblings = entry.getValue();
if (siblings.size() == 1) {
final ProblemDescriptionNode descriptorNode = ContainerUtil.getFirstItem(siblings);
LOG.assertTrue(descriptorNode != null);
CommonProblemDescriptor descriptor = descriptorNode.getDescriptor();
if (descriptor != null) {
descriptors.add(descriptor);
if (readOnlyFilesSink != null) {
collectReadOnlyFiles(descriptor, readOnlyFilesSink);
}
}
} else {
List<CommonProblemDescriptor> currentDescriptors = new ArrayList<>();
for (ProblemDescriptionNode sibling : siblings) {
final CommonProblemDescriptor descriptor = sibling.getDescriptor();
if (descriptor != null) {
if (readOnlyFilesSink != null) {
collectReadOnlyFiles(descriptor, readOnlyFilesSink);
}
currentDescriptors.add(descriptor);
}
}
if (sortedByPosition) {
Collections.sort(currentDescriptors, DESCRIPTOR_COMPARATOR);
}
descriptors.addAll(currentDescriptors);
Stream<CommonProblemDescriptor> stream = entry.getValue().stream();
if (sortedByPosition) {
stream = stream.sorted(DESCRIPTOR_COMPARATOR);
}
descriptors.add(stream.toArray(CommonProblemDescriptor.ARRAY_FACTORY::create));
}
return descriptors.toArray(CommonProblemDescriptor.EMPTY_ARRAY);
return descriptors;
}
@NotNull
@@ -372,48 +342,10 @@ public class InspectionTree extends Tree {
return count;
}
private static void processChildDescriptorsDeep(InspectionTreeNode node,
List<CommonProblemDescriptor> descriptors,
boolean sortedByPosition,
boolean allowResolved,
boolean allowSuppressed,
@Nullable Set<VirtualFile> readOnlyFilesSink) {
List<CommonProblemDescriptor> descriptorChildren = null;
for (int i = 0; i < node.getChildCount(); i++) {
final TreeNode child = node.getChildAt(i);
if (child instanceof ProblemDescriptionNode) {
if (isNodeValidAndIncluded((ProblemDescriptionNode)child, allowResolved, allowSuppressed)) {
if (sortedByPosition) {
if (descriptorChildren == null) {
descriptorChildren = new ArrayList<>();
}
descriptorChildren.add(((ProblemDescriptionNode)child).getDescriptor());
} else {
descriptors.add(((ProblemDescriptionNode)child).getDescriptor());
}
}
}
else {
processChildDescriptorsDeep((InspectionTreeNode)child, descriptors, sortedByPosition, allowResolved, allowSuppressed, readOnlyFilesSink);
}
}
if (descriptorChildren != null) {
if (descriptorChildren.size() > 1) {
Collections.sort(descriptorChildren, DESCRIPTOR_COMPARATOR);
}
if (readOnlyFilesSink != null) {
collectReadOnlyFiles(descriptorChildren, readOnlyFilesSink);
}
descriptors.addAll(descriptorChildren);
}
}
private static boolean isNodeValidAndIncluded(ProblemDescriptionNode node, boolean allowResolved, boolean allowSuppressed) {
private static boolean isNodeValidAndIncluded(ProblemDescriptionNode node, boolean allowResolved) {
return node.isValid() && (allowResolved ||
(!node.isExcluded() &&
(!node.isAlreadySuppressedFromView() || (allowSuppressed && !node.getAvailableSuppressActions().isEmpty())) &&
!node.isAlreadySuppressedFromView() &&
!node.isQuickFixAppliedFromView()));
}
@@ -488,21 +420,6 @@ public class InspectionTree extends Tree {
return (InspectionGroupNode)currentNode;
}
private static void collectReadOnlyFiles(@NotNull Collection<CommonProblemDescriptor> descriptors, @NotNull Set<VirtualFile> readOnlySink) {
for (CommonProblemDescriptor descriptor : descriptors) {
collectReadOnlyFiles(descriptor, readOnlySink);
}
}
private static void collectReadOnlyFiles(@NotNull CommonProblemDescriptor descriptor, @NotNull Set<VirtualFile> readOnlySink) {
if (descriptor instanceof ProblemDescriptor) {
PsiElement psiElement = ((ProblemDescriptor)descriptor).getPsiElement();
if (psiElement != null && !psiElement.isWritable()) {
readOnlySink.add(psiElement.getContainingFile().getVirtualFile());
}
}
}
@NotNull
private static String[] getGroupPath(@NotNull InspectionGroupNode node) {
List<String> path = new ArrayList<>(2);
@@ -515,20 +432,17 @@ public class InspectionTree extends Tree {
return ArrayUtil.toStringArray(path);
}
@NotNull
private static Object getVirtualFileFromNode(@NotNull Object node) {
if (node instanceof RefElementNode) {
RefEntity entity = ((RefElementNode)node).getElement();
if (entity instanceof RefElement) {
SmartPsiElementPointer pointer = ((RefElement)entity).getPointer();
if (pointer != null) {
VirtualFile file = pointer.getVirtualFile();
if (file != null) {
return file;
}
@Nullable
private static Object getVirtualFileOrEntity(@Nullable RefEntity entity) {
if (entity instanceof RefElement) {
SmartPsiElementPointer pointer = ((RefElement)entity).getPointer();
if (pointer != null) {
VirtualFile file = pointer.getVirtualFile();
if (file != null) {
return file;
}
}
}
return node;
return entity;
}
}
@@ -1,6 +1,4 @@
/*
* Copyright 2000-2017 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-2018 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.
package com.intellij.codeInspection.ui;
import com.intellij.codeInspection.ex.InspectionToolWrapper;
@@ -52,7 +50,7 @@ public class QuickFixPreviewPanelFactory {
myWrapper = view.getTree().getSelectedToolWrapper(true);
LOG.assertTrue(myWrapper != null);
QuickFixAction[] commonFixes = view.getProvider().getCommonQuickFixes(myWrapper, view.getTree());
boolean multipleDescriptors = myView.getTree().getSelectedDescriptors(false, null, false, true).length > 1;
boolean multipleDescriptors = myView.getTree().getSelectedDescriptors().length > 1;
QuickFixAction[] partialFixes = QuickFixAction.EMPTY;
if (multipleDescriptors && commonFixes.length == 0) {
partialFixes = view.getProvider().getPartialQuickFixes(myWrapper, view.getTree());