Skip to content

Commit 45fc428

Browse files
SONARPY-857 Add cross-file secondary location for SonarLint (#929)
1 parent 0becc84 commit 45fc428

File tree

4 files changed

+37
-4
lines changed

4 files changed

+37
-4
lines changed

sonar-python-plugin/src/main/java/org/sonar/plugins/python/PythonScanner.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import java.util.ArrayList;
2727
import java.util.Deque;
2828
import java.util.List;
29+
import java.util.Optional;
2930
import java.util.Set;
3031
import javax.annotation.CheckForNull;
3132
import org.sonar.api.SonarProduct;
@@ -172,8 +173,9 @@ private void saveIssues(InputFile inputFile, List<PreciseIssue> issues) {
172173
}
173174

174175
@CheckForNull
175-
private static InputFile component(String fileId, SensorContext sensorContext) {
176-
InputFile inputFile = sensorContext.fileSystem().inputFile(sensorContext.fileSystem().predicates().is(new File(fileId)));
176+
private InputFile component(String fileId, SensorContext sensorContext) {
177+
InputFile inputFile = Optional.ofNullable(sensorContext.fileSystem().inputFile(sensorContext.fileSystem().predicates().is(new File(fileId))))
178+
.orElseGet(() -> indexer.getFileWithId(fileId));
177179
if (inputFile == null) {
178180
LOG.debug("Failed to find InputFile for {}", fileId);
179181
}

sonar-python-plugin/src/main/java/org/sonar/plugins/python/indexer/PythonIndexer.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import java.net.URI;
2525
import java.util.HashMap;
2626
import java.util.Map;
27+
import javax.annotation.CheckForNull;
2728
import org.sonar.api.batch.fs.InputFile;
2829
import org.sonar.api.batch.sensor.SensorContext;
2930
import org.sonar.api.utils.log.Logger;
@@ -77,6 +78,12 @@ void addFile(InputFile inputFile) throws IOException {
7778

7879
public abstract void buildOnce(SensorContext context);
7980

81+
@CheckForNull
82+
public InputFile getFileWithId(String fileId) {
83+
// no op by default
84+
return null;
85+
}
86+
8087
class GlobalSymbolsScanner extends Scanner {
8188

8289
protected GlobalSymbolsScanner(SensorContext context) {

sonar-python-plugin/src/main/java/org/sonar/plugins/python/indexer/SonarLintPythonIndexer.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,9 @@
2222
import java.io.IOException;
2323
import java.util.ArrayList;
2424
import java.util.Collections;
25+
import java.util.HashMap;
2526
import java.util.List;
27+
import java.util.Map;
2628
import org.sonar.api.batch.fs.InputFile;
2729
import org.sonar.api.batch.sensor.SensorContext;
2830
import org.sonar.api.utils.log.Logger;
@@ -37,6 +39,7 @@
3739
public class SonarLintPythonIndexer extends PythonIndexer implements ModuleFileListener {
3840

3941
private final ModuleFileSystem moduleFileSystem;
42+
private final Map<String, InputFile> indexedFiles = new HashMap<>();
4043
private static final Logger LOG = Loggers.get(SonarLintPythonIndexer.class);
4144
private boolean shouldBuildProjectSymbolTable = true;
4245
private static final long DEFAULT_MAX_LINES_FOR_INDEXING = 150_000;
@@ -67,12 +70,30 @@ public void buildOnce(SensorContext context) {
6770
globalSymbolsStep.execute(files, context);
6871
}
6972

73+
@Override
74+
public InputFile getFileWithId(String fileId) {
75+
String compare = fileId.replace("\\", "/");
76+
return indexedFiles.getOrDefault(compare, null);
77+
}
78+
7079
private static List<InputFile> getInputFiles(ModuleFileSystem moduleFileSystem) {
7180
List<InputFile> files = new ArrayList<>();
7281
moduleFileSystem.files(Python.KEY, InputFile.Type.MAIN).forEach(files::add);
7382
return Collections.unmodifiableList(files);
7483
}
7584

85+
@Override
86+
void addFile(InputFile inputFile) throws IOException {
87+
super.addFile(inputFile);
88+
indexedFiles.put(inputFile.absolutePath(), inputFile);
89+
}
90+
91+
@Override
92+
void removeFile(InputFile inputFile) {
93+
super.removeFile(inputFile);
94+
indexedFiles.remove(inputFile.absolutePath());
95+
}
96+
7697
@Override
7798
public void process(ModuleFileEvent moduleFileEvent) {
7899
InputFile target = moduleFileEvent.getTarget();

sonar-python-plugin/src/test/java/org/sonar/plugins/python/PythonSensorTest.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -316,8 +316,11 @@ public void cross_files_issues_only_one_file_analyzed() {
316316
assertThat(context.allIssues()).hasSize(1);
317317
Issue issue = context.allIssues().iterator().next();
318318
assertThat(issue.primaryLocation().inputComponent()).isEqualTo(mainFile);
319-
// Secondary location outside of analyzed file is missing
320-
assertThat(issue.flows()).isEmpty();
319+
assertThat(issue.flows()).hasSize(1);
320+
Issue.Flow flow = issue.flows().get(0);
321+
assertThat(flow.locations()).hasSize(2);
322+
assertThat(flow.locations().get(0).inputComponent()).isEqualTo(mainFile);
323+
assertThat(flow.locations().get(1).inputComponent()).isEqualTo(modFile);
321324
}
322325

323326
@Test

0 commit comments

Comments
 (0)