import org.sonar.api.platform.ComponentContainer;
import org.sonar.api.resources.Project;
import org.sonar.batch.scan.SensorWrapper;
+import org.sonar.batch.scan2.AnalyzerOptimizer;
import javax.annotation.Nullable;
private FileSystem fs;
private AnalyzerContext context;
+ private AnalyzerOptimizer analyzerOptimizer;
- public BatchExtensionDictionnary(ComponentContainer componentContainer, FileSystem fs, AnalyzerContext context) {
+ public BatchExtensionDictionnary(ComponentContainer componentContainer, FileSystem fs, AnalyzerContext context, AnalyzerOptimizer analyzerOptimizer) {
super(componentContainer);
this.fs = fs;
this.context = context;
+ this.analyzerOptimizer = analyzerOptimizer;
}
public <T> Collection<T> select(Class<T> type, @Nullable Project project, boolean sort, @Nullable ExtensionMatcher matcher) {
List<T> result = Lists.newArrayList();
for (Object extension : getExtensions(type)) {
if (type == Sensor.class && extension instanceof Analyzer) {
- extension = new SensorWrapper((Analyzer) extension, context, fs);
+ extension = new SensorWrapper((Analyzer) extension, context, fs, analyzerOptimizer);
}
if (shouldKeep(type, extension, project, matcher)) {
result.add((T) extension);
import org.sonar.batch.scan.filesystem.ProjectFileSystemAdapter;
import org.sonar.batch.scan.filesystem.StatusDetectionFactory;
import org.sonar.batch.scan.report.JsonReport;
+import org.sonar.batch.scan2.AnalyzerOptimizer;
import org.sonar.core.component.ScanPerspectives;
import org.sonar.core.measure.MeasurementFilters;
ProjectFileSystemAdapter.class,
QProfileVerifier.class,
+ AnalyzerOptimizer.class,
+
// the Snapshot component will be removed when asynchronous measures are improved (required for AsynchronousMeasureSensor)
getComponentByType(ResourcePersister.class).getSnapshot(module),
import org.sonar.api.batch.fs.FileSystem;
import org.sonar.api.batch.measures.Metric;
import org.sonar.api.resources.Project;
+import org.sonar.batch.scan2.AnalyzerOptimizer;
import java.util.Arrays;
import java.util.List;
private AnalyzerContext adaptor;
private FileSystem fs;
private DefaultAnalyzerDescriptor descriptor;
+ private AnalyzerOptimizer optimizer;
- public SensorWrapper(Analyzer analyzer, AnalyzerContext adaptor, FileSystem fs) {
+ public SensorWrapper(Analyzer analyzer, AnalyzerContext adaptor, FileSystem fs, AnalyzerOptimizer optimizer) {
this.analyzer = analyzer;
+ this.optimizer = optimizer;
descriptor = new DefaultAnalyzerDescriptor();
analyzer.describe(descriptor);
this.adaptor = adaptor;
@Override
public boolean shouldExecuteOnProject(Project project) {
- if (!descriptor.languages().isEmpty()) {
- if (project.getLanguageKey() != null && !descriptor.languages().contains(project.getLanguageKey())) {
- return false;
- }
- boolean hasFile = false;
- for (String languageKey : descriptor.languages()) {
- hasFile |= fs.hasFiles(fs.predicates().hasLanguage(languageKey));
- }
- if (!hasFile) {
- return false;
- }
- }
- return true;
+ return optimizer.shouldExecute(descriptor);
}
@Override
--- /dev/null
+/*
+ * SonarQube, open source software quality management tool.
+ * Copyright (C) 2008-2014 SonarSource
+ * mailto:contact AT sonarsource DOT com
+ *
+ * SonarQube is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * SonarQube is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+package org.sonar.batch.scan2;
+
+import org.sonar.api.BatchComponent;
+import org.sonar.api.batch.analyzer.internal.DefaultAnalyzerDescriptor;
+import org.sonar.api.batch.fs.FilePredicate;
+import org.sonar.api.batch.fs.FileSystem;
+
+public class AnalyzerOptimizer implements BatchComponent {
+
+ private FileSystem fs;
+
+ public AnalyzerOptimizer(FileSystem fs) {
+ this.fs = fs;
+ }
+
+ /**
+ * Decide if the given Analyzer should be executed.
+ */
+ public boolean shouldExecute(DefaultAnalyzerDescriptor descriptor) {
+ FilePredicate predicate = fs.predicates().hasLanguages(descriptor.languages());
+ if (descriptor.types().size() == 1) {
+ // Size = 0 or Size = 2 means both main and test type
+ predicate = fs.predicates().and(
+ predicate,
+ fs.predicates().hasType(descriptor.types().iterator().next()));
+ }
+ return fs.hasFiles(predicate);
+ }
+
+}
private static final Logger LOG = LoggerFactory.getLogger(AnalyzersExecutor.class);
private BatchExtensionDictionnary selector;
+ private AnalyzerOptimizer optimizer;
- public AnalyzersExecutor(BatchExtensionDictionnary selector) {
+ public AnalyzersExecutor(BatchExtensionDictionnary selector, AnalyzerOptimizer optimizer) {
this.selector = selector;
+ this.optimizer = optimizer;
}
public void execute(AnalyzerContext context) {
DefaultAnalyzerDescriptor descriptor = new DefaultAnalyzerDescriptor();
analyzer.describe(descriptor);
+ if (!optimizer.shouldExecute(descriptor)) {
+ LOG.debug("Analyzer skipped: " + descriptor.name());
+ continue;
+ }
+
LOG.info("Execute analyzer: " + descriptor.name());
executeSensor(context, analyzer);
ModuleFileSystemInitializer.class,
QProfileVerifier.class,
+ AnalyzerOptimizer.class,
+
DefaultAnalyzerContext.class,
BatchExtensionDictionnary.class,
IssueFilters.class,
*/
package org.sonar.batch.bootstrap;
-import org.sonar.api.batch.analyzer.AnalyzerContext;
-
import org.junit.Test;
import org.sonar.api.BatchExtension;
import org.sonar.api.batch.Sensor;
import org.sonar.api.batch.SensorContext;
+import org.sonar.api.batch.analyzer.AnalyzerContext;
import org.sonar.api.batch.fs.FileSystem;
import org.sonar.api.platform.ComponentContainer;
import org.sonar.api.resources.Project;
+import org.sonar.batch.scan2.AnalyzerOptimizer;
import java.util.Collection;
for (BatchExtension extension : extensions) {
iocContainer.addSingleton(extension);
}
- return new BatchExtensionDictionnary(iocContainer, mock(FileSystem.class), mock(AnalyzerContext.class));
+ return new BatchExtensionDictionnary(iocContainer, mock(FileSystem.class), mock(AnalyzerContext.class), mock(AnalyzerOptimizer.class));
}
@Test
return Arrays.asList(languages);
}
- public InputFile.Type[] types() {
- return types;
+ public Collection<InputFile.Type> types() {
+ return Arrays.asList(types);
}
@Override