Skip to content

Commit 5b0e767

Browse files
SONARPY-1217 Update Python API to expose data related to caching (#1299)
1 parent b4c8ded commit 5b0e767

File tree

30 files changed

+221
-42
lines changed

30 files changed

+221
-42
lines changed

python-checks-testkit/src/main/java/org/sonar/python/checks/utils/PythonCheckVerifier.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import org.sonar.plugins.python.api.tree.Trivia;
3636
import org.sonar.python.SubscriptionVisitor;
3737
import org.sonar.python.TestPythonVisitorRunner;
38+
import org.sonar.python.caching.CacheContextImpl;
3839
import org.sonar.python.semantic.ProjectLevelSymbolTable;
3940
import org.sonar.python.tree.TreeUtils;
4041
import org.sonarsource.analyzer.commons.checks.verifier.MultiFileVerifier;
@@ -81,7 +82,7 @@ private static MultiFileVerifier createVerifier(List<File> files, PythonCheck ch
8182
MultiFileVerifier multiFileVerifier = MultiFileVerifier.create(files.get(0).toPath(), UTF_8);
8283
for (File file : files) {
8384
PythonVisitorContext context = baseDir != null
84-
? TestPythonVisitorRunner.createContext(file, null, pythonPackageName(file, baseDir.getAbsolutePath()), projectLevelSymbolTable)
85+
? TestPythonVisitorRunner.createContext(file, null, pythonPackageName(file, baseDir.getAbsolutePath()), projectLevelSymbolTable, CacheContextImpl.dummyCache())
8586
: TestPythonVisitorRunner.createContext(file);
8687
addFileIssues(check, multiFileVerifier, file, context);
8788
}

python-checks/src/test/java/org/sonar/python/checks/quickfix/PythonQuickFixVerifier.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,16 @@
2828
import java.util.List;
2929
import java.util.stream.Collectors;
3030
import java.util.stream.Stream;
31+
import org.mockito.Mockito;
32+
import org.sonar.api.batch.fs.InputFile;
3133
import org.sonar.plugins.python.api.PythonCheck;
3234
import org.sonar.plugins.python.api.PythonCheck.PreciseIssue;
3335
import org.sonar.plugins.python.api.PythonFile;
3436
import org.sonar.plugins.python.api.PythonSubscriptionCheck;
3537
import org.sonar.plugins.python.api.PythonVisitorContext;
3638
import org.sonar.plugins.python.api.tree.FileInput;
3739
import org.sonar.python.SubscriptionVisitor;
40+
import org.sonar.python.caching.CacheContextImpl;
3841
import org.sonar.python.parser.PythonParser;
3942
import org.sonar.python.quickfix.IssueWithQuickFix;
4043
import org.sonar.python.quickfix.PythonQuickFix;
@@ -115,7 +118,7 @@ private static List<PreciseIssue> getIssuesWithQuickFix(PythonCheck check, Strin
115118

116119
PythonVisitorContext visitorContext = new PythonVisitorContext(parse,
117120
pythonFile, null, "",
118-
ProjectLevelSymbolTable.empty());
121+
ProjectLevelSymbolTable.empty(), CacheContextImpl.dummyCache());
119122

120123
return scanFileForIssues(check, visitorContext);
121124
}
@@ -247,5 +250,10 @@ public String fileName() {
247250
public URI uri() {
248251
return URI.create(this.fileName());
249252
}
253+
254+
@Override
255+
public String key() {
256+
return "PythonQuickFixFile";
257+
}
250258
}
251259
}

python-frontend/src/main/java/org/sonar/plugins/python/api/PythonCheck.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public interface PythonCheck {
3333
void scanFile(PythonVisitorContext visitorContext);
3434

3535
@Beta
36-
default boolean scanWithoutParsing(InputFile inputFile) {
36+
default boolean scanWithoutParsing(PythonInputFileContext inputFileContext) {
3737
return true;
3838
}
3939

python-frontend/src/main/java/org/sonar/plugins/python/api/PythonFile.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,6 @@ public interface PythonFile {
2929

3030
URI uri();
3131

32+
String key();
33+
3234
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* SonarQube Python Plugin
3+
* Copyright (C) 2011-2022 SonarSource SA
4+
* mailto:info AT sonarsource DOT com
5+
*
6+
* This program is free software; you can redistribute it and/or
7+
* modify it under the terms of the GNU Lesser General Public
8+
* License as published by the Free Software Foundation; either
9+
* version 3 of the License, or (at your option) any later version.
10+
*
11+
* This program is distributed in the hope that it will be useful,
12+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14+
* Lesser General Public License for more details.
15+
*
16+
* You should have received a copy of the GNU Lesser General Public License
17+
* along with this program; if not, write to the Free Software Foundation,
18+
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19+
*/
20+
package org.sonar.plugins.python.api;
21+
22+
import java.io.File;
23+
import javax.annotation.CheckForNull;
24+
import javax.annotation.Nullable;
25+
import org.sonar.plugins.python.api.caching.CacheContext;
26+
27+
public class PythonInputFileContext {
28+
29+
private final PythonFile pythonFile;
30+
private final File workingDirectory;
31+
private final CacheContext cacheContext;
32+
33+
public PythonInputFileContext(PythonFile pythonFile, @Nullable File workingDirectory, CacheContext cacheContext) {
34+
this.pythonFile = pythonFile;
35+
this.workingDirectory = workingDirectory;
36+
this.cacheContext = cacheContext;
37+
}
38+
39+
public PythonFile pythonFile() {
40+
return pythonFile;
41+
}
42+
43+
public CacheContext cacheContext() {
44+
return cacheContext;
45+
}
46+
47+
@CheckForNull
48+
public File workingDirectory() {
49+
return workingDirectory;
50+
}
51+
}

python-frontend/src/main/java/org/sonar/plugins/python/api/PythonVisitorContext.java

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -23,53 +23,46 @@
2323
import java.io.File;
2424
import java.util.ArrayList;
2525
import java.util.List;
26-
import javax.annotation.CheckForNull;
2726
import javax.annotation.Nullable;
2827
import org.sonar.plugins.python.api.PythonCheck.PreciseIssue;
28+
import org.sonar.plugins.python.api.caching.CacheContext;
2929
import org.sonar.plugins.python.api.tree.FileInput;
30+
import org.sonar.python.caching.CacheContextImpl;
3031
import org.sonar.python.semantic.ProjectLevelSymbolTable;
3132
import org.sonar.python.semantic.SymbolTableBuilder;
3233

33-
public class PythonVisitorContext {
34+
public class PythonVisitorContext extends PythonInputFileContext {
3435

3536
private final FileInput rootTree;
36-
private final PythonFile pythonFile;
37-
private File workingDirectory = null;
3837
private final RecognitionException parsingException;
3938
private List<PreciseIssue> issues = new ArrayList<>();
4039

41-
4240
public PythonVisitorContext(FileInput rootTree, PythonFile pythonFile, @Nullable File workingDirectory, @Nullable String packageName) {
41+
super(pythonFile, workingDirectory, CacheContextImpl.dummyCache());
4342
this.rootTree = rootTree;
44-
this.pythonFile = pythonFile;
45-
this.workingDirectory = workingDirectory;
4643
this.parsingException = null;
47-
SymbolTableBuilder symbolTableBuilder = packageName != null ? new SymbolTableBuilder(packageName, pythonFile): new SymbolTableBuilder(pythonFile);
44+
SymbolTableBuilder symbolTableBuilder = packageName != null ? new SymbolTableBuilder(packageName, pythonFile) : new SymbolTableBuilder(pythonFile);
4845
symbolTableBuilder.visitFileInput(rootTree);
4946
}
5047

51-
public PythonVisitorContext(FileInput rootTree, PythonFile pythonFile, @Nullable File workingDirectory, String packageName, ProjectLevelSymbolTable projectLevelSymbolTable) {
48+
public PythonVisitorContext(FileInput rootTree, PythonFile pythonFile, @Nullable File workingDirectory, String packageName,
49+
ProjectLevelSymbolTable projectLevelSymbolTable, CacheContext cacheContext) {
50+
super(pythonFile, workingDirectory, cacheContext);
5251
this.rootTree = rootTree;
53-
this.pythonFile = pythonFile;
54-
this.workingDirectory = workingDirectory;
5552
this.parsingException = null;
5653
new SymbolTableBuilder(packageName, pythonFile, projectLevelSymbolTable).visitFileInput(rootTree);
5754
}
5855

5956
public PythonVisitorContext(PythonFile pythonFile, RecognitionException parsingException) {
57+
super(pythonFile, null, CacheContextImpl.dummyCache());
6058
this.rootTree = null;
61-
this.pythonFile = pythonFile;
6259
this.parsingException = parsingException;
6360
}
6461

6562
public FileInput rootTree() {
6663
return rootTree;
6764
}
6865

69-
public PythonFile pythonFile() {
70-
return pythonFile;
71-
}
72-
7366
public RecognitionException parsingException() {
7467
return parsingException;
7568
}
@@ -81,9 +74,4 @@ public void addIssue(PreciseIssue issue) {
8174
public List<PreciseIssue> getIssues() {
8275
return issues;
8376
}
84-
85-
@CheckForNull
86-
public File workingDirectory() {
87-
return workingDirectory;
88-
}
8977
}

python-frontend/src/main/java/org/sonar/plugins/python/api/SubscriptionContext.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import java.util.Collection;
2525
import javax.annotation.CheckForNull;
2626
import javax.annotation.Nullable;
27+
import org.sonar.plugins.python.api.caching.CacheContext;
2728
import org.sonar.plugins.python.api.symbols.Symbol;
2829
import org.sonar.plugins.python.api.tree.Token;
2930
import org.sonar.plugins.python.api.tree.Tree;
@@ -56,4 +57,6 @@ public interface SubscriptionContext {
5657
*/
5758
@CheckForNull
5859
File workingDirectory();
60+
61+
CacheContext cacheContext();
5962
}

python-frontend/src/main/java/org/sonar/python/SubscriptionVisitor.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
import org.sonar.plugins.python.api.PythonSubscriptionCheck;
3939
import org.sonar.plugins.python.api.PythonVisitorContext;
4040
import org.sonar.plugins.python.api.SubscriptionContext;
41+
import org.sonar.plugins.python.api.caching.CacheContext;
4142
import org.sonar.plugins.python.api.symbols.Symbol;
4243
import org.sonar.plugins.python.api.tree.FileInput;
4344
import org.sonar.plugins.python.api.tree.StringElement;
@@ -169,6 +170,11 @@ public File workingDirectory() {
169170
return pythonVisitorContext.workingDirectory();
170171
}
171172

173+
@Override
174+
public CacheContext cacheContext() {
175+
return pythonVisitorContext.cacheContext();
176+
}
177+
172178
public RegexParseResult regexForStringElement(StringElement stringElement, FlagSet flagSet) {
173179
return regexCache.computeIfAbsent(stringElement.hashCode() + "-" + flagSet.getMask(),
174180
s -> new RegexParser(new PythonAnalyzerRegexSource(stringElement), flagSet).parse());

python-frontend/src/main/java/org/sonar/python/TestPythonVisitorRunner.java

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@
3030
import org.sonar.plugins.python.api.PythonCheck;
3131
import org.sonar.plugins.python.api.PythonFile;
3232
import org.sonar.plugins.python.api.PythonVisitorContext;
33+
import org.sonar.plugins.python.api.caching.CacheContext;
3334
import org.sonar.plugins.python.api.tree.FileInput;
35+
import org.sonar.python.caching.CacheContextImpl;
3436
import org.sonar.python.parser.PythonParser;
3537
import org.sonar.python.semantic.ProjectLevelSymbolTable;
3638
import org.sonar.python.tree.PythonTreeMaker;
@@ -55,15 +57,16 @@ public static PythonVisitorContext createContext(File file) {
5557
}
5658

5759
public static PythonVisitorContext createContext(File file, @Nullable File workingDirectory) {
58-
return createContext(file, workingDirectory, "", ProjectLevelSymbolTable.empty());
60+
return createContext(file, workingDirectory, "", ProjectLevelSymbolTable.empty(), CacheContextImpl.dummyCache());
5961
}
6062

61-
public static PythonVisitorContext createContext(File file, @Nullable File workingDirectory, String packageName, ProjectLevelSymbolTable projectLevelSymbolTable) {
63+
public static PythonVisitorContext createContext(File file, @Nullable File workingDirectory, String packageName,
64+
ProjectLevelSymbolTable projectLevelSymbolTable, CacheContext cacheContext) {
6265
PythonParser parser = PythonParser.create();
6366
TestPythonFile pythonFile = new TestPythonFile(file);
6467
AstNode astNode = parser.parse(pythonFile.content());
6568
FileInput rootTree = new PythonTreeMaker().fileInput(astNode);
66-
return new PythonVisitorContext(rootTree, pythonFile, workingDirectory, packageName, projectLevelSymbolTable);
69+
return new PythonVisitorContext(rootTree, pythonFile, workingDirectory, packageName, projectLevelSymbolTable, cacheContext);
6770
}
6871

6972
public static ProjectLevelSymbolTable globalSymbols(List<File> files, File baseDir) {
@@ -105,6 +108,11 @@ public URI uri() {
105108
return file.toURI();
106109
}
107110

111+
@Override
112+
public String key() {
113+
return file.getPath();
114+
}
115+
108116
}
109117

110118
}

sonar-python-plugin/src/main/java/org/sonar/plugins/python/caching/CacheContextImpl.java renamed to python-frontend/src/main/java/org/sonar/python/caching/CacheContextImpl.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
* along with this program; if not, write to the Free Software Foundation,
1818
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
1919
*/
20-
package org.sonar.plugins.python.caching;
20+
package org.sonar.python.caching;
2121

2222
import org.sonar.api.SonarProduct;
2323
import org.sonar.api.batch.sensor.SensorContext;
@@ -59,4 +59,8 @@ public static CacheContextImpl of(SensorContext context) {
5959
}
6060
return new CacheContextImpl(false, new DummyCache(), new DummyCache());
6161
}
62+
63+
public static CacheContextImpl dummyCache() {
64+
return new CacheContextImpl(false, new DummyCache(), new DummyCache());
65+
}
6266
}

0 commit comments

Comments
 (0)