mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
test discovery: add action to find all tests for a changelist
(cherry picked from commit a6303e3fd4a6e4fec9ed48863ae2a24f0da43153)
This commit is contained in:
committed by
Sergey Ignatov
parent
d52ef307ba
commit
ec2e9357ad
+108
-37
@@ -1,6 +1,7 @@
|
||||
// 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.execution.testDiscovery;
|
||||
|
||||
import com.intellij.codeInsight.actions.FormatChangedTextUtil;
|
||||
import com.intellij.codeInsight.navigation.ListBackgroundUpdaterTask;
|
||||
import com.intellij.execution.Executor;
|
||||
import com.intellij.execution.JavaTestConfigurationBase;
|
||||
@@ -12,11 +13,14 @@ import com.intellij.find.FindUtil;
|
||||
import com.intellij.find.actions.CompositeActiveComponent;
|
||||
import com.intellij.icons.AllIcons;
|
||||
import com.intellij.ide.DataManager;
|
||||
import com.intellij.ide.highlighter.JavaFileType;
|
||||
import com.intellij.ide.util.DefaultPsiElementCellRenderer;
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.ReadAction;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.keymap.KeymapUtil;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.module.ModuleUtilCore;
|
||||
@@ -24,10 +28,14 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.popup.IconButton;
|
||||
import com.intellij.openapi.ui.popup.JBPopup;
|
||||
import com.intellij.openapi.ui.popup.PopupChooserBuilder;
|
||||
import com.intellij.openapi.util.Couple;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.openapi.vcs.VcsDataKeys;
|
||||
import com.intellij.openapi.vcs.changes.Change;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.intellij.ui.CollectionListModel;
|
||||
import com.intellij.ui.InplaceButton;
|
||||
import com.intellij.ui.components.JBList;
|
||||
@@ -37,12 +45,13 @@ import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.PsiNavigateUtil;
|
||||
import com.intellij.util.ui.EdtInvocationManager;
|
||||
import com.intellij.util.ui.JBDimension;
|
||||
import one.util.streamex.StreamEx;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.intellij.openapi.actionSystem.CommonDataKeys.EDITOR;
|
||||
@@ -57,43 +66,89 @@ public class ShowDiscoveredTestsAction extends AnAction {
|
||||
|
||||
PsiElement at = file == null || editor == null ? null : file.findElementAt(editor.getCaretModel().getOffset());
|
||||
PsiMethod method = PsiTreeUtil.getParentOfType(at, PsiMethod.class);
|
||||
if (method == null || project == null) {
|
||||
e.getPresentation().setEnabledAndVisible(false);
|
||||
}
|
||||
e.getPresentation().setEnabledAndVisible(method != null && project != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
Editor editor = e.getData(EDITOR);
|
||||
PsiFile file = e.getData(PSI_FILE);
|
||||
Editor editor = e.getRequiredData(EDITOR);
|
||||
PsiFile file = e.getRequiredData(PSI_FILE);
|
||||
Project project = e.getProject();
|
||||
|
||||
assert project != null;
|
||||
|
||||
PsiElement at = file == null || editor == null ? null : file.findElementAt(editor.getCaretModel().getOffset());
|
||||
PsiElement at = file.findElementAt(editor.getCaretModel().getOffset());
|
||||
PsiMethod method = PsiTreeUtil.getParentOfType(at, PsiMethod.class);
|
||||
assert method != null;
|
||||
|
||||
PsiClass c = method.getContainingClass();
|
||||
String fqn = c != null ? c.getQualifiedName() : null;
|
||||
if (fqn == null) return;
|
||||
String methodName = method.getName();
|
||||
String methodPresentationName = c.getName() + "." + methodName;
|
||||
|
||||
DataContext dataContext = DataManager.getInstance().getDataContext(editor.getContentComponent());
|
||||
showDiscoveredTests(project, dataContext, methodPresentationName, Collections.singletonList(method));
|
||||
}
|
||||
|
||||
public static class FromChangeList extends AnAction {
|
||||
@Override
|
||||
public void update(AnActionEvent e) {
|
||||
Project project = e.getProject();
|
||||
Change[] changes = e.getData(VcsDataKeys.CHANGES);
|
||||
|
||||
e.getPresentation().setEnabledAndVisible(project != null && changes != null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
Change[] changes = e.getRequiredData(VcsDataKeys.CHANGES);
|
||||
Project project = e.getProject();
|
||||
assert project != null;
|
||||
|
||||
List<PsiMethod> methods = FormatChangedTextUtil.getInstance().getChangedElements(project, Arrays.asList(changes), file -> {
|
||||
if (file.getFileType() != JavaFileType.INSTANCE) return null;
|
||||
PsiFile psiFile = PsiUtilCore.getPsiFile(project, file);
|
||||
|
||||
Document document = FileDocumentManager.getInstance().getDocument(file);
|
||||
if (document == null) return null;
|
||||
PsiDocumentManager.getInstance(project).commitDocument(document);
|
||||
|
||||
List<PsiMethod> fileMethods = new ArrayList<>();
|
||||
psiFile.accept(new JavaRecursiveElementVisitor() {
|
||||
@Override
|
||||
public void visitMethod(PsiMethod method) {
|
||||
super.visitMethod(method);
|
||||
if (psiFile.equals(method.getContainingFile())) {
|
||||
fileMethods.add(method);
|
||||
}
|
||||
}
|
||||
});
|
||||
return fileMethods;
|
||||
});
|
||||
|
||||
showDiscoveredTests(project, e.getDataContext(), "Selected Changes", methods);
|
||||
}
|
||||
}
|
||||
|
||||
private static void showDiscoveredTests(@NotNull Project project,
|
||||
@NotNull DataContext dataContext,
|
||||
@NotNull String title,
|
||||
@NotNull List<PsiMethod> methods) {
|
||||
CollectionListModel<PsiElement> model = new CollectionListModel<>();
|
||||
final JBList<PsiElement> list = new JBList<>(model);
|
||||
//list.setFixedCellHeight();
|
||||
HintUpdateSupply.installSimpleHintUpdateSupply(list);
|
||||
list.getSelectionModel().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
|
||||
|
||||
String initTitle = "Tests for " + methodPresentationName;
|
||||
String initTitle = "Tests for " + title;
|
||||
DefaultPsiElementCellRenderer renderer = new DefaultPsiElementCellRenderer();
|
||||
|
||||
Ref<JBPopup> ref = new Ref<>();
|
||||
|
||||
ConfigurationContext context = ConfigurationContext.getFromContext(dataContext);
|
||||
|
||||
InplaceButton runButton = new InplaceButton(new IconButton("Run All", AllIcons.Actions.Execute), __ -> {
|
||||
Executor executor = DefaultRunExecutor.getRunExecutorInstance();
|
||||
DataContext dataContext = DataManager.getInstance().getDataContext(editor.getContentComponent());
|
||||
ConfigurationContext context = ConfigurationContext.getFromContext(dataContext);
|
||||
List<Module> containingModules =
|
||||
model.getItems().stream()
|
||||
.map(element -> ModuleUtilCore.findModuleForPsiElement(element))
|
||||
@@ -101,17 +156,17 @@ public class ShowDiscoveredTestsAction extends AnAction {
|
||||
.collect(Collectors.toList());
|
||||
Module targetModule = TestDiscoveryConfigurationProducer.detectTargetModule(containingModules, project);
|
||||
//first producer with results will be picked
|
||||
getProducers(project).stream()
|
||||
.map(producer -> producer.createDelegate(method, targetModule).findOrCreateConfigurationFromContext(context))
|
||||
.filter(Objects::nonNull)
|
||||
.findFirst()
|
||||
.ifPresent(configuration -> {
|
||||
ExecutionUtil.runConfiguration(configuration.getConfigurationSettings(), executor);
|
||||
JBPopup popup = ref.get();
|
||||
if (popup != null) {
|
||||
popup.cancel();
|
||||
}
|
||||
});
|
||||
StreamEx.of(getProducers(project)).cross(methods)
|
||||
.mapKeyValue((producer, method) -> producer.createDelegate(method, targetModule).findOrCreateConfigurationFromContext(context))
|
||||
.filter(Objects::nonNull)
|
||||
.findFirst()
|
||||
.ifPresent(configuration -> {
|
||||
ExecutionUtil.runConfiguration(configuration.getConfigurationSettings(), executor);
|
||||
JBPopup popup = ref.get();
|
||||
if (popup != null) {
|
||||
popup.cancel();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
ActionListener pinActionListener = __ -> {
|
||||
@@ -146,10 +201,10 @@ public class ShowDiscoveredTestsAction extends AnAction {
|
||||
JBPopup popup = builder.createPopup();
|
||||
ref.set(popup);
|
||||
|
||||
list.setEmptyText("No tests captured for " + methodPresentationName);
|
||||
list.setEmptyText("No tests captured for " + title);
|
||||
list.setPaintBusy(true);
|
||||
|
||||
popup.showInBestPositionFor(editor);
|
||||
popup.showInBestPositionFor(dataContext);
|
||||
|
||||
JavaPsiFacade javaFacade = JavaPsiFacade.getInstance(project);
|
||||
GlobalSearchScope scope = GlobalSearchScope.projectScope(project);
|
||||
@@ -158,25 +213,32 @@ public class ShowDiscoveredTestsAction extends AnAction {
|
||||
ListBackgroundUpdaterTask loadTestsTask = new ListBackgroundUpdaterTask(project, "Load tests", renderer.getComparator()) {
|
||||
@Override
|
||||
public String getCaption(int size) {
|
||||
return "Found " + size + " Tests for " + methodPresentationName;
|
||||
return "Found " + size + " Tests for " + title;
|
||||
}
|
||||
};
|
||||
|
||||
loadTestsTask.init((AbstractPopup)popup, list, new Ref<>());
|
||||
|
||||
ApplicationManager.getApplication().executeOnPooledThread(() -> {
|
||||
for (TestDiscoveryConfigurationProducer producer : getProducers(project)) {
|
||||
String frameworkPrefix =
|
||||
((JavaTestConfigurationBase)producer.getConfigurationFactory().createTemplateConfiguration(project)).getFrameworkPrefix();
|
||||
TestDiscoveryProducer.consumeDiscoveredTests(project, fqn, methodName, frameworkPrefix, (testClass, testMethod) -> {
|
||||
PsiMethod psiMethod = ReadAction.compute(() -> {
|
||||
PsiClass cc = testClass == null ? null : javaFacade.findClass(testClass, scope);
|
||||
return cc == null ? null : ArrayUtil.getFirstElement(cc.findMethodsByName(testMethod, false));
|
||||
for (PsiMethod method : methods) {
|
||||
Couple<String> methodFqnName = ReadAction.compute(() -> getMethodQualifiedName(method));
|
||||
if (methodFqnName == null) continue;
|
||||
String fqn = methodFqnName.first;
|
||||
String methodName = methodFqnName.second;
|
||||
|
||||
for (TestDiscoveryConfigurationProducer producer : getProducers(project)) {
|
||||
String frameworkPrefix =
|
||||
((JavaTestConfigurationBase)producer.getConfigurationFactory().createTemplateConfiguration(project)).getFrameworkPrefix();
|
||||
TestDiscoveryProducer.consumeDiscoveredTests(project, fqn, methodName, frameworkPrefix, (testClass, testMethod) -> {
|
||||
PsiMethod psiMethod = ReadAction.compute(() -> {
|
||||
PsiClass cc = testClass == null ? null : javaFacade.findClass(testClass, scope);
|
||||
return cc == null ? null : ArrayUtil.getFirstElement(cc.findMethodsByName(testMethod, false));
|
||||
});
|
||||
if (psiMethod != null) {
|
||||
loadTestsTask.updateComponent(psiMethod);
|
||||
}
|
||||
});
|
||||
if (psiMethod != null) {
|
||||
loadTestsTask.updateComponent(psiMethod);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
EdtInvocationManager.getInstance().invokeLater(() -> {
|
||||
@@ -186,6 +248,15 @@ public class ShowDiscoveredTestsAction extends AnAction {
|
||||
});
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static Couple<String> getMethodQualifiedName(@NotNull PsiMethod method) {
|
||||
PsiClass c = method.getContainingClass();
|
||||
String fqn = c != null ? c.getQualifiedName() : null;
|
||||
if (fqn == null) return null;
|
||||
String methodName = method.getName();
|
||||
return Couple.of(fqn, methodName);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected static KeyStroke findUsagesKeyStroke() {
|
||||
AnAction action = ActionManager.getInstance().getAction(IdeActions.ACTION_FIND_USAGES);
|
||||
|
||||
@@ -30,15 +30,18 @@ import com.intellij.openapi.vcs.changes.Change;
|
||||
import com.intellij.openapi.vcs.changes.ChangeListManager;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiDirectory;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.codeStyle.ChangedRangesInfo;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.containers.Convertor;
|
||||
import com.intellij.util.diff.FilesTooBigForDiffException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
@@ -157,6 +160,23 @@ public class FormatChangedTextUtil {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public <T extends PsiElement> List<T> getChangedElements(@NotNull Project project,
|
||||
@NotNull List<Change> changes,
|
||||
@NotNull Convertor<VirtualFile, List<T>> elementsConvertor) {
|
||||
List<T> result = new ArrayList<>();
|
||||
for (Change change : changes) {
|
||||
VirtualFile file = change.getVirtualFile();
|
||||
if (file != null) {
|
||||
List<T> elements = elementsConvertor.convert(file);
|
||||
if (elements != null) {
|
||||
result.addAll(elements);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows to temporally suppress document modification tracking.
|
||||
*
|
||||
|
||||
+112
-24
@@ -17,42 +17,44 @@ package com.intellij.codeInsight.actions;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.util.text.StringUtilRt;
|
||||
import com.intellij.openapi.vcs.VcsException;
|
||||
import com.intellij.openapi.vcs.changes.Change;
|
||||
import com.intellij.openapi.vcs.changes.ChangeListManager;
|
||||
import com.intellij.openapi.vcs.changes.ChangeListManagerImpl;
|
||||
import com.intellij.openapi.vcs.changes.ContentRevision;
|
||||
import com.intellij.openapi.vcs.changes.*;
|
||||
import com.intellij.openapi.vcs.ex.LineStatusTracker;
|
||||
import com.intellij.openapi.vcs.ex.PartialLocalLineStatusTracker;
|
||||
import com.intellij.openapi.vcs.ex.Range;
|
||||
import com.intellij.openapi.vcs.ex.RangesBuilder;
|
||||
import com.intellij.openapi.vcs.impl.LineStatusTrackerManager;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.codeStyle.ChangedRangesInfo;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.util.diff.FilesTooBigForDiffException;
|
||||
import com.intellij.util.containers.Convertor;
|
||||
import com.intellij.vcsUtil.VcsUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.BitSet;
|
||||
import java.util.List;
|
||||
|
||||
class VcsAwareFormatChangedTextUtil extends FormatChangedTextUtil {
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public List<TextRange> getChangedTextRanges(@NotNull Project project, @NotNull PsiFile file) throws FilesTooBigForDiffException {
|
||||
public List<TextRange> getChangedTextRanges(@NotNull Project project, @NotNull PsiFile file) {
|
||||
ChangedRangesInfo helper = getChangedRangesInfo(file);
|
||||
return helper != null ? helper.allChangedRanges : ContainerUtil.newArrayList();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public ChangedRangesInfo getChangedRangesInfo(@NotNull PsiFile file) throws FilesTooBigForDiffException {
|
||||
public ChangedRangesInfo getChangedRangesInfo(@NotNull PsiFile file) {
|
||||
Project project = file.getProject();
|
||||
Document document = PsiDocumentManager.getInstance(project).getDocument(file);
|
||||
if (document == null) return null;
|
||||
@@ -82,6 +84,98 @@ class VcsAwareFormatChangedTextUtil extends FormatChangedTextUtil {
|
||||
return contentFromVcs != null ? calculateChangedRangesInfo(document, contentFromVcs) : null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public <T extends PsiElement> List<T> getChangedElements(@NotNull Project project,
|
||||
@NotNull List<Change> changes,
|
||||
@NotNull Convertor<VirtualFile, List<T>> elementsConvertor) {
|
||||
List<T> result = new ArrayList<>();
|
||||
for (Change change : changes) {
|
||||
if (change.getType() == Change.Type.DELETED) continue;
|
||||
if (!(change.getAfterRevision() instanceof CurrentContentRevision)) continue;
|
||||
|
||||
VirtualFile file = ((CurrentContentRevision)change.getAfterRevision()).getVirtualFile();
|
||||
if (file == null) continue;
|
||||
|
||||
Document document = FileDocumentManager.getInstance().getDocument(file);
|
||||
if (document == null) continue;
|
||||
|
||||
List<T> elements = elementsConvertor.convert(file);
|
||||
if (ContainerUtil.isEmpty(elements)) continue;
|
||||
|
||||
BitSet changedLines = getChangedLines(project, document, change);
|
||||
if (changedLines != null) {
|
||||
for (T element : elements) {
|
||||
if (isElementChanged(element, document, changedLines)) {
|
||||
result.add(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
result.addAll(elements);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static BitSet getChangedLines(@NotNull Project project, @NotNull Document document, @NotNull Change change) {
|
||||
if (change.getType() == Change.Type.NEW) return null;
|
||||
|
||||
List<? extends Range> ranges = getChangedRanges(project, document, change);
|
||||
if (ranges == null) return null;
|
||||
|
||||
BitSet changedLines = new BitSet();
|
||||
for (Range range : ranges) {
|
||||
if (range.getType() == Range.DELETED) {
|
||||
changedLines.set(range.getLine1() - 1, range.getLine1() + 1);
|
||||
}
|
||||
else {
|
||||
changedLines.set(range.getLine1(), range.getLine2());
|
||||
}
|
||||
}
|
||||
return changedLines;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static List<? extends Range> getChangedRanges(@NotNull Project project, @NotNull Document document, @NotNull Change change) {
|
||||
LineStatusTracker<?> tracker = LineStatusTrackerManager.getInstance(project).getLineStatusTracker(document);
|
||||
if (tracker != null) {
|
||||
if (change instanceof ChangeListChange && tracker instanceof PartialLocalLineStatusTracker) {
|
||||
String changeListId = ((ChangeListChange)change).getChangeListId();
|
||||
List<PartialLocalLineStatusTracker.LocalRange> ranges = ((PartialLocalLineStatusTracker)tracker).getRanges();
|
||||
if (ranges != null) {
|
||||
return ContainerUtil.filter(ranges, range -> range.getChangelistId().equals(changeListId));
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return tracker.getRanges();
|
||||
}
|
||||
}
|
||||
else {
|
||||
String contentFromVcs = getRevisionedContentFrom(change);
|
||||
if (contentFromVcs != null) {
|
||||
return getRanges(document, contentFromVcs);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isElementChanged(@NotNull PsiElement element, @NotNull Document document, @NotNull BitSet changedLines) {
|
||||
TextRange textRange = element.getTextRange();
|
||||
int startLine = document.getLineNumber(textRange.getStartOffset());
|
||||
int endLine = textRange.isEmpty()
|
||||
? startLine + 1
|
||||
: document.getLineNumber(textRange.getEndOffset() - 1) + 1;
|
||||
int nextSetBit = changedLines.nextSetBit(startLine);
|
||||
return nextSetBit != -1 && nextSetBit < endLine;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getRevisionedContentFrom(@NotNull Change change) {
|
||||
ContentRevision revision = change.getBeforeRevision();
|
||||
@@ -111,39 +205,33 @@ class VcsAwareFormatChangedTextUtil extends FormatChangedTextUtil {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static ChangedRangesInfo calculateChangedRangesInfo(@NotNull Document document,
|
||||
@NotNull CharSequence contentFromVcs) throws FilesTooBigForDiffException {
|
||||
private static ChangedRangesInfo calculateChangedRangesInfo(@NotNull Document document, @NotNull CharSequence contentFromVcs) {
|
||||
return getChangedTextRanges(document, getRanges(document, contentFromVcs));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static List<Range> getRanges(@NotNull Document document,
|
||||
@NotNull CharSequence contentFromVcs) throws FilesTooBigForDiffException {
|
||||
@NotNull CharSequence contentFromVcs) {
|
||||
return RangesBuilder.createRanges(document.getImmutableCharSequence(), StringUtilRt.convertLineSeparators(contentFromVcs, "\n"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int calculateChangedLinesNumber(@NotNull Document document, @NotNull CharSequence contentFromVcs) {
|
||||
try {
|
||||
List<Range> changedRanges = getRanges(document, contentFromVcs);
|
||||
int linesChanges = 0;
|
||||
for (Range range : changedRanges) {
|
||||
int inserted = range.getLine2() - range.getLine1();
|
||||
int deleted = range.getVcsLine2() - range.getVcsLine1();
|
||||
linesChanges += Math.max(inserted, deleted);
|
||||
}
|
||||
return linesChanges;
|
||||
} catch (FilesTooBigForDiffException e) {
|
||||
LOG.info("File too big, can not calculate changed lines number");
|
||||
return -1;
|
||||
List<Range> changedRanges = getRanges(document, contentFromVcs);
|
||||
int linesChanges = 0;
|
||||
for (Range range : changedRanges) {
|
||||
int inserted = range.getLine2() - range.getLine1();
|
||||
int deleted = range.getVcsLine2() - range.getVcsLine1();
|
||||
linesChanges += Math.max(inserted, deleted);
|
||||
}
|
||||
return linesChanges;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static ChangedRangesInfo getChangedTextRanges(@NotNull Document document, @NotNull List<? extends Range> changedRanges) {
|
||||
final List<TextRange> ranges = ContainerUtil.newArrayList();
|
||||
final List<TextRange> insertedRanges = ContainerUtil.newArrayList();
|
||||
|
||||
|
||||
for (Range range : changedRanges) {
|
||||
if (range.getType() != Range.DELETED) {
|
||||
int changeStartLine = range.getLine1();
|
||||
@@ -159,7 +247,7 @@ class VcsAwareFormatChangedTextUtil extends FormatChangedTextUtil {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return new ChangedRangesInfo(ranges, insertedRanges);
|
||||
}
|
||||
|
||||
|
||||
@@ -402,6 +402,9 @@
|
||||
<action class="com.intellij.execution.testDiscovery.ShowDiscoveredTestsAction" internal="true" id="ShowDiscoveredTests" text="Show Discovered Tests">
|
||||
<add-to-group group-id="Internal" anchor="last"/>
|
||||
</action>
|
||||
<action class="com.intellij.execution.testDiscovery.ShowDiscoveredTestsAction$FromChangeList" internal="true" id="ShowDiscoveredTestsFromChangeList" text="Show Discovered Tests">
|
||||
<add-to-group group-id="ChangesViewPopupMenu" anchor="last"/>
|
||||
</action>
|
||||
|
||||
<action id="JShell.Console"
|
||||
class="com.intellij.execution.jshell.LaunchJShellConsoleAction"
|
||||
|
||||
Reference in New Issue
Block a user