aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java9
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/highlighting/NewHighlighting.java2
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/InMemorySensorStorage.java82
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/MockAnalysisMode.java50
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java87
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorStorage.java6
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/symbol/NewSymbol.java50
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/symbol/NewSymbolTable.java63
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/symbol/internal/DefaultSymbolTable.java152
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/symbol/internal/package-info.java21
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/symbol/package-info.java21
-rw-r--r--sonar-plugin-api/src/main/java/org/sonar/api/source/Symbolizable.java5
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/batch/sensor/DefaultSensorContext.java12
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/batch/sensor/DefaultSensorStorage.java22
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/batch/sensor/noop/NoOpNewSymbolTable.java75
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/batch/source/DefaultSymbolTable.java123
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/batch/source/DefaultSymbolizable.java5
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/batch/source/DeprecatedDefaultSymbol.java (renamed from sonar-scanner-engine/src/main/java/org/sonar/batch/source/DefaultSymbol.java)25
-rw-r--r--sonar-scanner-engine/src/main/java/org/sonar/batch/source/DeprecatedDefaultSymbolTable.java78
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/batch/source/DefaultSymbolizableTest.java9
-rw-r--r--sonar-scanner-engine/src/test/java/org/sonar/batch/source/DeprecatedDefaultSymbolTableTest.java (renamed from sonar-scanner-engine/src/test/java/org/sonar/batch/source/DefaultSymbolTableTest.java)34
21 files changed, 679 insertions, 252 deletions
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java
index 1c159c38b78..044f5f36c16 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/SensorContext.java
@@ -32,6 +32,7 @@ import org.sonar.api.batch.sensor.issue.Issue;
import org.sonar.api.batch.sensor.issue.NewIssue;
import org.sonar.api.batch.sensor.measure.Measure;
import org.sonar.api.batch.sensor.measure.NewMeasure;
+import org.sonar.api.batch.sensor.symbol.NewSymbolTable;
import org.sonar.api.config.Settings;
import org.sonar.api.utils.Version;
@@ -89,9 +90,13 @@ public interface SensorContext {
*/
NewHighlighting newHighlighting();
- // ------------ SYMBOL REFERENCES ------------
+ // ------------ SYMBOL TABLE ------------
- // TODO
+ /**
+ * Builder to define symbol table of a file. Don't forget to call {@link NewSymbolTable#save()} once all symbols are provided.
+ * @since 5.6
+ */
+ NewSymbolTable newSymbolTable();
// ------------ TESTS ------------
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/highlighting/NewHighlighting.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/highlighting/NewHighlighting.java
index af4c145713f..6f59fad4bad 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/highlighting/NewHighlighting.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/highlighting/NewHighlighting.java
@@ -40,7 +40,9 @@ public interface NewHighlighting {
* @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.
+ * @deprecated since 5.6 Only supported to ease migration from old API. Please prefer {@link #highlight(int, int, int, int)}.
*/
+ @Deprecated
NewHighlighting highlight(int startOffset, int endOffset, TypeOfText typeOfText);
/**
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/InMemorySensorStorage.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/InMemorySensorStorage.java
new file mode 100644
index 00000000000..32c91d18610
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/InMemorySensorStorage.java
@@ -0,0 +1,82 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.internal;
+
+import com.google.common.collect.HashBasedTable;
+import com.google.common.collect.Table;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.EnumMap;
+import java.util.HashMap;
+import java.util.Map;
+import org.sonar.api.batch.sensor.coverage.CoverageType;
+import org.sonar.api.batch.sensor.coverage.internal.DefaultCoverage;
+import org.sonar.api.batch.sensor.cpd.internal.DefaultCpdTokens;
+import org.sonar.api.batch.sensor.highlighting.internal.DefaultHighlighting;
+import org.sonar.api.batch.sensor.issue.Issue;
+import org.sonar.api.batch.sensor.measure.Measure;
+import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable;
+
+class InMemorySensorStorage implements SensorStorage {
+
+ Table<String, String, Measure> measuresByComponentAndMetric = HashBasedTable.create();
+
+ Collection<Issue> allIssues = new ArrayList<>();
+
+ Map<String, DefaultHighlighting> highlightingByComponent = new HashMap<>();
+ Map<String, DefaultCpdTokens> cpdTokensByComponent = new HashMap<>();
+ Map<String, Map<CoverageType, DefaultCoverage>> coverageByComponent = new HashMap<>();
+ Map<String, DefaultSymbolTable> symbolsPerComponent = new HashMap<>();
+
+ @Override
+ public void store(Measure measure) {
+ measuresByComponentAndMetric.row(measure.inputComponent().key()).put(measure.metric().key(), measure);
+ }
+
+ @Override
+ public void store(Issue issue) {
+ allIssues.add(issue);
+ }
+
+ @Override
+ public void store(DefaultHighlighting highlighting) {
+ highlightingByComponent.put(highlighting.inputFile().key(), highlighting);
+ }
+
+ @Override
+ public void store(DefaultCoverage defaultCoverage) {
+ String key = defaultCoverage.inputFile().key();
+ if (!coverageByComponent.containsKey(key)) {
+ coverageByComponent.put(key, new EnumMap<CoverageType, DefaultCoverage>(CoverageType.class));
+ }
+ coverageByComponent.get(key).put(defaultCoverage.type(), defaultCoverage);
+ }
+
+ @Override
+ public void store(DefaultCpdTokens defaultCpdTokens) {
+ cpdTokensByComponent.put(defaultCpdTokens.inputFile().key(), defaultCpdTokens);
+ }
+
+ @Override
+ public void store(DefaultSymbolTable symbolTable) {
+ symbolsPerComponent.put(symbolTable.inputFile().key(), symbolTable);
+ }
+
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/MockAnalysisMode.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/MockAnalysisMode.java
new file mode 100644
index 00000000000..9193fdd3704
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/MockAnalysisMode.java
@@ -0,0 +1,50 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.internal;
+
+import org.sonar.api.batch.AnalysisMode;
+
+public class MockAnalysisMode implements AnalysisMode {
+ private boolean isPreview = false;
+ private boolean isIssues = false;
+
+ @Override
+ public boolean isPreview() {
+ return isPreview;
+ }
+
+ public void setPreview(boolean value) {
+ this.isPreview = value;
+ }
+
+ @Override
+ public boolean isIssues() {
+ return this.isIssues;
+ }
+
+ public void setIssues(boolean issues) {
+ this.isIssues = issues;
+ }
+
+ @Override
+ public boolean isPublish() {
+ return !isPreview && !isIssues;
+ }
+} \ No newline at end of file
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java
index b0c19108f16..0e4d51f9795 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorContextTester.java
@@ -20,22 +20,19 @@
package org.sonar.api.batch.sensor.internal;
import com.google.common.annotations.Beta;
-import com.google.common.collect.HashBasedTable;
-import com.google.common.collect.Table;
import java.io.File;
import java.io.Serializable;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
-import java.util.EnumMap;
-import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import javax.annotation.CheckForNull;
import org.sonar.api.SonarQubeVersion;
-import org.sonar.api.batch.AnalysisMode;
import org.sonar.api.batch.fs.InputModule;
+import org.sonar.api.batch.fs.TextRange;
import org.sonar.api.batch.fs.internal.DefaultFileSystem;
import org.sonar.api.batch.fs.internal.DefaultInputModule;
import org.sonar.api.batch.fs.internal.DefaultTextPointer;
@@ -58,6 +55,8 @@ import org.sonar.api.batch.sensor.issue.internal.DefaultIssue;
import org.sonar.api.batch.sensor.measure.Measure;
import org.sonar.api.batch.sensor.measure.NewMeasure;
import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
+import org.sonar.api.batch.sensor.symbol.NewSymbolTable;
+import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable;
import org.sonar.api.config.Settings;
import org.sonar.api.internal.SonarQubeVersionFactory;
import org.sonar.api.measures.Metric;
@@ -236,6 +235,11 @@ public class SensorContextTester implements SensorContext {
return new DefaultCpdTokens(settings, sensorStorage);
}
+ @Override
+ public NewSymbolTable newSymbolTable() {
+ return new DefaultSymbolTable(sensorStorage);
+ }
+
public List<TypeOfText> highlightingTypeAt(String componentKey, int line, int lineOffset) {
DefaultHighlighting syntaxHighlightingData = sensorStorage.highlightingByComponent.get(componentKey);
if (syntaxHighlightingData == null) {
@@ -251,73 +255,18 @@ public class SensorContextTester implements SensorContext {
return result;
}
- public static class MockAnalysisMode implements AnalysisMode {
- private boolean isPreview = false;
- private boolean isIssues = false;
-
- @Override
- public boolean isPreview() {
- return isPreview;
- }
-
- public void setPreview(boolean value) {
- this.isPreview = value;
- }
-
- @Override
- public boolean isIssues() {
- return this.isIssues;
- }
-
- public void setIssues(boolean issues) {
- this.isIssues = issues;
- }
-
- @Override
- public boolean isPublish() {
- return !isPreview && !isIssues;
- }
- }
-
- private static class InMemorySensorStorage implements SensorStorage {
-
- private Table<String, String, Measure> measuresByComponentAndMetric = HashBasedTable.create();
-
- private Collection<Issue> allIssues = new ArrayList<>();
-
- private Map<String, DefaultHighlighting> highlightingByComponent = new HashMap<>();
- private Map<String, DefaultCpdTokens> cpdTokensByComponent = new HashMap<>();
- private Map<String, Map<CoverageType, DefaultCoverage>> coverageByComponent = new HashMap<>();
-
- @Override
- public void store(Measure measure) {
- measuresByComponentAndMetric.row(measure.inputComponent().key()).put(measure.metric().key(), measure);
- }
-
- @Override
- public void store(Issue issue) {
- allIssues.add(issue);
- }
-
- @Override
- public void store(DefaultHighlighting highlighting) {
- highlightingByComponent.put(highlighting.inputFile().key(), highlighting);
+ public Collection<TextRange> referencesForSymbolAt(String componentKey, int line, int lineOffset) {
+ DefaultSymbolTable symbolTable = sensorStorage.symbolsPerComponent.get(componentKey);
+ if (symbolTable == null) {
+ return Collections.emptyList();
}
-
- @Override
- public void store(DefaultCoverage defaultCoverage) {
- String key = defaultCoverage.inputFile().key();
- if (!coverageByComponent.containsKey(key)) {
- coverageByComponent.put(key, new EnumMap<CoverageType, DefaultCoverage>(CoverageType.class));
+ DefaultTextPointer location = new DefaultTextPointer(line, lineOffset);
+ for (Map.Entry<TextRange, Set<TextRange>> symbol : symbolTable.getReferencesBySymbol().entrySet()) {
+ if (symbol.getKey().start().compareTo(location) <= 0 && symbol.getKey().end().compareTo(location) > 0) {
+ return symbol.getValue();
}
- coverageByComponent.get(key).put(defaultCoverage.type(), defaultCoverage);
}
-
- @Override
- public void store(DefaultCpdTokens defaultCpdTokens) {
- cpdTokensByComponent.put(defaultCpdTokens.inputFile().key(), defaultCpdTokens);
- }
-
+ return Collections.emptyList();
}
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorStorage.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorStorage.java
index 031ee725728..3ea574b5bf6 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorStorage.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/internal/SensorStorage.java
@@ -25,6 +25,7 @@ import org.sonar.api.batch.sensor.cpd.internal.DefaultCpdTokens;
import org.sonar.api.batch.sensor.highlighting.internal.DefaultHighlighting;
import org.sonar.api.batch.sensor.issue.Issue;
import org.sonar.api.batch.sensor.measure.Measure;
+import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable;
/**
* Interface for storing data computed by sensors.
@@ -49,4 +50,9 @@ public interface SensorStorage {
*/
void store(DefaultCpdTokens defaultCpdTokens);
+ /**
+ * @since 5.6
+ */
+ void store(DefaultSymbolTable symbolTable);
+
}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/symbol/NewSymbol.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/symbol/NewSymbol.java
new file mode 100644
index 00000000000..46368ed5ee1
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/symbol/NewSymbol.java
@@ -0,0 +1,50 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.symbol;
+
+import com.google.common.annotations.Beta;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.TextRange;
+
+/**
+ * This builder is used to define symbol references on files.
+ * @since 5.6
+ */
+@Beta
+public interface NewSymbol {
+
+ /**
+ * Register a new symbol reference.
+ * @param startOffset Starting position in file for the declaration of this symbol. Beginning of a file starts with offset '0'.
+ * @param endOffset End position in file for this symbol declaration.
+ */
+ NewSymbol newReference(int startOffset, int endOffset);
+
+ /**
+ * Register a new symbol.
+ * @param range Range of text for the symbol declaration. See for example {@link InputFile#newRange(int, int, int, int)}.
+ */
+ NewSymbol newReference(TextRange range);
+
+ /**
+ * Shortcut to avoid calling {@link InputFile#newRange(int, int, int, int)}
+ */
+ NewSymbol newReference(int startLine, int startLineOffset, int endLine, int endLineOffset);
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/symbol/NewSymbolTable.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/symbol/NewSymbolTable.java
new file mode 100644
index 00000000000..1e8487c557d
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/symbol/NewSymbolTable.java
@@ -0,0 +1,63 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.symbol;
+
+import com.google.common.annotations.Beta;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.TextRange;
+
+/**
+ * This builder is used to define symbol references on files.
+ * @since 5.6
+ */
+@Beta
+public interface NewSymbolTable {
+
+ /**
+ * The file the symbol table belongs to.
+ */
+ NewSymbolTable onFile(InputFile inputFile);
+
+ /**
+ * Register a new symbol declaration.
+ * @param startOffset Starting position in file for the declaration of this symbol. Beginning of a file starts with offset '0'.
+ * @param endOffset End position in file for this symbol declaration.
+ * @deprecated since 5.6 Only supported to ease migration from old API. Please prefer {@link #newSymbol(int, int, int, int)}.
+ */
+ @Deprecated
+ NewSymbol newSymbol(int startOffset, int endOffset);
+
+ /**
+ * Register a new symbol declaration.
+ * @param range Range of text for the symbol declaration. See for example {@link InputFile#newRange(int, int, int, int)}.
+ */
+ NewSymbol newSymbol(TextRange range);
+
+ /**
+ * Shortcut to avoid calling {@link InputFile#newRange(int, int, int, int)}
+ */
+ NewSymbol newSymbol(int startLine, int startLineOffset, int endLine, int endLineOffset);
+
+ /**
+ * Call this method only once when your are done with defining all symbols of the file.
+ * @throws IllegalStateException if you have defined overlapping symbols
+ */
+ void save();
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/symbol/internal/DefaultSymbolTable.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/symbol/internal/DefaultSymbolTable.java
new file mode 100644
index 00000000000..ba4aa897646
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/symbol/internal/DefaultSymbolTable.java
@@ -0,0 +1,152 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.symbol.internal;
+
+import com.google.common.base.Preconditions;
+import java.util.Collection;
+import java.util.Comparator;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeSet;
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.TextRange;
+import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.sensor.internal.DefaultStorable;
+import org.sonar.api.batch.sensor.internal.SensorStorage;
+import org.sonar.api.batch.sensor.symbol.NewSymbol;
+import org.sonar.api.batch.sensor.symbol.NewSymbolTable;
+
+public class DefaultSymbolTable extends DefaultStorable implements NewSymbolTable {
+
+ private final Map<TextRange, Set<TextRange>> referencesBySymbol;
+ private DefaultInputFile inputFile;
+
+ public DefaultSymbolTable(SensorStorage storage) {
+ super(storage);
+ referencesBySymbol = new LinkedHashMap<>();
+ }
+
+ public Map<TextRange, Set<TextRange>> getReferencesBySymbol() {
+ return referencesBySymbol;
+ }
+
+ @Override
+ public DefaultSymbolTable onFile(InputFile inputFile) {
+ Preconditions.checkNotNull(inputFile, "file can't be null");
+ this.inputFile = (DefaultInputFile) inputFile;
+ return this;
+ }
+
+ public InputFile inputFile() {
+ return inputFile;
+ }
+
+ @Override
+ public NewSymbol newSymbol(int startLine, int startLineOffset, int endLine, int endLineOffset) {
+ checkInputFileNotNull();
+ TextRange declarationRange;
+ try {
+ declarationRange = inputFile.newRange(startLine, startLineOffset, endLine, endLineOffset);
+ } catch (Exception e) {
+ throw new IllegalArgumentException("Unable to create symbol on file " + inputFile, e);
+ }
+ return newSymbol(declarationRange);
+ }
+
+ @Override
+ public NewSymbol newSymbol(int startOffset, int endOffset) {
+ checkInputFileNotNull();
+ TextRange declarationRange;
+ try {
+ declarationRange = inputFile.newRange(startOffset, endOffset);
+ } catch (Exception e) {
+ throw new IllegalArgumentException("Unable to create symbol on file " + inputFile, e);
+ }
+ return newSymbol(declarationRange);
+ }
+
+ @Override
+ public NewSymbol newSymbol(TextRange range) {
+ checkInputFileNotNull();
+ TreeSet<TextRange> references = new TreeSet<>(new Comparator<TextRange>() {
+ @Override
+ public int compare(TextRange o1, TextRange o2) {
+ return o1.start().compareTo(o2.start());
+ }
+ });
+ referencesBySymbol.put(range, references);
+ return new DefaultSymbol(inputFile, range, references);
+ }
+
+ private static class DefaultSymbol implements NewSymbol {
+
+ private final Collection<TextRange> references;
+ private final DefaultInputFile inputFile;
+ private final TextRange declaration;
+
+ public DefaultSymbol(DefaultInputFile inputFile, TextRange declaration, Collection<TextRange> references) {
+ this.inputFile = inputFile;
+ this.declaration = declaration;
+ this.references = references;
+ }
+
+ @Override
+ public NewSymbol newReference(int startOffset, int endOffset) {
+ TextRange referenceRange;
+ try {
+ referenceRange = inputFile.newRange(startOffset, endOffset);
+ } catch (Exception e) {
+ throw new IllegalArgumentException("Unable to create symbol reference on file " + inputFile, e);
+ }
+ return newReference(referenceRange);
+ }
+
+ @Override
+ public NewSymbol newReference(int startLine, int startLineOffset, int endLine, int endLineOffset) {
+ TextRange referenceRange;
+ try {
+ referenceRange = inputFile.newRange(startLine, startLineOffset, endLine, endLineOffset);
+ } catch (Exception e) {
+ throw new IllegalArgumentException("Unable to create symbol reference on file " + inputFile, e);
+ }
+ return newReference(referenceRange);
+ }
+
+ @Override
+ public NewSymbol newReference(TextRange range) {
+ Preconditions.checkNotNull(range, "Provided range is null");
+ Preconditions.checkArgument(!declaration.overlap(range), "Overlapping symbol declaration and reference for symbol at %s", declaration);
+ references.add(range);
+ return this;
+ }
+
+ }
+
+ @Override
+ protected void doSave() {
+ checkInputFileNotNull();
+ storage.store(this);
+ }
+
+ private void checkInputFileNotNull() {
+ Preconditions.checkState(inputFile != null, "Call onFile() first");
+ }
+}
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/symbol/internal/package-info.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/symbol/internal/package-info.java
new file mode 100644
index 00000000000..532d1a1744a
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/symbol/internal/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.symbol.internal;
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/symbol/package-info.java b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/symbol/package-info.java
new file mode 100644
index 00000000000..ff6a1ac9138
--- /dev/null
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/batch/sensor/symbol/package-info.java
@@ -0,0 +1,21 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.symbol;
diff --git a/sonar-plugin-api/src/main/java/org/sonar/api/source/Symbolizable.java b/sonar-plugin-api/src/main/java/org/sonar/api/source/Symbolizable.java
index e6dac0d2840..1e40f26a23c 100644
--- a/sonar-plugin-api/src/main/java/org/sonar/api/source/Symbolizable.java
+++ b/sonar-plugin-api/src/main/java/org/sonar/api/source/Symbolizable.java
@@ -19,11 +19,10 @@
*/
package org.sonar.api.source;
+import java.util.List;
import org.sonar.api.component.Perspective;
import org.sonar.api.component.ResourcePerspectives;
-import java.util.List;
-
/**
* Use this perspective to save symbol references on files.
* See {@link ResourcePerspectives}.
@@ -44,7 +43,7 @@ public interface Symbolizable extends Perspective {
* The length of the reference is assumed to be the same as the symbol's length.
*/
void newReference(Symbol symbol, int fromOffset);
-
+
/**
* Creates a new reference for a symbol.
* The offsets are global in the file.
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/batch/sensor/DefaultSensorContext.java b/sonar-scanner-engine/src/main/java/org/sonar/batch/sensor/DefaultSensorContext.java
index 48dde9fd12d..f8a88f24b63 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/batch/sensor/DefaultSensorContext.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/batch/sensor/DefaultSensorContext.java
@@ -37,14 +37,18 @@ import org.sonar.api.batch.sensor.issue.NewIssue;
import org.sonar.api.batch.sensor.issue.internal.DefaultIssue;
import org.sonar.api.batch.sensor.measure.NewMeasure;
import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
+import org.sonar.api.batch.sensor.symbol.NewSymbolTable;
+import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable;
import org.sonar.api.config.Settings;
import org.sonar.api.utils.Version;
import org.sonar.batch.sensor.noop.NoOpNewCpdTokens;
import org.sonar.batch.sensor.noop.NoOpNewHighlighting;
+import org.sonar.batch.sensor.noop.NoOpNewSymbolTable;
public class DefaultSensorContext implements SensorContext {
private static final NoOpNewHighlighting NO_OP_NEW_HIGHLIGHTING = new NoOpNewHighlighting();
+ private static final NoOpNewSymbolTable NO_OP_NEW_SYMBOL_TABLE = new NoOpNewSymbolTable();
private static final NoOpNewCpdTokens NO_OP_NEW_CPD_TOKENS = new NoOpNewCpdTokens();
private final Settings settings;
@@ -110,6 +114,14 @@ public class DefaultSensorContext implements SensorContext {
}
@Override
+ public NewSymbolTable newSymbolTable() {
+ if (analysisMode.isIssues()) {
+ return NO_OP_NEW_SYMBOL_TABLE;
+ }
+ return new DefaultSymbolTable(sensorStorage);
+ }
+
+ @Override
public NewCoverage newCoverage() {
return new DefaultCoverage(sensorStorage);
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/batch/sensor/DefaultSensorStorage.java b/sonar-scanner-engine/src/main/java/org/sonar/batch/sensor/DefaultSensorStorage.java
index ce3ae500bd1..e80a5627c41 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/batch/sensor/DefaultSensorStorage.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/batch/sensor/DefaultSensorStorage.java
@@ -45,12 +45,12 @@ import org.sonar.api.batch.sensor.internal.SensorStorage;
import org.sonar.api.batch.sensor.issue.Issue;
import org.sonar.api.batch.sensor.measure.Measure;
import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure;
+import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable;
import org.sonar.api.config.Settings;
import org.sonar.api.measures.CoreMetrics;
import org.sonar.api.measures.Metric;
import org.sonar.api.resources.File;
import org.sonar.api.resources.Resource;
-import org.sonar.api.source.Symbol;
import org.sonar.api.utils.KeyValueFormat;
import org.sonar.api.utils.SonarException;
import org.sonar.batch.cpd.deprecated.DefaultCpdBlockIndexer;
@@ -62,7 +62,6 @@ import org.sonar.batch.report.ReportPublisher;
import org.sonar.batch.report.ScannerReportUtils;
import org.sonar.batch.scan.measure.MeasureCache;
import org.sonar.batch.sensor.coverage.CoverageExclusions;
-import org.sonar.batch.source.DefaultSymbol;
import org.sonar.duplications.block.Block;
import org.sonar.duplications.internal.pmd.PmdBlockChunker;
import org.sonar.scanner.protocol.output.ScannerReport;
@@ -199,22 +198,23 @@ public class DefaultSensorStorage implements SensorStorage {
Iterables.transform(highlighting.getSyntaxHighlightingRuleSet(), new BuildSyntaxHighlighting()));
}
- public void store(DefaultInputFile inputFile, Map<Symbol, Set<TextRange>> referencesBySymbol) {
+ @Override
+ public void store(DefaultSymbolTable symbolTable) {
ScannerReportWriter writer = reportPublisher.getWriter();
- writer.writeComponentSymbols(componentCache.get(inputFile).batchId(),
- Iterables.transform(referencesBySymbol.entrySet(), new Function<Map.Entry<Symbol, Set<TextRange>>, ScannerReport.Symbol>() {
+ writer.writeComponentSymbols(componentCache.get(symbolTable.inputFile()).batchId(),
+ Iterables.transform(symbolTable.getReferencesBySymbol().entrySet(), new Function<Map.Entry<TextRange, Set<TextRange>>, ScannerReport.Symbol>() {
private ScannerReport.Symbol.Builder builder = ScannerReport.Symbol.newBuilder();
private ScannerReport.TextRange.Builder rangeBuilder = ScannerReport.TextRange.newBuilder();
@Override
- public ScannerReport.Symbol apply(Map.Entry<Symbol, Set<TextRange>> input) {
+ public ScannerReport.Symbol apply(Map.Entry<TextRange, Set<TextRange>> input) {
builder.clear();
rangeBuilder.clear();
- DefaultSymbol symbol = (DefaultSymbol) input.getKey();
- builder.setDeclaration(rangeBuilder.setStartLine(symbol.range().start().line())
- .setStartOffset(symbol.range().start().lineOffset())
- .setEndLine(symbol.range().end().line())
- .setEndOffset(symbol.range().end().lineOffset())
+ TextRange declaration = input.getKey();
+ builder.setDeclaration(rangeBuilder.setStartLine(declaration.start().line())
+ .setStartOffset(declaration.start().lineOffset())
+ .setEndLine(declaration.end().line())
+ .setEndOffset(declaration.end().lineOffset())
.build());
for (TextRange reference : input.getValue()) {
builder.addReference(rangeBuilder.setStartLine(reference.start().line())
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/batch/sensor/noop/NoOpNewSymbolTable.java b/sonar-scanner-engine/src/main/java/org/sonar/batch/sensor/noop/NoOpNewSymbolTable.java
new file mode 100644
index 00000000000..46e8ed22e29
--- /dev/null
+++ b/sonar-scanner-engine/src/main/java/org/sonar/batch/sensor/noop/NoOpNewSymbolTable.java
@@ -0,0 +1,75 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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.sensor.noop;
+
+import org.sonar.api.batch.fs.InputFile;
+import org.sonar.api.batch.fs.TextRange;
+import org.sonar.api.batch.sensor.symbol.NewSymbol;
+import org.sonar.api.batch.sensor.symbol.NewSymbolTable;
+
+public class NoOpNewSymbolTable implements NewSymbolTable, NewSymbol {
+ @Override
+ public void save() {
+ // Do nothing
+ }
+
+ @Override
+ public NoOpNewSymbolTable onFile(InputFile inputFile) {
+ // Do nothing
+ return this;
+ }
+
+ @Override
+ public NewSymbol newSymbol(int startOffset, int endOffset) {
+ // Do nothing
+ return this;
+ }
+
+ @Override
+ public NewSymbol newSymbol(int startLine, int startLineOffset, int endLine, int endLineOffset) {
+ // Do nothing
+ return this;
+ }
+
+ @Override
+ public NewSymbol newSymbol(TextRange range) {
+ // Do nothing
+ return this;
+ }
+
+ @Override
+ public NewSymbol newReference(int startLine, int startLineOffset, int endLine, int endLineOffset) {
+ // Do nothing
+ return this;
+ }
+
+ @Override
+ public NewSymbol newReference(int startOffset, int endOffset) {
+ // Do nothing
+ return this;
+ }
+
+ @Override
+ public NewSymbol newReference(TextRange range) {
+ // Do nothing
+ return this;
+ }
+
+}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/batch/source/DefaultSymbolTable.java b/sonar-scanner-engine/src/main/java/org/sonar/batch/source/DefaultSymbolTable.java
deleted file mode 100644
index f4ecc8e3761..00000000000
--- a/sonar-scanner-engine/src/main/java/org/sonar/batch/source/DefaultSymbolTable.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program 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.
- *
- * This program 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 java.util.ArrayList;
-import java.util.Comparator;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.TreeSet;
-import org.sonar.api.batch.fs.TextRange;
-import org.sonar.api.batch.fs.internal.DefaultInputFile;
-import org.sonar.api.source.Symbol;
-import org.sonar.api.source.Symbolizable;
-
-public class DefaultSymbolTable implements Symbolizable.SymbolTable {
-
- private Map<Symbol, Set<TextRange>> referencesBySymbol;
-
- private DefaultSymbolTable(Map<Symbol, Set<TextRange>> referencesBySymbol) {
- this.referencesBySymbol = referencesBySymbol;
- }
-
- public Map<Symbol, Set<TextRange>> getReferencesBySymbol() {
- return referencesBySymbol;
- }
-
- @Override
- public List<Symbol> symbols() {
- List<Symbol> result = new ArrayList<>();
- for (Symbol symbol : referencesBySymbol.keySet()) {
- result.add((Symbol) symbol);
- }
- return result;
- }
-
- @Override
- public List<Integer> references(Symbol symbol) {
- throw new UnsupportedOperationException("references");
- }
-
- public static class Builder implements Symbolizable.SymbolTableBuilder {
-
- private static final class FakeSymbol implements Symbol {
- @Override
- public String getFullyQualifiedName() {
- return null;
- }
-
- @Override
- public int getDeclarationStartOffset() {
- return 0;
- }
-
- @Override
- public int getDeclarationEndOffset() {
- return 0;
- }
- }
-
- private final Map<Symbol, Set<TextRange>> referencesBySymbol = new LinkedHashMap<>();
- private final DefaultInputFile inputFile;
-
- public Builder(DefaultInputFile inputFile) {
- this.inputFile = inputFile;
- }
-
- @Override
- public Symbol newSymbol(int fromOffset, int toOffset) {
- TextRange declarationRange = inputFile.newRange(fromOffset, toOffset);
- DefaultSymbol symbol = new DefaultSymbol(declarationRange, toOffset - fromOffset);
- referencesBySymbol.put(symbol, new TreeSet<>(new Comparator<TextRange>() {
- @Override
- public int compare(TextRange o1, TextRange o2) {
- return o1.start().compareTo(o2.start());
- }
- }));
- return symbol;
- }
-
- @Override
- public void newReference(Symbol symbol, int fromOffset) {
- newReference(symbol, fromOffset, fromOffset + ((DefaultSymbol) symbol).getLength());
- }
-
- @Override
- public void newReference(Symbol symbol, int fromOffset, int toOffset) {
- if (!referencesBySymbol.containsKey(symbol)) {
- throw new UnsupportedOperationException("Cannot add reference to a symbol in another file");
- }
- TextRange referenceRange = inputFile.newRange(fromOffset, toOffset);
-
- if (referenceRange.overlap(((DefaultSymbol) symbol).range())) {
- throw new UnsupportedOperationException("Cannot add reference (" + fromOffset + ") overlapping " + symbol + " in " + inputFile.key());
- }
- referencesBySymbol.get(symbol).add(referenceRange);
- }
-
- @Override
- public Symbolizable.SymbolTable build() {
- return new DefaultSymbolTable(referencesBySymbol);
- }
-
- }
-}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/batch/source/DefaultSymbolizable.java b/sonar-scanner-engine/src/main/java/org/sonar/batch/source/DefaultSymbolizable.java
index cddeabb9683..04c7f560e9e 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/batch/source/DefaultSymbolizable.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/batch/source/DefaultSymbolizable.java
@@ -23,6 +23,7 @@ import java.util.Collections;
import java.util.List;
import org.sonar.api.batch.AnalysisMode;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
+import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable;
import org.sonar.api.source.Symbol;
import org.sonar.api.source.Symbolizable;
import org.sonar.batch.sensor.DefaultSensorStorage;
@@ -99,7 +100,7 @@ public class DefaultSymbolizable implements Symbolizable {
if (analysisMode.isIssues()) {
return NO_OP_SYMBOL_TABLE_BUILDER;
}
- return new DefaultSymbolTable.Builder(inputFile);
+ return new DeprecatedDefaultSymbolTable.Builder(new DefaultSymbolTable(sensorStorage).onFile(inputFile));
}
@Override
@@ -108,6 +109,6 @@ public class DefaultSymbolizable implements Symbolizable {
// No need for symbols in issues mode
return;
}
- sensorStorage.store(inputFile, ((DefaultSymbolTable) symbolTable).getReferencesBySymbol());
+ ((DeprecatedDefaultSymbolTable) symbolTable).getWrapped().save();
}
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/batch/source/DefaultSymbol.java b/sonar-scanner-engine/src/main/java/org/sonar/batch/source/DeprecatedDefaultSymbol.java
index a317bfb2de8..e63dc70b141 100644
--- a/sonar-scanner-engine/src/main/java/org/sonar/batch/source/DefaultSymbol.java
+++ b/sonar-scanner-engine/src/main/java/org/sonar/batch/source/DeprecatedDefaultSymbol.java
@@ -19,18 +19,15 @@
*/
package org.sonar.batch.source;
-import com.google.common.base.Objects;
-import org.sonar.api.batch.fs.TextRange;
+import org.sonar.api.batch.sensor.symbol.NewSymbol;
-import java.io.Serializable;
+public class DeprecatedDefaultSymbol implements org.sonar.api.source.Symbol {
-public class DefaultSymbol implements org.sonar.api.source.Symbol, Serializable {
+ private final NewSymbol wrapped;
+ private final int length;
- private TextRange range;
- private int length;
-
- public DefaultSymbol(TextRange range, int length) {
- this.range = range;
+ public DeprecatedDefaultSymbol(NewSymbol newSymbol, int length) {
+ this.wrapped = newSymbol;
this.length = length;
}
@@ -49,18 +46,12 @@ public class DefaultSymbol implements org.sonar.api.source.Symbol, Serializable
throw new UnsupportedOperationException("getFullyQualifiedName");
}
- public TextRange range() {
- return range;
+ public NewSymbol getWrapped() {
+ return wrapped;
}
public int getLength() {
return length;
}
- @Override
- public String toString() {
- return Objects.toStringHelper("Symbol")
- .add("range", range)
- .toString();
- }
}
diff --git a/sonar-scanner-engine/src/main/java/org/sonar/batch/source/DeprecatedDefaultSymbolTable.java b/sonar-scanner-engine/src/main/java/org/sonar/batch/source/DeprecatedDefaultSymbolTable.java
new file mode 100644
index 00000000000..a902b017e8c
--- /dev/null
+++ b/sonar-scanner-engine/src/main/java/org/sonar/batch/source/DeprecatedDefaultSymbolTable.java
@@ -0,0 +1,78 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program 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.
+ *
+ * This program 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 java.util.List;
+import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable;
+import org.sonar.api.source.Symbol;
+import org.sonar.api.source.Symbolizable;
+
+public class DeprecatedDefaultSymbolTable implements Symbolizable.SymbolTable {
+
+ private final DefaultSymbolTable wrapped;
+
+ public DeprecatedDefaultSymbolTable(DefaultSymbolTable wrapped) {
+ this.wrapped = wrapped;
+ }
+
+ public DefaultSymbolTable getWrapped() {
+ return wrapped;
+ }
+
+ @Override
+ public List<Symbol> symbols() {
+ throw new UnsupportedOperationException("symbols");
+ }
+
+ @Override
+ public List<Integer> references(Symbol symbol) {
+ throw new UnsupportedOperationException("references");
+ }
+
+ public static class Builder implements Symbolizable.SymbolTableBuilder {
+
+ private final DefaultSymbolTable symbolTable;
+
+ public Builder(DefaultSymbolTable symbolTable) {
+ this.symbolTable = symbolTable;
+ }
+
+ @Override
+ public Symbol newSymbol(int fromOffset, int toOffset) {
+ return new DeprecatedDefaultSymbol(symbolTable.newSymbol(fromOffset, toOffset), toOffset - fromOffset);
+ }
+
+ @Override
+ public void newReference(Symbol symbol, int fromOffset) {
+ ((DeprecatedDefaultSymbol) symbol).getWrapped().newReference(fromOffset, fromOffset + ((DeprecatedDefaultSymbol) symbol).getLength());
+ }
+
+ @Override
+ public void newReference(Symbol symbol, int fromOffset, int toOffset) {
+ ((DeprecatedDefaultSymbol) symbol).getWrapped().newReference(fromOffset, toOffset);
+ }
+
+ @Override
+ public Symbolizable.SymbolTable build() {
+ return new DeprecatedDefaultSymbolTable(symbolTable);
+ }
+
+ }
+}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/batch/source/DefaultSymbolizableTest.java b/sonar-scanner-engine/src/test/java/org/sonar/batch/source/DefaultSymbolizableTest.java
index f19a4b04099..a6dde755b35 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/batch/source/DefaultSymbolizableTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/batch/source/DefaultSymbolizableTest.java
@@ -21,18 +21,17 @@ package org.sonar.batch.source;
import com.google.common.base.Strings;
import java.io.StringReader;
-import java.util.Map;
import org.junit.Test;
import org.mockito.ArgumentCaptor;
import org.sonar.api.batch.AnalysisMode;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.fs.internal.FileMetadata;
+import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable;
import org.sonar.api.source.Symbol;
import org.sonar.api.source.Symbolizable;
import org.sonar.batch.sensor.DefaultSensorStorage;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
@@ -58,9 +57,9 @@ public class DefaultSymbolizableTest {
symbolPerspective.setSymbolTable(symbolTable);
- ArgumentCaptor<Map> argCaptor = ArgumentCaptor.forClass(Map.class);
- verify(sensorStorage).store(eq(inputFile), argCaptor.capture());
+ ArgumentCaptor<DefaultSymbolTable> argCaptor = ArgumentCaptor.forClass(DefaultSymbolTable.class);
+ verify(sensorStorage).store(argCaptor.capture());
// Map<Symbol, Set<TextRange>>
- assertThat(argCaptor.getValue().keySet()).hasSize(2);
+ assertThat(argCaptor.getValue().getReferencesBySymbol().keySet()).hasSize(2);
}
}
diff --git a/sonar-scanner-engine/src/test/java/org/sonar/batch/source/DefaultSymbolTableTest.java b/sonar-scanner-engine/src/test/java/org/sonar/batch/source/DeprecatedDefaultSymbolTableTest.java
index 86c7b7b316d..e8b6d6df380 100644
--- a/sonar-scanner-engine/src/test/java/org/sonar/batch/source/DefaultSymbolTableTest.java
+++ b/sonar-scanner-engine/src/test/java/org/sonar/batch/source/DeprecatedDefaultSymbolTableTest.java
@@ -19,23 +19,23 @@
*/
package org.sonar.batch.source;
-import org.sonar.api.batch.fs.TextRange;
import com.google.common.base.Strings;
-
import java.io.StringReader;
import java.util.Set;
-
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
+import org.sonar.api.batch.fs.TextRange;
import org.sonar.api.batch.fs.internal.DefaultInputFile;
import org.sonar.api.batch.fs.internal.FileMetadata;
+import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable;
import org.sonar.api.source.Symbol;
import org.sonar.api.source.Symbolizable;
+
import static org.assertj.core.api.Assertions.assertThat;
-public class DefaultSymbolTableTest {
+public class DeprecatedDefaultSymbolTableTest {
@Rule
public ExpectedException throwable = ExpectedException.none();
@@ -50,30 +50,31 @@ public class DefaultSymbolTableTest {
@Test
public void should_order_symbol_and_references() {
- Symbolizable.SymbolTableBuilder symbolTableBuilder = new DefaultSymbolTable.Builder(inputFile);
+ Symbolizable.SymbolTableBuilder symbolTableBuilder = new DeprecatedDefaultSymbolTable.Builder(new DefaultSymbolTable(null).onFile(inputFile));
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();
- assertThat(symbolTable.symbols()).containsExactly(firstSymbol, secondSymbol, thirdSymbol);
+ DeprecatedDefaultSymbolTable symbolTable = (DeprecatedDefaultSymbolTable) symbolTableBuilder.build();
+
+ assertThat(symbolTable.getWrapped().getReferencesBySymbol().keySet()).containsExactly(range(10, 20), range(84, 92), range(55, 62));
}
@Test
public void variable_length_references() {
- Symbolizable.SymbolTableBuilder symbolTableBuilder = new DefaultSymbolTable.Builder(inputFile);
+ Symbolizable.SymbolTableBuilder symbolTableBuilder = new DeprecatedDefaultSymbolTable.Builder(new DefaultSymbolTable(null).onFile(inputFile));
Symbol firstSymbol = symbolTableBuilder.newSymbol(10, 20);
symbolTableBuilder.newReference(firstSymbol, 32);
symbolTableBuilder.newReference(firstSymbol, 44, 47);
- DefaultSymbolTable symbolTable = (DefaultSymbolTable) symbolTableBuilder.build();
+ DeprecatedDefaultSymbolTable symbolTable = (DeprecatedDefaultSymbolTable) symbolTableBuilder.build();
- assertThat(symbolTable.symbols()).containsExactly(firstSymbol);
+ assertThat(symbolTable.getWrapped().getReferencesBySymbol().keySet()).containsExactly(range(10, 20));
- Set<TextRange> references = symbolTable.getReferencesBySymbol().get(firstSymbol);
+ Set<TextRange> references = symbolTable.getWrapped().getReferencesBySymbol().get(range(10, 20));
assertThat(references).containsExactly(range(32, 42), range(44, 47));
}
@@ -83,18 +84,11 @@ public class DefaultSymbolTableTest {
@Test
public void should_reject_reference_conflicting_with_declaration() {
- throwable.expect(UnsupportedOperationException.class);
+ throwable.expect(IllegalArgumentException.class);
- Symbolizable.SymbolTableBuilder symbolTableBuilder = new DefaultSymbolTable.Builder(inputFile);
+ Symbolizable.SymbolTableBuilder symbolTableBuilder = new DeprecatedDefaultSymbolTable.Builder(new DefaultSymbolTable(null).onFile(inputFile));
Symbol symbol = symbolTableBuilder.newSymbol(10, 20);
symbolTableBuilder.newReference(symbol, 15);
}
- @Test
- public void test_toString() throws Exception {
- Symbolizable.SymbolTableBuilder symbolTableBuilder = new DefaultSymbolTable.Builder(inputFile);
- Symbol symbol = symbolTableBuilder.newSymbol(10, 20);
-
- assertThat(symbol.toString()).isEqualTo("Symbol{range=Range[from [line=2, lineOffset=3] to [line=3, lineOffset=6]]}");
- }
}