diff --git a/java-coverage-impl/src/main/java/com/intellij/java/coverage/CoverageJavaRunConfigurationExtension.java b/java-coverage-impl/src/main/java/com/intellij/java/coverage/CoverageJavaRunConfigurationExtension.java index 1705379838..87f19630c3 100644 --- a/java-coverage-impl/src/main/java/com/intellij/java/coverage/CoverageJavaRunConfigurationExtension.java +++ b/java-coverage-impl/src/main/java/com/intellij/java/coverage/CoverageJavaRunConfigurationExtension.java @@ -48,234 +48,269 @@ */ @ExtensionImpl public class CoverageJavaRunConfigurationExtension extends RunConfigurationExtension { - public void attachToProcess(@Nonnull final RunConfigurationBase configuration, @Nonnull ProcessHandler handler, RunnerSettings runnerSettings) { - CoverageDataManager.getInstance(configuration.getProject()).attachToProcess(handler, configuration, runnerSettings); - } - - @Nullable - public SettingsEditor createEditor(@Nonnull RunConfigurationBase configuration) { - return new CoverageConfigurable(configuration); - } - - public String getEditorTitle() { - return CoverageEngine.getEditorTitle(); - } - - @Nonnull - @Override - public String getSerializationId() { - return "coverage"; - } - - public void updateJavaParameters(RunConfigurationBase configuration, OwnJavaParameters params, RunnerSettings runnerSettings) { - if (!isApplicableFor(configuration)) { - return; + @Override + public void attachToProcess( + @Nonnull RunConfigurationBase configuration, + @Nonnull ProcessHandler handler, + RunnerSettings runnerSettings + ) { + CoverageDataManager.getInstance(configuration.getProject()).attachToProcess(handler, configuration, runnerSettings); } - final JavaCoverageEnabledConfiguration coverageConfig = JavaCoverageEnabledConfiguration.getFrom(configuration); - //noinspection ConstantConditions - coverageConfig.setCurrentCoverageSuite(null); - final CoverageRunner coverageRunner = coverageConfig.getCoverageRunner(); - if (runnerSettings instanceof CoverageRunnerData && coverageRunner != null) { - final CoverageDataManager coverageDataManager = CoverageDataManager.getInstance(configuration.getProject()); - coverageConfig.setCurrentCoverageSuite(coverageDataManager.addCoverageSuite(coverageConfig)); - coverageConfig.appendCoverageArgument(params); - - final Sdk jdk = params.getJdk(); - if (jdk != null && JavaSdkTypeUtil.isOfVersionOrHigher(jdk, JavaSdkVersion.JDK_1_7) && coverageRunner instanceof JavaCoverageRunner && !((JavaCoverageRunner)coverageRunner).isJdk7Compatible()) { - Notifications.Bus.notify(new Notification(NotificationGroup.balloonGroup("Coverage"), "Coverage instrumentation is not fully compatible with JDK 7", - coverageRunner.getPresentableName() + - " coverage instrumentation can lead to java.lang.VerifyError errors with JDK 7. If so, please try IDEA coverage runner.", - NotificationType.WARNING)); - } + @Override + @Nullable + public SettingsEditor createEditor(@Nonnull RunConfigurationBase configuration) { + return new CoverageConfigurable(configuration); } - } - @Override - public void readExternal(@Nonnull final RunConfigurationBase runConfiguration, @Nonnull Element element) throws InvalidDataException { - if (!isApplicableFor(runConfiguration)) { - return; + @Override + public String getEditorTitle() { + return CoverageEngine.getEditorTitle(); } - //noinspection ConstantConditions - JavaCoverageEnabledConfiguration.getFrom(runConfiguration).readExternal(element); - } - - @Override - public void writeExternal(@Nonnull RunConfigurationBase runConfiguration, @Nonnull Element element) throws WriteExternalException { - if (!isApplicableFor(runConfiguration)) { - return; - } - //noinspection ConstantConditions - JavaCoverageEnabledConfiguration.getFrom(runConfiguration).writeExternal(element); - } - - @Override - public void extendCreatedConfiguration(@Nonnull RunConfigurationBase runJavaConfiguration, @Nonnull Location location) { - final JavaCoverageEnabledConfiguration coverageEnabledConfiguration = JavaCoverageEnabledConfiguration.getFrom(runJavaConfiguration); - assert coverageEnabledConfiguration != null; - if (runJavaConfiguration instanceof CommonJavaRunConfigurationParameters) { - coverageEnabledConfiguration.setUpCoverageFilters(((CommonJavaRunConfigurationParameters)runJavaConfiguration).getRunClass(), - ((CommonJavaRunConfigurationParameters)runJavaConfiguration).getPackage()); - } - } - - @Override - public void cleanUserData(RunConfigurationBase runConfiguration) { - runConfiguration.putCopyableUserData(CoverageEnabledConfiguration.COVERAGE_KEY, null); - } - - @Override - public void validateConfiguration(@Nonnull RunConfigurationBase runJavaConfiguration, boolean isExecution) - throws RuntimeConfigurationException { - } - - @Override - public RefactoringElementListener wrapElementListener(PsiElement element, - RunConfigurationBase configuration, - RefactoringElementListener listener) { - if (!isApplicableFor(configuration)) { - return listener; + @Nonnull + @Override + public String getSerializationId() { + return "coverage"; } - final JavaCoverageEnabledConfiguration coverageEnabledConfiguration = JavaCoverageEnabledConfiguration.getFrom(configuration); - if (coverageEnabledConfiguration != null) { - final Project project = configuration.getProject(); - final ClassFilter[] patterns = coverageEnabledConfiguration.getCoveragePatterns(); - final String[] filters = getFilters(coverageEnabledConfiguration); - if (patterns != null) { - assert filters != null; - if (element instanceof PsiClass) { - final int idx = ArrayUtil.find(filters, ((PsiClass)element).getQualifiedName()); - if (idx > -1) { - final RefactoringListeners.Accessor accessor = new MyClassAccessor(project, patterns, idx, filters); - final RefactoringElementListener classListener = RefactoringListeners.getClassOrPackageListener(element, accessor); - if (classListener != null) { - listener = appendListener(listener, classListener); - } - } - } else if (element instanceof PsiJavaPackage) { - final String qualifiedName = ((PsiJavaPackage)element).getQualifiedName(); - for (int i = 0, filtersLength = filters.length; i < filtersLength; i++) { - if (filters[i].startsWith(qualifiedName + ".")) { - final RefactoringElementListener packageListener; - if (filters[i].endsWith("*")) { - packageListener = RefactoringListeners.getListener((PsiJavaPackage)element, - new MyPackageAccessor(project, patterns, i, filters)); - } else { - packageListener = RefactoringListeners.getClassOrPackageListener(element, - new MyClassAccessor(project, patterns, i, filters)); - } - if (packageListener != null) { - listener = appendListener(listener, packageListener); - } + + @Override + public void updateJavaParameters(RunConfigurationBase configuration, OwnJavaParameters params, RunnerSettings runnerSettings) { + if (!isApplicableFor(configuration)) { + return; + } + + JavaCoverageEnabledConfiguration coverageConfig = JavaCoverageEnabledConfiguration.getFrom(configuration); + //noinspection ConstantConditions + coverageConfig.setCurrentCoverageSuite(null); + CoverageRunner coverageRunner = coverageConfig.getCoverageRunner(); + if (runnerSettings instanceof CoverageRunnerData && coverageRunner != null) { + CoverageDataManager coverageDataManager = CoverageDataManager.getInstance(configuration.getProject()); + coverageConfig.setCurrentCoverageSuite(coverageDataManager.addCoverageSuite(coverageConfig)); + coverageConfig.appendCoverageArgument(params); + + Sdk jdk = params.getJdk(); + if (jdk != null && JavaSdkTypeUtil.isOfVersionOrHigher(jdk, JavaSdkVersion.JDK_1_7) + && coverageRunner instanceof JavaCoverageRunner javaCoverageRunner && !javaCoverageRunner.isJdk7Compatible()) { + Notifications.Bus.notify(new Notification( + NotificationGroup.balloonGroup("Coverage"), + "Coverage instrumentation is not fully compatible with JDK 7", + coverageRunner.getPresentableName() + + " coverage instrumentation can lead to java.lang.VerifyError errors with JDK 7. " + + "If so, please try IDEA coverage runner.", + NotificationType.WARNING + )); } - } } - } - } - return listener; - } - - @Nullable - private static String[] getFilters(JavaCoverageEnabledConfiguration coverageEnabledConfiguration) { - final ClassFilter[] patterns = coverageEnabledConfiguration.getCoveragePatterns(); - if (patterns != null) { - final List filters = new ArrayList(); - for (ClassFilter classFilter : patterns) { - filters.add(classFilter.getPattern()); - } - return ArrayUtil.toStringArray(filters); - } - return null; - } - - private static RefactoringElementListener appendListener(RefactoringElementListener listener, - final RefactoringElementListener classOrPackageListener) { - if (listener == null) { - listener = new RefactoringElementListenerComposite(); - } else if (!(listener instanceof RefactoringElementListenerComposite)) { - final RefactoringElementListenerComposite composite = new RefactoringElementListenerComposite(); - composite.addListener(listener); - listener = composite; } - ((RefactoringElementListenerComposite)listener).addListener(classOrPackageListener); - return listener; - } - - @Override - 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.isSampling()); - } - return false; - } - - protected boolean isApplicableFor(@Nonnull final RunConfigurationBase configuration) { - return CoverageEnabledConfiguration.isApplicableTo(configuration); - } - private static class MyPackageAccessor extends MyAccessor implements RefactoringListeners.Accessor { + @Override + public void readExternal(@Nonnull RunConfigurationBase runConfiguration, @Nonnull Element element) throws InvalidDataException { + if (!isApplicableFor(runConfiguration)) { + return; + } + //noinspection ConstantConditions + JavaCoverageEnabledConfiguration.getFrom(runConfiguration).readExternal(element); + } - private MyPackageAccessor(Project project, ClassFilter[] patterns, int idx, String[] filters) { - super(project, patterns, idx, filters); + @Override + public void writeExternal(@Nonnull RunConfigurationBase runConfiguration, @Nonnull Element element) throws WriteExternalException { + if (!isApplicableFor(runConfiguration)) { + return; + } + //noinspection ConstantConditions + JavaCoverageEnabledConfiguration.getFrom(runConfiguration).writeExternal(element); } - public void setName(String qualifiedName) { - super.setName(qualifiedName + ".*"); + @Override + public void extendCreatedConfiguration(@Nonnull RunConfigurationBase runJavaConfiguration, @Nonnull Location location) { + JavaCoverageEnabledConfiguration coverageEnabledConfiguration = + JavaCoverageEnabledConfiguration.getFrom(runJavaConfiguration); + assert coverageEnabledConfiguration != null; + if (runJavaConfiguration instanceof CommonJavaRunConfigurationParameters commonJavaRunConfigurationParameters) { + coverageEnabledConfiguration.setUpCoverageFilters( + commonJavaRunConfigurationParameters.getRunClass(), + commonJavaRunConfigurationParameters.getPackage() + ); + } } - public PsiJavaPackage getPsiElement() { - final String name = getName(); - return JavaPsiFacade.getInstance(getProject()).findPackage(name.substring(0, name.length() - ".*".length())); + @Override + public void cleanUserData(RunConfigurationBase runConfiguration) { + runConfiguration.putCopyableUserData(CoverageEnabledConfiguration.COVERAGE_KEY, null); } - public void setPsiElement(PsiJavaPackage psiElement) { - setName(psiElement.getQualifiedName()); + @Override + public void validateConfiguration(@Nonnull RunConfigurationBase runJavaConfiguration, boolean isExecution) + throws RuntimeConfigurationException { } - } - private static class MyClassAccessor extends MyAccessor implements RefactoringListeners.Accessor { + @Override + public RefactoringElementListener wrapElementListener( + PsiElement element, + RunConfigurationBase configuration, + RefactoringElementListener listener + ) { + if (!isApplicableFor(configuration)) { + return listener; + } + JavaCoverageEnabledConfiguration coverageEnabledConfiguration = JavaCoverageEnabledConfiguration.getFrom(configuration); + if (coverageEnabledConfiguration != null) { + Project project = configuration.getProject(); + ClassFilter[] patterns = coverageEnabledConfiguration.getCoveragePatterns(); + String[] filters = getFilters(coverageEnabledConfiguration); + if (patterns != null) { + assert filters != null; + if (element instanceof PsiClass psiClass) { + int idx = ArrayUtil.find(filters, psiClass.getQualifiedName()); + if (idx > -1) { + RefactoringListeners.Accessor accessor = new MyClassAccessor(project, patterns, idx, filters); + RefactoringElementListener classListener = RefactoringListeners.getClassOrPackageListener(element, accessor); + if (classListener != null) { + listener = appendListener(listener, classListener); + } + } + } + else if (element instanceof PsiJavaPackage javaPackage) { + String qualifiedName = javaPackage.getQualifiedName(); + for (int i = 0, filtersLength = filters.length; i < filtersLength; i++) { + if (filters[i].startsWith(qualifiedName + ".")) { + RefactoringElementListener packageListener; + if (filters[i].endsWith("*")) { + packageListener = RefactoringListeners.getListener( + (PsiJavaPackage) element, + new MyPackageAccessor(project, patterns, i, filters) + ); + } + else { + packageListener = RefactoringListeners.getClassOrPackageListener( + element, + new MyClassAccessor(project, patterns, i, filters) + ); + } + if (packageListener != null) { + listener = appendListener(listener, packageListener); + } + } + } + } + } + } + return listener; + } - private MyClassAccessor(Project project, ClassFilter[] patterns, int idx, String[] filters) { - super(project, patterns, idx, filters); + @Nullable + private static String[] getFilters(JavaCoverageEnabledConfiguration coverageEnabledConfiguration) { + ClassFilter[] patterns = coverageEnabledConfiguration.getCoveragePatterns(); + if (patterns != null) { + List filters = new ArrayList<>(); + for (ClassFilter classFilter : patterns) { + filters.add(classFilter.getPattern()); + } + return ArrayUtil.toStringArray(filters); + } + return null; } - public PsiClass getPsiElement() { - return JavaPsiFacade.getInstance(getProject()).findClass(getName(), GlobalSearchScope.allScope(getProject())); + private static RefactoringElementListener appendListener( + RefactoringElementListener listener, + RefactoringElementListener classOrPackageListener + ) { + if (listener == null) { + listener = new RefactoringElementListenerComposite(); + } + else if (!(listener instanceof RefactoringElementListenerComposite)) { + RefactoringElementListenerComposite composite = new RefactoringElementListenerComposite(); + composite.addListener(listener); + listener = composite; + } + ((RefactoringElementListenerComposite) listener).addListener(classOrPackageListener); + return listener; } - public void setPsiElement(PsiClass psiElement) { - setName(psiElement.getQualifiedName()); + @Override + public boolean isListenerDisabled(RunConfigurationBase configuration, Object listener, RunnerSettings runnerSettings) { + if (listener instanceof CoverageListener) { + if (!(runnerSettings instanceof CoverageRunnerData)) { + return true; + } + CoverageEnabledConfiguration coverageEnabledConfiguration = CoverageEnabledConfiguration.getOrCreate(configuration); + return !(coverageEnabledConfiguration.getCoverageRunner() instanceof IDEACoverageRunner) + || !(coverageEnabledConfiguration.isTrackPerTestCoverage() && !coverageEnabledConfiguration.isSampling()); + } + return false; } - } - - private static class MyAccessor { - private final Project myProject; - private final ClassFilter[] myPatterns; - private final int myIdx; - private final String[] myFilters; - - private MyAccessor(Project project, ClassFilter[] patterns, int idx, String[] filters) { - myProject = project; - myPatterns = patterns; - myIdx = idx; - myFilters = filters; + + @Override + protected boolean isApplicableFor(@Nonnull RunConfigurationBase configuration) { + return CoverageEnabledConfiguration.isApplicableTo(configuration); } - public void setName(String qName) { - myPatterns[myIdx] = new ClassFilter(qName); + private static class MyPackageAccessor extends MyAccessor implements RefactoringListeners.Accessor { + + + private MyPackageAccessor(Project project, ClassFilter[] patterns, int idx, String[] filters) { + super(project, patterns, idx, filters); + } + + @Override + public void setName(String qualifiedName) { + super.setName(qualifiedName + ".*"); + } + + @Override + public PsiJavaPackage getPsiElement() { + String name = getName(); + return JavaPsiFacade.getInstance(getProject()).findPackage(name.substring(0, name.length() - ".*".length())); + } + + @Override + public void setPsiElement(PsiJavaPackage psiElement) { + setName(psiElement.getQualifiedName()); + } } - public String getName() { - return myFilters[myIdx]; + private static class MyClassAccessor extends MyAccessor implements RefactoringListeners.Accessor { + + private MyClassAccessor(Project project, ClassFilter[] patterns, int idx, String[] filters) { + super(project, patterns, idx, filters); + } + + @Override + public PsiClass getPsiElement() { + return JavaPsiFacade.getInstance(getProject()).findClass(getName(), GlobalSearchScope.allScope(getProject())); + } + + @Override + public void setPsiElement(PsiClass psiElement) { + setName(psiElement.getQualifiedName()); + } } - public Project getProject() { - return myProject; + private static class MyAccessor { + private final Project myProject; + private final ClassFilter[] myPatterns; + private final int myIdx; + private final String[] myFilters; + + private MyAccessor(Project project, ClassFilter[] patterns, int idx, String[] filters) { + myProject = project; + myPatterns = patterns; + myIdx = idx; + myFilters = filters; + } + + public void setName(String qName) { + myPatterns[myIdx] = new ClassFilter(qName); + } + + public String getName() { + return myFilters[myIdx]; + } + + public Project getProject() { + return myProject; + } } - } } \ No newline at end of file diff --git a/java-coverage-impl/src/main/java/com/intellij/java/coverage/CoverageProjectViewClassNodeDecorator.java b/java-coverage-impl/src/main/java/com/intellij/java/coverage/CoverageProjectViewClassNodeDecorator.java index 52160ec15c..7a9801d352 100644 --- a/java-coverage-impl/src/main/java/com/intellij/java/coverage/CoverageProjectViewClassNodeDecorator.java +++ b/java-coverage-impl/src/main/java/com/intellij/java/coverage/CoverageProjectViewClassNodeDecorator.java @@ -1,15 +1,14 @@ package com.intellij.java.coverage; import com.intellij.java.language.psi.PsiClass; +import consulo.annotation.access.RequiredReadAction; import consulo.annotation.component.ExtensionImpl; -import consulo.execution.coverage.CoverageAnnotator; import consulo.execution.coverage.CoverageDataManager; import consulo.execution.coverage.CoverageSuitesBundle; import consulo.execution.coverage.view.AbstractCoverageProjectViewNodeDecorator; import consulo.language.psi.PsiElement; import consulo.language.psi.PsiUtilCore; import consulo.language.psi.SmartPsiElementPointer; -import consulo.language.psi.scope.GlobalSearchScope; import consulo.project.Project; import consulo.project.ui.view.tree.PackageElement; import consulo.project.ui.view.tree.ProjectViewNode; @@ -23,82 +22,82 @@ */ @ExtensionImpl public class CoverageProjectViewClassNodeDecorator extends AbstractCoverageProjectViewNodeDecorator { - @Inject - public CoverageProjectViewClassNodeDecorator(final CoverageDataManager coverageDataManager) { - super(coverageDataManager); - } + @Inject + public CoverageProjectViewClassNodeDecorator(CoverageDataManager coverageDataManager) { + super(coverageDataManager); + } -// @Override -// public void decorate(PackageDependenciesNode node, ColoredTreeCellRenderer cellRenderer) { -// final PsiElement element = node.getPsiElement(); -// if (element == null || !element.isValid()) { -// return; -// } +// @Override +// public void decorate(PackageDependenciesNode node, ColoredTreeCellRenderer cellRenderer) { +// PsiElement element = node.getPsiElement(); +// if (element == null || !element.isValid()) { +// return; +// } // -// final CoverageDataManager dataManager = getCoverageDataManager(); -// final CoverageSuitesBundle currentSuite = dataManager.getCurrentSuitesBundle(); -// final Project project = element.getProject(); +// CoverageDataManager dataManager = getCoverageDataManager(); +// CoverageSuitesBundle currentSuite = dataManager.getCurrentSuitesBundle(); +// Project project = element.getProject(); // -// final JavaCoverageAnnotator javaCovAnnotator = getCovAnnotator(currentSuite, project); -// // This decorator is applicable only to JavaCoverageAnnotator -// if (javaCovAnnotator == null) { -// return; -// } +// JavaCoverageAnnotator javaCovAnnotator = getCovAnnotator(currentSuite, project); +// // This decorator is applicable only to JavaCoverageAnnotator +// if (javaCovAnnotator == null) { +// return; +// } // -// if (element instanceof PsiClass) { -// final String qName = ((PsiClass) element).getQualifiedName(); -// if (qName != null) { -// appendCoverageInfo(cellRenderer, javaCovAnnotator.getClassCoverageInformationString(qName, dataManager)); -// } +// if (element instanceof PsiClass psiClass) { +// String qName = psiClass.getQualifiedName(); +// if (qName != null) { +// appendCoverageInfo(cellRenderer, javaCovAnnotator.getClassCoverageInformationString(qName, dataManager)); +// } +// } // } -// } - @Override - public void decorate(ProjectViewNode node, PresentationData data) { - final CoverageDataManager coverageDataManager = getCoverageDataManager(); - final CoverageSuitesBundle currentSuite = coverageDataManager.getCurrentSuitesBundle(); + @Override + @RequiredReadAction + public void decorate(ProjectViewNode node, PresentationData data) { + CoverageDataManager coverageDataManager = getCoverageDataManager(); + CoverageSuitesBundle currentSuite = coverageDataManager.getCurrentSuitesBundle(); - final Project project = node.getProject(); - final JavaCoverageAnnotator javaCovAnnotator = getCovAnnotator(currentSuite, project); - // This decorator is applicable only to JavaCoverageAnnotator - if (javaCovAnnotator == null) { - return; - } + Project project = node.getProject(); + JavaCoverageAnnotator javaCovAnnotator = getCovAnnotator(currentSuite, project); + // This decorator is applicable only to JavaCoverageAnnotator + if (javaCovAnnotator == null) { + return; + } - final Object value = node.getValue(); - PsiElement element = null; - if (value instanceof PsiElement) { - element = (PsiElement) value; - } else if (value instanceof SmartPsiElementPointer) { - element = ((SmartPsiElementPointer) value).getElement(); - } else if (value instanceof PackageElement) { - PackageElement packageElement = (PackageElement) value; - final String coverageString = javaCovAnnotator.getPackageCoverageInformationString(packageElement.getPackage(), - packageElement.getModule(), - coverageDataManager); - data.setLocationString(coverageString); - } + Object value = node.getValue(); + PsiElement element = null; + if (value instanceof PsiElement psiElement) { + element = psiElement; + } + else if (value instanceof SmartPsiElementPointer smartPsiElementPointer) { + element = smartPsiElementPointer.getElement(); + } + else if (value instanceof PackageElement packageElement) { + String coverageString = javaCovAnnotator.getPackageCoverageInformationString( + packageElement.getPackage(), + packageElement.getModule(), + coverageDataManager + ); + data.setLocationString(coverageString); + } - if (element instanceof PsiClass) { - final GlobalSearchScope searchScope = currentSuite.getSearchScope(project); - final VirtualFile vFile = PsiUtilCore.getVirtualFile(element); - if (vFile != null && searchScope.contains(vFile)) { - final String qName = ((PsiClass) element).getQualifiedName(); - if (qName != null) { - data.setLocationString(javaCovAnnotator.getClassCoverageInformationString(qName, coverageDataManager)); + if (element instanceof PsiClass psiClass) { + VirtualFile vFile = PsiUtilCore.getVirtualFile(element); + if (vFile != null && currentSuite.getSearchScope(project).contains(vFile)) { + String qName = psiClass.getQualifiedName(); + if (qName != null) { + data.setLocationString(javaCovAnnotator.getClassCoverageInformationString(qName, coverageDataManager)); + } + } } - } } - } - @Nullable - private static JavaCoverageAnnotator getCovAnnotator(final CoverageSuitesBundle currentSuite, Project project) { - if (currentSuite != null) { - final CoverageAnnotator coverageAnnotator = currentSuite.getAnnotator(project); - if (coverageAnnotator instanceof JavaCoverageAnnotator) { - return (JavaCoverageAnnotator) coverageAnnotator; - } + @Nullable + private static JavaCoverageAnnotator getCovAnnotator(CoverageSuitesBundle currentSuite, Project project) { + if (currentSuite != null && currentSuite.getAnnotator(project) instanceof JavaCoverageAnnotator javaCoverageAnnotator) { + return javaCoverageAnnotator; + } + return null; } - return null; - } } \ No newline at end of file diff --git a/java-coverage-impl/src/main/java/com/intellij/java/coverage/DefaultJavaCoverageRunner.java b/java-coverage-impl/src/main/java/com/intellij/java/coverage/DefaultJavaCoverageRunner.java index 0c86ddb8fe..de9637071e 100644 --- a/java-coverage-impl/src/main/java/com/intellij/java/coverage/DefaultJavaCoverageRunner.java +++ b/java-coverage-impl/src/main/java/com/intellij/java/coverage/DefaultJavaCoverageRunner.java @@ -41,9 +41,9 @@ public boolean canRun(@Nonnull String executorId, @Nonnull RunProfile profile) { return executorId.equals(CoverageExecutor.EXECUTOR_ID) // && profile instanceof ModuleBasedConfiguration && !(profile instanceof RunConfigurationWithSuppressedDefaultRunAction) - && profile instanceof RunConfigurationBase + && profile instanceof RunConfigurationBase runConfigurationBase && myApplication.getExtensionPoint(CoverageEngine.class) - .findExtensionOrFail(JavaCoverageEngine.class).isApplicableTo((RunConfigurationBase)profile); + .findExtensionOrFail(JavaCoverageEngine.class).isApplicableTo(runConfigurationBase); } catch (Exception e) { return false; diff --git a/java-coverage-impl/src/main/java/com/intellij/java/coverage/IDEACoverageRunner.java b/java-coverage-impl/src/main/java/com/intellij/java/coverage/IDEACoverageRunner.java index bf4f257c06..9e10f3eccd 100644 --- a/java-coverage-impl/src/main/java/com/intellij/java/coverage/IDEACoverageRunner.java +++ b/java-coverage-impl/src/main/java/com/intellij/java/coverage/IDEACoverageRunner.java @@ -13,75 +13,78 @@ import java.io.File; import java.io.IOException; -/* - * User: anna - * Date: 20-May-2008 +/** + * @author anna + * @since 2008-05-20 */ @ExtensionImpl public class IDEACoverageRunner extends JavaCoverageRunner { - private static final Logger LOG = Logger.getInstance(IDEACoverageRunner.class); + private static final Logger LOG = Logger.getInstance(IDEACoverageRunner.class); - @Override - public ProjectData loadCoverageData(@Nonnull final File sessionDataFile, @Nullable final CoverageSuite coverageSuite) { - return ProjectDataLoader.load(sessionDataFile); - } + @Override + public ProjectData loadCoverageData(@Nonnull File sessionDataFile, @Nullable CoverageSuite coverageSuite) { + return ProjectDataLoader.load(sessionDataFile); + } - @Override - public void appendCoverageArgument(final String sessionDataFilePath, - final String[] patterns, - final OwnJavaParameters javaParameters, - final boolean collectLineInfo, - final boolean isSampling) { - StringBuilder argument = new StringBuilder("-javaagent:"); - File agentFile = new File(PluginManager.getPluginPath(IDEACoverageRunner.class), "coverage/consulo/agent.jar"); + @Override + public void appendCoverageArgument( + String sessionDataFilePath, + String[] patterns, + OwnJavaParameters javaParameters, + boolean collectLineInfo, + boolean isSampling + ) { + StringBuilder argument = new StringBuilder("-javaagent:"); + File agentFile = new File(PluginManager.getPluginPath(IDEACoverageRunner.class), "coverage/consulo/agent.jar"); - final String parentPath = handleSpacesInPath(agentFile); - argument.append(parentPath).append(File.separator).append(agentFile.getName()); - argument.append("="); - try { - final File tempFile = createTempFile(); - tempFile.deleteOnExit(); - write2file(tempFile, sessionDataFilePath); - write2file(tempFile, String.valueOf(collectLineInfo)); - write2file(tempFile, Boolean.FALSE.toString()); //append unloaded - write2file(tempFile, Boolean.FALSE.toString());//merge with existing - write2file(tempFile, String.valueOf(isSampling)); - if (patterns != null) { - for (String coveragePattern : patterns) { - coveragePattern = coveragePattern.replace("$", "\\$").replace(".", "\\.").replaceAll("\\*", ".*"); - if (!coveragePattern.endsWith(".*")) { //include inner classes - coveragePattern += "(\\$.*)*"; - } - write2file(tempFile, coveragePattern); + String parentPath = handleSpacesInPath(agentFile); + argument.append(parentPath).append(File.separator).append(agentFile.getName()); + argument.append("="); + try { + File tempFile = createTempFile(); + tempFile.deleteOnExit(); + write2file(tempFile, sessionDataFilePath); + write2file(tempFile, String.valueOf(collectLineInfo)); + write2file(tempFile, Boolean.FALSE.toString()); //append unloaded + write2file(tempFile, Boolean.FALSE.toString());//merge with existing + write2file(tempFile, String.valueOf(isSampling)); + if (patterns != null) { + for (String coveragePattern : patterns) { + coveragePattern = coveragePattern.replace("$", "\\$").replace(".", "\\.").replaceAll("\\*", ".*"); + if (!coveragePattern.endsWith(".*")) { //include inner classes + coveragePattern += "(\\$.*)*"; + } + write2file(tempFile, coveragePattern); + } + } + argument.append(tempFile.getCanonicalPath()); + } + catch (IOException e) { + LOG.info("Coverage was not enabled", e); + return; } - } - argument.append(tempFile.getCanonicalPath()); - } catch (IOException e) { - LOG.info("Coverage was not enabled", e); - return; - } - javaParameters.getVMParametersList().add(argument.toString()); - } + javaParameters.getVMParametersList().add(argument.toString()); + } - @Override - public String getPresentableName() { - return "Consulo (Internal)"; - } + @Override + public String getPresentableName() { + return "Consulo (Internal)"; + } - @Override - public String getId() { - return "idea"; - } + @Override + public String getId() { + return "idea"; + } - @Override - public String getDataFileExtension() { - return "ic"; - } + @Override + public String getDataFileExtension() { + return "ic"; + } - @Override - public boolean isCoverageByTestApplicable() { - return true; - } + @Override + public boolean isCoverageByTestApplicable() { + return true; + } } \ No newline at end of file diff --git a/java-coverage-impl/src/main/java/com/intellij/java/coverage/JaCoCoCoverageRunner.java b/java-coverage-impl/src/main/java/com/intellij/java/coverage/JaCoCoCoverageRunner.java index ff2beb7670..c586bfbac6 100644 --- a/java-coverage-impl/src/main/java/com/intellij/java/coverage/JaCoCoCoverageRunner.java +++ b/java-coverage-impl/src/main/java/com/intellij/java/coverage/JaCoCoCoverageRunner.java @@ -1,13 +1,10 @@ -/* - * User: anna - * Date: 20-May-2008 - */ package com.intellij.java.coverage; import com.intellij.rt.coverage.data.ClassData; import com.intellij.rt.coverage.data.LineCoverage; import com.intellij.rt.coverage.data.LineData; import com.intellij.rt.coverage.data.ProjectData; +import consulo.annotation.access.RequiredReadAction; import consulo.annotation.component.ExtensionImpl; import consulo.compiler.ModuleCompilerPathsManager; import consulo.container.plugin.PluginManager; @@ -26,136 +23,141 @@ import org.jacoco.core.analysis.*; import org.jacoco.core.data.ExecutionDataReader; import org.jacoco.core.data.ExecutionDataStore; -import org.jacoco.core.data.ISessionInfoVisitor; -import org.jacoco.core.data.SessionInfo; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.util.Collection; +/** + * @author anna + * @since 2008-05-20 + */ @ExtensionImpl public class JaCoCoCoverageRunner extends JavaCoverageRunner { - @Override - public ProjectData loadCoverageData(@Nonnull File sessionDataFile, @Nullable CoverageSuite baseCoverageSuite) { - final ProjectData data = new ProjectData(); - try { - final Project project = baseCoverageSuite instanceof BaseCoverageSuite ? ((BaseCoverageSuite) baseCoverageSuite).getProject() : null; - if (project != null) { - loadExecutionData(sessionDataFile, data, project); - } - } catch (Exception e) { - return data; - } - return data; - } - - private static void loadExecutionData(@Nonnull final File sessionDataFile, ProjectData data, @Nonnull Project project) throws IOException { - final ExecutionDataStore executionDataStore = new ExecutionDataStore(); - FileInputStream fis = null; - try { - fis = new FileInputStream(sessionDataFile); - final ExecutionDataReader executionDataReader = new ExecutionDataReader(fis); - - executionDataReader.setExecutionDataVisitor(executionDataStore); - executionDataReader.setSessionInfoVisitor(new ISessionInfoVisitor() { - @Override - public void visitSessionInfo(SessionInfo info) { - System.out.println(info.toString()); + @Override + @RequiredReadAction + public ProjectData loadCoverageData(@Nonnull File sessionDataFile, @Nullable CoverageSuite baseCoverageSuite) { + ProjectData data = new ProjectData(); + try { + Project project = + baseCoverageSuite instanceof BaseCoverageSuite ? baseCoverageSuite.getProject() : null; + if (project != null) { + loadExecutionData(sessionDataFile, data, project); + } } - }); - - while (executionDataReader.read()) { - } - } finally { - if (fis != null) { - fis.close(); - } + catch (Exception e) { + return data; + } + return data; } - final CoverageBuilder coverageBuilder = new CoverageBuilder(); - final Analyzer analyzer = new Analyzer(executionDataStore, coverageBuilder); - - final Module[] modules = ModuleManager.getInstance(project).getModules(); - for (Module module : modules) { - final ModuleCompilerPathsManager compilerModuleExtension = ModuleCompilerPathsManager.getInstance(module); - VirtualFile compilerOutput = compilerModuleExtension.getCompilerOutput(ProductionContentFolderTypeProvider.getInstance()); - if (compilerOutput != null) { - analyzer.analyzeAll(VirtualFileUtil.virtualToIoFile(compilerOutput)); - } - - compilerOutput = compilerModuleExtension.getCompilerOutput(TestContentFolderTypeProvider.getInstance()); - if (compilerOutput != null) { - analyzer.analyzeAll(VirtualFileUtil.virtualToIoFile(compilerOutput)); - } - } + @RequiredReadAction + private static void loadExecutionData(@Nonnull File sessionDataFile, ProjectData data, @Nonnull Project project) throws IOException { + ExecutionDataStore executionDataStore = new ExecutionDataStore(); + FileInputStream fis = null; + try { + fis = new FileInputStream(sessionDataFile); + ExecutionDataReader executionDataReader = new ExecutionDataReader(fis); + + executionDataReader.setExecutionDataVisitor(executionDataStore); + executionDataReader.setSessionInfoVisitor(info -> System.out.println(info.toString())); + + //noinspection StatementWithEmptyBody + while (executionDataReader.read()) { + } + } + finally { + if (fis != null) { + fis.close(); + } + } + + CoverageBuilder coverageBuilder = new CoverageBuilder(); + Analyzer analyzer = new Analyzer(executionDataStore, coverageBuilder); + + Module[] modules = ModuleManager.getInstance(project).getModules(); + for (Module module : modules) { + ModuleCompilerPathsManager compilerModuleExtension = ModuleCompilerPathsManager.getInstance(module); + VirtualFile compilerOutput = compilerModuleExtension.getCompilerOutput(ProductionContentFolderTypeProvider.getInstance()); + if (compilerOutput != null) { + analyzer.analyzeAll(VirtualFileUtil.virtualToIoFile(compilerOutput)); + } - for (IClassCoverage classCoverage : coverageBuilder.getClasses()) { - String className = classCoverage.getName(); - className = className.replace('\\', '.').replace('/', '.'); - final ClassData classData = data.getOrCreateClassData(className); - final Collection methods = classCoverage.getMethods(); - LineData[] lines = new LineData[classCoverage.getLastLine()]; - for (IMethodCoverage method : methods) { - final String desc = method.getName() + method.getDesc(); - final int firstLine = method.getFirstLine(); - final int lastLine = method.getLastLine(); - for (int i = firstLine; i < lastLine; i++) { - final ILine methodLine = method.getLine(i); - final int methodLineStatus = methodLine.getStatus(); - final LineData lineData = new LineData(i, desc) { - @Override - public int getStatus() { - switch (methodLineStatus) { - case ICounter.FULLY_COVERED: - return LineCoverage.FULL; - case ICounter.PARTLY_COVERED: - return LineCoverage.PARTIAL; - default: - return LineCoverage.NONE; - } + compilerOutput = compilerModuleExtension.getCompilerOutput(TestContentFolderTypeProvider.getInstance()); + if (compilerOutput != null) { + analyzer.analyzeAll(VirtualFileUtil.virtualToIoFile(compilerOutput)); } - }; - lineData.setHits(methodLineStatus == ICounter.FULLY_COVERED || methodLineStatus == ICounter.PARTLY_COVERED ? 1 : 0); - lines[i] = lineData; } - } - classData.setLines(lines); + + for (IClassCoverage classCoverage : coverageBuilder.getClasses()) { + String className = classCoverage.getName(); + className = className.replace('\\', '.').replace('/', '.'); + ClassData classData = data.getOrCreateClassData(className); + Collection methods = classCoverage.getMethods(); + LineData[] lines = new LineData[classCoverage.getLastLine()]; + for (IMethodCoverage method : methods) { + final String desc = method.getName() + method.getDesc(); + int firstLine = method.getFirstLine(); + int lastLine = method.getLastLine(); + for (int i = firstLine; i < lastLine; i++) { + ILine methodLine = method.getLine(i); + final int methodLineStatus = methodLine.getStatus(); + LineData lineData = new LineData(i, desc) { + @Override + public int getStatus() { + return switch (methodLineStatus) { + case ICounter.FULLY_COVERED -> LineCoverage.FULL; + case ICounter.PARTLY_COVERED -> LineCoverage.PARTIAL; + default -> LineCoverage.NONE; + }; + } + }; + lineData.setHits(methodLineStatus == ICounter.FULLY_COVERED || methodLineStatus == ICounter.PARTLY_COVERED ? 1 : 0); + lines[i] = lineData; + } + } + classData.setLines(lines); + } + } + + @Override + public void appendCoverageArgument( + String sessionDataFilePath, + String[] patterns, + OwnJavaParameters javaParameters, + boolean collectLineInfo, + boolean isSampling + ) { + File agentFile = new File(PluginManager.getPluginPath(JaCoCoCoverageRunner.class), "coverage/jacoco/jacocoagent.jar"); + + StringBuilder argument = new StringBuilder("-javaagent:"); + String parentPath = handleSpacesInPath(agentFile); + argument.append(parentPath).append(File.separator).append(agentFile.getName()); + argument.append("="); + argument.append("destfile=").append(sessionDataFilePath); + argument.append(",append=false"); + javaParameters.getVMParametersList().add(argument.toString()); + } + + + @Override + public String getPresentableName() { + return "JaCoCo"; + } + + @Override + public String getId() { + return "jacoco"; + } + + @Override + public String getDataFileExtension() { + return "exec"; + } + + @Override + public boolean isCoverageByTestApplicable() { + return false; } - } - - - @Override - public void appendCoverageArgument(final String sessionDataFilePath, final String[] patterns, final OwnJavaParameters javaParameters, final boolean collectLineInfo, final boolean isSampling) { - final File agentFile = new File(PluginManager.getPluginPath(JaCoCoCoverageRunner.class), "coverage/jacoco/jacocoagent.jar"); - - StringBuilder argument = new StringBuilder("-javaagent:"); - final String parentPath = handleSpacesInPath(agentFile); - argument.append(parentPath).append(File.separator).append(agentFile.getName()); - argument.append("="); - argument.append("destfile=").append(sessionDataFilePath); - argument.append(",append=false"); - javaParameters.getVMParametersList().add(argument.toString()); - } - - - @Override - public String getPresentableName() { - return "JaCoCo"; - } - - @Override - public String getId() { - return "jacoco"; - } - - @Override - public String getDataFileExtension() { - return "exec"; - } - - @Override - public boolean isCoverageByTestApplicable() { - return false; - } } diff --git a/java-coverage-impl/src/main/java/com/intellij/java/coverage/JavaCoverageAnnotator.java b/java-coverage-impl/src/main/java/com/intellij/java/coverage/JavaCoverageAnnotator.java index d9814d0a90..56648baa69 100644 --- a/java-coverage-impl/src/main/java/com/intellij/java/coverage/JavaCoverageAnnotator.java +++ b/java-coverage-impl/src/main/java/com/intellij/java/coverage/JavaCoverageAnnotator.java @@ -4,7 +4,6 @@ import consulo.annotation.component.ComponentScope; import consulo.annotation.component.ServiceAPI; import consulo.annotation.component.ServiceImpl; -import consulo.application.ApplicationManager; import consulo.execution.coverage.BaseCoverageAnnotator; import consulo.execution.coverage.CoverageDataManager; import consulo.execution.coverage.CoverageSuite; @@ -19,11 +18,11 @@ import consulo.module.content.ProjectRootManager; import consulo.project.Project; import consulo.virtualFileSystem.VirtualFile; +import jakarta.annotation.Nonnull; +import jakarta.annotation.Nullable; import jakarta.inject.Inject; import jakarta.inject.Singleton; -import jakarta.annotation.Nonnull; -import jakarta.annotation.Nullable; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -36,267 +35,310 @@ @ServiceAPI(ComponentScope.PROJECT) @ServiceImpl public class JavaCoverageAnnotator extends BaseCoverageAnnotator { - private final Map myPackageCoverageInfos = - new HashMap<>(); - private final Map myFlattenPackageCoverageInfos = - new HashMap<>(); - private final Map myDirCoverageInfos = - new HashMap<>(); - private final Map myTestDirCoverageInfos = - new HashMap<>(); - private final Map myClassCoverageInfos = - new HashMap<>(); - - @Inject - public JavaCoverageAnnotator(final Project project) { - super(project); - } - - public static JavaCoverageAnnotator getInstance(final Project project) { - return ServiceManager.getService(project, JavaCoverageAnnotator.class); - } - - @Nullable - public String getDirCoverageInformationString(@Nonnull final PsiDirectory directory, - @Nonnull final CoverageSuitesBundle currentSuite, - @Nonnull final CoverageDataManager coverageDataManager) { - final PsiJavaPackage psiPackage = JavaDirectoryService.getInstance().getPackage(directory); - if (psiPackage == null) return null; - - final ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(directory.getProject()).getFileIndex(); - final VirtualFile virtualFile = directory.getVirtualFile(); - - final boolean isInTestContent = projectFileIndex.isInTestSourceContent(virtualFile); - - if (!currentSuite.isTrackTestFolders() && isInTestContent) { - return null; + private final Map myPackageCoverageInfos = new HashMap<>(); + private final Map myFlattenPackageCoverageInfos = new HashMap<>(); + private final Map myDirCoverageInfos = new HashMap<>(); + private final Map myTestDirCoverageInfos = new HashMap<>(); + private final Map myClassCoverageInfos = new HashMap<>(); + + @Inject + public JavaCoverageAnnotator(Project project) { + super(project); } - return isInTestContent ? getCoverageInformationString(myTestDirCoverageInfos.get(virtualFile), - coverageDataManager.isSubCoverageActive()) - : getCoverageInformationString(myDirCoverageInfos.get(virtualFile), coverageDataManager.isSubCoverageActive()); - } + public static JavaCoverageAnnotator getInstance(Project project) { + return ServiceManager.getService(project, JavaCoverageAnnotator.class); + } - @Nullable - public String getFileCoverageInformationString(@Nonnull PsiFile file, - @Nonnull CoverageSuitesBundle currentSuite, - @Nonnull CoverageDataManager manager) { - // N/A here we work with java classes - return null; - } + @Nullable + @Override + public String getDirCoverageInformationString( + @Nonnull PsiDirectory directory, + @Nonnull CoverageSuitesBundle currentSuite, + @Nonnull CoverageDataManager coverageDataManager + ) { + PsiJavaPackage psiPackage = JavaDirectoryService.getInstance().getPackage(directory); + if (psiPackage == null) { + return null; + } - public void onSuiteChosen(CoverageSuitesBundle newSuite) { - super.onSuiteChosen(newSuite); + ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(directory.getProject()).getFileIndex(); + VirtualFile virtualFile = directory.getVirtualFile(); - myPackageCoverageInfos.clear(); - myFlattenPackageCoverageInfos.clear(); - myDirCoverageInfos.clear(); - myTestDirCoverageInfos.clear(); - myClassCoverageInfos.clear(); - } + boolean isInTestContent = projectFileIndex.isInTestSourceContent(virtualFile); - protected Runnable createRenewRequest(@Nonnull final CoverageSuitesBundle suite, @Nonnull final CoverageDataManager dataManager) { + if (!currentSuite.isTrackTestFolders() && isInTestContent) { + return null; + } + return isInTestContent + ? getCoverageInformationString(myTestDirCoverageInfos.get(virtualFile), coverageDataManager.isSubCoverageActive()) + : getCoverageInformationString(myDirCoverageInfos.get(virtualFile), coverageDataManager.isSubCoverageActive()); + } + @Nullable + @Override + public String getFileCoverageInformationString( + @Nonnull PsiFile file, + @Nonnull CoverageSuitesBundle currentSuite, + @Nonnull CoverageDataManager manager + ) { + // N/A here we work with java classes + return null; + } - final Project project = getProject(); - final List packages = new ArrayList<>(); - final List classes = new ArrayList<>(); + @Override + public void onSuiteChosen(CoverageSuitesBundle newSuite) { + super.onSuiteChosen(newSuite); - for (CoverageSuite coverageSuite : suite.getSuites()) { - final JavaCoverageSuite javaSuite = (JavaCoverageSuite)coverageSuite; - classes.addAll(javaSuite.getCurrentSuiteClasses(project)); - packages.addAll(javaSuite.getCurrentSuitePackages(project)); + myPackageCoverageInfos.clear(); + myFlattenPackageCoverageInfos.clear(); + myDirCoverageInfos.clear(); + myTestDirCoverageInfos.clear(); + myClassCoverageInfos.clear(); } - if (packages.isEmpty() && classes.isEmpty()) { - return null; - } + @Override + protected Runnable createRenewRequest(@Nonnull CoverageSuitesBundle suite, @Nonnull CoverageDataManager dataManager) { + Project project = getProject(); + List packages = new ArrayList<>(); + List classes = new ArrayList<>(); + + for (CoverageSuite coverageSuite : suite.getSuites()) { + JavaCoverageSuite javaSuite = (JavaCoverageSuite) coverageSuite; + classes.addAll(javaSuite.getCurrentSuiteClasses(project)); + packages.addAll(javaSuite.getCurrentSuitePackages(project)); + } + + if (packages.isEmpty() && classes.isEmpty()) { + return null; + } - return new Runnable() { - public void run() { - final PackageAnnotator.Annotator annotator = new PackageAnnotator.Annotator() { - public void annotatePackage(String packageQualifiedName, PackageAnnotator.PackageCoverageInfo packageCoverageInfo) { - myPackageCoverageInfos.put(packageQualifiedName, packageCoverageInfo); - } - - public void annotatePackage(String packageQualifiedName, - PackageAnnotator.PackageCoverageInfo packageCoverageInfo, - boolean flatten) { - if (flatten) { - myFlattenPackageCoverageInfos.put(packageQualifiedName, packageCoverageInfo); + return () -> { + PackageAnnotator.Annotator annotator = new PackageAnnotator.Annotator() { + @Override + public void annotatePackage(String packageQualifiedName, PackageAnnotator.PackageCoverageInfo packageCoverageInfo) { + myPackageCoverageInfos.put(packageQualifiedName, packageCoverageInfo); + } + + @Override + public void annotatePackage( + String packageQualifiedName, + PackageAnnotator.PackageCoverageInfo packageCoverageInfo, + boolean flatten + ) { + if (flatten) { + myFlattenPackageCoverageInfos.put(packageQualifiedName, packageCoverageInfo); + } + else { + annotatePackage(packageQualifiedName, packageCoverageInfo); + } + } + + @Override + public void annotateSourceDirectory( + VirtualFile dir, + PackageAnnotator.PackageCoverageInfo dirCoverageInfo, + Module module + ) { + myDirCoverageInfos.put(dir, dirCoverageInfo); + } + + @Override + public void annotateTestDirectory( + VirtualFile virtualFile, + PackageAnnotator.PackageCoverageInfo packageCoverageInfo, + Module module + ) { + myTestDirCoverageInfos.put(virtualFile, packageCoverageInfo); + } + + @Override + public void annotateClass(String classQualifiedName, PackageAnnotator.ClassCoverageInfo classCoverageInfo) { + myClassCoverageInfos.put(classQualifiedName, classCoverageInfo); + } + }; + for (PsiJavaPackage aPackage : packages) { + new PackageAnnotator(aPackage).annotate(suite, annotator); } - else { - annotatePackage(packageQualifiedName, packageCoverageInfo); + for (PsiClass aClass : classes) { + Runnable runnable = () -> { + String packageName = ((PsiClassOwner) aClass.getContainingFile()).getPackageName(); + PsiJavaPackage psiPackage = JavaPsiFacade.getInstance(project).findPackage(packageName); + if (psiPackage == null) { + return; + } + new PackageAnnotator(psiPackage).annotateFilteredClass(aClass, suite, annotator); + }; + aClass.getApplication().runReadAction(runnable); } - } - - public void annotateSourceDirectory(VirtualFile dir, - PackageAnnotator.PackageCoverageInfo dirCoverageInfo, - Module module) { - myDirCoverageInfos.put(dir, dirCoverageInfo); - } - - public void annotateTestDirectory(VirtualFile virtualFile, - PackageAnnotator.PackageCoverageInfo packageCoverageInfo, - Module module) { - myTestDirCoverageInfos.put(virtualFile, packageCoverageInfo); - } - - public void annotateClass(String classQualifiedName, PackageAnnotator.ClassCoverageInfo classCoverageInfo) { - myClassCoverageInfos.put(classQualifiedName, classCoverageInfo); - } + dataManager.triggerPresentationUpdate(); }; - for (PsiJavaPackage aPackage : packages) { - new PackageAnnotator(aPackage).annotate(suite, annotator); + } + + @Nullable + public static String getCoverageInformationString(PackageAnnotator.PackageCoverageInfo info, boolean subCoverageActive) { + if (info == null) { + return null; + } + if (info.totalClassCount == 0 || info.totalLineCount == 0) { + return null; + } + if (subCoverageActive) { + return info.coveredClassCount + info.coveredLineCount > 0 ? "covered" : null; + } + return (int) ((double) info.coveredClassCount / info.totalClassCount * 100) + "% classes, " + + (int) ((double) info.coveredLineCount / info.totalLineCount * 100) + "% lines covered"; + } + + /** + * @param psiPackage qualified name of a package to obtain coverage information for + * @param module optional parameter to restrict coverage to source directories of a certain module + * @param coverageDataManager + * @return human-readable coverage information + */ + @Nullable + public String getPackageCoverageInformationString( + PsiPackage psiPackage, + @Nullable Module module, + @Nonnull CoverageDataManager coverageDataManager + ) { + return getPackageCoverageInformationString(psiPackage, module, coverageDataManager, false); + } + + /** + * @param psiPackage qualified name of a package to obtain coverage information for + * @param module optional parameter to restrict coverage to source directories of a certain module + * @param coverageDataManager + * @param flatten + * @return human-readable coverage information + */ + @Nullable + public String getPackageCoverageInformationString( + PsiPackage psiPackage, + @Nullable Module module, + @Nonnull CoverageDataManager coverageDataManager, + boolean flatten + ) { + if (psiPackage == null) { + return null; } - for (final PsiClass aClass : classes) { - Runnable runnable = new Runnable() { - public void run() { - final String packageName = ((PsiClassOwner)aClass.getContainingFile()).getPackageName(); - final PsiJavaPackage psiPackage = JavaPsiFacade.getInstance(project).findPackage(packageName); - if (psiPackage == null) return; - new PackageAnnotator(psiPackage).annotateFilteredClass(aClass, suite, annotator); + boolean subCoverageActive = coverageDataManager.isSubCoverageActive(); + PackageAnnotator.PackageCoverageInfo info; + if (module != null) { + PsiDirectory[] directories = psiPackage.getDirectories(GlobalSearchScope.moduleScope(module)); + PackageAnnotator.PackageCoverageInfo result = null; + for (PsiDirectory directory : directories) { + VirtualFile virtualFile = directory.getVirtualFile(); + result = merge(result, myDirCoverageInfos.get(virtualFile)); + result = merge(result, myTestDirCoverageInfos.get(virtualFile)); } - }; - ApplicationManager.getApplication().runReadAction(runnable); + return getCoverageInformationString(result, subCoverageActive); } - dataManager.triggerPresentationUpdate(); - } - }; - } - - @Nullable - public static String getCoverageInformationString(PackageAnnotator.PackageCoverageInfo info, boolean subCoverageActive) { - if (info == null) return null; - if (info.totalClassCount == 0 || info.totalLineCount == 0) return null; - if (subCoverageActive) { - return info.coveredClassCount + info.coveredLineCount > 0 ? "covered" : null; + else { + info = getPackageCoverageInfo(psiPackage, flatten); + } + return getCoverageInformationString(info, subCoverageActive); } - return (int)((double)info.coveredClassCount / info.totalClassCount * 100) + "% classes, " + - (int)((double)info.coveredLineCount / info.totalLineCount * 100) + "% lines covered"; - } - - /** - * @param psiPackage qualified name of a package to obtain coverage information for - * @param module optional parameter to restrict coverage to source directories of a certain module - * @param coverageDataManager - * @return human-readable coverage information - */ - @Nullable - public String getPackageCoverageInformationString(final PsiPackage psiPackage, - @Nullable final Module module, - @Nonnull final CoverageDataManager coverageDataManager) { - return getPackageCoverageInformationString(psiPackage, module, coverageDataManager, false); - } - - /** - * @param psiPackage qualified name of a package to obtain coverage information for - * @param module optional parameter to restrict coverage to source directories of a certain module - * @param coverageDataManager - * @param flatten - * @return human-readable coverage information - */ - @Nullable - public String getPackageCoverageInformationString(final PsiPackage psiPackage, - @Nullable final Module module, - @Nonnull final CoverageDataManager coverageDataManager, - boolean flatten) { - if (psiPackage == null) return null; - final boolean subCoverageActive = coverageDataManager.isSubCoverageActive(); - PackageAnnotator.PackageCoverageInfo info; - if (module != null) { - final PsiDirectory[] directories = psiPackage.getDirectories(GlobalSearchScope.moduleScope(module)); - PackageAnnotator.PackageCoverageInfo result = null; - for (PsiDirectory directory : directories) { - final VirtualFile virtualFile = directory.getVirtualFile(); - result = merge(result, myDirCoverageInfos.get(virtualFile)); - result = merge(result, myTestDirCoverageInfos.get(virtualFile)); - } - return getCoverageInformationString(result, subCoverageActive); + + public PackageAnnotator.PackageCoverageInfo getPackageCoverageInfo(@Nonnull PsiPackage psiPackage, boolean flattenPackages) { + String qualifiedName = psiPackage.getQualifiedName(); + return flattenPackages ? myFlattenPackageCoverageInfos.get(qualifiedName) : myPackageCoverageInfos.get(qualifiedName); } - else { - info = getPackageCoverageInfo(psiPackage, flatten); + + public String getPackageClassPercentage(@Nonnull PsiPackage psiPackage, boolean flatten) { + PackageAnnotator.PackageCoverageInfo packageCoverageInfo = getPackageCoverageInfo(psiPackage, flatten); + if (packageCoverageInfo == null) { + return null; + } + return getPercentage(packageCoverageInfo.coveredClassCount, packageCoverageInfo.totalClassCount); } - return getCoverageInformationString(info, subCoverageActive); - } - - public PackageAnnotator.PackageCoverageInfo getPackageCoverageInfo(@Nonnull PsiPackage psiPackage, boolean flattenPackages) { - final String qualifiedName = psiPackage.getQualifiedName(); - return flattenPackages ? myFlattenPackageCoverageInfos.get(qualifiedName) : myPackageCoverageInfos.get(qualifiedName); - } - - public String getPackageClassPercentage(@Nonnull final PsiPackage psiPackage, boolean flatten) { - final PackageAnnotator.PackageCoverageInfo packageCoverageInfo = getPackageCoverageInfo(psiPackage, flatten); - if (packageCoverageInfo == null) return null; - return getPercentage(packageCoverageInfo.coveredClassCount, packageCoverageInfo.totalClassCount); - } - - public String getPackageMethodPercentage(PsiPackage psiPackage, boolean flatten) { - final PackageAnnotator.PackageCoverageInfo packageCoverageInfo = getPackageCoverageInfo(psiPackage, flatten); - if (packageCoverageInfo == null) return null; - return getPercentage(packageCoverageInfo.coveredMethodCount, packageCoverageInfo.totalMethodCount); - } - - public String getPackageLinePercentage(final PsiPackage psiPackage, boolean flatten) { - final PackageAnnotator.PackageCoverageInfo packageCoverageInfo = getPackageCoverageInfo(psiPackage, flatten); - if (packageCoverageInfo == null) return null; - return getPercentage(packageCoverageInfo.coveredLineCount, packageCoverageInfo.totalLineCount); - } - - public String getClassLinePercentage(String classFQName) { - final PackageAnnotator.ClassCoverageInfo info = myClassCoverageInfos.get(classFQName); - if (info == null) return null; - final int coveredLines = info.fullyCoveredLineCount + info.partiallyCoveredLineCount; - return getPercentage(coveredLines, info.totalLineCount); - } - - public String getClassMethodPercentage(String classFQName) { - final PackageAnnotator.ClassCoverageInfo info = myClassCoverageInfos.get(classFQName); - if (info == null) return null; - return getPercentage(info.coveredMethodCount, info.totalMethodCount); - } - - public String getClassCoveredPercentage(String classFQName) { - final PackageAnnotator.ClassCoverageInfo info = myClassCoverageInfos.get(classFQName); - if (info == null) return null; - return getPercentage(info.coveredClassCount, info.totalClassCount); - } - - private static String getPercentage(int covered, int total) { - return (int)((double)covered / total * 100) + "% (" + covered + "/" + total + ")"; - } - - public static PackageAnnotator.PackageCoverageInfo merge(final PackageAnnotator.PackageCoverageInfo info, - final PackageAnnotator.PackageCoverageInfo testInfo) { - if (info == null) return testInfo; - if (testInfo == null) return info; - final PackageAnnotator.PackageCoverageInfo coverageInfo = new PackageAnnotator.PackageCoverageInfo(); - coverageInfo.totalClassCount = info.totalClassCount + testInfo.totalClassCount; - coverageInfo.coveredClassCount = info.coveredClassCount + testInfo.coveredClassCount; - - coverageInfo.totalLineCount = info.totalLineCount + testInfo.totalLineCount; - coverageInfo.coveredLineCount = info.coveredLineCount + testInfo.coveredLineCount; - return coverageInfo; - } - - /** - * @param classFQName to obtain coverage information for - * @return human-readable coverage information - */ - @Nullable - public String getClassCoverageInformationString(String classFQName, CoverageDataManager coverageDataManager) { - final PackageAnnotator.ClassCoverageInfo info = myClassCoverageInfos.get(classFQName); - if (info == null) return null; - if (info.totalMethodCount == 0 || info.totalLineCount == 0) return null; - if (coverageDataManager.isSubCoverageActive()) { - return info.coveredMethodCount + info.fullyCoveredLineCount + info.partiallyCoveredLineCount > 0 ? "covered" : null; + + public String getPackageMethodPercentage(PsiPackage psiPackage, boolean flatten) { + PackageAnnotator.PackageCoverageInfo packageCoverageInfo = getPackageCoverageInfo(psiPackage, flatten); + if (packageCoverageInfo == null) { + return null; + } + return getPercentage(packageCoverageInfo.coveredMethodCount, packageCoverageInfo.totalMethodCount); + } + + public String getPackageLinePercentage( PsiPackage psiPackage, boolean flatten) { + PackageAnnotator.PackageCoverageInfo packageCoverageInfo = getPackageCoverageInfo(psiPackage, flatten); + if (packageCoverageInfo == null) { + return null; + } + return getPercentage(packageCoverageInfo.coveredLineCount, packageCoverageInfo.totalLineCount); + } + + public String getClassLinePercentage(String classFQName) { + PackageAnnotator.ClassCoverageInfo info = myClassCoverageInfos.get(classFQName); + if (info == null) { + return null; + } + int coveredLines = info.fullyCoveredLineCount + info.partiallyCoveredLineCount; + return getPercentage(coveredLines, info.totalLineCount); + } + + public String getClassMethodPercentage(String classFQName) { + PackageAnnotator.ClassCoverageInfo info = myClassCoverageInfos.get(classFQName); + if (info == null) { + return null; + } + return getPercentage(info.coveredMethodCount, info.totalMethodCount); + } + + public String getClassCoveredPercentage(String classFQName) { + PackageAnnotator.ClassCoverageInfo info = myClassCoverageInfos.get(classFQName); + if (info == null) { + return null; + } + return getPercentage(info.coveredClassCount, info.totalClassCount); + } + + private static String getPercentage(int covered, int total) { + return (int) ((double) covered / total * 100) + "% (" + covered + "/" + total + ")"; + } + + public static PackageAnnotator.PackageCoverageInfo merge( + PackageAnnotator.PackageCoverageInfo info, + PackageAnnotator.PackageCoverageInfo testInfo + ) { + if (info == null) { + return testInfo; + } + if (testInfo == null) { + return info; + } + PackageAnnotator.PackageCoverageInfo coverageInfo = new PackageAnnotator.PackageCoverageInfo(); + coverageInfo.totalClassCount = info.totalClassCount + testInfo.totalClassCount; + coverageInfo.coveredClassCount = info.coveredClassCount + testInfo.coveredClassCount; + + coverageInfo.totalLineCount = info.totalLineCount + testInfo.totalLineCount; + coverageInfo.coveredLineCount = info.coveredLineCount + testInfo.coveredLineCount; + return coverageInfo; + } + + /** + * @param classFQName to obtain coverage information for + * @return human-readable coverage information + */ + @Nullable + public String getClassCoverageInformationString(String classFQName, CoverageDataManager coverageDataManager) { + PackageAnnotator.ClassCoverageInfo info = myClassCoverageInfos.get(classFQName); + if (info == null) { + return null; + } + if (info.totalMethodCount == 0 || info.totalLineCount == 0) { + return null; + } + if (coverageDataManager.isSubCoverageActive()) { + return info.coveredMethodCount + info.fullyCoveredLineCount + info.partiallyCoveredLineCount > 0 ? "covered" : null; + } + return (int) ((double) info.coveredMethodCount / info.totalMethodCount * 100) + "% methods, " + + (int) ((double) (info.fullyCoveredLineCount + info.partiallyCoveredLineCount) / info.totalLineCount * 100) + "% lines covered"; + } + + @Nullable + public PackageAnnotator.ClassCoverageInfo getClassCoverageInfo(String classFQName) { + return myClassCoverageInfos.get(classFQName); } - return (int)((double)info.coveredMethodCount / info.totalMethodCount * 100) + "% methods, " + - (int)((double)(info.fullyCoveredLineCount + info.partiallyCoveredLineCount) / info.totalLineCount * 100) + "% lines covered"; - } - - @Nullable - public PackageAnnotator.ClassCoverageInfo getClassCoverageInfo(String classFQName) { - return myClassCoverageInfos.get(classFQName); - } } diff --git a/java-coverage-impl/src/main/java/com/intellij/java/coverage/JavaCoverageEnabledConfiguration.java b/java-coverage-impl/src/main/java/com/intellij/java/coverage/JavaCoverageEnabledConfiguration.java index 2e164d00cb..e88f293c7f 100644 --- a/java-coverage-impl/src/main/java/com/intellij/java/coverage/JavaCoverageEnabledConfiguration.java +++ b/java-coverage-impl/src/main/java/com/intellij/java/coverage/JavaCoverageEnabledConfiguration.java @@ -13,211 +13,214 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.intellij.java.coverage; -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -import jakarta.annotation.Nullable; - -import consulo.execution.coverage.CoverageEnabledConfiguration; +import com.intellij.java.debugger.ui.classFilter.ClassFilter; import consulo.execution.configuration.RunConfigurationBase; +import consulo.execution.coverage.CoverageEnabledConfiguration; import consulo.execution.coverage.CoverageRunner; -import jakarta.annotation.Nonnull; -import org.jdom.Element; -import org.jetbrains.annotations.NonNls; +import consulo.java.execution.configurations.OwnJavaParameters; import consulo.logging.Logger; +import consulo.util.collection.ArrayUtil; import consulo.util.xml.serializer.InvalidDataException; import consulo.util.xml.serializer.WriteExternalException; -import com.intellij.java.debugger.ui.classFilter.ClassFilter; -import consulo.util.collection.ArrayUtil; -import consulo.java.execution.configurations.OwnJavaParameters; +import jakarta.annotation.Nonnull; +import jakarta.annotation.Nullable; +import org.jdom.Element; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; /** * Base class for java run configurations with enabled code coverage + * * @author ven */ public class JavaCoverageEnabledConfiguration extends CoverageEnabledConfiguration { - private static final Logger LOG = Logger.getInstance(JavaCoverageEnabledConfiguration.class); - - private ClassFilter[] myCoveragePatterns; + private static final Logger LOG = Logger.getInstance(JavaCoverageEnabledConfiguration.class); - private boolean myIsMergeWithPreviousResults = false; - private String mySuiteToMergeWith; + private ClassFilter[] myCoveragePatterns; - @NonNls private static final String COVERAGE_PATTERN_ELEMENT_NAME = "pattern"; - @NonNls private static final String COVERAGE_MERGE_ATTRIBUTE_NAME = "merge"; - @NonNls private static final String COVERAGE_MERGE_SUITE_ATT_NAME = "merge_suite"; + private boolean myIsMergeWithPreviousResults = false; + private String mySuiteToMergeWith; - private JavaCoverageEngine myCoverageProvider; + private static final String COVERAGE_PATTERN_ELEMENT_NAME = "pattern"; + private static final String COVERAGE_MERGE_ATTRIBUTE_NAME = "merge"; + private static final String COVERAGE_MERGE_SUITE_ATT_NAME = "merge_suite"; - public JavaCoverageEnabledConfiguration(final RunConfigurationBase configuration, - final JavaCoverageEngine coverageProvider) { - super(configuration); - myCoverageProvider = coverageProvider; - setCoverageRunner(CoverageRunner.getInstance(IDEACoverageRunner.class)); - } + private JavaCoverageEngine myCoverageProvider; - @Nullable - public static JavaCoverageEnabledConfiguration getFrom(final RunConfigurationBase configuration) { - final CoverageEnabledConfiguration coverageEnabledConfiguration = getOrCreate(configuration); - if (coverageEnabledConfiguration instanceof JavaCoverageEnabledConfiguration) { - return (JavaCoverageEnabledConfiguration)coverageEnabledConfiguration; - } - return null; - } - - public void appendCoverageArgument(final OwnJavaParameters javaParameters) { - final CoverageRunner runner = getCoverageRunner(); - try { - if (runner != null && runner instanceof JavaCoverageRunner) { - final String path = getCoverageFilePath(); - assert path != null; // cannot be null here if runner != null - - ((JavaCoverageRunner)runner).appendCoverageArgument(new File(path).getCanonicalPath(), - getPatterns(), - javaParameters, - isTrackPerTestCoverage() && !isSampling(), - isSampling()); - } + public JavaCoverageEnabledConfiguration(RunConfigurationBase configuration, JavaCoverageEngine coverageProvider) { + super(configuration); + myCoverageProvider = coverageProvider; + setCoverageRunner(CoverageRunner.getInstance(IDEACoverageRunner.class)); } - catch (IOException e) { - LOG.info(e); - } - } - - - @Nonnull - public JavaCoverageEngine getCoverageProvider() { - return myCoverageProvider; - } - - public ClassFilter[] getCoveragePatterns() { - return myCoveragePatterns; - } - - @Nullable - public String [] getPatterns() { - if (myCoveragePatterns != null) { - List patterns = new ArrayList(); - for (ClassFilter coveragePattern : myCoveragePatterns) { - if (coveragePattern.isEnabled()) patterns.add(coveragePattern.getPattern()); - } - return ArrayUtil.toStringArray(patterns); - } - return null; - } - - public void setCoveragePatterns(final ClassFilter[] coveragePatterns) { - myCoveragePatterns = coveragePatterns; - } - - public void readExternal(Element element) throws InvalidDataException { - super.readExternal(element); - - // merge with prev results - final String mergeAttribute = element.getAttributeValue(COVERAGE_MERGE_ATTRIBUTE_NAME); - myIsMergeWithPreviousResults = mergeAttribute != null && Boolean.valueOf(mergeAttribute).booleanValue(); - - mySuiteToMergeWith = element.getAttributeValue(COVERAGE_MERGE_SUITE_ATT_NAME); - - // coverage patters - final List children = element.getChildren(COVERAGE_PATTERN_ELEMENT_NAME); - if (children.size() > 0) { - myCoveragePatterns = new ClassFilter[children.size()]; - for (int i = 0; i < children.size(); i++) { - myCoveragePatterns[i] = new ClassFilter(); - @NonNls final Element e = (Element)children.get(i); - myCoveragePatterns[i].readExternal(e); - final String val = e.getAttributeValue("value"); - if (val != null) { - myCoveragePatterns[i].setPattern(val); + + @Nullable + public static JavaCoverageEnabledConfiguration getFrom(RunConfigurationBase configuration) { + if (getOrCreate(configuration) instanceof JavaCoverageEnabledConfiguration javaCoverageEnabledConfiguration) { + return javaCoverageEnabledConfiguration; } - } + return null; } - } - - public void writeExternal(Element element) throws WriteExternalException { - // just for backward compatibility with settings format before "Huge Coverage Refactoring" - // see [IDEA-56800] ProjectRunConfigurationManager component: "coverage" extension: "merge" attribute is misplaced - // here we can't use super.writeExternal(...) due to differences in format between IDEA 10 and IDEA 9.x - // enabled - element.setAttribute(COVERAGE_ENABLED_ATTRIBUTE_NAME, String.valueOf(isCoverageEnabled())); + public void appendCoverageArgument(OwnJavaParameters javaParameters) { + CoverageRunner runner = getCoverageRunner(); + try { + if (runner instanceof JavaCoverageRunner javaCoverageRunner) { + String path = getCoverageFilePath(); + assert path != null; // cannot be null here if runner != null + + javaCoverageRunner.appendCoverageArgument( + new File(path).getCanonicalPath(), + getPatterns(), + javaParameters, + isTrackPerTestCoverage() && !isSampling(), + isSampling() + ); + } + } + catch (IOException e) { + LOG.info(e); + } + } - // merge with prev - element.setAttribute(COVERAGE_MERGE_ATTRIBUTE_NAME, String.valueOf(myIsMergeWithPreviousResults)); - if (myIsMergeWithPreviousResults && mySuiteToMergeWith != null) { - element.setAttribute(COVERAGE_MERGE_SUITE_ATT_NAME, mySuiteToMergeWith); + @Nonnull + public JavaCoverageEngine getCoverageProvider() { + return myCoverageProvider; } - // track per test - final boolean trackPerTestCoverage = isTrackPerTestCoverage(); - if (!trackPerTestCoverage) { - element.setAttribute(TRACK_PER_TEST_COVERAGE_ATTRIBUTE_NAME, String.valueOf(trackPerTestCoverage)); + public ClassFilter[] getCoveragePatterns() { + return myCoveragePatterns; } - // sampling - final boolean sampling = isSampling(); - if (sampling) { - element.setAttribute(SAMPLING_COVERAGE_ATTRIBUTE_NAME, String.valueOf(sampling)); + @Nullable + public String[] getPatterns() { + if (myCoveragePatterns != null) { + List patterns = new ArrayList<>(); + for (ClassFilter coveragePattern : myCoveragePatterns) { + if (coveragePattern.isEnabled()) { + patterns.add(coveragePattern.getPattern()); + } + } + return ArrayUtil.toStringArray(patterns); + } + return null; } - // test folders - final boolean trackTestFolders = isTrackTestFolders(); - if (trackTestFolders) { - element.setAttribute(TRACK_TEST_FOLDERS, String.valueOf(trackTestFolders)); + public void setCoveragePatterns(ClassFilter[] coveragePatterns) { + myCoveragePatterns = coveragePatterns; } - // runner - final CoverageRunner coverageRunner = getCoverageRunner(); - final String runnerId = getRunnerId(); - if (coverageRunner != null) { - element.setAttribute(COVERAGE_RUNNER, coverageRunner.getId()); - } else if (runnerId != null) { - element.setAttribute(COVERAGE_RUNNER, runnerId); + @Override + public void readExternal(Element element) throws InvalidDataException { + super.readExternal(element); + + // merge with prev results + String mergeAttribute = element.getAttributeValue(COVERAGE_MERGE_ATTRIBUTE_NAME); + myIsMergeWithPreviousResults = mergeAttribute != null && Boolean.valueOf(mergeAttribute); + + mySuiteToMergeWith = element.getAttributeValue(COVERAGE_MERGE_SUITE_ATT_NAME); + + // coverage patters + List children = element.getChildren(COVERAGE_PATTERN_ELEMENT_NAME); + if (children.size() > 0) { + myCoveragePatterns = new ClassFilter[children.size()]; + for (int i = 0; i < children.size(); i++) { + myCoveragePatterns[i] = new ClassFilter(); + Element e = children.get(i); + myCoveragePatterns[i].readExternal(e); + String val = e.getAttributeValue("value"); + if (val != null) { + myCoveragePatterns[i].setPattern(val); + } + } + } } - // patterns - if (myCoveragePatterns != null) { - for (ClassFilter pattern : myCoveragePatterns) { - @NonNls final Element patternElement = new Element(COVERAGE_PATTERN_ELEMENT_NAME); - pattern.writeExternal(patternElement); - element.addContent(patternElement); - } - } - } + @Override + public void writeExternal(Element element) throws WriteExternalException { + // just for backward compatibility with settings format before "Huge Coverage Refactoring" + // see [IDEA-56800] ProjectRunConfigurationManager component: "coverage" extension: "merge" attribute is misplaced + // here we can't use super.writeExternal(...) due to differences in format between IDEA 10 and IDEA 9.x - @Nullable - public String getCoverageFilePath() { - if (myCoverageFilePath != null ) { - return myCoverageFilePath; - } - myCoverageFilePath = createCoverageFile(); - return myCoverageFilePath; - } - - public void setUpCoverageFilters(String className, String packageName) { - if (getCoveragePatterns() == null) { - String pattern = null; - if (className != null && className.length() > 0) { - int index = className.lastIndexOf('.'); - if (index >= 0) { - pattern = className.substring(0, index); + // enabled + element.setAttribute(COVERAGE_ENABLED_ATTRIBUTE_NAME, String.valueOf(isCoverageEnabled())); + + // merge with prev + element.setAttribute(COVERAGE_MERGE_ATTRIBUTE_NAME, String.valueOf(myIsMergeWithPreviousResults)); + + if (myIsMergeWithPreviousResults && mySuiteToMergeWith != null) { + element.setAttribute(COVERAGE_MERGE_SUITE_ATT_NAME, mySuiteToMergeWith); + } + + // track per test + boolean trackPerTestCoverage = isTrackPerTestCoverage(); + if (!trackPerTestCoverage) { + element.setAttribute(TRACK_PER_TEST_COVERAGE_ATTRIBUTE_NAME, String.valueOf(trackPerTestCoverage)); + } + + // sampling + boolean sampling = isSampling(); + if (sampling) { + element.setAttribute(SAMPLING_COVERAGE_ATTRIBUTE_NAME, String.valueOf(sampling)); + } + + // test folders + boolean trackTestFolders = isTrackTestFolders(); + if (trackTestFolders) { + element.setAttribute(TRACK_TEST_FOLDERS, String.valueOf(trackTestFolders)); + } + + // runner + CoverageRunner coverageRunner = getCoverageRunner(); + String runnerId = getRunnerId(); + if (coverageRunner != null) { + element.setAttribute(COVERAGE_RUNNER, coverageRunner.getId()); + } + else if (runnerId != null) { + element.setAttribute(COVERAGE_RUNNER, runnerId); } - } - else if (packageName != null) { - pattern = packageName; - } + // patterns + if (myCoveragePatterns != null) { + for (ClassFilter pattern : myCoveragePatterns) { + Element patternElement = new Element(COVERAGE_PATTERN_ELEMENT_NAME); + pattern.writeExternal(patternElement); + element.addContent(patternElement); + } + } + } - if (pattern != null && pattern.length() > 0) { - setCoveragePatterns(new ClassFilter[]{new ClassFilter(pattern + ".*")}); - } + @Nullable + @Override + public String getCoverageFilePath() { + if (myCoverageFilePath != null) { + return myCoverageFilePath; + } + myCoverageFilePath = createCoverageFile(); + return myCoverageFilePath; + } + + public void setUpCoverageFilters(String className, String packageName) { + if (getCoveragePatterns() == null) { + String pattern = null; + if (className != null && className.length() > 0) { + int index = className.lastIndexOf('.'); + if (index >= 0) { + pattern = className.substring(0, index); + } + } + else if (packageName != null) { + pattern = packageName; + } + + if (pattern != null && pattern.length() > 0) { + setCoveragePatterns(new ClassFilter[]{new ClassFilter(pattern + ".*")}); + } + } } - } } diff --git a/java-coverage-impl/src/main/java/com/intellij/java/coverage/JavaCoverageEngine.java b/java-coverage-impl/src/main/java/com/intellij/java/coverage/JavaCoverageEngine.java index 2f9b82f60f..87c1baa923 100644 --- a/java-coverage-impl/src/main/java/com/intellij/java/coverage/JavaCoverageEngine.java +++ b/java-coverage-impl/src/main/java/com/intellij/java/coverage/JavaCoverageEngine.java @@ -144,9 +144,6 @@ public CoverageAnnotator getCoverageAnnotator(Project project) { /** * Determines if coverage information should be displayed for given file - * - * @param psiFile - * @return */ @Override public boolean coverageEditorHighlightingApplicableTo(@Nonnull PsiFile psiFile) { @@ -154,7 +151,7 @@ public boolean coverageEditorHighlightingApplicableTo(@Nonnull PsiFile psiFile) return false; } // let's show coverage only for module files - Module module = psiFile.getApplication().runReadAction((Supplier)psiFile::getModule); + Module module = psiFile.getApplication().runReadAction((Supplier) psiFile::getModule); return module != null; } @@ -171,10 +168,10 @@ public boolean acceptedByFilters(@Nonnull PsiFile psiFile, @Nonnull CoverageSuit } for (CoverageSuite coverageSuite : suite.getSuites()) { - JavaCoverageSuite javaSuite = (JavaCoverageSuite)coverageSuite; + JavaCoverageSuite javaSuite = (JavaCoverageSuite) coverageSuite; List packages = javaSuite.getCurrentSuitePackages(project); - if (isUnderFilteredPackages((PsiClassOwner)psiFile, packages)) { + if (isUnderFilteredPackages((PsiClassOwner) psiFile, packages)) { return true; } else { @@ -223,7 +220,7 @@ && isModuleOutputNeeded(module, TestContentFolderTypeProvider.getInstance()))) { if (aborted || errors != 0) { return; } - Application.get().invokeLater(() -> { + project.getApplication().invokeLater(() -> { if (project.isDisposed()) { return; } @@ -247,7 +244,7 @@ private static boolean isModuleOutputNeeded(Module module, ContentFolderTypeProv } public static boolean isUnderFilteredPackages(PsiClassOwner javaFile, List packages) { - String hisPackageName = javaFile.getApplication().runReadAction((Supplier)javaFile::getPackageName); + String hisPackageName = javaFile.getApplication().runReadAction((Supplier) javaFile::getPackageName); PsiPackage hisPackage = JavaPsiFacade.getInstance(javaFile.getProject()).findPackage(hisPackageName); if (hisPackage == null) { return false; @@ -290,7 +287,7 @@ public boolean includeUntouchedFileInCoverage( @Nonnull CoverageSuitesBundle suite ) { for (CoverageSuite coverageSuite : suite.getSuites()) { - JavaCoverageSuite javaSuite = (JavaCoverageSuite)coverageSuite; + JavaCoverageSuite javaSuite = (JavaCoverageSuite) coverageSuite; if (javaSuite.isClassFiltered(qualifiedName) || javaSuite.isPackageFiltered(getPackageName(sourceFile))) { return true; } @@ -309,15 +306,15 @@ public String getQualifiedName(@Nonnull File outputFile, @Nonnull PsiFile source @Override public Set getQualifiedNames(@Nonnull PsiFile sourceFile) { Application application = sourceFile.getApplication(); - PsiClass[] classes = application.runReadAction((Supplier)((PsiClassOwner)sourceFile)::getClasses); + PsiClass[] classes = application.runReadAction((Supplier) ((PsiClassOwner) sourceFile)::getClasses); Set qNames = new HashSet<>(); for (JavaCoverageEngineExtension nameExtension : JavaCoverageEngineExtension.EP_NAME.getExtensions()) { - if (application.runReadAction((Supplier)() -> nameExtension.suggestQualifiedName(sourceFile, classes, qNames))) { + if (application.runReadAction((Supplier) () -> nameExtension.suggestQualifiedName(sourceFile, classes, qNames))) { return qNames; } } for (PsiClass aClass : classes) { - String qName = application.runReadAction((Supplier)aClass::getQualifiedName); + String qName = application.runReadAction((Supplier) aClass::getQualifiedName); if (qName == null) { continue; } @@ -372,9 +369,9 @@ public Set getCorrespondingOutputFiles( } Application application = srcFile.getApplication(); - PsiClass[] classes = application.runReadAction((Supplier)((PsiClassOwner)srcFile)::getClasses); + PsiClass[] classes = application.runReadAction((Supplier) ((PsiClassOwner) srcFile)::getClasses); for (PsiClass psiClass : classes) { - String className = application.runReadAction((Supplier)psiClass::getName); + String className = application.runReadAction((Supplier) psiClass::getName); for (File child : children) { if (FileUtil.extensionEquals(child.getName(), JavaClassFileType.INSTANCE.getDefaultExtension())) { String childName = FileUtil.getNameWithoutExtension(child); @@ -458,7 +455,7 @@ else if (parent instanceof PsiAssertStatement assertStatement) { int hits = 0; if (lineData.getJumps() != null) { for (Object o : lineData.getJumps()) { - JumpData jumpData = (JumpData)o; + JumpData jumpData = (JumpData) o; if (jumpData.getTrueHits() + jumpData.getFalseHits() > 0) { PsiExpression expression = expressions.get(idx++); PsiElement parentExpression = expression.getParent(); @@ -484,7 +481,7 @@ else if (parent instanceof PsiAssertStatement assertStatement) { if (lineData.getSwitches() != null) { for (Object o : lineData.getSwitches()) { - SwitchData switchData = (SwitchData)o; + SwitchData switchData = (SwitchData) o; PsiExpression conditionExpression = expressions.get(idx++); buf.append(indent).append(conditionExpression.getText()).append("\n"); int i = 0; @@ -567,7 +564,7 @@ private static void collectTestsByName(List elements, String testNam private static boolean hasDefaultLabel(PsiElement conditionExpression) { boolean hasDefault = false; PsiSwitchStatement switchStatement = PsiTreeUtil.getParentOfType(conditionExpression, PsiSwitchStatement.class); - PsiCodeBlock body = ((PsiSwitchStatementImpl)conditionExpression.getParent()).getBody(); + PsiCodeBlock body = ((PsiSwitchStatementImpl) conditionExpression.getParent()).getBody(); if (body != null) { PsiElement bodyElement = body.getFirstBodyElement(); if (bodyElement != null) { @@ -610,7 +607,7 @@ protected JavaCoverageSuite createSuite( @Nonnull protected static String getPackageName(PsiFile sourceFile) { - return sourceFile.getApplication().runReadAction((Supplier)((PsiClassOwner)sourceFile)::getPackageName); + return sourceFile.getApplication().runReadAction((Supplier) ((PsiClassOwner) sourceFile)::getPackageName); } @Override @@ -624,6 +621,6 @@ public CoverageViewExtension createCoverageViewExtension( CoverageSuitesBundle suiteBundle, CoverageViewManager.StateBean stateBean ) { - return new JavaCoverageViewExtension((JavaCoverageAnnotator)getCoverageAnnotator(project), project, suiteBundle, stateBean); + return new JavaCoverageViewExtension((JavaCoverageAnnotator) getCoverageAnnotator(project), project, suiteBundle, stateBean); } } diff --git a/java-coverage-impl/src/main/java/com/intellij/java/coverage/JavaCoverageRunner.java b/java-coverage-impl/src/main/java/com/intellij/java/coverage/JavaCoverageRunner.java index 7efd9092cc..469d3aa346 100644 --- a/java-coverage-impl/src/main/java/com/intellij/java/coverage/JavaCoverageRunner.java +++ b/java-coverage-impl/src/main/java/com/intellij/java/coverage/JavaCoverageRunner.java @@ -20,84 +20,89 @@ * @author Roman.Chernyatchik */ public abstract class JavaCoverageRunner extends CoverageRunner { - private static final Logger LOG = Logger.getInstance(JavaCoverageRunner.class); - private static final String COVERAGE_AGENT_PATH = "coverage.lib.path"; + private static final Logger LOG = Logger.getInstance(JavaCoverageRunner.class); + private static final String COVERAGE_AGENT_PATH = "coverage.lib.path"; - public boolean isJdk7Compatible() { - return true; - } + public boolean isJdk7Compatible() { + return true; + } - @Override - public boolean acceptsCoverageEngine(@Nonnull CoverageEngine engine) { - return engine instanceof JavaCoverageEngine; - } + @Override + public boolean acceptsCoverageEngine(@Nonnull CoverageEngine engine) { + return engine instanceof JavaCoverageEngine; + } - public abstract void appendCoverageArgument( - final String sessionDataFilePath, - @Nullable final String[] patterns, - final OwnJavaParameters parameters, - final boolean collectLineInfo, - final boolean isSampling - ); + public abstract void appendCoverageArgument( + String sessionDataFilePath, + @Nullable String[] patterns, + OwnJavaParameters parameters, + boolean collectLineInfo, + boolean isSampling + ); - @Nonnull - protected static String handleSpacesInPath(@Nonnull File parent) { - String agentPath; - final String userDefined = Platform.current().jvm().getRuntimeProperty(COVERAGE_AGENT_PATH); - if (userDefined != null && new File(userDefined).exists()) { - agentPath = userDefined; - } else { - agentPath = parent.getParent(); - } - if (!Platform.current().os().isWindows() && agentPath.contains(" ")) { - File dir = new File(ContainerPathManager.get().getSystemPath(), "coverageJars"); - if (dir.getAbsolutePath().contains(" ")) { - try { - TempFileService tempFileService = Application.get().getInstance(TempFileService.class); - dir = tempFileService.createTempDirectory("coverage", "jars").toFile(); - if (dir.getAbsolutePath().contains(" ")) { - LOG.info("Coverage agent not used since the agent path contains spaces: " + agentPath + "\n" + - "One can move the agent libraries to a directory with no spaces in path and specify its path in idea.properties as " - + COVERAGE_AGENT_PATH + "="); - return agentPath; - } - } catch (IOException e) { - LOG.info(e); - return agentPath; + @Nonnull + protected static String handleSpacesInPath(@Nonnull File parent) { + String agentPath; + String userDefined = Platform.current().jvm().getRuntimeProperty(COVERAGE_AGENT_PATH); + if (userDefined != null && new File(userDefined).exists()) { + agentPath = userDefined; } - } + else { + agentPath = parent.getParent(); + } + if (!Platform.current().os().isWindows() && agentPath.contains(" ")) { + File dir = new File(ContainerPathManager.get().getSystemPath(), "coverageJars"); + if (dir.getAbsolutePath().contains(" ")) { + try { + TempFileService tempFileService = Application.get().getInstance(TempFileService.class); + dir = tempFileService.createTempDirectory("coverage", "jars").toFile(); + if (dir.getAbsolutePath().contains(" ")) { + LOG.info( + "Coverage agent not used since the agent path contains spaces: " + agentPath + "\n" + + "One can move the agent libraries to a directory with no spaces in path " + + "and specify its path in idea.properties as " + COVERAGE_AGENT_PATH + "=" + ); + return agentPath; + } + } + catch (IOException e) { + LOG.info(e); + return agentPath; + } + } - try { - LOG.info("Coverage jars were copied to " + dir.getPath()); - FileUtil.copyDir(new File(agentPath), dir, FilePermissionCopier.BY_NIO2); - return dir.getPath(); - } catch (IOException e) { - LOG.info(e); - } + try { + LOG.info("Coverage jars were copied to " + dir.getPath()); + FileUtil.copyDir(new File(agentPath), dir, FilePermissionCopier.BY_NIO2); + return dir.getPath(); + } + catch (IOException e) { + LOG.info(e); + } + } + return agentPath; } - return agentPath; - } - protected static void write2file(File tempFile, String arg) throws IOException { - FileUtil.writeToFile(tempFile, (arg + "\n").getBytes("UTF-8"), true); - } + protected static void write2file(File tempFile, String arg) throws IOException { + FileUtil.writeToFile(tempFile, (arg + "\n").getBytes("UTF-8"), true); + } - protected static File createTempFile() throws IOException { - File tempFile = FileUtil.createTempFile("coverage", "args"); - if (!Platform.current().os().isWindows() && tempFile.getAbsolutePath().contains(" ")) { - tempFile = FileUtil.createTempFile( - new File(ContainerPathManager.get().getSystemPath(), "coverage"), - "coverage", - "args", - true - ); - if (tempFile.getAbsolutePath().contains(" ")) { - final String userDefined = Platform.current().jvm().getRuntimeProperty(COVERAGE_AGENT_PATH); - if (userDefined != null && new File(userDefined).isDirectory()) { - tempFile = FileUtil.createTempFile(new File(userDefined), "coverage", "args", true); + protected static File createTempFile() throws IOException { + File tempFile = FileUtil.createTempFile("coverage", "args"); + if (!Platform.current().os().isWindows() && tempFile.getAbsolutePath().contains(" ")) { + tempFile = FileUtil.createTempFile( + new File(ContainerPathManager.get().getSystemPath(), "coverage"), + "coverage", + "args", + true + ); + if (tempFile.getAbsolutePath().contains(" ")) { + String userDefined = Platform.current().jvm().getRuntimeProperty(COVERAGE_AGENT_PATH); + if (userDefined != null && new File(userDefined).isDirectory()) { + tempFile = FileUtil.createTempFile(new File(userDefined), "coverage", "args", true); + } + } } - } + return tempFile; } - return tempFile; - } } diff --git a/java-coverage-impl/src/main/java/com/intellij/java/coverage/JavaCoverageSuite.java b/java-coverage-impl/src/main/java/com/intellij/java/coverage/JavaCoverageSuite.java index c9e4f9993e..3c81e8c088 100644 --- a/java-coverage-impl/src/main/java/com/intellij/java/coverage/JavaCoverageSuite.java +++ b/java-coverage-impl/src/main/java/com/intellij/java/coverage/JavaCoverageSuite.java @@ -1,249 +1,259 @@ package com.intellij.java.coverage; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import jakarta.annotation.Nonnull; - -import consulo.execution.coverage.*; -import consulo.logging.Logger; -import org.jdom.Element; -import org.jetbrains.annotations.NonNls; - -import jakarta.annotation.Nullable; -import consulo.application.ApplicationManager; -import consulo.project.Project; -import consulo.util.lang.Comparing; -import consulo.application.util.function.Computable; -import consulo.util.xml.serializer.InvalidDataException; -import consulo.util.xml.serializer.WriteExternalException; import com.intellij.java.language.psi.JavaPsiFacade; import com.intellij.java.language.psi.PsiClass; import com.intellij.java.language.psi.PsiJavaPackage; +import com.intellij.rt.coverage.data.ProjectData; +import consulo.execution.coverage.*; import consulo.language.psi.PsiManager; import consulo.language.psi.scope.GlobalSearchScope; -import com.intellij.rt.coverage.data.ProjectData; +import consulo.logging.Logger; +import consulo.project.Project; import consulo.util.collection.ArrayUtil; +import consulo.util.lang.Comparing; +import consulo.util.xml.serializer.InvalidDataException; +import consulo.util.xml.serializer.WriteExternalException; +import jakarta.annotation.Nonnull; +import jakarta.annotation.Nullable; +import org.jdom.Element; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.function.Supplier; /** * @author ven */ public class JavaCoverageSuite extends BaseCoverageSuite { - private static final Logger LOG = Logger.getInstance(JavaCoverageSuite.class); - - private String[] myFilters; - private String mySuiteToMerge; - - @NonNls - private static final String FILTER = "FILTER"; - @NonNls - private static final String MERGE_SUITE = "MERGE_SUITE"; - @NonNls - private static final String COVERAGE_RUNNER = "RUNNER"; - private final CoverageEngine myCoverageEngine; - - //read external only - public JavaCoverageSuite(@Nonnull final JavaCoverageEngine coverageSupportProvider) { - super(); - myCoverageEngine = coverageSupportProvider; - } - - public JavaCoverageSuite(final String name, - final CoverageFileProvider coverageDataFileProvider, - final String[] filters, - final long lastCoverageTimeStamp, - final boolean coverageByTestEnabled, - final boolean tracingEnabled, - final boolean trackTestFolders, - final CoverageRunner coverageRunner, - @Nonnull final JavaCoverageEngine coverageSupportProvider, - final Project project) { - super(name, coverageDataFileProvider, lastCoverageTimeStamp, coverageByTestEnabled, - tracingEnabled, trackTestFolders, - coverageRunner != null ? coverageRunner : CoverageRunner.getInstance(IDEACoverageRunner.class), project); - - myFilters = filters; - myCoverageEngine = coverageSupportProvider; - } - - @Nonnull - public String[] getFilteredPackageNames() { - if (myFilters == null || myFilters.length == 0) return ArrayUtil.EMPTY_STRING_ARRAY; - List result = new ArrayList(); - for (String filter : myFilters) { - if (filter.equals("*")) { - result.add(""); //default package - } - else if (filter.endsWith(".*")) result.add(filter.substring(0, filter.length() - 2)); + private static final Logger LOG = Logger.getInstance(JavaCoverageSuite.class); + + private String[] myFilters; + private String mySuiteToMerge; + + private static final String FILTER = "FILTER"; + private static final String MERGE_SUITE = "MERGE_SUITE"; + private static final String COVERAGE_RUNNER = "RUNNER"; + private final CoverageEngine myCoverageEngine; + + //read external only + public JavaCoverageSuite(@Nonnull JavaCoverageEngine coverageSupportProvider) { + super(); + myCoverageEngine = coverageSupportProvider; } - return ArrayUtil.toStringArray(result); - } - - @Nonnull - public String[] getFilteredClassNames() { - if (myFilters == null) return ArrayUtil.EMPTY_STRING_ARRAY; - List result = new ArrayList(); - for (String filter : myFilters) { - if (!filter.equals("*") && !filter.endsWith(".*")) result.add(filter); + + public JavaCoverageSuite( + String name, + CoverageFileProvider coverageDataFileProvider, + String[] filters, + long lastCoverageTimeStamp, + boolean coverageByTestEnabled, + boolean tracingEnabled, + boolean trackTestFolders, + CoverageRunner coverageRunner, + @Nonnull JavaCoverageEngine coverageSupportProvider, + Project project + ) { + super(name, coverageDataFileProvider, lastCoverageTimeStamp, coverageByTestEnabled, + tracingEnabled, trackTestFolders, + coverageRunner != null ? coverageRunner : CoverageRunner.getInstance(IDEACoverageRunner.class), project + ); + + myFilters = filters; + myCoverageEngine = coverageSupportProvider; + } + + @Nonnull + public String[] getFilteredPackageNames() { + if (myFilters == null || myFilters.length == 0) { + return ArrayUtil.EMPTY_STRING_ARRAY; + } + List result = new ArrayList<>(); + for (String filter : myFilters) { + if (filter.equals("*")) { + result.add(""); //default package + } + else if (filter.endsWith(".*")) { + result.add(filter.substring(0, filter.length() - 2)); + } + } + return ArrayUtil.toStringArray(result); } - return ArrayUtil.toStringArray(result); - } - - public void readExternal(Element element) throws InvalidDataException { - super.readExternal(element); - - // filters - final List children = element.getChildren(FILTER); - List filters = new ArrayList(); - //noinspection unchecked - for (Element child : ((Iterable)children)) { - filters.add(child.getValue()); + + @Nonnull + public String[] getFilteredClassNames() { + if (myFilters == null) { + return ArrayUtil.EMPTY_STRING_ARRAY; + } + List result = new ArrayList<>(); + for (String filter : myFilters) { + if (!filter.equals("*") && !filter.endsWith(".*")) { + result.add(filter); + } + } + return ArrayUtil.toStringArray(result); } - myFilters = filters.isEmpty() ? null : ArrayUtil.toStringArray(filters); - // suite to merge - mySuiteToMerge = element.getAttributeValue(MERGE_SUITE); + @Override + public void readExternal(Element element) throws InvalidDataException { + super.readExternal(element); + + // filters + List children = element.getChildren(FILTER); + List filters = new ArrayList<>(); + //noinspection unchecked + for (Element child : ((Iterable) children)) { + filters.add(child.getValue()); + } + myFilters = filters.isEmpty() ? null : ArrayUtil.toStringArray(filters); - if (getRunner() == null) { - setRunner(CoverageRunner.getInstance(IDEACoverageRunner.class)); //default + // suite to merge + mySuiteToMerge = element.getAttributeValue(MERGE_SUITE); + + if (getRunner() == null) { + setRunner(CoverageRunner.getInstance(IDEACoverageRunner.class)); //default + } } - } - public void writeExternal(final Element element) throws WriteExternalException { - super.writeExternal(element); - if (mySuiteToMerge != null) { - element.setAttribute(MERGE_SUITE, mySuiteToMerge); + @Override + public void writeExternal(Element element) throws WriteExternalException { + super.writeExternal(element); + if (mySuiteToMerge != null) { + element.setAttribute(MERGE_SUITE, mySuiteToMerge); + } + if (myFilters != null) { + for (String filter : myFilters) { + Element filterElement = new Element(FILTER); + filterElement.setText(filter); + element.addContent(filterElement); + } + } + CoverageRunner coverageRunner = getRunner(); + element.setAttribute(COVERAGE_RUNNER, coverageRunner != null ? coverageRunner.getId() : "emma"); } - if (myFilters != null) { - for (String filter : myFilters) { - final Element filterElement = new Element(FILTER); - filterElement.setText(filter); - element.addContent(filterElement); - } + + @Nullable + @Override + public ProjectData getCoverageData(CoverageDataManager coverageDataManager) { + ProjectData data = getCoverageData(); + if (data != null) { + return data; + } + ProjectData map = loadProjectInfo(); + if (mySuiteToMerge != null) { + JavaCoverageSuite toMerge = null; + CoverageSuite[] suites = coverageDataManager.getSuites(); + for (CoverageSuite suite : suites) { + if (Comparing.strEqual(suite.getPresentableName(), mySuiteToMerge)) { + if (!Comparing.strEqual(((JavaCoverageSuite) suite).getSuiteToMerge(), getPresentableName())) { + toMerge = (JavaCoverageSuite) suite; + } + break; + } + } + if (toMerge != null) { + ProjectData projectInfo = toMerge.getCoverageData(coverageDataManager); + if (map != null) { + map.merge(projectInfo); + } + else { + map = projectInfo; + } + } + } + setCoverageData(map); + return map; } - final CoverageRunner coverageRunner = getRunner(); - element.setAttribute(COVERAGE_RUNNER, coverageRunner != null ? coverageRunner.getId() : "emma"); - } - - @Nullable - public ProjectData getCoverageData(final CoverageDataManager coverageDataManager) { - final ProjectData data = getCoverageData(); - if (data != null) return data; - ProjectData map = loadProjectInfo(); - if (mySuiteToMerge != null) { - JavaCoverageSuite toMerge = null; - final CoverageSuite[] suites = coverageDataManager.getSuites(); - for (CoverageSuite suite : suites) { - if (Comparing.strEqual(suite.getPresentableName(), mySuiteToMerge)) { - if (!Comparing.strEqual(((JavaCoverageSuite)suite).getSuiteToMerge(), getPresentableName())) { - toMerge = (JavaCoverageSuite)suite; - } - break; - } - } - if (toMerge != null) { - final ProjectData projectInfo = toMerge.getCoverageData(coverageDataManager); - if (map != null) { - map.merge(projectInfo); - } else { - map = projectInfo; - } - } + + @Nonnull + @Override + public CoverageEngine getCoverageEngine() { + return myCoverageEngine; } - setCoverageData(map); - return map; - } - - @Nonnull - public CoverageEngine getCoverageEngine() { - return myCoverageEngine; - } - - @Nullable - public String getSuiteToMerge() { - return mySuiteToMerge; - } - - public boolean isClassFiltered(final String classFQName) { - for (final String className : getFilteredClassNames()) { - if (className.equals(classFQName) || classFQName.startsWith(className) && classFQName.charAt(className.length()) == '$') { - return true; - } + + @Nullable + public String getSuiteToMerge() { + return mySuiteToMerge; } - return false; - } - - public boolean isPackageFiltered(final String packageFQName) { - final String[] filteredPackageNames = getFilteredPackageNames(); - for (final String packName : filteredPackageNames) { - if (packName.equals(packageFQName) || packageFQName.startsWith(packName) && packageFQName.charAt(packName.length()) == '.') { - return true; - } + + public boolean isClassFiltered(String classFQName) { + for (String className : getFilteredClassNames()) { + if (className.equals(classFQName) || classFQName.startsWith(className) && classFQName.charAt(className.length()) == '$') { + return true; + } + } + return false; } - return filteredPackageNames.length == 0 && getFilteredClassNames().length == 0; - } - - public @Nonnull - List getCurrentSuitePackages(Project project) { - List packages = new ArrayList(); - final PsiManager psiManager = PsiManager.getInstance(project); - final String[] filters = getFilteredPackageNames(); - if (filters.length == 0) { - if (getFilteredClassNames().length > 0) return Collections.emptyList(); - - final PsiJavaPackage defaultPackage = JavaPsiFacade.getInstance(psiManager.getProject()).findPackage(""); - if (defaultPackage != null) { - packages.add(defaultPackage); - } - } else { - final List nonInherited = new ArrayList(); - for (final String filter : filters) { - if (!isSubPackage(filters, filter)) { - nonInherited.add(filter); - } - } - - for (String filter : nonInherited) { - final PsiJavaPackage psiPackage = JavaPsiFacade.getInstance(psiManager.getProject()).findPackage(filter); - if (psiPackage != null) { - packages.add(psiPackage); - } - } + + public boolean isPackageFiltered(String packageFQName) { + String[] filteredPackageNames = getFilteredPackageNames(); + for (String packName : filteredPackageNames) { + if (packName.equals(packageFQName) || packageFQName.startsWith(packName) && packageFQName.charAt(packName.length()) == '.') { + return true; + } + } + return filteredPackageNames.length == 0 && getFilteredClassNames().length == 0; } - return packages; - } + public @Nonnull + List getCurrentSuitePackages(Project project) { + List packages = new ArrayList<>(); + PsiManager psiManager = PsiManager.getInstance(project); + String[] filters = getFilteredPackageNames(); + if (filters.length == 0) { + if (getFilteredClassNames().length > 0) { + return Collections.emptyList(); + } - private static boolean isSubPackage(String[] filters, String filter) { - for (String supPackageFilter : filters) { - if (filter.startsWith(supPackageFilter + ".")) { - return true; - } + PsiJavaPackage defaultPackage = JavaPsiFacade.getInstance(psiManager.getProject()).findPackage(""); + if (defaultPackage != null) { + packages.add(defaultPackage); + } + } + else { + List nonInherited = new ArrayList<>(); + for (String filter : filters) { + if (!isSubPackage(filters, filter)) { + nonInherited.add(filter); + } + } + + for (String filter : nonInherited) { + PsiJavaPackage psiPackage = JavaPsiFacade.getInstance(psiManager.getProject()).findPackage(filter); + if (psiPackage != null) { + packages.add(psiPackage); + } + } + } + + return packages; } - return false; - } - - public @Nonnull - List getCurrentSuiteClasses(final Project project) { - final List classes = new ArrayList(); - final PsiManager psiManager = PsiManager.getInstance(project); - final String[] classNames = getFilteredClassNames(); - if (classNames.length > 0) { - for (final String className : classNames) { - final PsiClass aClass = - ApplicationManager.getApplication().runReadAction(new Computable() { - @Nullable - public PsiClass compute() { - return JavaPsiFacade.getInstance(psiManager.getProject()).findClass(className.replace("$", "."), GlobalSearchScope.allScope(project)); + + private static boolean isSubPackage(String[] filters, String filter) { + for (String supPackageFilter : filters) { + if (filter.startsWith(supPackageFilter + ".")) { + return true; } - }); - if (aClass != null) { - classes.add(aClass); } - } + return false; } - return classes; - } + @Nonnull + public List getCurrentSuiteClasses(Project project) { + List classes = new ArrayList<>(); + PsiManager psiManager = PsiManager.getInstance(project); + String[] classNames = getFilteredClassNames(); + if (classNames.length > 0) { + for (String className : classNames) { + PsiClass aClass = + project.getApplication().runReadAction((Supplier) () -> JavaPsiFacade.getInstance(psiManager.getProject()) + .findClass(className.replace("$", "."), GlobalSearchScope.allScope(project))); + if (aClass != null) { + classes.add(aClass); + } + } + } + + return classes; + } } diff --git a/java-coverage-impl/src/main/java/com/intellij/java/coverage/PackageAnnotator.java b/java-coverage-impl/src/main/java/com/intellij/java/coverage/PackageAnnotator.java index ccdf8e4db0..eeb11d6b90 100644 --- a/java-coverage-impl/src/main/java/com/intellij/java/coverage/PackageAnnotator.java +++ b/java-coverage-impl/src/main/java/com/intellij/java/coverage/PackageAnnotator.java @@ -7,8 +7,9 @@ import com.intellij.rt.coverage.data.LineCoverage; import com.intellij.rt.coverage.data.LineData; import com.intellij.rt.coverage.data.ProjectData; -import consulo.application.util.function.Computable; +import consulo.annotation.access.RequiredReadAction; import consulo.compiler.ModuleCompilerPathsManager; +import consulo.content.ContentFolderTypeProvider; import consulo.execution.coverage.CoverageDataManager; import consulo.execution.coverage.CoverageSuite; import consulo.execution.coverage.CoverageSuitesBundle; @@ -17,7 +18,6 @@ import consulo.language.content.TestContentFolderTypeProvider; import consulo.language.psi.PsiManager; import consulo.language.psi.scope.GlobalSearchScope; -import consulo.language.util.ModuleUtilCore; import consulo.module.Module; import consulo.module.ModuleManager; import consulo.module.content.ModuleFileIndex; @@ -30,441 +30,498 @@ import consulo.util.lang.StringUtil; import consulo.virtualFileSystem.VirtualFile; import consulo.virtualFileSystem.util.VirtualFileUtil; - import jakarta.annotation.Nullable; + import java.io.File; import java.io.IOException; import java.nio.file.Files; import java.util.*; +import java.util.function.Predicate; /** * @author ven */ public class PackageAnnotator { + private final PsiJavaPackage myPackage; + private final Project myProject; + private final PsiManager myManager; + private final CoverageDataManager myCoverageManager; + + public PackageAnnotator(PsiJavaPackage aPackage) { + myPackage = aPackage; + myProject = myPackage.getProject(); + myManager = PsiManager.getInstance(myProject); + myCoverageManager = CoverageDataManager.getInstance(myProject); + } - private final PsiJavaPackage myPackage; - private final Project myProject; - private final PsiManager myManager; - private final CoverageDataManager myCoverageManager; - - public PackageAnnotator(final PsiJavaPackage aPackage) { - myPackage = aPackage; - myProject = myPackage.getProject(); - myManager = PsiManager.getInstance(myProject); - myCoverageManager = CoverageDataManager.getInstance(myProject); - } - - public interface Annotator { - void annotateSourceDirectory(VirtualFile virtualFile, PackageCoverageInfo packageCoverageInfo, Module module); - - void annotateTestDirectory(VirtualFile virtualFile, PackageCoverageInfo packageCoverageInfo, Module module); - - void annotatePackage(String packageQualifiedName, PackageCoverageInfo packageCoverageInfo); - - void annotatePackage(String packageQualifiedName, PackageCoverageInfo packageCoverageInfo, boolean flatten); - - void annotateClass(String classQualifiedName, ClassCoverageInfo classCoverageInfo); - } + public interface Annotator { + void annotateSourceDirectory(VirtualFile virtualFile, PackageCoverageInfo packageCoverageInfo, Module module); - public static class ClassCoverageInfo { - public int totalLineCount; - public int fullyCoveredLineCount; - public int partiallyCoveredLineCount; - public int totalMethodCount; - public int coveredMethodCount; + void annotateTestDirectory(VirtualFile virtualFile, PackageCoverageInfo packageCoverageInfo, Module module); - public int totalClassCount = 1; - public int coveredClassCount; - } + void annotatePackage(String packageQualifiedName, PackageCoverageInfo packageCoverageInfo); - public static class PackageCoverageInfo { - public int totalClassCount; - public int coveredClassCount; - public int totalLineCount; - public int coveredLineCount; + void annotatePackage(String packageQualifiedName, PackageCoverageInfo packageCoverageInfo, boolean flatten); - public int coveredMethodCount; - public int totalMethodCount; - } + void annotateClass(String classQualifiedName, ClassCoverageInfo classCoverageInfo); + } - public static class DirCoverageInfo extends PackageCoverageInfo { - public VirtualFile sourceRoot; + public static class ClassCoverageInfo { + public int totalLineCount; + public int fullyCoveredLineCount; + public int partiallyCoveredLineCount; + public int totalMethodCount; + public int coveredMethodCount; - public DirCoverageInfo(VirtualFile sourceRoot) { - this.sourceRoot = sourceRoot; + public int totalClassCount = 1; + public int coveredClassCount; } - } - //get read lock myself when needed - public void annotate(final CoverageSuitesBundle suite, Annotator annotator) { - final ProjectData data = suite.getCoverageData(); + public static class PackageCoverageInfo { + public int totalClassCount; + public int coveredClassCount; + public int totalLineCount; + public int coveredLineCount; - if (data == null) { - return; + public int coveredMethodCount; + public int totalMethodCount; } - final String qualifiedName = myPackage.getQualifiedName(); - boolean filtered = false; - for (CoverageSuite coverageSuite : suite.getSuites()) { - if (((JavaCoverageSuite) coverageSuite).isPackageFiltered(qualifiedName)) { - filtered = true; - break; - } + public static class DirCoverageInfo extends PackageCoverageInfo { + public VirtualFile sourceRoot; - } - if (!filtered) { - return; + public DirCoverageInfo(VirtualFile sourceRoot) { + this.sourceRoot = sourceRoot; + } } - final GlobalSearchScope scope = suite.getSearchScope(myProject); - final Module[] modules = myCoverageManager.doInReadActionIfProjectOpen(new Computable() { - public Module[] compute() { - return ModuleManager.getInstance(myProject).getModules(); - } - }); + //get read lock myself when needed + public void annotate(CoverageSuitesBundle suite, Annotator annotator) { + ProjectData data = suite.getCoverageData(); - if (modules == null) { - return; - } + if (data == null) { + return; + } + + String qualifiedName = myPackage.getQualifiedName(); + boolean filtered = false; + for (CoverageSuite coverageSuite : suite.getSuites()) { + if (((JavaCoverageSuite) coverageSuite).isPackageFiltered(qualifiedName)) { + filtered = true; + break; + } - Map packageCoverageMap = new HashMap(); - Map flattenPackageCoverageMap = new HashMap(); - for (final Module module : modules) { - if (!scope.isSearchInModuleContent(module)) { - continue; - } - final String rootPackageVMName = qualifiedName.replaceAll("\\.", "/"); - final VirtualFile output = myCoverageManager.doInReadActionIfProjectOpen(new Computable() { - @Nullable - public VirtualFile compute() { - return ModuleCompilerPathsManager.getInstance(module).getCompilerOutput(ProductionContentFolderTypeProvider.getInstance()); } - }); + if (!filtered) { + return; + } + GlobalSearchScope scope = suite.getSearchScope(myProject); + Module[] modules = myCoverageManager.doInReadActionIfProjectOpen(() -> ModuleManager.getInstance(myProject).getModules()); - if (output != null) { - File outputRoot = findRelativeFile(rootPackageVMName, output); - if (outputRoot.exists()) { - collectCoverageInformation(outputRoot, packageCoverageMap, flattenPackageCoverageMap, data, rootPackageVMName, annotator, - module, suite.isTrackTestFolders(), false); + if (modules == null) { + return; } - } + Map packageCoverageMap = new HashMap<>(); + Map flattenPackageCoverageMap = new HashMap<>(); + for (Module module : modules) { + if (!scope.isSearchInModuleContent(module)) { + continue; + } + String rootPackageVMName = qualifiedName.replaceAll("\\.", "/"); + VirtualFile output = myCoverageManager.doInReadActionIfProjectOpen(() -> ModuleCompilerPathsManager.getInstance(module) + .getCompilerOutput(ProductionContentFolderTypeProvider.getInstance())); + + if (output != null) { + File outputRoot = findRelativeFile(rootPackageVMName, output); + if (outputRoot.exists()) { + collectCoverageInformation( + outputRoot, + packageCoverageMap, + flattenPackageCoverageMap, + data, + rootPackageVMName, + annotator, + module, + suite.isTrackTestFolders(), + false + ); + } - if (suite.isTrackTestFolders()) { - final VirtualFile testPackageRoot = myCoverageManager.doInReadActionIfProjectOpen(new Computable() { - @Nullable - public VirtualFile compute() { - return ModuleCompilerPathsManager.getInstance(module).getCompilerOutput(TestContentFolderTypeProvider.getInstance()); - } - }); + } - if (testPackageRoot != null) { - final File outputRoot = findRelativeFile(rootPackageVMName, testPackageRoot); - if (outputRoot.exists()) { - collectCoverageInformation(outputRoot, packageCoverageMap, flattenPackageCoverageMap, data, rootPackageVMName, annotator, - module, suite.isTrackTestFolders(), true); - } + if (suite.isTrackTestFolders()) { + VirtualFile testPackageRoot = + myCoverageManager.doInReadActionIfProjectOpen(() -> ModuleCompilerPathsManager.getInstance(module) + .getCompilerOutput(TestContentFolderTypeProvider.getInstance())); + + if (testPackageRoot != null) { + File outputRoot = findRelativeFile(rootPackageVMName, testPackageRoot); + if (outputRoot.exists()) { + collectCoverageInformation( + outputRoot, + packageCoverageMap, + flattenPackageCoverageMap, + data, + rootPackageVMName, + annotator, + module, + suite.isTrackTestFolders(), + true + ); + } + } + } } - } - } - for (Map.Entry entry : packageCoverageMap.entrySet()) { - final String packageFQName = entry.getKey().replaceAll("/", "."); - final PackageCoverageInfo info = entry.getValue(); - annotator.annotatePackage(packageFQName, info); - } + for (Map.Entry entry : packageCoverageMap.entrySet()) { + String packageFQName = entry.getKey().replaceAll("/", "."); + PackageCoverageInfo info = entry.getValue(); + annotator.annotatePackage(packageFQName, info); + } - for (Map.Entry entry : flattenPackageCoverageMap.entrySet()) { - final String packageFQName = entry.getKey().replaceAll("/", "."); - final PackageCoverageInfo info = entry.getValue(); - annotator.annotatePackage(packageFQName, info, true); + for (Map.Entry entry : flattenPackageCoverageMap.entrySet()) { + String packageFQName = entry.getKey().replaceAll("/", "."); + PackageCoverageInfo info = entry.getValue(); + annotator.annotatePackage(packageFQName, info, true); + } } - } - - private static File findRelativeFile(String rootPackageVMName, VirtualFile output) { - File outputRoot = VirtualFileUtil.virtualToIoFile(output); - outputRoot = rootPackageVMName.length() > 0 ? new File(outputRoot, FileUtil.toSystemDependentName(rootPackageVMName)) : outputRoot; - return outputRoot; - } - - public void annotateFilteredClass(PsiClass psiClass, CoverageSuitesBundle bundle, Annotator annotator) { - final ProjectData data = bundle.getCoverageData(); - if (data == null) { - return; + + private static File findRelativeFile(String rootPackageVMName, VirtualFile output) { + File outputRoot = VirtualFileUtil.virtualToIoFile(output); + outputRoot = rootPackageVMName.length() > 0 ? new File(outputRoot, FileUtil.toSystemDependentName(rootPackageVMName)) : outputRoot; + return outputRoot; } - final Module module = ModuleUtilCore.findModuleForPsiElement(psiClass); - if (module != null) { - final boolean isInTests = ProjectRootManager.getInstance(module.getProject()).getFileIndex().isInTestSourceContent(psiClass - .getContainingFile().getVirtualFile()); - final ModuleCompilerPathsManager moduleExtension = ModuleCompilerPathsManager.getInstance(module); - final VirtualFile outputPath = isInTests ? moduleExtension.getCompilerOutput(TestContentFolderTypeProvider.getInstance()) : - moduleExtension.getCompilerOutput(ProductionContentFolderTypeProvider.getInstance()); - - if (outputPath != null) { - final String qualifiedName = psiClass.getQualifiedName(); - if (qualifiedName == null) { - return; + + @RequiredReadAction + public void annotateFilteredClass(PsiClass psiClass, CoverageSuitesBundle bundle, Annotator annotator) { + ProjectData data = bundle.getCoverageData(); + if (data == null) { + return; } - final String packageVMName = StringUtil.getPackageName(qualifiedName).replace('.', '/'); - final File packageRoot = findRelativeFile(packageVMName, outputPath); - if (packageRoot != null && packageRoot.exists()) { - Map toplevelClassCoverage = new HashMap(); - final File[] files = packageRoot.listFiles(); - if (files != null) { - for (File child : files) { - if (isClassFile(child)) { - final String childName = getClassName(child); - final String classFqVMName = packageVMName.length() > 0 ? packageVMName + "/" + childName : childName; - final String toplevelClassSrcFQName = getSourceToplevelFQName(classFqVMName); - if (toplevelClassSrcFQName.equals(qualifiedName)) { - collectClassCoverageInformation(child, new PackageCoverageInfo(), data, toplevelClassCoverage, - classFqVMName.replace("/", "."), toplevelClassSrcFQName); + Module module = psiClass.getModule(); + if (module != null) { + boolean isInTests = ProjectRootManager.getInstance(module.getProject()).getFileIndex() + .isInTestSourceContent(psiClass.getContainingFile().getVirtualFile()); + ModuleCompilerPathsManager moduleExtension = ModuleCompilerPathsManager.getInstance(module); + VirtualFile outputPath = isInTests + ? moduleExtension.getCompilerOutput(TestContentFolderTypeProvider.getInstance()) + : moduleExtension.getCompilerOutput(ProductionContentFolderTypeProvider.getInstance()); + + if (outputPath != null) { + String qualifiedName = psiClass.getQualifiedName(); + if (qualifiedName == null) { + return; + } + String packageVMName = StringUtil.getPackageName(qualifiedName).replace('.', '/'); + File packageRoot = findRelativeFile(packageVMName, outputPath); + if (packageRoot != null && packageRoot.exists()) { + Map toplevelClassCoverage = new HashMap<>(); + File[] files = packageRoot.listFiles(); + if (files != null) { + for (File child : files) { + if (isClassFile(child)) { + String childName = getClassName(child); + String classFqVMName = packageVMName.length() > 0 ? packageVMName + "/" + childName : childName; + String toplevelClassSrcFQName = getSourceToplevelFQName(classFqVMName); + if (toplevelClassSrcFQName.equals(qualifiedName)) { + collectClassCoverageInformation(child, new PackageCoverageInfo(), data, toplevelClassCoverage, + classFqVMName.replace("/", "."), toplevelClassSrcFQName + ); + } + } + } + } + for (ClassCoverageInfo coverageInfo : toplevelClassCoverage.values()) { + annotator.annotateClass(qualifiedName, coverageInfo); + } } - } } - } - for (ClassCoverageInfo coverageInfo : toplevelClassCoverage.values()) { - annotator.annotateClass(qualifiedName, coverageInfo); - } - } - } - } - } - - @Nullable - private DirCoverageInfo[] collectCoverageInformation(final File packageOutputRoot, final Map packageCoverageMap, - Map flattenPackageCoverageMap, final ProjectData projectInfo, final String packageVMName, - final Annotator annotator, final Module module, final boolean trackTestFolders, final boolean isTestHierarchy) { - final List dirs = new ArrayList(); - final ContentEntry[] contentEntries = ModuleRootManager.getInstance(module).getContentEntries(); - for (ContentEntry contentEntry : contentEntries) { - for (ContentFolder folder : contentEntry.getFolders(isTestHierarchy ? LanguageContentFolderScopes.productionAndTest() : LanguageContentFolderScopes.production())) { - final VirtualFile file = folder.getFile(); - if (file == null) { - continue; } - final VirtualFile relativeSrcRoot = file.findFileByRelativePath(StringUtil.trimStart(packageVMName, "")); - dirs.add(new DirCoverageInfo(relativeSrcRoot)); - } } - final File[] children = packageOutputRoot.listFiles(); + @Nullable + private DirCoverageInfo[] collectCoverageInformation( + File packageOutputRoot, + Map packageCoverageMap, + Map flattenPackageCoverageMap, + ProjectData projectInfo, + String packageVMName, + Annotator annotator, + Module module, + boolean trackTestFolders, + boolean isTestHierarchy + ) { + List dirs = new ArrayList<>(); + ContentEntry[] contentEntries = ModuleRootManager.getInstance(module).getContentEntries(); + for (ContentEntry contentEntry : contentEntries) { + Predicate predicate = isTestHierarchy + ? LanguageContentFolderScopes.productionAndTest() + : LanguageContentFolderScopes.production(); + for (ContentFolder folder : contentEntry.getFolders(predicate)) { + VirtualFile file = folder.getFile(); + if (file == null) { + continue; + } + VirtualFile relativeSrcRoot = file.findFileByRelativePath(StringUtil.trimStart(packageVMName, "")); + dirs.add(new DirCoverageInfo(relativeSrcRoot)); + } + } - if (children == null) { - return null; - } + File[] children = packageOutputRoot.listFiles(); - Map toplevelClassCoverage = new HashMap(); - for (File child : children) { - if (child.isDirectory()) { - final String childName = child.getName(); - final String childPackageVMName = packageVMName.length() > 0 ? packageVMName + "/" + childName : childName; - final DirCoverageInfo[] childCoverageInfo = collectCoverageInformation(child, packageCoverageMap, flattenPackageCoverageMap, - projectInfo, childPackageVMName, annotator, module, trackTestFolders, isTestHierarchy); - if (childCoverageInfo != null) { - for (int i = 0; i < childCoverageInfo.length; i++) { - DirCoverageInfo coverageInfo = childCoverageInfo[i]; - final DirCoverageInfo parentDir = dirs.get(i); - parentDir.totalClassCount += coverageInfo.totalClassCount; - parentDir.coveredClassCount += coverageInfo.coveredClassCount; - parentDir.totalLineCount += coverageInfo.totalLineCount; - parentDir.coveredLineCount += coverageInfo.coveredLineCount; - parentDir.totalMethodCount += coverageInfo.totalMethodCount; - parentDir.coveredMethodCount += coverageInfo.coveredMethodCount; - } + if (children == null) { + return null; } - } else { - if (isClassFile(child)) { - final String childName = getClassName(child); - final String classFqVMName = packageVMName.length() > 0 ? packageVMName + "/" + childName : childName; - final String toplevelClassSrcFQName = getSourceToplevelFQName(classFqVMName); - final VirtualFile[] containingFile = new VirtualFile[1]; - final Boolean isInSource = myCoverageManager.doInReadActionIfProjectOpen(new Computable() { - public Boolean compute() { - final PsiClass aClass = JavaPsiFacade.getInstance(myManager.getProject()).findClass(toplevelClassSrcFQName, - GlobalSearchScope.moduleScope(module)); - if (aClass == null || !aClass.isValid()) { - return Boolean.FALSE; - } - containingFile[0] = aClass.getContainingFile().getVirtualFile(); - assert containingFile[0] != null : aClass; - final ModuleFileIndex fileIndex = ModuleRootManager.getInstance(module).getFileIndex(); - return fileIndex.isInSourceContent(containingFile[0]) && (trackTestFolders || - !fileIndex.isInTestSourceContent(containingFile[0])); + + Map toplevelClassCoverage = new HashMap<>(); + for (File child : children) { + if (child.isDirectory()) { + String childName = child.getName(); + String childPackageVMName = packageVMName.length() > 0 ? packageVMName + "/" + childName : childName; + DirCoverageInfo[] childCoverageInfo = collectCoverageInformation( + child, + packageCoverageMap, + flattenPackageCoverageMap, + projectInfo, + childPackageVMName, + annotator, + module, + trackTestFolders, + isTestHierarchy + ); + if (childCoverageInfo != null) { + for (int i = 0; i < childCoverageInfo.length; i++) { + DirCoverageInfo coverageInfo = childCoverageInfo[i]; + DirCoverageInfo parentDir = dirs.get(i); + parentDir.totalClassCount += coverageInfo.totalClassCount; + parentDir.coveredClassCount += coverageInfo.coveredClassCount; + parentDir.totalLineCount += coverageInfo.totalLineCount; + parentDir.coveredLineCount += coverageInfo.coveredLineCount; + parentDir.totalMethodCount += coverageInfo.totalMethodCount; + parentDir.coveredMethodCount += coverageInfo.coveredMethodCount; + } + } } - }); - if (isInSource != null && isInSource.booleanValue()) { - for (DirCoverageInfo dirCoverageInfo : dirs) { - if (dirCoverageInfo.sourceRoot != null && VirtualFileUtil.isAncestor(dirCoverageInfo.sourceRoot, containingFile[0], false)) { - collectClassCoverageInformation(child, dirCoverageInfo, projectInfo, toplevelClassCoverage, - classFqVMName.replace("/", "."), toplevelClassSrcFQName); - break; - } + else { + if (isClassFile(child)) { + String childName = getClassName(child); + String classFqVMName = packageVMName.length() > 0 ? packageVMName + "/" + childName : childName; + String toplevelClassSrcFQName = getSourceToplevelFQName(classFqVMName); + VirtualFile[] containingFile = new VirtualFile[1]; + Boolean isInSource = myCoverageManager.doInReadActionIfProjectOpen(() -> { + PsiClass aClass = JavaPsiFacade.getInstance(myManager.getProject()).findClass( + toplevelClassSrcFQName, + GlobalSearchScope.moduleScope(module) + ); + if (aClass == null || !aClass.isValid()) { + return Boolean.FALSE; + } + containingFile[0] = aClass.getContainingFile().getVirtualFile(); + assert containingFile[0] != null : aClass; + ModuleFileIndex fileIndex = ModuleRootManager.getInstance(module).getFileIndex(); + return fileIndex.isInSourceContent(containingFile[0]) + && (trackTestFolders || !fileIndex.isInTestSourceContent(containingFile[0])); + }); + if (isInSource != null && isInSource) { + for (DirCoverageInfo dirCoverageInfo : dirs) { + if (dirCoverageInfo.sourceRoot != null + && VirtualFileUtil.isAncestor(dirCoverageInfo.sourceRoot, containingFile[0], false)) { + collectClassCoverageInformation( + child, + dirCoverageInfo, + projectInfo, + toplevelClassCoverage, + classFqVMName.replace("/", "."), + toplevelClassSrcFQName + ); + break; + } + } + } + } } - } } - } - } - for (Map.Entry entry : toplevelClassCoverage.entrySet()) { - final String toplevelClassName = entry.getKey(); - final ClassCoverageInfo coverageInfo = entry.getValue(); - annotator.annotateClass(toplevelClassName, coverageInfo); - } + for (Map.Entry entry : toplevelClassCoverage.entrySet()) { + String toplevelClassName = entry.getKey(); + ClassCoverageInfo coverageInfo = entry.getValue(); + annotator.annotateClass(toplevelClassName, coverageInfo); + } + + PackageCoverageInfo flattenPackageCoverageInfo = getOrCreateCoverageInfo(flattenPackageCoverageMap, packageVMName); + for (Map.Entry entry : toplevelClassCoverage.entrySet()) { + ClassCoverageInfo coverageInfo = entry.getValue(); + flattenPackageCoverageInfo.coveredClassCount += coverageInfo.coveredClassCount; + flattenPackageCoverageInfo.totalClassCount += coverageInfo.totalClassCount; + + flattenPackageCoverageInfo.coveredLineCount += coverageInfo.fullyCoveredLineCount + coverageInfo.partiallyCoveredLineCount; + flattenPackageCoverageInfo.totalLineCount += coverageInfo.totalLineCount; - PackageCoverageInfo flattenPackageCoverageInfo = getOrCreateCoverageInfo(flattenPackageCoverageMap, packageVMName); - for (Map.Entry entry : toplevelClassCoverage.entrySet()) { - final ClassCoverageInfo coverageInfo = entry.getValue(); - flattenPackageCoverageInfo.coveredClassCount += coverageInfo.coveredClassCount; - flattenPackageCoverageInfo.totalClassCount += coverageInfo.totalClassCount; + flattenPackageCoverageInfo.coveredMethodCount += coverageInfo.coveredMethodCount; + flattenPackageCoverageInfo.totalMethodCount += coverageInfo.totalMethodCount; + } - flattenPackageCoverageInfo.coveredLineCount += coverageInfo.fullyCoveredLineCount + coverageInfo.partiallyCoveredLineCount; - flattenPackageCoverageInfo.totalLineCount += coverageInfo.totalLineCount; + PackageCoverageInfo packageCoverageInfo = getOrCreateCoverageInfo(packageCoverageMap, packageVMName); + for (DirCoverageInfo dir : dirs) { + packageCoverageInfo.totalClassCount += dir.totalClassCount; + packageCoverageInfo.totalLineCount += dir.totalLineCount; + packageCoverageInfo.coveredClassCount += dir.coveredClassCount; + packageCoverageInfo.coveredLineCount += dir.coveredLineCount; + packageCoverageInfo.coveredMethodCount += dir.coveredMethodCount; + packageCoverageInfo.totalMethodCount += dir.totalMethodCount; + + if (isTestHierarchy) { + annotator.annotateTestDirectory(dir.sourceRoot, dir, module); + } + else { + annotator.annotateSourceDirectory(dir.sourceRoot, dir, module); + } + } - flattenPackageCoverageInfo.coveredMethodCount += coverageInfo.coveredMethodCount; - flattenPackageCoverageInfo.totalMethodCount += coverageInfo.totalMethodCount; + return dirs.toArray(new DirCoverageInfo[dirs.size()]); } - PackageCoverageInfo packageCoverageInfo = getOrCreateCoverageInfo(packageCoverageMap, packageVMName); - for (DirCoverageInfo dir : dirs) { - packageCoverageInfo.totalClassCount += dir.totalClassCount; - packageCoverageInfo.totalLineCount += dir.totalLineCount; - packageCoverageInfo.coveredClassCount += dir.coveredClassCount; - packageCoverageInfo.coveredLineCount += dir.coveredLineCount; - packageCoverageInfo.coveredMethodCount += dir.coveredMethodCount; - packageCoverageInfo.totalMethodCount += dir.totalMethodCount; - - if (isTestHierarchy) { - annotator.annotateTestDirectory(dir.sourceRoot, dir, module); - } else { - annotator.annotateSourceDirectory(dir.sourceRoot, dir, module); - } + private static boolean isClassFile(File classFile) { + return classFile.getName().endsWith(".class"); } - return dirs.toArray(new DirCoverageInfo[dirs.size()]); - } + private static String getClassName(File classFile) { + return StringUtil.trimEnd(classFile.getName(), ".class"); + } - private static boolean isClassFile(File classFile) { - return classFile.getName().endsWith(".class"); - } + private static PackageCoverageInfo getOrCreateCoverageInfo( + Map packageCoverageMap, + String packageVMName + ) { + PackageCoverageInfo coverageInfo = packageCoverageMap.get(packageVMName); + if (coverageInfo == null) { + coverageInfo = new PackageCoverageInfo(); + packageCoverageMap.put(packageVMName, coverageInfo); + } + return coverageInfo; + } - private static String getClassName(File classFile) { - return StringUtil.trimEnd(classFile.getName(), ".class"); - } + private void collectClassCoverageInformation( + File classFile, + PackageCoverageInfo packageCoverageInfo, + ProjectData projectInfo, + Map toplevelClassCoverage, + String className, + String toplevelClassSrcFQName + ) { + ClassCoverageInfo toplevelClassCoverageInfo = new ClassCoverageInfo(); + + ClassData classData = projectInfo.getClassData(className); + + if (classData != null && classData.getLines() != null) { + for (Object l : classData.getLines()) { + if (l instanceof LineData lineData) { + if (lineData.getStatus() == LineCoverage.FULL) { + toplevelClassCoverageInfo.fullyCoveredLineCount++; + } + else if (lineData.getStatus() == LineCoverage.PARTIAL) { + toplevelClassCoverageInfo.partiallyCoveredLineCount++; + } + toplevelClassCoverageInfo.totalLineCount++; + packageCoverageInfo.totalLineCount++; + } + } + boolean touchedClass = false; + Collection methodSigs = classData.getMethodSigs(); + for (String nameAndSig : methodSigs) { + int covered = classData.getStatus(nameAndSig); + if (covered != LineCoverage.NONE) { + toplevelClassCoverageInfo.coveredMethodCount++; + touchedClass = true; + } + } + if (!methodSigs.isEmpty()) { + if (touchedClass) { + packageCoverageInfo.coveredClassCount++; + } + toplevelClassCoverageInfo.totalMethodCount += methodSigs.size(); + packageCoverageInfo.totalClassCount++; - private static PackageCoverageInfo getOrCreateCoverageInfo(final Map packageCoverageMap, final String packageVMName) { - PackageCoverageInfo coverageInfo = packageCoverageMap.get(packageVMName); - if (coverageInfo == null) { - coverageInfo = new PackageCoverageInfo(); - packageCoverageMap.put(packageVMName, coverageInfo); - } - return coverageInfo; - } - - private void collectClassCoverageInformation(final File classFile, final PackageCoverageInfo packageCoverageInfo, final ProjectData projectInfo, - final Map toplevelClassCoverage, final String className, final String toplevelClassSrcFQName) { - final ClassCoverageInfo toplevelClassCoverageInfo = new ClassCoverageInfo(); - - final ClassData classData = projectInfo.getClassData(className); - - if (classData != null && classData.getLines() != null) { - final Object[] lines = classData.getLines(); - for (Object l : lines) { - if (l instanceof LineData) { - final LineData lineData = (LineData) l; - if (lineData.getStatus() == LineCoverage.FULL) { - toplevelClassCoverageInfo.fullyCoveredLineCount++; - } else if (lineData.getStatus() == LineCoverage.PARTIAL) { - toplevelClassCoverageInfo.partiallyCoveredLineCount++; - } - toplevelClassCoverageInfo.totalLineCount++; - packageCoverageInfo.totalLineCount++; - } - } - boolean touchedClass = false; - final Collection methodSigs = classData.getMethodSigs(); - for (final Object nameAndSig : methodSigs) { - final int covered = classData.getStatus((String) nameAndSig); - if (covered != LineCoverage.NONE) { - toplevelClassCoverageInfo.coveredMethodCount++; - touchedClass = true; + packageCoverageInfo.coveredLineCount += toplevelClassCoverageInfo.fullyCoveredLineCount; + packageCoverageInfo.coveredLineCount += toplevelClassCoverageInfo.partiallyCoveredLineCount; + packageCoverageInfo.coveredMethodCount += toplevelClassCoverageInfo.coveredMethodCount; + packageCoverageInfo.totalMethodCount += toplevelClassCoverageInfo.totalMethodCount; + } + else { + return; + } } - } - if (!methodSigs.isEmpty()) { - if (touchedClass) { - packageCoverageInfo.coveredClassCount++; + else if (!collectNonCoveredClassInfo(classFile, toplevelClassCoverageInfo, packageCoverageInfo)) { + return; } - toplevelClassCoverageInfo.totalMethodCount += methodSigs.size(); - packageCoverageInfo.totalClassCount++; - - packageCoverageInfo.coveredLineCount += toplevelClassCoverageInfo.fullyCoveredLineCount; - packageCoverageInfo.coveredLineCount += toplevelClassCoverageInfo.partiallyCoveredLineCount; - packageCoverageInfo.coveredMethodCount += toplevelClassCoverageInfo.coveredMethodCount; - packageCoverageInfo.totalMethodCount += toplevelClassCoverageInfo.totalMethodCount; - } else { - return; - } - } else { - if (!collectNonCoveredClassInfo(classFile, toplevelClassCoverageInfo, packageCoverageInfo)) { - return; - } - } - ClassCoverageInfo classCoverageInfo = getOrCreateClassCoverageInfo(toplevelClassCoverage, toplevelClassSrcFQName); - classCoverageInfo.totalLineCount += toplevelClassCoverageInfo.totalLineCount; - classCoverageInfo.fullyCoveredLineCount += toplevelClassCoverageInfo.fullyCoveredLineCount; - classCoverageInfo.partiallyCoveredLineCount += toplevelClassCoverageInfo.partiallyCoveredLineCount; + ClassCoverageInfo classCoverageInfo = getOrCreateClassCoverageInfo(toplevelClassCoverage, toplevelClassSrcFQName); + classCoverageInfo.totalLineCount += toplevelClassCoverageInfo.totalLineCount; + classCoverageInfo.fullyCoveredLineCount += toplevelClassCoverageInfo.fullyCoveredLineCount; + classCoverageInfo.partiallyCoveredLineCount += toplevelClassCoverageInfo.partiallyCoveredLineCount; - classCoverageInfo.totalMethodCount += toplevelClassCoverageInfo.totalMethodCount; - classCoverageInfo.coveredMethodCount += toplevelClassCoverageInfo.coveredMethodCount; - if (toplevelClassCoverageInfo.coveredMethodCount > 0) { - classCoverageInfo.coveredClassCount++; - } - } - - private static ClassCoverageInfo getOrCreateClassCoverageInfo(final Map toplevelClassCoverage, - final String sourceToplevelFQName) { - ClassCoverageInfo toplevelClassCoverageInfo = toplevelClassCoverage.get(sourceToplevelFQName); - if (toplevelClassCoverageInfo == null) { - toplevelClassCoverageInfo = new ClassCoverageInfo(); - toplevelClassCoverage.put(sourceToplevelFQName, toplevelClassCoverageInfo); - } else { - toplevelClassCoverageInfo.totalClassCount++; + classCoverageInfo.totalMethodCount += toplevelClassCoverageInfo.totalMethodCount; + classCoverageInfo.coveredMethodCount += toplevelClassCoverageInfo.coveredMethodCount; + if (toplevelClassCoverageInfo.coveredMethodCount > 0) { + classCoverageInfo.coveredClassCount++; + } } - return toplevelClassCoverageInfo; - } - private static String getSourceToplevelFQName(String classFQVMName) { - final int index = classFQVMName.indexOf('$'); - if (index > 0) { - classFQVMName = classFQVMName.substring(0, index); + private static ClassCoverageInfo getOrCreateClassCoverageInfo( + Map toplevelClassCoverage, + String sourceToplevelFQName + ) { + ClassCoverageInfo toplevelClassCoverageInfo = toplevelClassCoverage.get(sourceToplevelFQName); + if (toplevelClassCoverageInfo == null) { + toplevelClassCoverageInfo = new ClassCoverageInfo(); + toplevelClassCoverage.put(sourceToplevelFQName, toplevelClassCoverageInfo); + } + else { + toplevelClassCoverageInfo.totalClassCount++; + } + return toplevelClassCoverageInfo; } - if (classFQVMName.startsWith("/")) { - classFQVMName = classFQVMName.substring(1); + + private static String getSourceToplevelFQName(String classFQVMName) { + int index = classFQVMName.indexOf('$'); + if (index > 0) { + classFQVMName = classFQVMName.substring(0, index); + } + if (classFQVMName.startsWith("/")) { + classFQVMName = classFQVMName.substring(1); + } + return classFQVMName.replaceAll("/", "."); } - return classFQVMName.replaceAll("/", "."); - } - /* - return true if there is executable code in the class + /** + * return true if there is executable code in the class */ - private boolean collectNonCoveredClassInfo(final File classFile, final ClassCoverageInfo classCoverageInfo, - final PackageCoverageInfo packageCoverageInfo) { - final byte[] content = myCoverageManager.doInReadActionIfProjectOpen(new Computable() { - public byte[] compute() { - try { - return Files.readAllBytes(classFile.toPath()); - } catch (IOException e) { - return null; + private boolean collectNonCoveredClassInfo( + File classFile, + ClassCoverageInfo classCoverageInfo, + PackageCoverageInfo packageCoverageInfo + ) { + byte[] content = myCoverageManager.doInReadActionIfProjectOpen(() -> { + try { + return Files.readAllBytes(classFile.toPath()); + } + catch (IOException e) { + return null; + } + }); + CoverageSuitesBundle coverageSuite = CoverageDataManager.getInstance(myProject).getCurrentSuitesBundle(); + //noinspection SimplifiableIfStatement + if (coverageSuite == null) { + return false; } - } - }); - final CoverageSuitesBundle coverageSuite = CoverageDataManager.getInstance(myProject).getCurrentSuitesBundle(); - if (coverageSuite == null) { - return false; + return SourceLineCounterUtil.collectNonCoveredClassInfo( + classCoverageInfo, + packageCoverageInfo, + content, + coverageSuite.isTracingEnabled() + ); } - return SourceLineCounterUtil.collectNonCoveredClassInfo(classCoverageInfo, packageCoverageInfo, content, coverageSuite.isTracingEnabled()); - } } diff --git a/java-coverage-impl/src/main/java/com/intellij/java/coverage/SourceLineCounter.java b/java-coverage-impl/src/main/java/com/intellij/java/coverage/SourceLineCounter.java index 7cc58660a8..7054acc5f5 100644 --- a/java-coverage-impl/src/main/java/com/intellij/java/coverage/SourceLineCounter.java +++ b/java-coverage-impl/src/main/java/com/intellij/java/coverage/SourceLineCounter.java @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package com.intellij.java.coverage; import com.intellij.rt.coverage.data.ClassData; @@ -30,195 +29,189 @@ /** * @author anna - * @since 27-Jun-2008 + * @since 2008-06-27 */ public class SourceLineCounter extends ClassVisitor { - private final boolean myExcludeLines; - private final ClassData myClassData; - private final ProjectData myProjectData; - - private final IntObjectMap myNSourceLines = IntMaps.newIntObjectHashMap(); - private final Set myMethodsWithSourceCode = new HashSet(); - private int myCurrentLine; - private boolean myInterface; - private boolean myEnum; - - public SourceLineCounter(final ClassData classData, final boolean excludeLines, final ProjectData projectData) { - super(Opcodes.API_VERSION, new ClassVisitor(Opcodes.API_VERSION) { - }); - myProjectData = projectData; - myClassData = classData; - myExcludeLines = excludeLines; - } - - @Override - public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { - myInterface = (access & Opcodes.ACC_INTERFACE) != 0; - myEnum = (access & Opcodes.ACC_ENUM) != 0; - super.visit(version, access, name, signature, superName, interfaces); - } - - @Override - public void visitSource(String sourceFileName, String debug) { - if (myProjectData != null) { - myClassData.setSource(sourceFileName); + private final boolean myExcludeLines; + private final ClassData myClassData; + private final ProjectData myProjectData; + + private final IntObjectMap myNSourceLines = IntMaps.newIntObjectHashMap(); + private final Set myMethodsWithSourceCode = new HashSet<>(); + private int myCurrentLine; + private boolean myInterface; + private boolean myEnum; + + public SourceLineCounter(ClassData classData, boolean excludeLines, ProjectData projectData) { + super(Opcodes.API_VERSION, new ClassVisitor(Opcodes.API_VERSION) { + }); + myProjectData = projectData; + myClassData = classData; + myExcludeLines = excludeLines; } - super.visitSource(sourceFileName, debug); - } - @Override - public void visitOuterClass(String outerClassName, String methodName, String methodSig) { - if (myProjectData != null) { - myProjectData.getOrCreateClassData(outerClassName).setSource(myClassData.getSource()); - } - super.visitOuterClass(outerClassName, methodName, methodSig); - } - - @Override - public MethodVisitor visitMethod(final int access, final String name, final String desc, final String signature, final String[] exceptions) { - final MethodVisitor v = cv.visitMethod(access, name, desc, signature, exceptions); - if (myInterface) { - return v; + @Override + public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { + myInterface = (access & Opcodes.ACC_INTERFACE) != 0; + myEnum = (access & Opcodes.ACC_ENUM) != 0; + super.visit(version, access, name, signature, superName, interfaces); } - if ((access & Opcodes.ACC_BRIDGE) != 0) { - return v; + + @Override + public void visitSource(String sourceFileName, String debug) { + if (myProjectData != null) { + myClassData.setSource(sourceFileName); + } + super.visitSource(sourceFileName, debug); } - if (myEnum) { - if (name.equals("values") && desc.startsWith("()[L")) { - return v; - } - if (name.equals("valueOf") && desc.startsWith("(Ljava/lang/String;)L")) { - return v; - } - if (name.equals("") && signature != null && signature.equals("()V")) { - return v; - } + + @Override + public void visitOuterClass(String outerClassName, String methodName, String methodSig) { + if (myProjectData != null) { + myProjectData.getOrCreateClassData(outerClassName).setSource(myClassData.getSource()); + } + super.visitOuterClass(outerClassName, methodName, methodSig); } - return new MethodVisitor(Opcodes.ASM5, v) { - private boolean myHasInstructions; - - - @Override - public void visitLineNumber(final int line, final Label start) { - myHasInstructions = false; - myCurrentLine = line; - if (!myExcludeLines || - myClassData == null || - myClassData.getStatus(name + desc) != null || - (!name.equals("") && !name.equals(""))) { - myNSourceLines.put(line, name + desc); - myMethodsWithSourceCode.add(name + desc); + + @Override + public MethodVisitor visitMethod(int access, final String name, final String desc, String signature, String[] exceptions) { + final MethodVisitor v = cv.visitMethod(access, name, desc, signature, exceptions); + if (myInterface) { + return v; + } + if ((access & Opcodes.ACC_BRIDGE) != 0) { + return v; } - } - - @Override - public void visitInsn(final int opcode) { - if (myExcludeLines) { - if (opcode == Opcodes.RETURN && !myHasInstructions) { - myNSourceLines.remove(myCurrentLine); - } else { - myHasInstructions = true; - } + if (myEnum) { + if (name.equals("values") && desc.startsWith("()[L")) { + return v; + } + if (name.equals("valueOf") && desc.startsWith("(Ljava/lang/String;)L")) { + return v; + } + if (name.equals("") && signature != null && signature.equals("()V")) { + return v; + } } - } - - @Override - public void visitIntInsn(final int opcode, final int operand) { - super.visitIntInsn(opcode, operand); - myHasInstructions = true; - } - - @Override - public void visitVarInsn(final int opcode, final int var) { - super.visitVarInsn(opcode, var); - myHasInstructions = true; - } - - @Override - public void visitTypeInsn(final int opcode, final String type) { - super.visitTypeInsn(opcode, type); - myHasInstructions = true; - } - - @Override - public void visitFieldInsn(final int opcode, final String owner, final String name, final String desc) { - super.visitFieldInsn(opcode, owner, name, desc); - myHasInstructions = true; - } - - @Override - public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) { - super.visitMethodInsn(opcode, owner, name, desc, itf); - myHasInstructions = true; - } - - @Override - public void visitJumpInsn(final int opcode, final Label label) { - super.visitJumpInsn(opcode, label); - myHasInstructions = true; - } - - @Override - public void visitLdcInsn(final Object cst) { - super.visitLdcInsn(cst); - myHasInstructions = true; - } - - - @Override - public void visitIincInsn(final int var, final int increment) { - super.visitIincInsn(var, increment); - myHasInstructions = true; - } - - - @Override - public void visitTableSwitchInsn(final int min, final int max, final Label dflt, final Label[] labels) { - super.visitTableSwitchInsn(min, max, dflt, labels); - myHasInstructions = true; - } - - - @Override - public void visitLookupSwitchInsn(final Label dflt, final int[] keys, final Label[] labels) { - super.visitLookupSwitchInsn(dflt, keys, labels); - myHasInstructions = true; - } - - - @Override - public void visitMultiANewArrayInsn(final String desc, final int dims) { - super.visitMultiANewArrayInsn(desc, dims); - myHasInstructions = true; - } - - - @Override - public void visitTryCatchBlock(final Label start, final Label end, final Label handler, final String type) { - super.visitTryCatchBlock(start, end, handler, type); - myHasInstructions = true; - } - - }; - } - - public int getNSourceLines() { - return myNSourceLines.size(); - } - - public IntObjectMap getSourceLines() { - return myNSourceLines; - } - - public Set getMethodsWithSourceCode() { - return myMethodsWithSourceCode; - } - - public int getNMethodsWithCode() { - return myMethodsWithSourceCode.size(); - } - - public boolean isInterface() { - return myInterface; - } + return new MethodVisitor(Opcodes.ASM5, v) { + private boolean myHasInstructions; + + @Override + public void visitLineNumber(int line, Label start) { + myHasInstructions = false; + myCurrentLine = line; + if (!myExcludeLines || + myClassData == null || + myClassData.getStatus(name + desc) != null || + (!name.equals("") && !name.equals(""))) { + myNSourceLines.put(line, name + desc); + myMethodsWithSourceCode.add(name + desc); + } + } + + @Override + public void visitInsn(int opcode) { + if (myExcludeLines) { + if (opcode == Opcodes.RETURN && !myHasInstructions) { + myNSourceLines.remove(myCurrentLine); + } + else { + myHasInstructions = true; + } + } + } + + @Override + public void visitIntInsn(int opcode, int operand) { + super.visitIntInsn(opcode, operand); + myHasInstructions = true; + } + + @Override + public void visitVarInsn(int opcode, int var) { + super.visitVarInsn(opcode, var); + myHasInstructions = true; + } + + @Override + public void visitTypeInsn(int opcode, String type) { + super.visitTypeInsn(opcode, type); + myHasInstructions = true; + } + + @Override + public void visitFieldInsn(int opcode, String owner, String name, String desc) { + super.visitFieldInsn(opcode, owner, name, desc); + myHasInstructions = true; + } + + @Override + public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) { + super.visitMethodInsn(opcode, owner, name, desc, itf); + myHasInstructions = true; + } + + @Override + public void visitJumpInsn(int opcode, Label label) { + super.visitJumpInsn(opcode, label); + myHasInstructions = true; + } + + @Override + public void visitLdcInsn(Object cst) { + super.visitLdcInsn(cst); + myHasInstructions = true; + } + + @Override + public void visitIincInsn(int var, int increment) { + super.visitIincInsn(var, increment); + myHasInstructions = true; + } + + @Override + public void visitTableSwitchInsn(int min, int max, Label dflt, Label[] labels) { + super.visitTableSwitchInsn(min, max, dflt, labels); + myHasInstructions = true; + } + + @Override + public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) { + super.visitLookupSwitchInsn(dflt, keys, labels); + myHasInstructions = true; + } + + @Override + public void visitMultiANewArrayInsn(String desc, int dims) { + super.visitMultiANewArrayInsn(desc, dims); + myHasInstructions = true; + } + + @Override + public void visitTryCatchBlock(Label start, Label end, Label handler, String type) { + super.visitTryCatchBlock(start, end, handler, type); + myHasInstructions = true; + } + }; + } + + public int getNSourceLines() { + return myNSourceLines.size(); + } + + public IntObjectMap getSourceLines() { + return myNSourceLines; + } + + public Set getMethodsWithSourceCode() { + return myMethodsWithSourceCode; + } + + public int getNMethodsWithCode() { + return myMethodsWithSourceCode.size(); + } + + public boolean isInterface() { + return myInterface; + } } diff --git a/java-coverage-impl/src/main/java/com/intellij/java/coverage/SourceLineCounterUtil.java b/java-coverage-impl/src/main/java/com/intellij/java/coverage/SourceLineCounterUtil.java index 5e0468c899..e1526d66f5 100644 --- a/java-coverage-impl/src/main/java/com/intellij/java/coverage/SourceLineCounterUtil.java +++ b/java-coverage-impl/src/main/java/com/intellij/java/coverage/SourceLineCounterUtil.java @@ -6,45 +6,41 @@ import java.util.List; /** - * User: anna - * Date: 12/30/11 + * @author anna + * @since 2011-12-30 */ -public class SourceLineCounterUtil -{ - public static boolean collectNonCoveredClassInfo(final PackageAnnotator.ClassCoverageInfo classCoverageInfo, - final PackageAnnotator.PackageCoverageInfo packageCoverageInfo, - byte[] content, - final boolean excludeLines) - { - if(content == null) - { - return false; - } - ClassReader reader = new ClassReader(content, 0, content.length); +public class SourceLineCounterUtil { + public static boolean collectNonCoveredClassInfo( + PackageAnnotator.ClassCoverageInfo classCoverageInfo, + PackageAnnotator.PackageCoverageInfo packageCoverageInfo, + byte[] content, + boolean excludeLines + ) { + if (content == null) { + return false; + } + ClassReader reader = new ClassReader(content, 0, content.length); - SourceLineCounter counter = new SourceLineCounter(null, excludeLines, null); - reader.accept(counter, 0); - classCoverageInfo.totalLineCount += counter.getNSourceLines(); - classCoverageInfo.totalMethodCount += counter.getNMethodsWithCode(); - packageCoverageInfo.totalLineCount += counter.getNSourceLines(); - packageCoverageInfo.totalMethodCount += counter.getNMethodsWithCode(); - if(!counter.isInterface()) - { - packageCoverageInfo.totalClassCount++; - } - return false; - } + SourceLineCounter counter = new SourceLineCounter(null, excludeLines, null); + reader.accept(counter, 0); + classCoverageInfo.totalLineCount += counter.getNSourceLines(); + classCoverageInfo.totalMethodCount += counter.getNMethodsWithCode(); + packageCoverageInfo.totalLineCount += counter.getNSourceLines(); + packageCoverageInfo.totalMethodCount += counter.getNMethodsWithCode(); + if (!counter.isInterface()) { + packageCoverageInfo.totalClassCount++; + } + return false; + } - public static void collectSrcLinesForUntouchedFiles(final List uncoveredLines, - byte[] content, final boolean excludeLines) - { - final ClassReader reader = new ClassReader(content); - final SourceLineCounter collector = new SourceLineCounter(null, excludeLines, null); - reader.accept(collector, 0); - final IntObjectMap lines = collector.getSourceLines(); - lines.keySet().forEach(line -> { - line--; - uncoveredLines.add(line); - }); - } + public static void collectSrcLinesForUntouchedFiles(List uncoveredLines, byte[] content, boolean excludeLines) { + ClassReader reader = new ClassReader(content); + SourceLineCounter collector = new SourceLineCounter(null, excludeLines, null); + reader.accept(collector, 0); + IntObjectMap lines = collector.getSourceLines(); + lines.keySet().forEach(line -> { + line--; + uncoveredLines.add(line); + }); + } } diff --git a/java-coverage-impl/src/main/java/com/intellij/java/coverage/info/CoberturaLoaderUtil.java b/java-coverage-impl/src/main/java/com/intellij/java/coverage/info/CoberturaLoaderUtil.java index b899e7f532..fdfb6ff3ea 100644 --- a/java-coverage-impl/src/main/java/com/intellij/java/coverage/info/CoberturaLoaderUtil.java +++ b/java-coverage-impl/src/main/java/com/intellij/java/coverage/info/CoberturaLoaderUtil.java @@ -16,82 +16,93 @@ import java.io.IOException; public class CoberturaLoaderUtil { - private static final Logger LOG = Logger.getInstance(CoberturaLoaderUtil.class); + private static final Logger LOG = Logger.getInstance(CoberturaLoaderUtil.class); - private CoberturaLoaderUtil() { - } - - public static ProjectData load(final File sessionDataFile) { - ProjectData projectInfo = new ProjectData(); - DataInputStream dataFile = null; - try { - dataFile = new DataInputStream(new FileInputStream(sessionDataFile)); - int classesCount = dataFile.read(); - for (int i = 0; i < classesCount; i++) { - final String classFQName = dataFile.readUTF(); - dataFile.readUTF(); //sourcefilename - final ClassData classData = projectInfo.getOrCreateClassData(classFQName); - final int numberOfLines = dataFile.read(); - for (int l = 0; l < numberOfLines; l++) { - final int lineNumber = dataFile.read(); - final LineData lineData = null; //todo classData.getOrCreateLine(lineNumber, dataFile.readUTF() + dataFile.readUTF()); - long hits = dataFile.readLong(); - final int jumpsNumber = dataFile.read(); - int trueHits = 0; - int falseHits = 0; - int totalHits = 0; - for (int j = 0; j < jumpsNumber; j++) { - dataFile.read(); //jump number - totalHits++; - if (dataFile.readLong() > 0) trueHits++; - totalHits++; - if (dataFile.readLong() > 0) falseHits++; - } - int defaultHitsNumber = 0; - int branchHitNumber = 0; - final int switchNumber = dataFile.read(); - for (int s = 0; s < switchNumber; s++) { - dataFile.read(); //switch number - dataFile.read(); //number of keys - long defaultHits = dataFile.readLong(); - if (defaultHits > 0) defaultHitsNumber++; - int coveredSwitchBranches = 0; - final int switchBranchesNumber = dataFile.read(); - for (int b = 0; b < switchBranchesNumber; b++) { - final long branchHit = dataFile.readLong(); - if (branchHit > 0) coveredSwitchBranches ++; - } - if (coveredSwitchBranches == switchBranchesNumber) branchHitNumber++; - } - if (hits > 0) { - if (totalHits == trueHits + falseHits) { - if (defaultHitsNumber == switchNumber && branchHitNumber == switchNumber) { - lineData.setStatus(LineCoverage.FULL); - continue; - } - } - lineData.setStatus(LineCoverage.PARTIAL); - } else { - lineData.setStatus(LineCoverage.NONE); - } - } - } - } - catch (IOException e) { - LOG.info(e); + private CoberturaLoaderUtil() { } - finally { - if (dataFile != null) { + + public static ProjectData load(File sessionDataFile) { + ProjectData projectInfo = new ProjectData(); + DataInputStream dataFile = null; try { - dataFile.close(); + dataFile = new DataInputStream(new FileInputStream(sessionDataFile)); + int classesCount = dataFile.read(); + for (int i = 0; i < classesCount; i++) { + String classFQName = dataFile.readUTF(); + dataFile.readUTF(); //sourcefilename + ClassData classData = projectInfo.getOrCreateClassData(classFQName); + int numberOfLines = dataFile.read(); + for (int l = 0; l < numberOfLines; l++) { + int lineNumber = dataFile.read(); + LineData lineData = null; //todo classData.getOrCreateLine(lineNumber, dataFile.readUTF() + dataFile.readUTF()); + long hits = dataFile.readLong(); + int jumpsNumber = dataFile.read(); + int trueHits = 0; + int falseHits = 0; + int totalHits = 0; + for (int j = 0; j < jumpsNumber; j++) { + dataFile.read(); //jump number + totalHits++; + if (dataFile.readLong() > 0) { + trueHits++; + } + totalHits++; + if (dataFile.readLong() > 0) { + falseHits++; + } + } + int defaultHitsNumber = 0; + int branchHitNumber = 0; + int switchNumber = dataFile.read(); + for (int s = 0; s < switchNumber; s++) { + dataFile.read(); //switch number + dataFile.read(); //number of keys + long defaultHits = dataFile.readLong(); + if (defaultHits > 0) { + defaultHitsNumber++; + } + int coveredSwitchBranches = 0; + int switchBranchesNumber = dataFile.read(); + for (int b = 0; b < switchBranchesNumber; b++) { + long branchHit = dataFile.readLong(); + if (branchHit > 0) { + coveredSwitchBranches++; + } + } + if (coveredSwitchBranches == switchBranchesNumber) { + branchHitNumber++; + } + } + if (hits > 0) { + if (totalHits == trueHits + falseHits) { + if (defaultHitsNumber == switchNumber && branchHitNumber == switchNumber) { + lineData.setStatus(LineCoverage.FULL); + continue; + } + } + lineData.setStatus(LineCoverage.PARTIAL); + } + else { + lineData.setStatus(LineCoverage.NONE); + } + } + } } catch (IOException e) { - LOG.error(e); + LOG.info(e); } - } + finally { + if (dataFile != null) { + try { + dataFile.close(); + } + catch (IOException e) { + LOG.error(e); + } + } + } + return projectInfo; } - return projectInfo; - } /*public static List loadTestLines(final File testSessionFile, ProjectInfo projectInfo) { final List result = new ArrayList();