Bläddra i källkod

SONAR-5389 Support syntax highlighting in the new sensor API

tags/4.5-RC1
Julien HENRY 10 år sedan
förälder
incheckning
ff03a597a9
29 ändrade filer med 543 tillägg och 40 borttagningar
  1. 52
    0
      sonar-batch/src/main/java/org/sonar/batch/highlighting/DefaultHighlightingBuilder.java
  2. 5
    5
      sonar-batch/src/main/java/org/sonar/batch/highlighting/SyntaxHighlightingData.java
  3. 5
    4
      sonar-batch/src/main/java/org/sonar/batch/highlighting/SyntaxHighlightingDataBuilder.java
  4. 1
    1
      sonar-batch/src/main/java/org/sonar/batch/highlighting/SyntaxHighlightingRule.java
  5. 23
    0
      sonar-batch/src/main/java/org/sonar/batch/highlighting/package-info.java
  6. 4
    0
      sonar-batch/src/main/java/org/sonar/batch/index/ComponentDataCache.java
  7. 0
    2
      sonar-batch/src/main/java/org/sonar/batch/index/Data.java
  8. 0
    5
      sonar-batch/src/main/java/org/sonar/batch/index/StringData.java
  9. 38
    0
      sonar-batch/src/main/java/org/sonar/batch/mediumtest/BatchMediumTester.java
  10. 12
    1
      sonar-batch/src/main/java/org/sonar/batch/scan/SensorContextAdaptor.java
  11. 11
    1
      sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultSensorContext.java
  12. 3
    0
      sonar-batch/src/main/java/org/sonar/batch/scan2/ProjectScanContainer.java
  13. 16
    3
      sonar-batch/src/main/java/org/sonar/batch/source/DefaultHighlightable.java
  14. 3
    0
      sonar-batch/src/main/java/org/sonar/batch/source/HighlightableBuilder.java
  15. 2
    6
      sonar-batch/src/main/java/org/sonar/batch/source/SymbolData.java
  16. 50
    0
      sonar-batch/src/test/java/org/sonar/batch/highlighting/DefaultHighlightingBuilderTest.java
  17. 2
    1
      sonar-batch/src/test/java/org/sonar/batch/highlighting/SyntaxHighlightingDataBuilderTest.java
  18. 2
    2
      sonar-batch/src/test/java/org/sonar/batch/highlighting/SyntaxHighlightingDataTest.java
  19. 0
    4
      sonar-batch/src/test/java/org/sonar/batch/index/ComponentDataCacheTest.java
  20. 92
    0
      sonar-batch/src/test/java/org/sonar/batch/mediumtest/highlighting/HighlightingMediumTest.java
  21. 2
    0
      sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/plugin/XooPlugin.java
  22. 1
    1
      sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/plugin/lang/MeasureSensor.java
  23. 95
    0
      sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/plugin/lang/SyntaxHighlightingSensor.java
  24. 3
    1
      sonar-batch/src/test/java/org/sonar/batch/scan/SensorContextAdapterTest.java
  25. 10
    3
      sonar-batch/src/test/java/org/sonar/batch/source/DefaultHighlightableTest.java
  26. 9
    0
      sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java
  27. 78
    0
      sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/highlighting/HighlightingBuilder.java
  28. 21
    0
      sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/highlighting/package-info.java
  29. 3
    0
      sonar-plugin-api/src/main/java/org/sonar/api/source/Highlightable.java

+ 52
- 0
sonar-batch/src/main/java/org/sonar/batch/highlighting/DefaultHighlightingBuilder.java Visa fil

@@ -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());
}
}

sonar-batch/src/main/java/org/sonar/batch/source/SyntaxHighlightingData.java → sonar-batch/src/main/java/org/sonar/batch/highlighting/SyntaxHighlightingData.java Visa fil

@@ -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();
}
}

sonar-batch/src/main/java/org/sonar/batch/source/SyntaxHighlightingDataBuilder.java → sonar-batch/src/main/java/org/sonar/batch/highlighting/SyntaxHighlightingDataBuilder.java Visa fil

@@ -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);
}
}

sonar-batch/src/main/java/org/sonar/batch/source/SyntaxHighlightingRule.java → sonar-batch/src/main/java/org/sonar/batch/highlighting/SyntaxHighlightingRule.java Visa fil

@@ -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;


+ 23
- 0
sonar-batch/src/main/java/org/sonar/batch/highlighting/package-info.java Visa fil

@@ -0,0 +1,23 @@
/*
* 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.
*/
@ParametersAreNonnullByDefault
package org.sonar.batch.highlighting;

import javax.annotation.ParametersAreNonnullByDefault;

+ 4
- 0
sonar-batch/src/main/java/org/sonar/batch/index/ComponentDataCache.java Visa fil

@@ -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();

+ 0
- 2
sonar-batch/src/main/java/org/sonar/batch/index/Data.java Visa fil

@@ -25,6 +25,4 @@ public interface Data extends Serializable {

String writeString();

void readString(String s);

}

+ 0
- 5
sonar-batch/src/main/java/org/sonar/batch/index/StringData.java Visa fil

@@ -37,9 +37,4 @@ public class StringData implements Data {
public String writeString() {
return data;
}

@Override
public void readString(String s) {
this.data = s;
}
}

+ 38
- 0
sonar-batch/src/main/java/org/sonar/batch/mediumtest/BatchMediumTester.java Visa fil

@@ -20,12 +20,16 @@
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.config.Settings;
@@ -36,6 +40,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;
@@ -49,6 +56,9 @@ import org.sonar.batch.scan2.ScanTaskObserver;
import org.sonar.batch.settings.SettingsReferential;
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;
@@ -200,13 +210,18 @@ 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>();

@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 +238,15 @@ 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);
}
}

}

public List<Issue> issues() {
@@ -240,6 +264,20 @@ 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 highlightingTypeAt(InputFile file, int charIndex) {
for (SyntaxHighlightingRule sortedRule : highlightingPerFile.get(file).syntaxHighlightingRuleSet()) {
if (sortedRule.getStartPosition() <= charIndex && sortedRule.getEndPosition() > charIndex) {
return HighlightingBuilder.TypeOfText.forCssClass(sortedRule.getTextType());
}
}
return null;
}
}

private static class FakeGlobalReferentialsLoader implements GlobalReferentialsLoader {

+ 12
- 1
sonar-batch/src/main/java/org/sonar/batch/scan/SensorContextAdaptor.java Visa fil

@@ -23,9 +23,11 @@ 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;
@@ -46,6 +48,8 @@ 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 java.io.Serializable;

@@ -62,9 +66,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 +77,7 @@ public class SensorContextAdaptor implements SensorContext {
this.settings = settings;
this.fs = fs;
this.activeRules = activeRules;
this.componentDataCache = componentDataCache;
}

@Override
@@ -236,4 +242,9 @@ public class SensorContextAdaptor implements SensorContext {
.build();
}

@Override
public HighlightingBuilder highlightingBuilder(InputFile inputFile) {
return new DefaultHighlightingBuilder(((DefaultInputFile) inputFile).key(), componentDataCache);
}

}

+ 11
- 1
sonar-batch/src/main/java/org/sonar/batch/scan2/DefaultSensorContext.java Visa fil

@@ -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;
@@ -38,6 +40,8 @@ import org.sonar.api.batch.sensor.measure.internal.DefaultMeasureBuilder;
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.core.component.ComponentKeys;
@@ -53,9 +57,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 +68,7 @@ public class DefaultSensorContext implements SensorContext {
this.fs = fs;
this.activeRules = activeRules;
this.issueFilters = issueFilters;
this.componentDataCache = componentDataCache;
}

@Override
@@ -155,7 +161,11 @@ 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);
}

}

+ 3
- 0
sonar-batch/src/main/java/org/sonar/batch/scan2/ProjectScanContainer.java Visa fil

@@ -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);
}


+ 16
- 3
sonar-batch/src/main/java/org/sonar/batch/source/DefaultHighlightable.java Visa fil

@@ -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 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());
}
}
}

+ 3
- 0
sonar-batch/src/main/java/org/sonar/batch/source/HighlightableBuilder.java Visa fil

@@ -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 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);

+ 2
- 6
sonar-batch/src/main/java/org/sonar/batch/source/SymbolData.java Visa fil

@@ -42,9 +42,9 @@ public class SymbolData implements Data {
public String writeString() {
StringBuilder sb = new StringBuilder();

Multimap<Symbol, Integer> referencesBySymbol = ((DefaultSymbolTable)symbolTable).getReferencesBySymbol();
Multimap<Symbol, Integer> referencesBySymbol = ((DefaultSymbolTable) symbolTable).getReferencesBySymbol();

for (Symbol symbol : ((DefaultSymbolTable)symbolTable).getReferencesBySymbol().keySet()) {
for (Symbol symbol : ((DefaultSymbolTable) symbolTable).getReferencesBySymbol().keySet()) {

sb.append(symbol.getDeclarationStartOffset())
.append(FIELD_SEPARATOR)
@@ -59,8 +59,4 @@ public class SymbolData implements Data {
return sb.toString();
}

@Override
public void readString(String s) {
throw new UnsupportedOperationException();
}
}

+ 50
- 0
sonar-batch/src/test/java/org/sonar/batch/highlighting/DefaultHighlightingBuilderTest.java Visa fil

@@ -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;");
}
}

sonar-batch/src/test/java/org/sonar/batch/source/SyntaxHighlightingDataBuilderTest.java → sonar-batch/src/test/java/org/sonar/batch/highlighting/SyntaxHighlightingDataBuilderTest.java Visa fil

@@ -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;

sonar-batch/src/test/java/org/sonar/batch/source/SyntaxHighlightingDataTest.java → sonar-batch/src/test/java/org/sonar/batch/highlighting/SyntaxHighlightingDataTest.java Visa fil

@@ -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;");

+ 0
- 4
sonar-batch/src/test/java/org/sonar/batch/index/ComponentDataCacheTest.java Visa fil

@@ -83,9 +83,5 @@ public class ComponentDataCacheTest {
return String.valueOf(data);
}

@Override
public void readString(String s) {
data = Long.parseLong(s);
}
}
}

+ 92
- 0
sonar-batch/src/test/java/org/sonar/batch/mediumtest/highlighting/HighlightingMediumTest.java Visa fil

@@ -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.highlightingTypeAt(file, 0)).isEqualTo(HighlightingBuilder.TypeOfText.STRING);
assertThat(result.highlightingTypeAt(file, 9)).isEqualTo(HighlightingBuilder.TypeOfText.STRING);
assertThat(result.highlightingTypeAt(file, 10)).isNull();
assertThat(result.highlightingTypeAt(file, 11)).isEqualTo(HighlightingBuilder.TypeOfText.KEYWORD);

}

}

+ 2
- 0
sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/plugin/XooPlugin.java Visa fil

@@ -23,6 +23,7 @@ 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.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 +39,7 @@ public final class XooPlugin extends SonarPlugin {
// language
MeasureSensor.class,
ScmActivitySensor.class,
SyntaxHighlightingSensor.class,
Xoo.class,

// sensors

+ 1
- 1
sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/plugin/lang/MeasureSensor.java Visa fil

@@ -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);

+ 95
- 0
sonar-batch/src/test/java/org/sonar/batch/mediumtest/xoo/plugin/lang/SyntaxHighlightingSensor.java Visa fil

@@ -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);
}
}
}

+ 3
- 1
sonar-batch/src/test/java/org/sonar/batch/scan/SensorContextAdapterTest.java Visa fil

@@ -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

+ 10
- 3
sonar-batch/src/test/java/org/sonar/batch/source/DefaultHighlightableTest.java Visa fil

@@ -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;");
}
}

+ 9
- 0
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java Visa fil

@@ -24,6 +24,7 @@ import org.sonar.api.batch.fs.FileSystem;
import org.sonar.api.batch.fs.InputFile;
import org.sonar.api.batch.measure.Metric;
import org.sonar.api.batch.rule.ActiveRules;
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.measure.Measure;
@@ -108,4 +109,12 @@ public interface SensorContext {
*/
boolean addIssue(Issue issue);

// ------------ HIGHLIGHTING ------------

/**
* Builder to define highlighting of a file.
* @since 4.5
*/
HighlightingBuilder highlightingBuilder(InputFile inputFile);

}

+ 78
- 0
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/highlighting/HighlightingBuilder.java Visa fil

@@ -0,0 +1,78 @@
/*
* 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.api.batch.sensor.highlighting;


/**
* This builder is used to define syntax highlighting (aka code coloration) on files.
* @since 4.5
*/
public interface HighlightingBuilder {

/**
* See sonar-colorizer.css
*/
enum TypeOfText {
ANNOTATION("a"),
CONSTANT("c"),
JAVADOC("j"),
CLASSIC_COMMENT("cd"),
CPP_DOC("cppd"),
KEYWORD("k"),
STRING("s"),
KEYWORD_LIGHT("h"),
PREPROCESS_DIRECTIVE("p");

private final String cssClass;

private TypeOfText(String cssClass) {
this.cssClass = cssClass;
}

public static TypeOfText forCssClass(String cssClass) {
for (TypeOfText typeOfText : TypeOfText.values()) {
if (typeOfText.cssClass().equals(cssClass)) {
return typeOfText;
}
}
throw new IllegalArgumentException("No TypeOfText for CSS class " + cssClass);
}

/**
* For internal use
*/
public String cssClass() {
return cssClass;
}
}

/**
* Call this method to indicate the type of text in a range.
* @param startOffset Starting position in file for this type of text. Beginning of a file starts with offset '0'.
* @param endOffset End position in file for this type of text.
* @param typeOfText see {@link TypeOfText} values.
*/
HighlightingBuilder highlight(int startOffset, int endOffset, TypeOfText typeOfText);

/**
* Call this method only once when your are done with defining highlighting of the file.
*/
void done();
}

+ 21
- 0
sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/highlighting/package-info.java Visa fil

@@ -0,0 +1,21 @@
/*
* 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.
*/
@javax.annotation.ParametersAreNonnullByDefault
package org.sonar.api.batch.sensor.highlighting;

+ 3
- 0
sonar-plugin-api/src/main/java/org/sonar/api/source/Highlightable.java Visa fil

@@ -19,11 +19,14 @@
*/
package org.sonar.api.source;

import org.sonar.api.batch.sensor.SensorContext;
import org.sonar.api.component.Perspective;

/**
* @since 3.6
* @deprecated since 4.5 use {@link SensorContext#highlightingBuilder(org.sonar.api.batch.fs.InputFile)}
*/
@Deprecated
public interface Highlightable extends Perspective {

interface HighlightingBuilder {

Laddar…
Avbryt
Spara