diff options
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]]}"); - } } |