try to reuse coverage infrastructure:
[idea/community.git] / plugins / coverage-common / src / com / intellij / coverage / CoverageSuitesBundle.java
1 package com.intellij.coverage;
2
3 import com.intellij.execution.configurations.ModuleBasedConfiguration;
4 import com.intellij.execution.configurations.RunConfigurationBase;
5 import com.intellij.openapi.diagnostic.Logger;
6 import com.intellij.openapi.module.Module;
7 import com.intellij.openapi.project.Project;
8 import com.intellij.openapi.roots.ProjectRootModificationTracker;
9 import com.intellij.openapi.util.Comparing;
10 import com.intellij.openapi.util.text.StringUtil;
11 import com.intellij.psi.search.GlobalSearchScope;
12 import com.intellij.psi.search.GlobalSearchScopesCore;
13 import com.intellij.psi.util.CachedValue;
14 import com.intellij.psi.util.CachedValueProvider;
15 import com.intellij.psi.util.CachedValuesManager;
16 import com.intellij.reference.SoftReference;
17 import com.intellij.rt.coverage.data.LineData;
18 import com.intellij.rt.coverage.data.ProjectData;
19 import com.intellij.util.ArrayUtilRt;
20 import com.intellij.util.Function;
21 import org.jetbrains.annotations.NotNull;
22 import org.jetbrains.annotations.Nullable;
23
24 import java.util.HashSet;
25 import java.util.Set;
26 import java.util.TreeMap;
27
28 /**
29  * User: anna
30  * Date: 12/14/10
31  */
32 public class CoverageSuitesBundle {
33   private CoverageSuite[] mySuites;
34   private CoverageEngine myEngine;
35
36   private Set<Module> myProcessedModules;
37
38   private CachedValue<GlobalSearchScope> myCachedValue;
39
40   private SoftReference<ProjectData> myData = new SoftReference<ProjectData>(null);
41   private static final Logger LOG = Logger.getInstance("#" + CoverageSuitesBundle.class.getName());
42
43   public CoverageSuitesBundle(CoverageSuite suite) {
44     this(new CoverageSuite[]{suite});
45   }
46
47   public CoverageSuitesBundle(CoverageSuite[] suites) {
48     mySuites = suites;
49     LOG.assertTrue(mySuites.length > 0);
50     myEngine = mySuites[0].getCoverageEngine();
51     for (CoverageSuite suite : suites) {
52       final CoverageEngine engine = suite.getCoverageEngine();
53       LOG.assertTrue(Comparing.equal(engine, myEngine));
54     }
55   }
56
57
58   public boolean isValid() {
59     for (CoverageSuite suite : mySuites) {
60       if (!suite.isValid()) return false;
61     }
62     return true;
63   }
64
65
66   public long getLastCoverageTimeStamp() {
67     long max = 0;
68     for (CoverageSuite suite : mySuites) {
69       max = Math.max(max, suite.getLastCoverageTimeStamp());
70     }
71     return max;
72   }
73
74   public boolean isCoverageByTestApplicable() {
75     for (CoverageSuite suite : mySuites) {
76       if (suite.isCoverageByTestApplicable()) return true;
77     }
78     return false;
79   }
80
81   public boolean isCoverageByTestEnabled() {
82     for (CoverageSuite suite : mySuites) {
83       if (suite.isCoverageByTestEnabled()) return true;
84     }
85     return false;
86   }
87
88   @Nullable
89   public ProjectData getCoverageData() {
90     final ProjectData projectData = myData.get();
91     if (projectData != null) return projectData;
92     ProjectData data = new ProjectData();
93     for (CoverageSuite suite : mySuites) {
94       final ProjectData coverageData = suite.getCoverageData(null);
95       if (coverageData != null) {
96         data.merge(coverageData);
97       }
98     }
99     myData = new SoftReference<ProjectData>(data);
100     return data;
101   }
102
103   public boolean isTrackTestFolders() {
104     for (CoverageSuite suite : mySuites) {
105       if (suite.isTrackTestFolders()) return true;
106     }
107     return false;
108   }
109
110   public boolean isTracingEnabled() {
111     for (CoverageSuite suite : mySuites) {
112       if (suite.isTracingEnabled()) return true;
113     }
114     return false;
115   }
116
117   @NotNull
118   public CoverageEngine getCoverageEngine() {
119     return myEngine;
120   }
121
122   public LineMarkerRendererWithErrorStripe getLineMarkerRenderer(int lineNumber,
123                                                                  @Nullable final String className,
124                                                                  final TreeMap<Integer, LineData> lines,
125                                                                  final boolean coverageByTestApplicable,
126                                                                  @NotNull final CoverageSuitesBundle coverageSuite,
127                                                                  final Function<Integer, Integer> newToOldConverter,
128                                                                  final Function<Integer, Integer> oldToNewConverter, boolean subCoverageActive) {
129     return myEngine.getLineMarkerRenderer(lineNumber, className, lines, coverageByTestApplicable, coverageSuite, newToOldConverter, oldToNewConverter, subCoverageActive);
130   }
131
132   public CoverageAnnotator getAnnotator(Project project) {
133     return myEngine.getCoverageAnnotator(project);
134   }
135
136   public CoverageSuite[] getSuites() {
137     return mySuites;
138   }
139
140   public boolean contains(CoverageSuite suite) {
141     return ArrayUtilRt.find(mySuites, suite) > -1;
142   }
143
144   public void setCoverageData(ProjectData projectData) {
145     myData = new SoftReference<ProjectData>(projectData);
146   }
147
148   public void restoreCoverageData() {
149     myData = new SoftReference<ProjectData>(null);
150   }
151
152   public String getPresentableName() {
153     return StringUtil.join(mySuites, coverageSuite -> coverageSuite.getPresentableName(), ", ");
154   }
155
156   public boolean isModuleChecked(final Module module) {
157     return myProcessedModules != null && myProcessedModules.contains(module);
158   }
159
160   public void checkModule(final Module module) {
161     if (myProcessedModules == null) {
162       myProcessedModules = new HashSet<Module>();
163     }
164     myProcessedModules.add(module);
165   }
166
167   @Nullable
168   public RunConfigurationBase getRunConfiguration() {
169     for (CoverageSuite suite : mySuites) {
170       if (suite instanceof BaseCoverageSuite) {
171         final RunConfigurationBase configuration = ((BaseCoverageSuite)suite).getConfiguration();
172         if (configuration != null) {
173           return configuration;
174         }
175       }
176     }
177     return null;
178   }
179
180   public GlobalSearchScope getSearchScope(final Project project) {
181     if (myCachedValue == null) {
182       myCachedValue = CachedValuesManager.getManager(project).createCachedValue(
183         () -> new CachedValueProvider.Result<GlobalSearchScope>(getSearchScopeInner(project), ProjectRootModificationTracker.getInstance(project)), false);
184     }
185     return myCachedValue.getValue();
186     
187   }
188
189   private GlobalSearchScope getSearchScopeInner(Project project) {
190     final RunConfigurationBase configuration = getRunConfiguration();
191     if (configuration instanceof ModuleBasedConfiguration) {
192       final Module module = ((ModuleBasedConfiguration)configuration).getConfigurationModule().getModule();
193       if (module != null) {
194         return GlobalSearchScope.moduleRuntimeScope(module, isTrackTestFolders());
195       }
196     }
197     return isTrackTestFolders() ? GlobalSearchScope.projectScope(project) : GlobalSearchScopesCore.projectProductionScope(project);
198   }
199 }