aboutsummaryrefslogtreecommitdiffstats
path: root/sonar-batch/src
diff options
context:
space:
mode:
Diffstat (limited to 'sonar-batch/src')
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/highlighting/DefaultHighlightingBuilder.java52
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/highlighting/SyntaxHighlightingData.java (renamed from sonar-batch/src/main/java/org/sonar/batch/source/SyntaxHighlightingData.java)10
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/highlighting/SyntaxHighlightingDataBuilder.java (renamed from sonar-batch/src/main/java/org/sonar/batch/source/SyntaxHighlightingDataBuilder.java)9
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/highlighting/SyntaxHighlightingRule.java (renamed from sonar-batch/src/main/java/org/sonar/batch/source/SyntaxHighlightingRule.java)2
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/highlighting/package-info.java (renamed from sonar-batch/src/main/java/org/sonar/batch/source/DefaultSymbol.java)37
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/index/ComponentDataCache.java4
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/index/Data.java2
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/index/StringData.java5
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/mediumtest/BatchMediumTester.java69
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan/SensorContextAdaptor.java20
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan2/AnalysisPublisher.java11
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan2/AnalyzerOptimizer.java20
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultSensorContext.java19
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan2/ProjectScanContainer.java3
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/scan2/SensorsExecutor.java8
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/source/DefaultHighlightable.java19
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/source/DefaultSymbolTable.java51
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/source/DefaultSymbolizable.java5
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/source/HighlightableBuilder.java3
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/symbol/DefaultSymbolTableBuilder.java90
-rw-r--r--sonar-batch/src/main/java/org/sonar/batch/symbol/SymbolData.java (renamed from sonar-batch/src/main/java/org/sonar/batch/source/SymbolData.java)25
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/highlighting/DefaultHighlightingBuilderTest.java50
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/highlighting/SyntaxHighlightingDataBuilderTest.java (renamed from sonar-batch/src/test/java/org/sonar/batch/source/SyntaxHighlightingDataBuilderTest.java)3
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/highlighting/SyntaxHighlightingDataTest.java (renamed from sonar-batch/src/test/java/org/sonar/batch/source/SyntaxHighlightingDataTest.java)4
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/index/ComponentDataCacheTest.java4
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/mediumtest/highlighting/HighlightingMediumTest.java92
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/mediumtest/symbol/SymbolMediumTest.java87
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/plugin/XooPlugin.java4
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/plugin/lang/MeasureSensor.java2
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/plugin/lang/SymbolReferencesSensor.java98
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/plugin/lang/SyntaxHighlightingSensor.java95
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/scan/SensorContextAdapterTest.java4
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/source/DefaultHighlightableTest.java13
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/source/DefaultSymbolTableTest.java8
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/source/SymbolDataTest.java60
-rw-r--r--sonar-batch/src/test/java/org/sonar/batch/symbol/DefaultSymbolTableBuilderTest.java108
36 files changed, 899 insertions, 197 deletions
diff --git a/sonar-batch/src/main/java/org/sonar/batch/highlighting/DefaultHighlightingBuilder.java b/sonar-batch/src/main/java/org/sonar/batch/highlighting/DefaultHighlightingBuilder.java
new file mode 100644
index 00000000000..786ad0cca68
--- /dev/null
+++ b/sonar-batch/src/main/java/org/sonar/batch/highlighting/DefaultHighlightingBuilder.java
@@ -0,0 +1,52 @@
+/*
+ * 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.highlighting;
+
+import com.google.common.base.Preconditions;
+import org.sonar.api.batch.sensor.highlighting.HighlightingBuilder;
+import org.sonar.batch.index.ComponentDataCache;
+import org.sonar.core.source.SnapshotDataTypes;
+
+public class DefaultHighlightingBuilder implements HighlightingBuilder {
+
+ private final SyntaxHighlightingDataBuilder builder;
+ private String componentKey;
+ private ComponentDataCache cache;
+ private boolean done = false;
+
+ public DefaultHighlightingBuilder(String componentKey, ComponentDataCache cache) {
+ this.componentKey = componentKey;
+ this.cache = cache;
+ this.builder = new SyntaxHighlightingDataBuilder();
+ }
+
+ @Override
+ public HighlightingBuilder highlight(int startOffset, int endOffset, TypeOfText typeOfText) {
+ Preconditions.checkState(!done, "done() already called");
+ builder.registerHighlightingRule(startOffset, endOffset, typeOfText.cssClass());
+ return this;
+ }
+
+ @Override
+ public void done() {
+ Preconditions.checkState(!done, "done() already called");
+ cache.setData(componentKey, SnapshotDataTypes.SYNTAX_HIGHLIGHTING, builder.build());
+ }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/source/SyntaxHighlightingData.java b/sonar-batch/src/main/java/org/sonar/batch/highlighting/SyntaxHighlightingData.java
index cf0dde3580f..56c9b795ac9 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/source/SyntaxHighlightingData.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/highlighting/SyntaxHighlightingData.java
@@ -17,7 +17,7 @@
* 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.source;
+package org.sonar.batch.highlighting;
import org.sonar.batch.index.Data;
@@ -34,6 +34,10 @@ public class SyntaxHighlightingData implements Data {
this.syntaxHighlightingRuleSet = syntaxHighlightingRuleSet;
}
+ public List<SyntaxHighlightingRule> syntaxHighlightingRuleSet() {
+ return syntaxHighlightingRuleSet;
+ }
+
@Override
public String writeString() {
StringBuilder sb = new StringBuilder();
@@ -51,8 +55,4 @@ public class SyntaxHighlightingData implements Data {
return sb.toString();
}
- @Override
- public void readString(String s) {
- throw new UnsupportedOperationException();
- }
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/source/SyntaxHighlightingDataBuilder.java b/sonar-batch/src/main/java/org/sonar/batch/highlighting/SyntaxHighlightingDataBuilder.java
index 58dbd717a58..38ae875af98 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/source/SyntaxHighlightingDataBuilder.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/highlighting/SyntaxHighlightingDataBuilder.java
@@ -17,7 +17,7 @@
* 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.source;
+package org.sonar.batch.highlighting;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Predicate;
@@ -26,6 +26,7 @@ import com.google.common.collect.Ordering;
import org.slf4j.LoggerFactory;
import javax.annotation.Nullable;
+
import java.util.Collection;
import java.util.List;
@@ -83,11 +84,11 @@ public class SyntaxHighlightingDataBuilder {
}
@VisibleForTesting
- protected List<SyntaxHighlightingRule> getSortedRules() {
+ public List<SyntaxHighlightingRule> getSortedRules() {
Ordering<SyntaxHighlightingRule> ruleOrdering = new Ordering<SyntaxHighlightingRule>() {
@Override
public int compare(@Nullable SyntaxHighlightingRule left,
- @Nullable SyntaxHighlightingRule right) {
+ @Nullable SyntaxHighlightingRule right) {
int result;
if (left != null && right != null) {
result = left.getStartPosition() - right.getStartPosition();
@@ -100,6 +101,6 @@ public class SyntaxHighlightingDataBuilder {
}
};
- return ruleOrdering.immutableSortedCopy(syntaxHighlightingRuleSet);
+ return ruleOrdering.sortedCopy(syntaxHighlightingRuleSet);
}
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/source/SyntaxHighlightingRule.java b/sonar-batch/src/main/java/org/sonar/batch/highlighting/SyntaxHighlightingRule.java
index d8232c1ba9d..08985752d60 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/source/SyntaxHighlightingRule.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/highlighting/SyntaxHighlightingRule.java
@@ -17,7 +17,7 @@
* 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.source;
+package org.sonar.batch.highlighting;
import java.io.Serializable;
diff --git a/sonar-batch/src/main/java/org/sonar/batch/source/DefaultSymbol.java b/sonar-batch/src/main/java/org/sonar/batch/highlighting/package-info.java
index 629633a05de..93b92f3e9ae 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/source/DefaultSymbol.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/highlighting/package-info.java
@@ -17,38 +17,7 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+@ParametersAreNonnullByDefault
+package org.sonar.batch.highlighting;
-package org.sonar.batch.source;
-
-import com.google.common.base.Objects;
-import org.sonar.api.source.Symbol;
-
-public class DefaultSymbol implements Symbol {
-
- private final int declarationStartOffset;
- private final int declarationEndOffset;
-
- public DefaultSymbol(int startOffset, int endOffset) {
- this.declarationStartOffset = startOffset;
- this.declarationEndOffset = endOffset;
- }
-
- public int getDeclarationStartOffset() {
- return declarationStartOffset;
- }
-
- public int getDeclarationEndOffset() {
- return declarationEndOffset;
- }
-
- public String getFullyQualifiedName() {
- return null;
- }
-
- @Override
- public String toString() {
- return Objects.toStringHelper("Symbol")
- .add("offset", String.format("%d-%d", declarationStartOffset, declarationEndOffset))
- .toString();
- }
-}
+import javax.annotation.ParametersAreNonnullByDefault;
diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/ComponentDataCache.java b/sonar-batch/src/main/java/org/sonar/batch/index/ComponentDataCache.java
index 16be9501117..0523212bf75 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/index/ComponentDataCache.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/index/ComponentDataCache.java
@@ -21,6 +21,8 @@ package org.sonar.batch.index;
import org.sonar.api.BatchComponent;
+import javax.annotation.CheckForNull;
+
public class ComponentDataCache implements BatchComponent {
private final Cache cache;
@@ -37,10 +39,12 @@ public class ComponentDataCache implements BatchComponent {
return setData(componentKey, dataType, new StringData(data));
}
+ @CheckForNull
public <D extends Data> D getData(String componentKey, String dataType) {
return (D) cache.get(componentKey, dataType);
}
+ @CheckForNull
public String getStringData(String componentKey, String dataType) {
Data data = (Data) cache.get(componentKey, dataType);
return data == null ? null : ((StringData) data).data();
diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/Data.java b/sonar-batch/src/main/java/org/sonar/batch/index/Data.java
index 66e5b596fc4..aa47c04e799 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/index/Data.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/index/Data.java
@@ -25,6 +25,4 @@ public interface Data extends Serializable {
String writeString();
- void readString(String s);
-
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/index/StringData.java b/sonar-batch/src/main/java/org/sonar/batch/index/StringData.java
index 17605657112..6a88b5979b2 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/index/StringData.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/index/StringData.java
@@ -37,9 +37,4 @@ public class StringData implements Data {
public String writeString() {
return data;
}
-
- @Override
- public void readString(String s) {
- this.data = s;
- }
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/mediumtest/BatchMediumTester.java b/sonar-batch/src/main/java/org/sonar/batch/mediumtest/BatchMediumTester.java
index c3aa2646c6c..c305474b7f2 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/mediumtest/BatchMediumTester.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/mediumtest/BatchMediumTester.java
@@ -20,14 +20,19 @@
package org.sonar.batch.mediumtest;
import org.apache.commons.io.IOUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.sonar.api.SonarPlugin;
import org.sonar.api.batch.bootstrap.ProjectReactor;
import org.sonar.api.batch.debt.internal.DefaultDebtModel;
import org.sonar.api.batch.fs.InputDir;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.InputPath;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.sensor.highlighting.HighlightingBuilder;
import org.sonar.api.batch.sensor.issue.Issue;
import org.sonar.api.batch.sensor.measure.Measure;
+import org.sonar.api.batch.sensor.symbol.Symbol;
import org.sonar.api.config.Settings;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.Metric;
@@ -36,6 +41,9 @@ import org.sonar.api.resources.Languages;
import org.sonar.batch.bootstrap.PluginsReferential;
import org.sonar.batch.bootstrapper.Batch;
import org.sonar.batch.bootstrapper.EnvironmentInformation;
+import org.sonar.batch.highlighting.SyntaxHighlightingData;
+import org.sonar.batch.highlighting.SyntaxHighlightingRule;
+import org.sonar.batch.index.ComponentDataCache;
import org.sonar.batch.protocol.input.ActiveRule;
import org.sonar.batch.protocol.input.GlobalReferentials;
import org.sonar.batch.protocol.input.ProjectReferentials;
@@ -47,8 +55,12 @@ import org.sonar.batch.scan2.AnalyzerMeasureCache;
import org.sonar.batch.scan2.ProjectScanContainer;
import org.sonar.batch.scan2.ScanTaskObserver;
import org.sonar.batch.settings.SettingsReferential;
+import org.sonar.batch.symbol.SymbolData;
import org.sonar.core.plugins.DefaultPluginMetadata;
import org.sonar.core.plugins.RemotePlugin;
+import org.sonar.core.source.SnapshotDataTypes;
+
+import javax.annotation.CheckForNull;
import java.io.File;
import java.io.FileReader;
@@ -59,6 +71,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
+import java.util.Set;
public class BatchMediumTester {
@@ -200,13 +213,19 @@ public class BatchMediumTester {
}
public static class TaskResult implements ScanTaskObserver {
+
+ private static final Logger LOG = LoggerFactory.getLogger(BatchMediumTester.TaskResult.class);
+
private List<Issue> issues = new ArrayList<Issue>();
private List<Measure> measures = new ArrayList<Measure>();
private List<InputFile> inputFiles = new ArrayList<InputFile>();
private List<InputDir> inputDirs = new ArrayList<InputDir>();
+ private Map<InputFile, SyntaxHighlightingData> highlightingPerFile = new HashMap<InputFile, SyntaxHighlightingData>();
+ private Map<InputFile, SymbolData> symbolTablePerFile = new HashMap<InputFile, SymbolData>();
@Override
public void scanTaskCompleted(ProjectScanContainer container) {
+ LOG.info("Store analysis results in memory for later assertions in medium test");
for (Issue issue : container.getComponentByType(AnalyzerIssueCache.class).all()) {
issues.add(issue);
}
@@ -223,6 +242,19 @@ public class BatchMediumTester {
inputDirs.add((InputDir) inputPath);
}
}
+
+ ComponentDataCache componentDataCache = container.getComponentByType(ComponentDataCache.class);
+ for (InputFile file : inputFiles) {
+ SyntaxHighlightingData highlighting = componentDataCache.getData(((DefaultInputFile) file).key(), SnapshotDataTypes.SYNTAX_HIGHLIGHTING);
+ if (highlighting != null) {
+ highlightingPerFile.put(file, highlighting);
+ }
+ SymbolData symbolTable = componentDataCache.getData(((DefaultInputFile) file).key(), SnapshotDataTypes.SYMBOL_HIGHLIGHTING);
+ if (symbolTable != null) {
+ symbolTablePerFile.put(file, symbolTable);
+ }
+ }
+
}
public List<Issue> issues() {
@@ -240,6 +272,43 @@ public class BatchMediumTester {
public List<InputDir> inputDirs() {
return inputDirs;
}
+
+ /**
+ * Get highlighting type at a given position in an inputfile
+ * @param charIndex 0-based offset in file
+ */
+ @CheckForNull
+ public HighlightingBuilder.TypeOfText highlightingTypeFor(InputFile file, int charIndex) {
+ SyntaxHighlightingData syntaxHighlightingData = highlightingPerFile.get(file);
+ if (syntaxHighlightingData == null) {
+ return null;
+ }
+ for (SyntaxHighlightingRule sortedRule : syntaxHighlightingData.syntaxHighlightingRuleSet()) {
+ if (sortedRule.getStartPosition() <= charIndex && sortedRule.getEndPosition() > charIndex) {
+ return HighlightingBuilder.TypeOfText.forCssClass(sortedRule.getTextType());
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Get list of all positions of a symbol in an inputfile
+ * @param symbolStartOffset 0-based start offset for the symbol in file
+ * @param symbolEndOffset 0-based end offset for the symbol in file
+ */
+ @CheckForNull
+ public Set<Integer> symbolReferencesFor(InputFile file, int symbolStartOffset, int symbolEndOffset) {
+ SymbolData data = symbolTablePerFile.get(file);
+ if (data == null) {
+ return null;
+ }
+ for (Symbol symbol : data.referencesBySymbol().keySet()) {
+ if (symbol.getDeclarationStartOffset() == symbolStartOffset && symbol.getDeclarationEndOffset() == symbolEndOffset) {
+ return data.referencesBySymbol().get(symbol);
+ }
+ }
+ return null;
+ }
}
private static class FakeGlobalReferentialsLoader implements GlobalReferentialsLoader {
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan/SensorContextAdaptor.java b/sonar-batch/src/main/java/org/sonar/batch/scan/SensorContextAdaptor.java
index a0c99598d31..1de8fd7201c 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/scan/SensorContextAdaptor.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/scan/SensorContextAdaptor.java
@@ -23,15 +23,18 @@ import org.sonar.api.batch.fs.FileSystem;
import org.sonar.api.batch.fs.InputDir;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.fs.InputPath;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.measure.Metric;
import org.sonar.api.batch.rule.ActiveRules;
import org.sonar.api.batch.sensor.SensorContext;
+import org.sonar.api.batch.sensor.highlighting.HighlightingBuilder;
import org.sonar.api.batch.sensor.issue.Issue;
import org.sonar.api.batch.sensor.issue.IssueBuilder;
import org.sonar.api.batch.sensor.issue.internal.DefaultIssueBuilder;
import org.sonar.api.batch.sensor.measure.Measure;
import org.sonar.api.batch.sensor.measure.MeasureBuilder;
import org.sonar.api.batch.sensor.measure.internal.DefaultMeasureBuilder;
+import org.sonar.api.batch.sensor.symbol.SymbolTableBuilder;
import org.sonar.api.component.ResourcePerspectives;
import org.sonar.api.config.Settings;
import org.sonar.api.issue.Issuable;
@@ -46,6 +49,9 @@ import org.sonar.api.resources.Project;
import org.sonar.api.resources.Resource;
import org.sonar.api.resources.Scopes;
import org.sonar.api.rule.RuleKey;
+import org.sonar.batch.highlighting.DefaultHighlightingBuilder;
+import org.sonar.batch.index.ComponentDataCache;
+import org.sonar.batch.symbol.DefaultSymbolTableBuilder;
import java.io.Serializable;
@@ -62,9 +68,10 @@ public class SensorContextAdaptor implements SensorContext {
private Settings settings;
private FileSystem fs;
private ActiveRules activeRules;
+ private ComponentDataCache componentDataCache;
public SensorContextAdaptor(org.sonar.api.batch.SensorContext sensorContext, MetricFinder metricFinder, Project project, ResourcePerspectives perspectives,
- Settings settings, FileSystem fs, ActiveRules activeRules) {
+ Settings settings, FileSystem fs, ActiveRules activeRules, ComponentDataCache componentDataCache) {
this.sensorContext = sensorContext;
this.metricFinder = metricFinder;
this.project = project;
@@ -72,6 +79,7 @@ public class SensorContextAdaptor implements SensorContext {
this.settings = settings;
this.fs = fs;
this.activeRules = activeRules;
+ this.componentDataCache = componentDataCache;
}
@Override
@@ -236,4 +244,14 @@ public class SensorContextAdaptor implements SensorContext {
.build();
}
+ @Override
+ public HighlightingBuilder highlightingBuilder(InputFile inputFile) {
+ return new DefaultHighlightingBuilder(((DefaultInputFile) inputFile).key(), componentDataCache);
+ }
+
+ @Override
+ public SymbolTableBuilder symbolTableBuilder(InputFile inputFile) {
+ return new DefaultSymbolTableBuilder(((DefaultInputFile) inputFile).key(), componentDataCache);
+ }
+
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan2/AnalysisPublisher.java b/sonar-batch/src/main/java/org/sonar/batch/scan2/AnalysisPublisher.java
index 757f320f559..7fb7dacf375 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/scan2/AnalysisPublisher.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/scan2/AnalysisPublisher.java
@@ -44,9 +44,11 @@ public final class AnalysisPublisher {
private final FileSystem fs;
private final AnalyzerMeasureCache measureCache;
private final ProjectDefinition def;
- private AnalyzerIssueCache issueCache;
+ private final AnalyzerIssueCache issueCache;
- public AnalysisPublisher(ProjectDefinition def, Settings settings, FileSystem fs, AnalyzerMeasureCache measureCache, AnalyzerIssueCache analyzerIssueCache) {
+ public AnalysisPublisher(ProjectDefinition def, Settings settings, FileSystem fs,
+ AnalyzerMeasureCache measureCache,
+ AnalyzerIssueCache analyzerIssueCache) {
this.def = def;
this.settings = settings;
this.fs = fs;
@@ -132,8 +134,9 @@ public final class AnalysisPublisher {
for (Measure<?> measure : measureCache.byModule(def.getKey())) {
jsonWriter.beginObject()
.prop("metricKey", measure.metric().key());
- if (measure.inputFile() != null) {
- jsonWriter.prop("filePath", measure.inputFile().relativePath());
+ InputFile inputFile = measure.inputFile();
+ if (inputFile != null) {
+ jsonWriter.prop("filePath", inputFile.relativePath());
}
jsonWriter.prop("value", String.valueOf(measure.value()))
.endObject();
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan2/AnalyzerOptimizer.java b/sonar-batch/src/main/java/org/sonar/batch/scan2/AnalyzerOptimizer.java
index fb461854c69..4ae3ddfce09 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/scan2/AnalyzerOptimizer.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/scan2/AnalyzerOptimizer.java
@@ -19,16 +19,19 @@
*/
package org.sonar.batch.scan2;
-import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor;
-
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.sonar.api.BatchComponent;
import org.sonar.api.batch.fs.FilePredicate;
import org.sonar.api.batch.fs.FileSystem;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.rule.ActiveRules;
+import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor;
public class AnalyzerOptimizer implements BatchComponent {
+ private static final Logger LOG = LoggerFactory.getLogger(AnalyzerOptimizer.class);
+
private final FileSystem fs;
private final ActiveRules activeRules;
@@ -41,10 +44,15 @@ public class AnalyzerOptimizer implements BatchComponent {
* Decide if the given Analyzer should be executed.
*/
public boolean shouldExecute(DefaultSensorDescriptor descriptor) {
- // FS Conditions
- boolean fsCondition = fsCondition(descriptor);
- boolean activeRulesCondition = activeRulesCondition(descriptor);
- return fsCondition && activeRulesCondition;
+ if (!fsCondition(descriptor)) {
+ LOG.debug("'{}' skipped because there is no related file in current project", descriptor.name());
+ return false;
+ }
+ if (!activeRulesCondition(descriptor)) {
+ LOG.debug("'{}' skipped because there is no related rule activated in the quality profile", descriptor.name());
+ return false;
+ }
+ return true;
}
private boolean activeRulesCondition(DefaultSensorDescriptor descriptor) {
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultSensorContext.java b/sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultSensorContext.java
index 6f4b2bdec70..dcd6efd1ca4 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultSensorContext.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultSensorContext.java
@@ -23,10 +23,12 @@ import com.google.common.base.Strings;
import org.sonar.api.batch.bootstrap.ProjectDefinition;
import org.sonar.api.batch.fs.FileSystem;
import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.measure.Metric;
import org.sonar.api.batch.rule.ActiveRules;
import org.sonar.api.batch.rule.internal.DefaultActiveRule;
import org.sonar.api.batch.sensor.SensorContext;
+import org.sonar.api.batch.sensor.highlighting.HighlightingBuilder;
import org.sonar.api.batch.sensor.issue.Issue;
import org.sonar.api.batch.sensor.issue.IssueBuilder;
import org.sonar.api.batch.sensor.issue.internal.DefaultIssue;
@@ -35,11 +37,15 @@ import org.sonar.api.batch.sensor.measure.Measure;
import org.sonar.api.batch.sensor.measure.MeasureBuilder;
import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
import org.sonar.api.batch.sensor.measure.internal.DefaultMeasureBuilder;
+import org.sonar.api.batch.sensor.symbol.SymbolTableBuilder;
import org.sonar.api.config.Settings;
import org.sonar.api.rule.RuleKey;
import org.sonar.api.utils.MessageException;
+import org.sonar.batch.highlighting.DefaultHighlightingBuilder;
+import org.sonar.batch.index.ComponentDataCache;
import org.sonar.batch.issue.IssueFilters;
import org.sonar.batch.scan.SensorContextAdaptor;
+import org.sonar.batch.symbol.DefaultSymbolTableBuilder;
import org.sonar.core.component.ComponentKeys;
import java.io.Serializable;
@@ -53,9 +59,10 @@ public class DefaultSensorContext implements SensorContext {
private final FileSystem fs;
private final ActiveRules activeRules;
private final IssueFilters issueFilters;
+ private final ComponentDataCache componentDataCache;
public DefaultSensorContext(ProjectDefinition def, AnalyzerMeasureCache measureCache, AnalyzerIssueCache issueCache,
- Settings settings, FileSystem fs, ActiveRules activeRules, IssueFilters issueFilters) {
+ Settings settings, FileSystem fs, ActiveRules activeRules, IssueFilters issueFilters, ComponentDataCache componentDataCache) {
this.def = def;
this.measureCache = measureCache;
this.issueCache = issueCache;
@@ -63,6 +70,7 @@ public class DefaultSensorContext implements SensorContext {
this.fs = fs;
this.activeRules = activeRules;
this.issueFilters = issueFilters;
+ this.componentDataCache = componentDataCache;
}
@Override
@@ -155,7 +163,16 @@ public class DefaultSensorContext implements SensorContext {
if (issue.severity() == null) {
issue.setSeverity(activeRule.severity());
}
+ }
+ @Override
+ public HighlightingBuilder highlightingBuilder(InputFile inputFile) {
+ return new DefaultHighlightingBuilder(((DefaultInputFile) inputFile).key(), componentDataCache);
+ }
+
+ @Override
+ public SymbolTableBuilder symbolTableBuilder(InputFile inputFile) {
+ return new DefaultSymbolTableBuilder(((DefaultInputFile) inputFile).key(), componentDataCache);
}
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan2/ProjectScanContainer.java b/sonar-batch/src/main/java/org/sonar/batch/scan2/ProjectScanContainer.java
index b0738e420e4..e13fca37d28 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/scan2/ProjectScanContainer.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/scan2/ProjectScanContainer.java
@@ -34,6 +34,7 @@ import org.sonar.batch.bootstrap.ExtensionInstaller;
import org.sonar.batch.bootstrap.ExtensionMatcher;
import org.sonar.batch.bootstrap.ExtensionUtils;
import org.sonar.batch.index.Caches;
+import org.sonar.batch.index.ComponentDataCache;
import org.sonar.batch.languages.DefaultLanguagesReferential;
import org.sonar.batch.profiling.PhasesSumUpTimeProfiler;
import org.sonar.batch.referential.DefaultProjectReferentialsLoader;
@@ -104,6 +105,8 @@ public class ProjectScanContainer extends ComponentContainer {
// issues
AnalyzerIssueCache.class,
+ ComponentDataCache.class,
+
ScanTaskObservers.class);
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/scan2/SensorsExecutor.java b/sonar-batch/src/main/java/org/sonar/batch/scan2/SensorsExecutor.java
index 14b6326b150..d437eadb6fd 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/scan2/SensorsExecutor.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/scan2/SensorsExecutor.java
@@ -19,13 +19,12 @@
*/
package org.sonar.batch.scan2;
-import org.sonar.api.batch.sensor.Sensor;
-import org.sonar.api.batch.sensor.SensorContext;
-import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.BatchComponent;
+import org.sonar.api.batch.sensor.Sensor;
+import org.sonar.api.batch.sensor.SensorContext;
+import org.sonar.api.batch.sensor.internal.DefaultSensorDescriptor;
import org.sonar.batch.bootstrap.BatchExtensionDictionnary;
import java.util.Collection;
@@ -51,7 +50,6 @@ public class SensorsExecutor implements BatchComponent {
analyzer.describe(descriptor);
if (!optimizer.shouldExecute(descriptor)) {
- LOG.debug("Analyzer skipped: " + descriptor.name());
continue;
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/source/DefaultHighlightable.java b/sonar-batch/src/main/java/org/sonar/batch/source/DefaultHighlightable.java
index 249450fad15..5b15a3abcd8 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/source/DefaultHighlightable.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/source/DefaultHighlightable.java
@@ -21,12 +21,15 @@ package org.sonar.batch.source;
import org.sonar.api.component.Component;
import org.sonar.api.source.Highlightable;
+import org.sonar.batch.highlighting.SyntaxHighlightingDataBuilder;
import org.sonar.batch.index.ComponentDataCache;
import org.sonar.core.source.SnapshotDataTypes;
/**
* @since 3.6
+ * @deprecated since 4.5 no more used in batch 2.0
*/
+@Deprecated
public class DefaultHighlightable implements Highlightable {
private final Component component;
@@ -41,7 +44,7 @@ public class DefaultHighlightable implements Highlightable {
@Override
public HighlightingBuilder newHighlighting() {
- return new DefaultHighlightingBuilder();
+ return new DefaultHighlightingBuilder(component.key(), cache, builder);
}
@Override
@@ -53,7 +56,17 @@ public class DefaultHighlightable implements Highlightable {
return builder;
}
- private class DefaultHighlightingBuilder implements HighlightingBuilder {
+ private static class DefaultHighlightingBuilder implements HighlightingBuilder {
+
+ private final SyntaxHighlightingDataBuilder builder;
+ private String componentKey;
+ private ComponentDataCache cache;
+
+ public DefaultHighlightingBuilder(String componentKey, ComponentDataCache cache, SyntaxHighlightingDataBuilder builder) {
+ this.componentKey = componentKey;
+ this.cache = cache;
+ this.builder = builder;
+ }
@Override
public HighlightingBuilder highlight(int startOffset, int endOffset, String typeOfText) {
@@ -63,7 +76,7 @@ public class DefaultHighlightable implements Highlightable {
@Override
public void done() {
- cache.setStringData(component().key(), SnapshotDataTypes.SYNTAX_HIGHLIGHTING, builder.build().writeString());
+ cache.setData(componentKey, SnapshotDataTypes.SYNTAX_HIGHLIGHTING, builder.build());
}
}
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/source/DefaultSymbolTable.java b/sonar-batch/src/main/java/org/sonar/batch/source/DefaultSymbolTable.java
index 0d66c31b8f1..ee8997c259c 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/source/DefaultSymbolTable.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/source/DefaultSymbolTable.java
@@ -20,35 +20,35 @@
package org.sonar.batch.source;
-import com.google.common.collect.Multimap;
+import com.google.common.collect.SortedSetMultimap;
import com.google.common.collect.TreeMultimap;
+import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbol;
import org.sonar.api.source.Symbol;
import org.sonar.api.source.Symbolizable;
+import org.sonar.batch.symbol.DefaultSymbolTableBuilder;
-import java.io.Serializable;
import java.util.ArrayList;
-import java.util.Comparator;
import java.util.List;
public class DefaultSymbolTable implements Symbolizable.SymbolTable {
- private Multimap<Symbol, Integer> referencesBySymbol;
+ private SortedSetMultimap<org.sonar.api.batch.sensor.symbol.Symbol, Integer> referencesBySymbol;
- private DefaultSymbolTable(Multimap<Symbol, Integer> referencesBySymbol) {
+ private DefaultSymbolTable(SortedSetMultimap<org.sonar.api.batch.sensor.symbol.Symbol, Integer> referencesBySymbol) {
this.referencesBySymbol = referencesBySymbol;
}
- public static Builder builder() {
- return new Builder();
- }
-
- public Multimap<Symbol, Integer> getReferencesBySymbol() {
+ public SortedSetMultimap<org.sonar.api.batch.sensor.symbol.Symbol, Integer> getReferencesBySymbol() {
return referencesBySymbol;
}
@Override
public List<Symbol> symbols() {
- return new ArrayList<Symbol>(referencesBySymbol.keySet());
+ List<Symbol> result = new ArrayList<Symbol>();
+ for (org.sonar.api.batch.sensor.symbol.Symbol symbol : referencesBySymbol.keySet()) {
+ result.add((Symbol) symbol);
+ }
+ return result;
}
@Override
@@ -58,15 +58,17 @@ public class DefaultSymbolTable implements Symbolizable.SymbolTable {
public static class Builder implements Symbolizable.SymbolTableBuilder {
- private final Multimap<Symbol, Integer> referencesBySymbol;
+ private final SortedSetMultimap<org.sonar.api.batch.sensor.symbol.Symbol, Integer> referencesBySymbol;
+ private final String componentKey;
- public Builder() {
- referencesBySymbol = TreeMultimap.create(new SymbolComparator(), new ReferenceComparator());
+ public Builder(String componentKey) {
+ this.componentKey = componentKey;
+ referencesBySymbol = TreeMultimap.create(new DefaultSymbolTableBuilder.SymbolComparator(), new DefaultSymbolTableBuilder.ReferenceComparator());
}
@Override
public Symbol newSymbol(int fromOffset, int toOffset) {
- Symbol symbol = new DefaultSymbol(fromOffset, toOffset);
+ Symbol symbol = new DefaultSymbol(componentKey, fromOffset, toOffset);
referencesBySymbol.put(symbol, symbol.getDeclarationStartOffset());
return symbol;
}
@@ -84,24 +86,5 @@ public class DefaultSymbolTable implements Symbolizable.SymbolTable {
return new DefaultSymbolTable(referencesBySymbol);
}
- private static class SymbolComparator implements Comparator<Symbol>, Serializable {
- @Override
- public int compare(Symbol left, Symbol right) {
- return left.getDeclarationStartOffset() - right.getDeclarationStartOffset();
- }
- }
-
- private static class ReferenceComparator implements Comparator<Integer>, Serializable {
- @Override
- public int compare(Integer left, Integer right) {
- int result;
- if (left != null & right != null) {
- result = left - right;
- } else {
- result = left == null ? -1 : 1;
- }
- return result;
- }
- }
}
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/source/DefaultSymbolizable.java b/sonar-batch/src/main/java/org/sonar/batch/source/DefaultSymbolizable.java
index 1e3b33d939e..de073e50629 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/source/DefaultSymbolizable.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/source/DefaultSymbolizable.java
@@ -23,6 +23,7 @@ package org.sonar.batch.source;
import org.sonar.api.component.Component;
import org.sonar.api.source.Symbolizable;
import org.sonar.batch.index.ComponentDataCache;
+import org.sonar.batch.symbol.SymbolData;
import org.sonar.core.source.SnapshotDataTypes;
public class DefaultSymbolizable implements Symbolizable {
@@ -42,12 +43,12 @@ public class DefaultSymbolizable implements Symbolizable {
@Override
public SymbolTableBuilder newSymbolTableBuilder() {
- return new DefaultSymbolTable.Builder();
+ return new DefaultSymbolTable.Builder(component.key());
}
@Override
public void setSymbolTable(SymbolTable symbolTable) {
- SymbolData symbolData = new SymbolData(symbolTable);
+ SymbolData symbolData = new SymbolData(((DefaultSymbolTable) symbolTable).getReferencesBySymbol());
cache.setStringData(component().key(), SnapshotDataTypes.SYMBOL_HIGHLIGHTING, symbolData.writeString());
}
}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/source/HighlightableBuilder.java b/sonar-batch/src/main/java/org/sonar/batch/source/HighlightableBuilder.java
index 82f5c8dd213..d20fbebb147 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/source/HighlightableBuilder.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/source/HighlightableBuilder.java
@@ -28,11 +28,14 @@ import org.sonar.core.component.PerspectiveBuilder;
import org.sonar.core.component.ResourceComponent;
import javax.annotation.CheckForNull;
+
import java.util.Set;
/**
* @since 3.6
+ * @deprecated since 4.5 no more used in batch 2.0
*/
+@Deprecated
public class HighlightableBuilder extends PerspectiveBuilder<Highlightable> {
private static final Set<String> SUPPORTED_QUALIFIERS = ImmutableSet.of(Qualifiers.FILE, Qualifiers.UNIT_TEST_FILE);
diff --git a/sonar-batch/src/main/java/org/sonar/batch/symbol/DefaultSymbolTableBuilder.java b/sonar-batch/src/main/java/org/sonar/batch/symbol/DefaultSymbolTableBuilder.java
new file mode 100644
index 00000000000..ed347e60bd0
--- /dev/null
+++ b/sonar-batch/src/main/java/org/sonar/batch/symbol/DefaultSymbolTableBuilder.java
@@ -0,0 +1,90 @@
+/*
+ * 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.symbol;
+
+import com.google.common.collect.SortedSetMultimap;
+import com.google.common.collect.TreeMultimap;
+import org.sonar.api.batch.sensor.symbol.Symbol;
+import org.sonar.api.batch.sensor.symbol.SymbolTableBuilder;
+import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbol;
+import org.sonar.batch.index.ComponentDataCache;
+import org.sonar.core.source.SnapshotDataTypes;
+
+import java.io.Serializable;
+import java.util.Comparator;
+
+public class DefaultSymbolTableBuilder implements SymbolTableBuilder {
+
+ private final String componentKey;
+ private final ComponentDataCache cache;
+ private final SortedSetMultimap<Symbol, Integer> referencesBySymbol;
+
+ public DefaultSymbolTableBuilder(String componentKey, ComponentDataCache cache) {
+ this.componentKey = componentKey;
+ this.cache = cache;
+ this.referencesBySymbol = TreeMultimap.create(new SymbolComparator(), new ReferenceComparator());
+ }
+
+ @Override
+ public Symbol newSymbol(int fromOffset, int toOffset) {
+ Symbol symbol = new DefaultSymbol(componentKey, fromOffset, toOffset);
+ referencesBySymbol.put(symbol, symbol.getDeclarationStartOffset());
+ return symbol;
+ }
+
+ @Override
+ public void newReference(Symbol symbol, int fromOffset) {
+ String otherComponentKey = ((DefaultSymbol) symbol).componentKey();
+ if (!otherComponentKey.equals(componentKey)) {
+ throw new UnsupportedOperationException("Cannot add reference from (" + componentKey + ") to another file (" + otherComponentKey + ")");
+ }
+ if (fromOffset >= symbol.getDeclarationStartOffset() && fromOffset < symbol.getDeclarationEndOffset()) {
+ throw new UnsupportedOperationException("Cannot add reference (" + fromOffset + ") overlapping " + symbol);
+ }
+ referencesBySymbol.put(symbol, fromOffset);
+ }
+
+ @Override
+ public void done() {
+ SymbolData symbolData = new SymbolData(referencesBySymbol);
+ cache.setData(componentKey, SnapshotDataTypes.SYMBOL_HIGHLIGHTING, symbolData);
+ }
+
+ public static class SymbolComparator implements Comparator<Symbol>, Serializable {
+ @Override
+ public int compare(Symbol left, Symbol right) {
+ return left.getDeclarationStartOffset() - right.getDeclarationStartOffset();
+ }
+ }
+
+ public static class ReferenceComparator implements Comparator<Integer>, Serializable {
+ @Override
+ public int compare(Integer left, Integer right) {
+ int result;
+ if (left != null & right != null) {
+ result = left - right;
+ } else {
+ result = left == null ? -1 : 1;
+ }
+ return result;
+ }
+ }
+}
diff --git a/sonar-batch/src/main/java/org/sonar/batch/source/SymbolData.java b/sonar-batch/src/main/java/org/sonar/batch/symbol/SymbolData.java
index 38ed3ed42f9..11ab5cca7e5 100644
--- a/sonar-batch/src/main/java/org/sonar/batch/source/SymbolData.java
+++ b/sonar-batch/src/main/java/org/sonar/batch/symbol/SymbolData.java
@@ -18,11 +18,10 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-package org.sonar.batch.source;
+package org.sonar.batch.symbol;
-import com.google.common.collect.Multimap;
-import org.sonar.api.source.Symbol;
-import org.sonar.api.source.Symbolizable;
+import com.google.common.collect.SortedSetMultimap;
+import org.sonar.api.batch.sensor.symbol.Symbol;
import org.sonar.batch.index.Data;
import java.util.Collection;
@@ -32,19 +31,21 @@ public class SymbolData implements Data {
private static final String FIELD_SEPARATOR = ",";
private static final String SYMBOL_SEPARATOR = ";";
- private final Symbolizable.SymbolTable symbolTable;
+ private final SortedSetMultimap<Symbol, Integer> referencesBySymbol;
- public SymbolData(Symbolizable.SymbolTable symbolTable) {
- this.symbolTable = symbolTable;
+ public SymbolData(SortedSetMultimap<Symbol, Integer> referencesBySymbol) {
+ this.referencesBySymbol = referencesBySymbol;
+ }
+
+ public SortedSetMultimap<Symbol, Integer> referencesBySymbol() {
+ return referencesBySymbol;
}
@Override
public String writeString() {
StringBuilder sb = new StringBuilder();
- Multimap<Symbol, Integer> referencesBySymbol = ((DefaultSymbolTable)symbolTable).getReferencesBySymbol();
-
- for (Symbol symbol : ((DefaultSymbolTable)symbolTable).getReferencesBySymbol().keySet()) {
+ for (Symbol symbol : referencesBySymbol.keySet()) {
sb.append(symbol.getDeclarationStartOffset())
.append(FIELD_SEPARATOR)
@@ -59,8 +60,4 @@ public class SymbolData implements Data {
return sb.toString();
}
- @Override
- public void readString(String s) {
- throw new UnsupportedOperationException();
- }
}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/highlighting/DefaultHighlightingBuilderTest.java b/sonar-batch/src/test/java/org/sonar/batch/highlighting/DefaultHighlightingBuilderTest.java
new file mode 100644
index 00000000000..aefc5afd732
--- /dev/null
+++ b/sonar-batch/src/test/java/org/sonar/batch/highlighting/DefaultHighlightingBuilderTest.java
@@ -0,0 +1,50 @@
+/*
+ * 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.highlighting;
+
+import org.junit.Test;
+import org.mockito.ArgumentCaptor;
+import org.sonar.api.batch.sensor.highlighting.HighlightingBuilder.TypeOfText;
+import org.sonar.batch.index.ComponentDataCache;
+import org.sonar.core.source.SnapshotDataTypes;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+public class DefaultHighlightingBuilderTest {
+
+ @Test
+ public void should_apply_registered_highlighting() throws Exception {
+
+ ComponentDataCache cache = mock(ComponentDataCache.class);
+
+ DefaultHighlightingBuilder highlightable = new DefaultHighlightingBuilder("myComponent", cache);
+ highlightable
+ .highlight(0, 10, TypeOfText.KEYWORD)
+ .highlight(20, 30, TypeOfText.CPP_DOC)
+ .done();
+
+ ArgumentCaptor<SyntaxHighlightingData> argCaptor = ArgumentCaptor.forClass(SyntaxHighlightingData.class);
+ verify(cache).setData(eq("myComponent"), eq(SnapshotDataTypes.SYNTAX_HIGHLIGHTING), argCaptor.capture());
+ assertThat(argCaptor.getValue().writeString()).isEqualTo("0,10,k;20,30,cppd;");
+ }
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/source/SyntaxHighlightingDataBuilderTest.java b/sonar-batch/src/test/java/org/sonar/batch/highlighting/SyntaxHighlightingDataBuilderTest.java
index c190edc3ac7..6fad264c831 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/source/SyntaxHighlightingDataBuilderTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/highlighting/SyntaxHighlightingDataBuilderTest.java
@@ -17,9 +17,10 @@
* 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.source;
+package org.sonar.batch.highlighting;
+import org.sonar.batch.highlighting.SyntaxHighlightingDataBuilder;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
diff --git a/sonar-batch/src/test/java/org/sonar/batch/source/SyntaxHighlightingDataTest.java b/sonar-batch/src/test/java/org/sonar/batch/highlighting/SyntaxHighlightingDataTest.java
index 8a9ece89ef3..59de88ca848 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/source/SyntaxHighlightingDataTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/highlighting/SyntaxHighlightingDataTest.java
@@ -17,7 +17,7 @@
* 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.source;
+package org.sonar.batch.highlighting;
import com.google.common.collect.Lists;
import org.junit.Test;
@@ -38,7 +38,7 @@ public class SyntaxHighlightingDataTest {
SyntaxHighlightingRule.create(24, 38, "k"),
SyntaxHighlightingRule.create(24, 65, "cppd"),
SyntaxHighlightingRule.create(42, 50, "k")
- );
+ );
String serializedRules = new SyntaxHighlightingData(orderedHighlightingRules).writeString();
assertThat(serializedRules).isEqualTo("0,10,cd;10,12,k;12,20,cd;24,38,k;24,65,cppd;42,50,k;");
diff --git a/sonar-batch/src/test/java/org/sonar/batch/index/ComponentDataCacheTest.java b/sonar-batch/src/test/java/org/sonar/batch/index/ComponentDataCacheTest.java
index ff0e7eed20d..3a8835e7a3c 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/index/ComponentDataCacheTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/index/ComponentDataCacheTest.java
@@ -83,9 +83,5 @@ public class ComponentDataCacheTest {
return String.valueOf(data);
}
- @Override
- public void readString(String s) {
- data = Long.parseLong(s);
- }
}
}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/highlighting/HighlightingMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/highlighting/HighlightingMediumTest.java
new file mode 100644
index 00000000000..259b2ffcec0
--- /dev/null
+++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/highlighting/HighlightingMediumTest.java
@@ -0,0 +1,92 @@
+/*
+ * 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.mediumtest.highlighting;
+
+import com.google.common.collect.ImmutableMap;
+import org.apache.commons.io.FileUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.sensor.highlighting.HighlightingBuilder;
+import org.sonar.batch.mediumtest.BatchMediumTester;
+import org.sonar.batch.mediumtest.BatchMediumTester.TaskResult;
+import org.sonar.batch.mediumtest.xoo.plugin.XooPlugin;
+
+import java.io.File;
+import java.io.IOException;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class HighlightingMediumTest {
+
+ @org.junit.Rule
+ public TemporaryFolder temp = new TemporaryFolder();
+
+ public BatchMediumTester tester = BatchMediumTester.builder()
+ .registerPlugin("xoo", new XooPlugin())
+ .addDefaultQProfile("xoo", "Sonar Way")
+ .bootstrapProperties(ImmutableMap.of("sonar.analysis.mode", "sensor"))
+ .build();
+
+ @Before
+ public void prepare() {
+ tester.start();
+ }
+
+ @After
+ public void stop() {
+ tester.stop();
+ }
+
+ @Test
+ public void computeSyntaxHighlightingOnTempProject() throws IOException {
+
+ File baseDir = temp.newFolder();
+ File srcDir = new File(baseDir, "src");
+ srcDir.mkdir();
+
+ File xooFile = new File(srcDir, "sample.xoo");
+ File xoohighlightingFile = new File(srcDir, "sample.xoo.highlighting");
+ FileUtils.write(xooFile, "Sample xoo\ncontent");
+ FileUtils.write(xoohighlightingFile, "0:10:s\n11:18:k");
+
+ TaskResult result = tester.newTask()
+ .properties(ImmutableMap.<String, String>builder()
+ .put("sonar.task", "scan")
+ .put("sonar.projectBaseDir", baseDir.getAbsolutePath())
+ .put("sonar.projectKey", "com.foo.project")
+ .put("sonar.projectName", "Foo Project")
+ .put("sonar.projectVersion", "1.0-SNAPSHOT")
+ .put("sonar.projectDescription", "Description of Foo Project")
+ .put("sonar.sources", "src")
+ .build())
+ .start();
+
+ InputFile file = result.inputFiles().get(0);
+ assertThat(result.highlightingTypeFor(file, 0)).isEqualTo(HighlightingBuilder.TypeOfText.STRING);
+ assertThat(result.highlightingTypeFor(file, 9)).isEqualTo(HighlightingBuilder.TypeOfText.STRING);
+ assertThat(result.highlightingTypeFor(file, 10)).isNull();
+ assertThat(result.highlightingTypeFor(file, 11)).isEqualTo(HighlightingBuilder.TypeOfText.KEYWORD);
+
+ }
+
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/symbol/SymbolMediumTest.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/symbol/SymbolMediumTest.java
new file mode 100644
index 00000000000..c3875c625f3
--- /dev/null
+++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/symbol/SymbolMediumTest.java
@@ -0,0 +1,87 @@
+/*
+ * 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.mediumtest.symbol;
+
+import com.google.common.collect.ImmutableMap;
+import org.apache.commons.io.FileUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.batch.mediumtest.BatchMediumTester;
+import org.sonar.batch.mediumtest.BatchMediumTester.TaskResult;
+import org.sonar.batch.mediumtest.xoo.plugin.XooPlugin;
+
+import java.io.File;
+import java.io.IOException;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+public class SymbolMediumTest {
+
+ @org.junit.Rule
+ public TemporaryFolder temp = new TemporaryFolder();
+
+ public BatchMediumTester tester = BatchMediumTester.builder()
+ .registerPlugin("xoo", new XooPlugin())
+ .addDefaultQProfile("xoo", "Sonar Way")
+ .bootstrapProperties(ImmutableMap.of("sonar.analysis.mode", "sensor"))
+ .build();
+
+ @Before
+ public void prepare() {
+ tester.start();
+ }
+
+ @After
+ public void stop() {
+ tester.stop();
+ }
+
+ @Test
+ public void computeSyntaxHighlightingOnTempProject() throws IOException {
+
+ File baseDir = temp.newFolder();
+ File srcDir = new File(baseDir, "src");
+ srcDir.mkdir();
+
+ File xooFile = new File(srcDir, "sample.xoo");
+ File xooSymbolFile = new File(srcDir, "sample.xoo.symbol");
+ FileUtils.write(xooFile, "Sample xoo\ncontent\nanother xoo");
+ FileUtils.write(xooSymbolFile, "7,10,27");
+
+ TaskResult result = tester.newTask()
+ .properties(ImmutableMap.<String, String>builder()
+ .put("sonar.task", "scan")
+ .put("sonar.projectBaseDir", baseDir.getAbsolutePath())
+ .put("sonar.projectKey", "com.foo.project")
+ .put("sonar.projectName", "Foo Project")
+ .put("sonar.projectVersion", "1.0-SNAPSHOT")
+ .put("sonar.projectDescription", "Description of Foo Project")
+ .put("sonar.sources", "src")
+ .build())
+ .start();
+
+ InputFile file = result.inputFiles().get(0);
+ assertThat(result.symbolReferencesFor(file, 7, 10)).containsOnly(7, 27);
+ }
+
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/plugin/XooPlugin.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/plugin/XooPlugin.java
index f281ea09899..78718da3682 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/plugin/XooPlugin.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/plugin/XooPlugin.java
@@ -23,6 +23,8 @@ import org.sonar.api.SonarPlugin;
import org.sonar.batch.mediumtest.xoo.plugin.base.Xoo;
import org.sonar.batch.mediumtest.xoo.plugin.lang.MeasureSensor;
import org.sonar.batch.mediumtest.xoo.plugin.lang.ScmActivitySensor;
+import org.sonar.batch.mediumtest.xoo.plugin.lang.SymbolReferencesSensor;
+import org.sonar.batch.mediumtest.xoo.plugin.lang.SyntaxHighlightingSensor;
import org.sonar.batch.mediumtest.xoo.plugin.rule.CreateIssueByInternalKeySensor;
import org.sonar.batch.mediumtest.xoo.plugin.rule.OneIssueOnDirPerFileSensor;
import org.sonar.batch.mediumtest.xoo.plugin.rule.OneIssuePerLineSensor;
@@ -38,6 +40,8 @@ public final class XooPlugin extends SonarPlugin {
// language
MeasureSensor.class,
ScmActivitySensor.class,
+ SyntaxHighlightingSensor.class,
+ SymbolReferencesSensor.class,
Xoo.class,
// sensors
diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/plugin/lang/MeasureSensor.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/plugin/lang/MeasureSensor.java
index 9a4b46afd1a..c28ebd5a05c 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/plugin/lang/MeasureSensor.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/plugin/lang/MeasureSensor.java
@@ -104,7 +104,7 @@ public class MeasureSensor implements Sensor {
@Override
public void describe(SensorDescriptor descriptor) {
descriptor
- .name("Xoo Measure Analyzer")
+ .name("Xoo Measure Sensor")
.provides(CoreMetrics.LINES)
.workOnLanguages(Xoo.KEY)
.workOnFileTypes(InputFile.Type.MAIN, InputFile.Type.TEST);
diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/plugin/lang/SymbolReferencesSensor.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/plugin/lang/SymbolReferencesSensor.java
new file mode 100644
index 00000000000..91fa61e5c78
--- /dev/null
+++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/plugin/lang/SymbolReferencesSensor.java
@@ -0,0 +1,98 @@
+/*
+ * 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.mediumtest.xoo.plugin.lang;
+
+import com.google.common.base.Splitter;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.StringUtils;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.sensor.Sensor;
+import org.sonar.api.batch.sensor.SensorContext;
+import org.sonar.api.batch.sensor.SensorDescriptor;
+import org.sonar.api.batch.sensor.symbol.Symbol;
+import org.sonar.api.batch.sensor.symbol.SymbolTableBuilder;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.batch.mediumtest.xoo.plugin.base.Xoo;
+import org.sonar.batch.mediumtest.xoo.plugin.base.XooConstants;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Parse files *.xoo.symbol
+ */
+public class SymbolReferencesSensor implements Sensor {
+
+ private static final String SYMBOL_EXTENSION = ".symbol";
+
+ private void processFileHighlighting(InputFile inputFile, SensorContext context) {
+ File ioFile = inputFile.file();
+ File symbolFile = new File(ioFile.getParentFile(), ioFile.getName() + SYMBOL_EXTENSION);
+ if (symbolFile.exists()) {
+ XooConstants.LOG.debug("Processing " + symbolFile.getAbsolutePath());
+ try {
+ List<String> lines = FileUtils.readLines(symbolFile, context.fileSystem().encoding().name());
+ int lineNumber = 0;
+ SymbolTableBuilder symbolTableBuilder = context.symbolTableBuilder(inputFile);
+ for (String line : lines) {
+ lineNumber++;
+ if (StringUtils.isBlank(line)) {
+ continue;
+ }
+ if (line.startsWith("#")) {
+ continue;
+ }
+ try {
+ Iterator<String> split = Splitter.on(",").split(line).iterator();
+ int startOffset = Integer.parseInt(split.next());
+ int endOffset = Integer.parseInt(split.next());
+ Symbol s = symbolTableBuilder.newSymbol(startOffset, endOffset);
+ while (split.hasNext()) {
+ symbolTableBuilder.newReference(s, Integer.parseInt(split.next()));
+ }
+ } catch (Exception e) {
+ throw new IllegalStateException("Error processing line " + lineNumber + " of file " + symbolFile.getAbsolutePath(), e);
+ }
+ }
+ symbolTableBuilder.done();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ @Override
+ public void describe(SensorDescriptor descriptor) {
+ descriptor
+ .name("Xoo Highlighting Sensor")
+ .provides(CoreMetrics.LINES)
+ .workOnLanguages(Xoo.KEY)
+ .workOnFileTypes(InputFile.Type.MAIN, InputFile.Type.TEST);
+ }
+
+ @Override
+ public void execute(SensorContext context) {
+ for (InputFile file : context.fileSystem().inputFiles(context.fileSystem().predicates().hasLanguages(Xoo.KEY))) {
+ processFileHighlighting(file, context);
+ }
+ }
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/plugin/lang/SyntaxHighlightingSensor.java b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/plugin/lang/SyntaxHighlightingSensor.java
new file mode 100644
index 00000000000..5b78759dbb9
--- /dev/null
+++ b/sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/plugin/lang/SyntaxHighlightingSensor.java
@@ -0,0 +1,95 @@
+/*
+ * 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.mediumtest.xoo.plugin.lang;
+
+import com.google.common.base.Splitter;
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang.StringUtils;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.sensor.Sensor;
+import org.sonar.api.batch.sensor.SensorContext;
+import org.sonar.api.batch.sensor.SensorDescriptor;
+import org.sonar.api.batch.sensor.highlighting.HighlightingBuilder;
+import org.sonar.api.measures.CoreMetrics;
+import org.sonar.batch.mediumtest.xoo.plugin.base.Xoo;
+import org.sonar.batch.mediumtest.xoo.plugin.base.XooConstants;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Parse files *.xoo.highlighting
+ */
+public class SyntaxHighlightingSensor implements Sensor {
+
+ private static final String HIGHLIGHTING_EXTENSION = ".highlighting";
+
+ private void processFileHighlighting(InputFile inputFile, SensorContext context) {
+ File ioFile = inputFile.file();
+ File highlightingFile = new File(ioFile.getParentFile(), ioFile.getName() + HIGHLIGHTING_EXTENSION);
+ if (highlightingFile.exists()) {
+ XooConstants.LOG.debug("Processing " + highlightingFile.getAbsolutePath());
+ try {
+ List<String> lines = FileUtils.readLines(highlightingFile, context.fileSystem().encoding().name());
+ int lineNumber = 0;
+ HighlightingBuilder highlightingBuilder = context.highlightingBuilder(inputFile);
+ for (String line : lines) {
+ lineNumber++;
+ if (StringUtils.isBlank(line)) {
+ continue;
+ }
+ if (line.startsWith("#")) {
+ continue;
+ }
+ try {
+ Iterator<String> split = Splitter.on(":").split(line).iterator();
+ int startOffset = Integer.parseInt(split.next());
+ int endOffset = Integer.parseInt(split.next());
+ HighlightingBuilder.TypeOfText type = HighlightingBuilder.TypeOfText.forCssClass(split.next());
+ highlightingBuilder.highlight(startOffset, endOffset, type);
+ } catch (Exception e) {
+ throw new IllegalStateException("Error processing line " + lineNumber + " of file " + highlightingFile.getAbsolutePath(), e);
+ }
+ }
+ highlightingBuilder.done();
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ @Override
+ public void describe(SensorDescriptor descriptor) {
+ descriptor
+ .name("Xoo Highlighting Sensor")
+ .provides(CoreMetrics.LINES)
+ .workOnLanguages(Xoo.KEY)
+ .workOnFileTypes(InputFile.Type.MAIN, InputFile.Type.TEST);
+ }
+
+ @Override
+ public void execute(SensorContext context) {
+ for (InputFile file : context.fileSystem().inputFiles(context.fileSystem().predicates().hasLanguages(Xoo.KEY))) {
+ processFileHighlighting(file, context);
+ }
+ }
+}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/scan/SensorContextAdapterTest.java b/sonar-batch/src/test/java/org/sonar/batch/scan/SensorContextAdapterTest.java
index b4a8fdab7f0..7b7eb21ee58 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/scan/SensorContextAdapterTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/scan/SensorContextAdapterTest.java
@@ -42,6 +42,7 @@ import org.sonar.api.measures.MetricFinder;
import org.sonar.api.resources.File;
import org.sonar.api.resources.Project;
import org.sonar.api.rule.RuleKey;
+import org.sonar.batch.index.ComponentDataCache;
import static org.fest.assertions.Assertions.assertThat;
import static org.mockito.Matchers.eq;
@@ -69,8 +70,9 @@ public class SensorContextAdapterTest {
sensorContext = mock(SensorContext.class);
settings = new Settings();
resourcePerspectives = mock(ResourcePerspectives.class);
+ ComponentDataCache componentDataCache = mock(ComponentDataCache.class);
adaptor = new SensorContextAdaptor(sensorContext, metricFinder, new Project("myProject"),
- resourcePerspectives, settings, fs, activeRules);
+ resourcePerspectives, settings, fs, activeRules, componentDataCache);
}
@Test
diff --git a/sonar-batch/src/test/java/org/sonar/batch/source/DefaultHighlightableTest.java b/sonar-batch/src/test/java/org/sonar/batch/source/DefaultHighlightableTest.java
index 421f5d87679..2f98e07cc79 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/source/DefaultHighlightableTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/source/DefaultHighlightableTest.java
@@ -22,12 +22,17 @@ package org.sonar.batch.source;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
+import org.mockito.ArgumentCaptor;
import org.sonar.api.component.Component;
+import org.sonar.batch.highlighting.SyntaxHighlightingData;
import org.sonar.batch.index.ComponentDataCache;
import org.sonar.core.source.SnapshotDataTypes;
import static org.fest.assertions.Assertions.assertThat;
-import static org.mockito.Mockito.*;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
public class DefaultHighlightableTest {
@@ -36,7 +41,7 @@ public class DefaultHighlightableTest {
@Test
public void should_store_highlighting_rules() throws Exception {
- DefaultHighlightable highlightablePerspective = new DefaultHighlightable(null, null);
+ DefaultHighlightable highlightablePerspective = new DefaultHighlightable(mock(Component.class), null);
highlightablePerspective.newHighlighting().highlight(0, 10, "k").highlight(20, 30, "cppd");
assertThat(highlightablePerspective.getHighlightingRules().getSortedRules()).hasSize(2);
@@ -55,6 +60,8 @@ public class DefaultHighlightableTest {
.highlight(20, 30, "cppd")
.done();
- verify(cache).setStringData("myComponent", SnapshotDataTypes.SYNTAX_HIGHLIGHTING, "0,10,k;20,30,cppd;");
+ ArgumentCaptor<SyntaxHighlightingData> argCaptor = ArgumentCaptor.forClass(SyntaxHighlightingData.class);
+ verify(cache).setData(eq("myComponent"), eq(SnapshotDataTypes.SYNTAX_HIGHLIGHTING), argCaptor.capture());
+ assertThat(argCaptor.getValue().writeString()).isEqualTo("0,10,k;20,30,cppd;");
}
}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/source/DefaultSymbolTableTest.java b/sonar-batch/src/test/java/org/sonar/batch/source/DefaultSymbolTableTest.java
index 2e65c12473b..a1058b27d64 100644
--- a/sonar-batch/src/test/java/org/sonar/batch/source/DefaultSymbolTableTest.java
+++ b/sonar-batch/src/test/java/org/sonar/batch/source/DefaultSymbolTableTest.java
@@ -35,7 +35,7 @@ public class DefaultSymbolTableTest {
@Test
public void should_order_symbol_and_references() throws Exception {
- Symbolizable.SymbolTableBuilder symbolTableBuilder = new DefaultSymbolTable.Builder();
+ Symbolizable.SymbolTableBuilder symbolTableBuilder = new DefaultSymbolTable.Builder("foo");
Symbol firstSymbol = symbolTableBuilder.newSymbol(10, 20);
symbolTableBuilder.newReference(firstSymbol, 32);
Symbol secondSymbol = symbolTableBuilder.newSymbol(84, 92);
@@ -54,16 +54,16 @@ public class DefaultSymbolTableTest {
public void should_reject_reference_conflicting_with_declaration() throws Exception {
throwable.expect(UnsupportedOperationException.class);
- Symbolizable.SymbolTableBuilder symbolTableBuilder = new DefaultSymbolTable.Builder();
+ Symbolizable.SymbolTableBuilder symbolTableBuilder = new DefaultSymbolTable.Builder("foo");
Symbol symbol = symbolTableBuilder.newSymbol(10, 20);
symbolTableBuilder.newReference(symbol, 15);
}
@Test
public void test_toString() throws Exception {
- Symbolizable.SymbolTableBuilder symbolTableBuilder = new DefaultSymbolTable.Builder();
+ Symbolizable.SymbolTableBuilder symbolTableBuilder = new DefaultSymbolTable.Builder("foo");
Symbol symbol = symbolTableBuilder.newSymbol(10, 20);
- assertThat(symbol.toString()).isEqualTo("Symbol{offset=10-20}");
+ assertThat(symbol.toString()).isEqualTo("Symbol{component=foo, offset=10-20}");
}
}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/source/SymbolDataTest.java b/sonar-batch/src/test/java/org/sonar/batch/source/SymbolDataTest.java
deleted file mode 100644
index 8dfdd1cccd5..00000000000
--- a/sonar-batch/src/test/java/org/sonar/batch/source/SymbolDataTest.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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.source;
-
-import org.junit.Test;
-import org.sonar.api.source.Symbol;
-import org.sonar.api.source.Symbolizable;
-
-import static org.fest.assertions.Assertions.assertThat;
-
-public class SymbolDataTest {
-
- @Test
- public void should_serialize_symbols_in_natural_order() throws Exception {
-
- Symbolizable.SymbolTableBuilder symbolTableBuilder = new DefaultSymbolTable.Builder();
- Symbol firstSymbol = symbolTableBuilder.newSymbol(10, 20);
- symbolTableBuilder.newReference(firstSymbol, 32);
- Symbol secondSymbol = symbolTableBuilder.newSymbol(84, 92);
- symbolTableBuilder.newReference(secondSymbol, 124);
- Symbol thirdSymbol = symbolTableBuilder.newSymbol(55, 62);
- symbolTableBuilder.newReference(thirdSymbol, 70);
- Symbolizable.SymbolTable symbolTable = symbolTableBuilder.build();
-
- SymbolData dataRepository = new SymbolData(symbolTable);
- String serializedSymbolData = dataRepository.writeString();
-
- assertThat(serializedSymbolData).isEqualTo("10,20,10,32;55,62,55,70;84,92,84,124;");
- }
-
- @Test
- public void should_serialize_unused_symbol() throws Exception {
-
- Symbolizable.SymbolTableBuilder symbolTableBuilder = new DefaultSymbolTable.Builder();
- symbolTableBuilder.newSymbol(10, 20);
-
- SymbolData dataRepository = new SymbolData(symbolTableBuilder.build());
- String serializedSymbolData = dataRepository.writeString();
-
- assertThat(serializedSymbolData).isEqualTo("10,20,10;");
- }
-}
diff --git a/sonar-batch/src/test/java/org/sonar/batch/symbol/DefaultSymbolTableBuilderTest.java b/sonar-batch/src/test/java/org/sonar/batch/symbol/DefaultSymbolTableBuilderTest.java
new file mode 100644
index 00000000000..c661da30af1
--- /dev/null
+++ b/sonar-batch/src/test/java/org/sonar/batch/symbol/DefaultSymbolTableBuilderTest.java
@@ -0,0 +1,108 @@
+/*
+ * 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.symbol;
+
+import com.google.common.collect.SortedSetMultimap;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.mockito.ArgumentCaptor;
+import org.sonar.api.batch.sensor.symbol.Symbol;
+import org.sonar.api.batch.sensor.symbol.SymbolTableBuilder;
+import org.sonar.batch.index.ComponentDataCache;
+import org.sonar.core.source.SnapshotDataTypes;
+
+import java.util.ArrayList;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+public class DefaultSymbolTableBuilderTest {
+
+ @Rule
+ public ExpectedException throwable = ExpectedException.none();
+
+ @Test
+ public void should_order_symbol_and_references() throws Exception {
+ ComponentDataCache componentDataCache = mock(ComponentDataCache.class);
+ SymbolTableBuilder symbolTableBuilder = new DefaultSymbolTableBuilder("foo", componentDataCache);
+ Symbol firstSymbol = symbolTableBuilder.newSymbol(10, 20);
+ symbolTableBuilder.newReference(firstSymbol, 32);
+ Symbol secondSymbol = symbolTableBuilder.newSymbol(84, 92);
+ symbolTableBuilder.newReference(secondSymbol, 124);
+ Symbol thirdSymbol = symbolTableBuilder.newSymbol(55, 62);
+ symbolTableBuilder.newReference(thirdSymbol, 70);
+ symbolTableBuilder.done();
+
+ ArgumentCaptor<SymbolData> argCaptor = ArgumentCaptor.forClass(SymbolData.class);
+ verify(componentDataCache).setData(eq("foo"), eq(SnapshotDataTypes.SYMBOL_HIGHLIGHTING), argCaptor.capture());
+
+ SortedSetMultimap<Symbol, Integer> referencesBySymbol = argCaptor.getValue().referencesBySymbol();
+
+ assertThat(new ArrayList<Symbol>(referencesBySymbol.keySet())).containsExactly(firstSymbol, thirdSymbol, secondSymbol);
+ assertThat(new ArrayList<Integer>(referencesBySymbol.get(firstSymbol))).containsExactly(10, 32);
+ assertThat(new ArrayList<Integer>(referencesBySymbol.get(secondSymbol))).containsExactly(84, 124);
+ assertThat(new ArrayList<Integer>(referencesBySymbol.get(thirdSymbol))).containsExactly(55, 70);
+
+ assertThat(argCaptor.getValue().writeString()).isEqualTo("10,20,10,32;55,62,55,70;84,92,84,124;");
+ }
+
+ @Test
+ public void should_serialize_unused_symbol() throws Exception {
+
+ ComponentDataCache componentDataCache = mock(ComponentDataCache.class);
+ SymbolTableBuilder symbolTableBuilder = new DefaultSymbolTableBuilder("foo", componentDataCache);
+ symbolTableBuilder.newSymbol(10, 20);
+ symbolTableBuilder.done();
+
+ ArgumentCaptor<SymbolData> argCaptor = ArgumentCaptor.forClass(SymbolData.class);
+ verify(componentDataCache).setData(eq("foo"), eq(SnapshotDataTypes.SYMBOL_HIGHLIGHTING), argCaptor.capture());
+
+ assertThat(argCaptor.getValue().writeString()).isEqualTo("10,20,10;");
+ }
+
+ @Test
+ public void should_reject_reference_conflicting_with_declaration() throws Exception {
+ throwable.expect(UnsupportedOperationException.class);
+
+ ComponentDataCache componentDataCache = mock(ComponentDataCache.class);
+ SymbolTableBuilder symbolTableBuilder = new DefaultSymbolTableBuilder("foo", componentDataCache);
+ Symbol symbol = symbolTableBuilder.newSymbol(10, 20);
+ symbolTableBuilder.newReference(symbol, 15);
+ }
+
+ @Test
+ public void should_reject_reference_from_another_file() throws Exception {
+ throwable.expect(UnsupportedOperationException.class);
+
+ ComponentDataCache componentDataCache = mock(ComponentDataCache.class);
+ SymbolTableBuilder symbolTableBuilder = new DefaultSymbolTableBuilder("foo", componentDataCache);
+ Symbol symbol = symbolTableBuilder.newSymbol(10, 20);
+
+ SymbolTableBuilder symbolTableBuilder2 = new DefaultSymbolTableBuilder("foo2", componentDataCache);
+ Symbol symbol2 = symbolTableBuilder2.newSymbol(30, 40);
+
+ symbolTableBuilder.newReference(symbol2, 15);
+ }
+
+}