Skip to content

Commit

Permalink
SONAR-7512 New symbol reference API
Browse files Browse the repository at this point in the history
  • Loading branch information
henryju committed May 10, 2016
1 parent 5ae4a89 commit 08aef06
Show file tree
Hide file tree
Showing 21 changed files with 679 additions and 252 deletions.
Expand Up @@ -32,6 +32,7 @@
import org.sonar.api.batch.sensor.issue.NewIssue; import org.sonar.api.batch.sensor.issue.NewIssue;
import org.sonar.api.batch.sensor.measure.Measure; import org.sonar.api.batch.sensor.measure.Measure;
import org.sonar.api.batch.sensor.measure.NewMeasure; 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.config.Settings;
import org.sonar.api.utils.Version; import org.sonar.api.utils.Version;


Expand Down Expand Up @@ -89,9 +90,13 @@ public interface SensorContext {
*/ */
NewHighlighting newHighlighting(); 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 ------------ // ------------ TESTS ------------


Expand Down
Expand Up @@ -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 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 endOffset End position in file for this type of text.
* @param typeOfText see {@link TypeOfText} values. * @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); NewHighlighting highlight(int startOffset, int endOffset, TypeOfText typeOfText);


/** /**
Expand Down
@@ -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);
}

}
@@ -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;
}
}
Expand Up @@ -20,22 +20,19 @@
package org.sonar.api.batch.sensor.internal; package org.sonar.api.batch.sensor.internal;


import com.google.common.annotations.Beta; 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.File;
import java.io.Serializable; import java.io.Serializable;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import javax.annotation.CheckForNull; import javax.annotation.CheckForNull;
import org.sonar.api.SonarQubeVersion; import org.sonar.api.SonarQubeVersion;
import org.sonar.api.batch.AnalysisMode;
import org.sonar.api.batch.fs.InputModule; 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.DefaultFileSystem;
import org.sonar.api.batch.fs.internal.DefaultInputModule; import org.sonar.api.batch.fs.internal.DefaultInputModule;
import org.sonar.api.batch.fs.internal.DefaultTextPointer; import org.sonar.api.batch.fs.internal.DefaultTextPointer;
Expand All @@ -58,6 +55,8 @@
import org.sonar.api.batch.sensor.measure.Measure; import org.sonar.api.batch.sensor.measure.Measure;
import org.sonar.api.batch.sensor.measure.NewMeasure; import org.sonar.api.batch.sensor.measure.NewMeasure;
import org.sonar.api.batch.sensor.measure.internal.DefaultMeasure; 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.config.Settings;
import org.sonar.api.internal.SonarQubeVersionFactory; import org.sonar.api.internal.SonarQubeVersionFactory;
import org.sonar.api.measures.Metric; import org.sonar.api.measures.Metric;
Expand Down Expand Up @@ -236,6 +235,11 @@ public NewCpdTokens newCpdTokens() {
return new DefaultCpdTokens(settings, sensorStorage); return new DefaultCpdTokens(settings, sensorStorage);
} }


@Override
public NewSymbolTable newSymbolTable() {
return new DefaultSymbolTable(sensorStorage);
}

public List<TypeOfText> highlightingTypeAt(String componentKey, int line, int lineOffset) { public List<TypeOfText> highlightingTypeAt(String componentKey, int line, int lineOffset) {
DefaultHighlighting syntaxHighlightingData = sensorStorage.highlightingByComponent.get(componentKey); DefaultHighlighting syntaxHighlightingData = sensorStorage.highlightingByComponent.get(componentKey);
if (syntaxHighlightingData == null) { if (syntaxHighlightingData == null) {
Expand All @@ -251,73 +255,18 @@ public List<TypeOfText> highlightingTypeAt(String componentKey, int line, int li
return result; return result;
} }


public static class MockAnalysisMode implements AnalysisMode { public Collection<TextRange> referencesForSymbolAt(String componentKey, int line, int lineOffset) {
private boolean isPreview = false; DefaultSymbolTable symbolTable = sensorStorage.symbolsPerComponent.get(componentKey);
private boolean isIssues = false; if (symbolTable == null) {

return Collections.emptyList();
@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);
} }

DefaultTextPointer location = new DefaultTextPointer(line, lineOffset);
@Override for (Map.Entry<TextRange, Set<TextRange>> symbol : symbolTable.getReferencesBySymbol().entrySet()) {
public void store(DefaultCoverage defaultCoverage) { if (symbol.getKey().start().compareTo(location) <= 0 && symbol.getKey().end().compareTo(location) > 0) {
String key = defaultCoverage.inputFile().key(); return symbol.getValue();
if (!coverageByComponent.containsKey(key)) {
coverageByComponent.put(key, new EnumMap<CoverageType, DefaultCoverage>(CoverageType.class));
} }
coverageByComponent.get(key).put(defaultCoverage.type(), defaultCoverage);
} }

return Collections.emptyList();
@Override
public void store(DefaultCpdTokens defaultCpdTokens) {
cpdTokensByComponent.put(defaultCpdTokens.inputFile().key(), defaultCpdTokens);
}

} }


} }
Expand Up @@ -25,6 +25,7 @@
import org.sonar.api.batch.sensor.highlighting.internal.DefaultHighlighting; import org.sonar.api.batch.sensor.highlighting.internal.DefaultHighlighting;
import org.sonar.api.batch.sensor.issue.Issue; import org.sonar.api.batch.sensor.issue.Issue;
import org.sonar.api.batch.sensor.measure.Measure; import org.sonar.api.batch.sensor.measure.Measure;
import org.sonar.api.batch.sensor.symbol.internal.DefaultSymbolTable;


/** /**
* Interface for storing data computed by sensors. * Interface for storing data computed by sensors.
Expand All @@ -49,4 +50,9 @@ public interface SensorStorage {
*/ */
void store(DefaultCpdTokens defaultCpdTokens); void store(DefaultCpdTokens defaultCpdTokens);


/**
* @since 5.6
*/
void store(DefaultSymbolTable symbolTable);

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

0 comments on commit 08aef06

Please sign in to comment.