[coverage] IDEA-340863 Move coverage settings to project level

Save them in JavaCoverageOptionsProvider

GitOrigin-RevId: 6b8e974319800c9aced78c4a5e924746daba2c5f
This commit is contained in:
Maksim Zuev
2023-12-19 17:24:23 +00:00
committed by intellij-monorepo-bot
parent a102d20429
commit 5271d66222
9 changed files with 128 additions and 319 deletions
@@ -6,8 +6,9 @@ settings.coverage.java.java.coverage=Java Coverage
run.configuration.choose.coverage.runner=Choose coverage runner:
run.configuration.coverage.branches=Branch coverage
run.configuration.coverage.branches.comment=Collect coverage for all branches of if/switch statements
run.configuration.enable.coverage.in.test.folders=Enable coverage in test folders
run.configuration.enable.coverage.in.test.folders=Collect coverage in test folders
run.configuration.track.per.test.coverage=Track per test coverage
run.configuration.track.per.test.coverage.comment=Collect data about which code lines were tested by specific tests
settings.coverage.java.ignore.implicitly.declared.default.constructors=Ignore implicitly declared default constructors
# run config settings
@@ -234,7 +234,7 @@ public class JavaCoverageEngine extends CoverageEngine {
@Override
protected void deleteAssociatedTraces(CoverageSuite suite) {
if (suite.isBranchCoverage()) {
if (suite.isCoverageByTestEnabled()) {
File tracesDirectory = getTracesDirectory(suite);
if (tracesDirectory.exists()) {
FileUtil.delete(tracesDirectory);
@@ -270,13 +270,17 @@ public class JavaCoverageEngine extends CoverageEngine {
@NotNull CoverageFileProvider coverageDataFileProvider,
@NotNull CoverageEnabledConfiguration config) {
if (config instanceof JavaCoverageEnabledConfiguration javaConfig) {
return createSuite(covRunner, name, coverageDataFileProvider,
Project project = config.getConfiguration().getProject();
JavaCoverageOptionsProvider optionsProvider = JavaCoverageOptionsProvider.getInstance(project);
return createSuite(optionsProvider.getCoverageRunner(),
name, coverageDataFileProvider,
javaConfig.getPatterns(),
javaConfig.getExcludePatterns(),
javaConfig.createTimestamp(),
javaConfig.isTrackPerTestCoverage() && javaConfig.isBranchCoverageEnabled(),
javaConfig.isBranchCoverageEnabled(),
javaConfig.isTrackTestFolders(), config.getConfiguration().getProject());
optionsProvider.getTestTracking() && canHavePerTestCoverage(config.getConfiguration()),
optionsProvider.getBranchCoverage(),
optionsProvider.getTestModulesCoverage(),
project);
}
return null;
}
@@ -699,15 +703,15 @@ public class JavaCoverageEngine extends CoverageEngine {
}
public JavaCoverageSuite createSuite(CoverageRunner acceptedCovRunner,
String name, CoverageFileProvider coverageDataFileProvider,
String[] filters,
String[] excludePatterns,
long lastCoverageTimeStamp,
boolean coverageByTestEnabled,
boolean branchCoverage,
boolean trackTestFolders, Project project) {
return new JavaCoverageSuite(name, coverageDataFileProvider, filters, excludePatterns, lastCoverageTimeStamp, coverageByTestEnabled, branchCoverage,
trackTestFolders, acceptedCovRunner, this, project);
String name, CoverageFileProvider coverageDataFileProvider,
String[] filters,
String[] excludePatterns,
long lastCoverageTimeStamp,
boolean coverageByTestEnabled,
boolean branchCoverage,
boolean trackTestFolders, Project project) {
return new JavaCoverageSuite(name, coverageDataFileProvider, filters, excludePatterns, lastCoverageTimeStamp,
coverageByTestEnabled, branchCoverage, trackTestFolders, acceptedCovRunner, this, project);
}
@NotNull
@@ -4,11 +4,15 @@ package com.intellij.coverage
import com.intellij.codeInsight.AnnotationsPanel
import com.intellij.java.coverage.JavaCoverageBundle
import com.intellij.openapi.project.Project
import com.intellij.openapi.ui.ComboBox
import com.intellij.openapi.ui.DialogPanel
import com.intellij.psi.PsiClass
import com.intellij.ui.SimpleListCellRenderer
import com.intellij.ui.dsl.builder.Align
import com.intellij.ui.dsl.builder.bindItem
import com.intellij.ui.dsl.builder.bindSelected
import com.intellij.ui.dsl.builder.panel
import com.intellij.ui.layout.selectedValueMatches
import com.intellij.util.ArrayUtil
import javax.swing.JComponent
@@ -20,9 +24,34 @@ class JavaCoverageOptions(private val project: Project) : CoverageOptions() {
override fun createComponent(): JComponent? {
panel = panel {
group(JavaCoverageBundle.message("settings.coverage.java.java.coverage")) {
lateinit var runner: ComboBox<CoverageRunner>
row {
text(JavaCoverageBundle.message("run.configuration.choose.coverage.runner"))
val runnerCell = comboBox(collectJavaRunners(), SimpleListCellRenderer.create("", CoverageRunner::getPresentableName))
.bindItem(coverageOptionsProvider::coverageRunner)
runner = runnerCell.component
}
val isIdeaRunner = runner.selectedValueMatches { it is IDEACoverageRunner }
row {
checkBox(JavaCoverageBundle.message("run.configuration.coverage.branches"))
.bindSelected(coverageOptionsProvider::branchCoverage)
.comment(JavaCoverageBundle.message("run.configuration.coverage.branches.comment"))
.visibleIf(runner.selectedValueMatches(CoverageRunner?::mayHaveBranchCoverage))
}
row {
checkBox(JavaCoverageBundle.message("run.configuration.track.per.test.coverage"))
.bindSelected(coverageOptionsProvider::testTracking)
.comment(JavaCoverageBundle.message("run.configuration.track.per.test.coverage.comment"))
.visibleIf(runner.selectedValueMatches { it != null && it.isCoverageByTestApplicable })
}
row {
checkBox(JavaCoverageBundle.message("run.configuration.enable.coverage.in.test.folders"))
.bindSelected(coverageOptionsProvider::testModulesCoverage)
}
row {
checkBox(JavaCoverageBundle.message("settings.coverage.java.ignore.implicitly.declared.default.constructors"))
.bindSelected(coverageOptionsProvider::ignoreImplicitConstructors)
.visibleIf(isIdeaRunner)
}
row {
val excludeAnnotationsPanel = object : AnnotationsPanel(
@@ -37,6 +66,7 @@ class JavaCoverageOptions(private val project: Project) : CoverageOptions() {
cell(excludeAnnotationsPanel.component)
.align(Align.FILL)
.visibleIf(isIdeaRunner)
.onIsModified {
!excludeAnnotationsPanel.annotations.contentEquals(ArrayUtil.toStringArray(coverageOptionsProvider.excludeAnnotationPatterns))
}.onApply {
@@ -65,4 +95,20 @@ class JavaCoverageOptions(private val project: Project) : CoverageOptions() {
override fun disposeUIResources() {
panel = null
}
}
}
private fun collectJavaRunners(): List<CoverageRunner> {
val javaEngine = JavaCoverageEngine.getInstance()
return CoverageRunner.EP_NAME.extensionList.filter { it.acceptsCoverageEngine(javaEngine) }
}
/**
* @return true iff coverage runner may have (but not always) branch coverage
*/
private fun CoverageRunner?.mayHaveBranchCoverage(): Boolean {
if (this == null) return false
if (this !is JavaCoverageRunner) return true
val alwaysAvailable = isBranchInfoAvailable(false)
val neverAvailable = !isBranchInfoAvailable(true)
return !alwaysAvailable && !neverAvailable
}
@@ -15,8 +15,16 @@ import com.intellij.util.concurrency.annotations.RequiresBackgroundThread
class JavaCoverageOptionsProvider(private val project: Project) : PersistentStateComponent<JavaCoverageOptionsProvider.State?> {
private val state = State()
var branchCoverage: Boolean by state::myBranchCoverage
var testTracking: Boolean by state::myTestTracking
var testModulesCoverage: Boolean by state::myTestModulesCoverage
var ignoreImplicitConstructors: Boolean by state::myIgnoreImplicitConstructors
var excludeAnnotationPatterns: List<String> by state::myExcludeAnnotationPatterns
var coverageRunner: CoverageRunner?
get() = state.myRunnerId?.let { CoverageRunner.getInstanceById(it) }
set(value) {
state.myRunnerId = value?.id
}
@RequiresBackgroundThread
fun isGeneratedConstructor(qualifiedName: String, methodSignature: String): Boolean {
@@ -31,11 +39,18 @@ class JavaCoverageOptionsProvider(private val project: Project) : PersistentStat
override fun getState(): State = state
override fun loadState(loaded: State) {
state.myBranchCoverage = loaded.myBranchCoverage
state.myTestTracking = loaded.myTestTracking
state.myTestModulesCoverage = loaded.myTestModulesCoverage
state.myIgnoreImplicitConstructors = loaded.myIgnoreImplicitConstructors
state.myExcludeAnnotationPatterns = listWithDefaultAnnotations(loaded.myExcludeAnnotationPatterns)
}
class State {
internal var myRunnerId: String? = CoverageRunner.getInstance(IDEACoverageRunner::class.java).id
internal var myBranchCoverage: Boolean = false
internal var myTestTracking: Boolean = false
internal var myTestModulesCoverage: Boolean = false
internal var myIgnoreImplicitConstructors: Boolean = true
internal var myExcludeAnnotationPatterns: List<String> = defaultExcludeAnnotationPatterns
}
@@ -4,8 +4,6 @@ package com.intellij.coverage.view;
import com.intellij.coverage.*;
import com.intellij.coverage.analysis.JavaCoverageAnnotator;
import com.intellij.coverage.analysis.PackageAnnotator;
import com.intellij.execution.configurations.RunConfigurationBase;
import com.intellij.execution.configurations.coverage.JavaCoverageEnabledConfiguration;
import com.intellij.ide.util.treeView.AbstractTreeNode;
import com.intellij.java.coverage.JavaCoverageBundle;
import com.intellij.openapi.project.Project;
@@ -16,7 +14,9 @@ import com.intellij.util.ui.ColumnInfo;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
public class JavaCoverageViewExtension extends CoverageViewExtension {
private final JavaCoverageAnnotator myAnnotator;
@@ -139,19 +139,9 @@ public class JavaCoverageViewExtension extends CoverageViewExtension {
infos.add(new PercentageCoverageColumnInfo(1, JavaCoverageBundle.message("coverage.view.column.class"), mySuitesBundle, myStateBean));
infos.add(new PercentageCoverageColumnInfo(2, JavaCoverageBundle.message("coverage.view.column.method"), mySuitesBundle, myStateBean));
infos.add(new PercentageCoverageColumnInfo(3, JavaCoverageBundle.message("coverage.view.column.line"), mySuitesBundle, myStateBean));
RunConfigurationBase<?> runConfiguration = mySuitesBundle.getRunConfiguration();
if (runConfiguration != null) {
JavaCoverageEnabledConfiguration coverageEnabledConfiguration = JavaCoverageEnabledConfiguration.getFrom(runConfiguration);
if (coverageEnabledConfiguration != null) {
tryAddBranches(infos, coverageEnabledConfiguration.getCoverageRunner(), coverageEnabledConfiguration.isBranchCoverageEnabled());
}
}
else {
for (CoverageSuite suite : mySuitesBundle.getSuites()) {
CoverageRunner runner = suite.getRunner();
if (tryAddBranches(infos, runner, false)) {
break;
}
for (CoverageSuite suite : mySuitesBundle.getSuites()) {
if (tryAddBranches(infos, suite.getRunner(), suite.isBranchCoverage())) {
break;
}
}
return infos.toArray(ColumnInfo.EMPTY_ARRAY);
@@ -168,7 +158,7 @@ public class JavaCoverageViewExtension extends CoverageViewExtension {
}
protected boolean isBranchInfoAvailable(CoverageRunner coverageRunner, boolean branchCoverage) {
return coverageRunner instanceof JavaCoverageRunner && ((JavaCoverageRunner)coverageRunner).isBranchInfoAvailable(branchCoverage);
return coverageRunner instanceof JavaCoverageRunner javaCoverageRunner && javaCoverageRunner.isBranchInfoAvailable(branchCoverage);
}
private boolean isInCoverageScope(PsiElement element) {
@@ -2,38 +2,20 @@
package com.intellij.execution.configurations.coverage;
import com.intellij.coverage.CoverageRunner;
import com.intellij.coverage.JavaCoverageEngine;
import com.intellij.coverage.JavaCoverageRunner;
import com.intellij.execution.CommonJavaRunConfigurationParameters;
import com.intellij.execution.configurations.ModuleBasedConfiguration;
import com.intellij.execution.configurations.RunConfigurationBase;
import com.intellij.execution.util.JreVersionDetector;
import com.intellij.icons.AllIcons;
import com.intellij.java.coverage.JavaCoverageBundle;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.options.SettingsEditor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.openapi.ui.VerticalFlowLayout;
import com.intellij.ui.SimpleListCellRenderer;
import com.intellij.ui.TitledSeparator;
import com.intellij.ui.classFilter.ClassFilter;
import com.intellij.ui.components.JBPanel;
import com.intellij.ui.components.panels.VerticalLayout;
import com.intellij.util.ArrayUtil;
import com.intellij.util.ObjectUtils;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.JBInsets;
import com.intellij.util.ui.JBUI;
import com.intellij.util.ui.UI;
import com.intellij.util.ui.components.BorderLayoutPanel;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;
/**
@@ -46,80 +28,24 @@ import java.util.Arrays;
* </code>
*/
public final class CoverageConfigurable extends SettingsEditor<RunConfigurationBase<?>> {
private static final Logger LOG = Logger.getInstance(CoverageConfigurable.class);
private final JreVersionDetector myVersionDetector = new JreVersionDetector();
final Project myProject;
private final Project myProject;
private CoverageClassFilterEditor myClassFilterEditor;
private CoverageClassFilterEditor myExcludeClassFilterEditor;
private JLabel myCoverageNotSupportedLabel;
private ComboBox<CoverageRunnerItem> myCoverageRunnerCb;
private JPanel myRunnerPanel;
private JCheckBox myTrackPerTestCoverageCb;
private JCheckBox myTrackTestSourcesCb;
private JCheckBox myBranchCoverageCb;
private final RunConfigurationBase<?> myConfig;
public CoverageConfigurable(RunConfigurationBase<?> config) {
myConfig = config;
myProject = config.getProject();
}
@Override
protected void resetEditorFrom(@NotNull final RunConfigurationBase<?> runConfiguration) {
final boolean isJre50;
if (runConfiguration instanceof CommonJavaRunConfigurationParameters && myVersionDetector.isJre50Configured((CommonJavaRunConfigurationParameters)runConfiguration)) {
isJre50 = true;
} else if (runConfiguration instanceof ModuleBasedConfiguration){
isJre50 = myVersionDetector.isModuleJre50Configured((ModuleBasedConfiguration<?, ?>)runConfiguration);
} else {
isJre50 = true;
}
myCoverageNotSupportedLabel.setVisible(!isJre50);
final JavaCoverageEnabledConfiguration configuration = (JavaCoverageEnabledConfiguration)CoverageEnabledConfiguration.getOrCreate(runConfiguration);
CoverageRunner runner = configuration.getCoverageRunner();
if (runner != null) {
myCoverageRunnerCb.setSelectedItem(new CoverageRunnerItem(runner));
}
myRunnerPanel.setEnabled(isJre50);
var configuration = (JavaCoverageEnabledConfiguration)CoverageEnabledConfiguration.getOrCreate(runConfiguration);
myClassFilterEditor.setFilters(getCoveragePatterns(configuration, true));
myExcludeClassFilterEditor.setFilters(getCoveragePatterns(configuration, false));
setUpBranchCoverage(runner, configuration.isBranchCoverageEnabled(), configuration.isTrackPerTestCoverage());
myTrackTestSourcesCb.setSelected(configuration.isTrackTestFolders());
}
private void setUpBranchCoverage(CoverageRunner runner, boolean branchCoverage, boolean testTracking) {
if (runner instanceof JavaCoverageRunner javaRunner) {
final boolean alwaysAvailable = javaRunner.isBranchInfoAvailable(false);
final boolean neverAvailable = !javaRunner.isBranchInfoAvailable(true);
myBranchCoverageCb.setEnabled(!(alwaysAvailable || neverAvailable));
myBranchCoverageCb.setSelected(javaRunner.isBranchInfoAvailable(branchCoverage));
} else {
myBranchCoverageCb.setEnabled(true);
myBranchCoverageCb.setSelected(branchCoverage);
}
final boolean isCoverageByTestApplicable = runner != null && runner.isCoverageByTestApplicable();
myTrackPerTestCoverageCb.setSelected(testTracking);
myTrackPerTestCoverageCb.setEnabled(isCoverageByTestApplicable && myBranchCoverageCb.isSelected() && canHavePerTestCoverage());
}
static ClassFilter[] getCoveragePatterns(@NotNull JavaCoverageEnabledConfiguration configuration, boolean include) {
return Arrays.stream(ObjectUtils.chooseNotNull(configuration.getCoveragePatterns(), ClassFilter.EMPTY_ARRAY))
.filter(classFilter -> classFilter.INCLUDE == include).toArray(ClassFilter[]::new);
}
private boolean canHavePerTestCoverage() {
return CoverageEnabledConfiguration.getOrCreate(myConfig).canHavePerTestCoverage();
}
@Override
protected void applyEditorTo(@NotNull final RunConfigurationBase runConfiguration) {
final JavaCoverageEnabledConfiguration configuration = (JavaCoverageEnabledConfiguration)CoverageEnabledConfiguration.getOrCreate(runConfiguration);
var configuration = (JavaCoverageEnabledConfiguration)CoverageEnabledConfiguration.getOrCreate(runConfiguration);
ClassFilter[] newCoveragePatterns = ArrayUtil.mergeArrays(myClassFilterEditor.getFilters(), myExcludeClassFilterEditor.getFilters());
ClassFilter[] oldCoveragePatterns = ObjectUtils.chooseNotNull(configuration.getCoveragePatterns(), ClassFilter.EMPTY_ARRAY);
//apply new order if something else was changed as well
@@ -127,80 +53,20 @@ public final class CoverageConfigurable extends SettingsEditor<RunConfigurationB
!ContainerUtil.newHashSet(newCoveragePatterns).equals(ContainerUtil.newHashSet(oldCoveragePatterns))) {
configuration.setCoveragePatterns(newCoveragePatterns);
}
configuration.setCoverageRunner(getSelectedRunner());
configuration.setTrackPerTestCoverage(myTrackPerTestCoverageCb.isSelected());
configuration.setBranchCoverage(myBranchCoverageCb.isSelected());
configuration.setTrackTestFolders(myTrackTestSourcesCb.isSelected());
}
@Override
@NotNull
protected JComponent createEditor() {
JPanel result = new JPanel(new GridBagLayout());
JPanel result = new JPanel(new VerticalLayout(UIUtil.DEFAULT_VGAP));
final DefaultComboBoxModel<CoverageRunnerItem> runnersModel = new DefaultComboBoxModel<>();
myCoverageRunnerCb = new ComboBox<>(runnersModel);
final JavaCoverageEnabledConfiguration javaCoverageEnabledConfiguration = JavaCoverageEnabledConfiguration.getFrom(myConfig);
LOG.assertTrue(javaCoverageEnabledConfiguration != null);
final JavaCoverageEngine provider = JavaCoverageEngine.getInstance();
for (CoverageRunner runner : CoverageRunner.EP_NAME.getExtensionList()) {
if (runner.acceptsCoverageEngine(provider)) {
runnersModel.addElement(new CoverageRunnerItem(runner));
}
}
myCoverageRunnerCb.setRenderer(SimpleListCellRenderer.create("", CoverageRunnerItem::getPresentableName));
myCoverageRunnerCb.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
setUpBranchCoverage(getSelectedRunner(), myBranchCoverageCb.isSelected(), myTrackPerTestCoverageCb.isSelected());
}
});
myRunnerPanel = new JPanel(new GridBagLayout());
myRunnerPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
myRunnerPanel.add(new JLabel(JavaCoverageBundle.message("run.configuration.choose.coverage.runner")), new GridBagConstraints(0, 0, 1, 1, 0, 1, GridBagConstraints.WEST, GridBagConstraints.NONE, JBUI.insetsRight(10), 0, 0));
myRunnerPanel.add(myCoverageRunnerCb, new GridBagConstraints(1, 0, 1, 1, 1, 1, GridBagConstraints.WEST, GridBagConstraints.NONE,
JBInsets.emptyInsets(), 0, 0));
final JPanel cPanel = new JPanel(new VerticalFlowLayout());
myBranchCoverageCb = new JCheckBox(JavaCoverageBundle.message("run.configuration.coverage.branches"));
final JPanel branchCoveragePanel = UI.PanelFactory.panel(myBranchCoverageCb)
.withComment(JavaCoverageBundle.message("run.configuration.coverage.branches.comment"))
.createPanel();
cPanel.add(branchCoveragePanel);
final ActionListener branchCoverageListener = new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
setUpBranchCoverage(getSelectedRunner(), myBranchCoverageCb.isSelected(), myTrackPerTestCoverageCb.isSelected());
}
};
myBranchCoverageCb.addActionListener(branchCoverageListener);
myTrackPerTestCoverageCb = new JCheckBox(JavaCoverageBundle.message("run.configuration.track.per.test.coverage"));
final JBPanel<BorderLayoutPanel> testTrackingPanel = JBUI.Panels.simplePanel(myTrackPerTestCoverageCb).withBorder(JBUI.Borders.emptyLeft(15));
cPanel.add(testTrackingPanel);
myRunnerPanel.add(cPanel, new GridBagConstraints(0, 1, GridBagConstraints.REMAINDER, 1, 1, 1, GridBagConstraints.WEST, GridBagConstraints.NONE,
JBInsets.emptyInsets(), 0, 0));
final GridBagConstraints gc = new GridBagConstraints(0, GridBagConstraints.RELATIVE,
1, 1, 1, 0,
GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL,
JBInsets.emptyInsets(), 0, 0);
result.add(myRunnerPanel, gc);
JPanel panel = new JPanel(new GridBagLayout());
final GridBagConstraints bagConstraints =
new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH,
JBInsets.emptyInsets(), 0, 0);
//noinspection DialogTitleCapitalization
panel.add(new TitledSeparator(JavaCoverageBundle.message("record.coverage.filters.title")), bagConstraints);
result.add(new TitledSeparator(JavaCoverageBundle.message("record.coverage.filters.title")));
myClassFilterEditor = new CoverageClassFilterEditor(myProject);
panel.add(myClassFilterEditor, bagConstraints);
result.add(myClassFilterEditor);
//noinspection DialogTitleCapitalization
panel.add(new TitledSeparator(JavaCoverageBundle.message("exclude.coverage.filters.title")), bagConstraints);
result.add(new TitledSeparator(JavaCoverageBundle.message("exclude.coverage.filters.title")));
myExcludeClassFilterEditor = new CoverageClassFilterEditor(myProject) {
@NotNull
@Override
@@ -210,67 +76,12 @@ public final class CoverageConfigurable extends SettingsEditor<RunConfigurationB
return filter;
}
};
panel.add(myExcludeClassFilterEditor, bagConstraints);
bagConstraints.weighty = 0;
myTrackTestSourcesCb = new JCheckBox(JavaCoverageBundle.message("run.configuration.enable.coverage.in.test.folders"));
panel.add(myTrackTestSourcesCb, bagConstraints);
gc.weighty = 1;
gc.fill = GridBagConstraints.BOTH;
result.add(panel, gc);
myCoverageNotSupportedLabel = new JLabel(JavaCoverageBundle.message("code.coverage.is.not.supported"));
myCoverageNotSupportedLabel.setIcon(AllIcons.General.WarningDialog);
result.add(myCoverageNotSupportedLabel, gc);
result.add(myExcludeClassFilterEditor);
return result;
}
@Nullable
private CoverageRunner getSelectedRunner() {
final CoverageRunnerItem runnerItem = (CoverageRunnerItem)myCoverageRunnerCb.getSelectedItem();
if (runnerItem == null) {
LOG.debug("Available runners: " + myCoverageRunnerCb.getModel().getSize());
}
return runnerItem != null ? runnerItem.getRunner() : null;
}
private static final class CoverageRunnerItem {
private CoverageRunner myRunner;
private @NotNull final String myRunnerId;
private CoverageRunnerItem(@NotNull CoverageRunner runner) {
myRunner = runner;
myRunnerId = runner.getId();
}
private CoverageRunnerItem(@NotNull String runnerId) {
myRunnerId = runnerId;
}
public CoverageRunner getRunner() {
return myRunner;
}
public String getPresentableName() {
return myRunner != null ? myRunner.getPresentableName() : myRunnerId;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
CoverageRunnerItem that = (CoverageRunnerItem)o;
if (!myRunnerId.equals(that.myRunnerId)) return false;
return true;
}
@Override
public int hashCode() {
return myRunnerId.hashCode();
}
static ClassFilter @NotNull [] getCoveragePatterns(@NotNull JavaCoverageEnabledConfiguration configuration, boolean include) {
return Arrays.stream(ObjectUtils.chooseNotNull(configuration.getCoveragePatterns(), ClassFilter.EMPTY_ARRAY))
.filter(classFilter -> classFilter.INCLUDE == include).toArray(ClassFilter[]::new);
}
}
@@ -1,25 +1,17 @@
// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
package com.intellij.execution.configurations.coverage;
import com.intellij.coverage.CoverageRunner;
import com.intellij.coverage.IDEACoverageRunner;
import com.intellij.coverage.JavaCoverageEngine;
import com.intellij.execution.configurations.RunConfigurationBase;
import com.intellij.execution.ui.NestedGroupFragment;
import com.intellij.execution.ui.SettingsEditorFragment;
import com.intellij.java.coverage.JavaCoverageBundle;
import com.intellij.openapi.ui.ComboBox;
import com.intellij.openapi.ui.LabeledComponent;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.SimpleListCellRenderer;
import com.intellij.ui.classFilter.ClassFilter;
import com.intellij.util.ArrayUtil;
import com.intellij.util.ui.JBInsets;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
@@ -40,30 +32,19 @@ public final class CoverageFragment<T extends RunConfigurationBase<?>> extends N
@Override
protected List<SettingsEditorFragment<T, ?>> createChildren() {
List<SettingsEditorFragment<T, ?>> fragments = new ArrayList<>();
SettingsEditorFragment<T, CoverageClassFilterEditor> include =
createFilterEditor("coverage.include", JavaCoverageBundle.message("record.coverage.filters.title"), true,
JavaCoverageBundle.message("coverage.settings.include"));
include.setActionHint(JavaCoverageBundle.message("show.coverage.data.only.in.specified.classes.and.packages"));
fragments.add(include);
SettingsEditorFragment<T, CoverageClassFilterEditor> exclude =
createFilterEditor("coverage.exclude", JavaCoverageBundle.message("exclude.coverage.filters.title"), false,
JavaCoverageBundle.message("coverage.settings.exclude"));
exclude.setActionHint(JavaCoverageBundle.message("do.not.show.coverage.data.in.specified.classes.and.packages"));
fragments.add(exclude);
fragments.add(createRunnerFragment());
SettingsEditorFragment<T, ?> branchCoverage =
SettingsEditorFragment.createTag("coverage.tracing", JavaCoverageBundle.message("coverage.settings.tracing"), null,
t -> getConfiguration(t).isBranchCoverageEnabled(),
(t, value) -> getConfiguration(t).setBranchCoverage(value));
branchCoverage.setActionHint(JavaCoverageBundle.message("enables.accurate.collection"));
fragments.add(branchCoverage);
SettingsEditorFragment<T, ?> tests =
SettingsEditorFragment.createTag("coverage.test.folders", JavaCoverageBundle.message("coverage.settings.test.folders"), null,
t -> getConfiguration(t).isTrackTestFolders(),
(t, value) -> getConfiguration(t).setTrackTestFolders(value));
tests.setActionHint(JavaCoverageBundle.message("collect.code.coverage.statistics.for.tests"));
fragments.add(tests);
return fragments;
}
@@ -76,7 +57,9 @@ public final class CoverageFragment<T extends RunConfigurationBase<?>> extends N
filterEditor.setupEasyFocusTraversing();
return new SettingsEditorFragment<>(id, optionName, null, filterEditor,
(p, editor) -> editor.setFilters(CoverageConfigurable.getCoveragePatterns(getConfiguration(p), included)),
(p, editor) -> setCoveragePatterns(getConfiguration(p), isSelected() && filterEditor.isVisible() ? editor.getFilters() : ClassFilter.EMPTY_ARRAY, included),
(p, editor) -> setCoveragePatterns(getConfiguration(p), isSelected() && filterEditor.isVisible()
? editor.getFilters()
: ClassFilter.EMPTY_ARRAY, included),
p -> CoverageConfigurable.getCoveragePatterns(getConfiguration(p), included).length > 0);
}
@@ -92,29 +75,4 @@ public final class CoverageFragment<T extends RunConfigurationBase<?>> extends N
}
configuration.setCoveragePatterns(ArrayUtil.mergeArrays(filters, patterns));
}
private SettingsEditorFragment<T, ?> createRunnerFragment() {
final DefaultComboBoxModel<CoverageRunner> model = new DefaultComboBoxModel<>();
ComboBox<CoverageRunner> comboBox = new ComboBox<>(model);
final JavaCoverageEngine provider = JavaCoverageEngine.getInstance();
for (CoverageRunner runner : CoverageRunner.EP_NAME.getExtensionList()) {
if (runner.acceptsCoverageEngine(provider)) {
model.addElement(runner);
}
}
comboBox.setRenderer(SimpleListCellRenderer.create("", CoverageRunner::getPresentableName));
JPanel panel = new JPanel(new BorderLayout());
panel.add(comboBox, BorderLayout.WEST);
LabeledComponent<?> component = LabeledComponent.create(panel, JavaCoverageBundle.message("run.configuration.choose.coverage.runner"), BorderLayout.WEST);
SettingsEditorFragment<T, ? extends LabeledComponent<?>> fragment =
new SettingsEditorFragment<>("coverage.runner", JavaCoverageBundle.message("coverage.settings.runner"), null, component,
(t, c) -> comboBox.setItem(getConfiguration(t).getCoverageRunner()),
(t, c) -> getConfiguration(t)
.setCoverageRunner(isSelected() && component.isVisible() ? comboBox.getItem() : model.getElementAt(0)),
t -> !(getConfiguration(t).getCoverageRunner() instanceof IDEACoverageRunner));
fragment.setEditorGetter(c -> comboBox);
fragment.setActionHint(JavaCoverageBundle.message("select.to.use.a.code.coverage.runner.other.than.the.built.in.one"));
return fragment;
}
}
@@ -62,29 +62,29 @@ public final class JavaCoverageEnabledConfiguration extends CoverageEnabledConfi
return null;
}
public void appendCoverageArgument(@NotNull RunConfigurationBase<?> configuration, final SimpleJavaParameters javaParameters) {
final CoverageRunner runner = getCoverageRunner();
public void appendCoverageArgument(@NotNull CoverageSuite suite, final SimpleJavaParameters javaParameters) {
final CoverageRunner runner = suite.getRunner();
if (runner instanceof JavaCoverageRunner javaCoverageRunner) {
final String path = getCoverageFilePath();
final String path = suite.getCoverageDataFileName();
assert path != null; // cannot be null here if runner != null
String sourceMapPath = null;
if (JavaCoverageEngine.isSourceMapNeeded(configuration)) {
if (JavaCoverageEngine.isSourceMapNeeded(getConfiguration())) {
sourceMapPath = getSourceMapPath(path);
}
final String[] patterns = getPatterns();
final String[] excludePatterns = getExcludePatterns();
final Project project = configuration.getProject();
CoverageLogger.logStarted(javaCoverageRunner, isBranchCoverageEnabled(), isTrackPerTestCoverage(),
final Project project = getConfiguration().getProject();
CoverageLogger.logStarted(runner, suite.isBranchCoverage(), suite.isCoverageByTestEnabled(),
patterns == null ? 0 : patterns.length,
excludePatterns == null ? 0 : excludePatterns.length);
javaCoverageRunner.appendCoverageArgument(new File(path).getAbsolutePath(),
patterns,
excludePatterns,
javaParameters,
isTrackPerTestCoverage() && isBranchCoverageEnabled(),
isBranchCoverageEnabled(),
suite.isCoverageByTestEnabled(),
suite.isBranchCoverage(),
sourceMapPath,
project);
}
@@ -186,16 +186,6 @@ public final class JavaCoverageEnabledConfiguration extends CoverageEnabledConfi
}
}
@Override
@Nullable
public String getCoverageFilePath() {
if (myCoverageFilePath != null ) {
return myCoverageFilePath;
}
myCoverageFilePath = createCoverageFile();
return myCoverageFilePath;
}
public void setUpCoverageFilters(@Nullable String className, @Nullable String packageName) {
if (getCoveragePatterns() == null) {
String pattern = null;
@@ -23,15 +23,10 @@ import com.intellij.java.coverage.JavaCoverageBundle;
import com.intellij.notification.Notification;
import com.intellij.notification.NotificationType;
import com.intellij.notification.Notifications;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.options.SettingsEditor;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.JavaSdk;
import com.intellij.openapi.projectRoots.JavaSdkVersion;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.util.InvalidDataException;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.JavaPsiFacade;
@@ -130,25 +125,24 @@ public class CoverageJavaRunConfigurationExtension extends RunConfigurationExten
final JavaCoverageEnabledConfiguration coverageConfig = JavaCoverageEnabledConfiguration.getFrom(configuration);
if (coverageConfig == null) return;
coverageConfig.setCurrentCoverageSuite(null);
final CoverageRunner coverageRunner = coverageConfig.getCoverageRunner();
CoverageRunner coverageRunner = coverageConfig.getCoverageRunner();
if (runnerSettings instanceof CoverageRunnerData && coverageRunner != null) {
Project project = configuration.getProject();
final CoverageDataManager coverageDataManager = CoverageDataManager.getInstance(project);
ApplicationManager.getApplication().invokeLater(() -> {
coverageConfig.setCurrentCoverageSuite(coverageDataManager.addCoverageSuite(coverageConfig));
}, ModalityState.nonModal(), project.getDisposed());
appendCoverageArgument(configuration, params, coverageConfig);
CoverageSuite suite = CoverageDataManager.getInstance(configuration.getProject()).addCoverageSuite(coverageConfig);
if (suite != null) {
coverageConfig.setCurrentCoverageSuite(suite);
appendCoverageArgument(suite, params, coverageConfig);
}
}
}
private void appendCoverageArgument(@NotNull RunConfigurationBase<?> configuration,
private void appendCoverageArgument(@NotNull CoverageSuite suite,
@NotNull JavaParameters params,
JavaCoverageEnabledConfiguration coverageConfig) {
JavaParameters coverageParams = new JavaParameters();
coverageConfig.appendCoverageArgument(configuration, coverageParams);
coverageConfig.appendCoverageArgument(suite, coverageParams);
boolean runsUnderNonLocalTarget = configuration instanceof TargetEnvironmentAwareRunProfile
&& ((TargetEnvironmentAwareRunProfile)configuration).needPrepareTarget();
boolean runsUnderNonLocalTarget = coverageConfig.getConfiguration() instanceof TargetEnvironmentAwareRunProfile profile
&& profile.needPrepareTarget();
if (!runsUnderNonLocalTarget) {
params.getVMParametersList().addAll(coverageParams.getTargetDependentParameters().toLocalParameters());
myTargetDependentParameters = null;
@@ -277,9 +271,9 @@ public class CoverageJavaRunConfigurationExtension extends RunConfigurationExten
public boolean isListenerDisabled(RunConfigurationBase configuration, Object listener, RunnerSettings runnerSettings) {
if (listener instanceof CoverageListener) {
if (!(runnerSettings instanceof CoverageRunnerData)) return true;
final CoverageEnabledConfiguration coverageEnabledConfiguration = CoverageEnabledConfiguration.getOrCreate(configuration);
return !(coverageEnabledConfiguration.getCoverageRunner() instanceof IDEACoverageRunner) ||
!(coverageEnabledConfiguration.isTrackPerTestCoverage() && coverageEnabledConfiguration.isBranchCoverageEnabled());
CoverageEnabledConfiguration coverageEnabledConfiguration = CoverageEnabledConfiguration.getOrCreate(configuration);
CoverageSuite suite = coverageEnabledConfiguration.getCurrentCoverageSuite();
return suite == null || !suite.getRunner().isCoverageByTestApplicable() || !suite.isCoverageByTestEnabled();
}
return false;
}