Skip to content

Commit 4911690

Browse files
maksim-grebeniuk-sonarsourcesonartech
authored andcommitted
SONARPY-2811 Share the ProjectLevelTypeTable instance across files rules execution (#216)
GitOrigin-RevId: c7c8ff947ad8efbb3f6d243ed1bf399ac64ba1b5
1 parent 63074d3 commit 4911690

4 files changed

Lines changed: 38 additions & 19 deletions

File tree

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

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
import java.util.ArrayList;
2525
import java.util.Collections;
2626
import java.util.Deque;
27-
import java.util.HashMap;
2827
import java.util.HashSet;
2928
import java.util.List;
3029
import java.util.Map;
@@ -56,7 +55,6 @@
5655
import org.sonar.plugins.python.api.PythonInputFileContext;
5756
import org.sonar.plugins.python.api.PythonSubscriptionCheck;
5857
import org.sonar.plugins.python.api.PythonVisitorContext;
59-
import org.sonar.plugins.python.api.internal.EndOfAnalysis;
6058
import org.sonar.plugins.python.api.quickfix.PythonQuickFix;
6159
import org.sonar.plugins.python.api.quickfix.PythonTextEdit;
6260
import org.sonar.plugins.python.api.tree.FileInput;
@@ -120,6 +118,7 @@ protected void scanFile(PythonInputFile inputFile) throws IOException {
120118
getWorkingDirectory(context),
121119
indexer.packageName(inputFile),
122120
indexer.projectLevelSymbolTable(),
121+
indexer.projectLevelTypeTable(),
123122
indexer.cacheContext(),
124123
context.runtime().getProduct());
125124
if (fileType == InputFile.Type.MAIN) {

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

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import org.sonar.plugins.python.api.tree.FileInput;
4343
import org.sonar.python.parser.PythonParser;
4444
import org.sonar.python.semantic.ProjectLevelSymbolTable;
45+
import org.sonar.python.semantic.v2.ProjectLevelTypeTable;
4546
import org.sonar.python.tree.PythonTreeMaker;
4647

4748
import static org.sonar.python.semantic.SymbolUtils.pythonPackageName;
@@ -55,11 +56,15 @@ public abstract class PythonIndexer {
5556
private final Map<URI, String> packageNames = new ConcurrentHashMap<>();
5657
private final Supplier<PythonParser> parserSupplier = PythonParser::create;
5758
private final ProjectLevelSymbolTable projectLevelSymbolTable = ProjectLevelSymbolTable.empty();
59+
private final ProjectLevelTypeTable projectLevelTypeTable = new ProjectLevelTypeTable(projectLevelSymbolTable);
5860

5961
public ProjectLevelSymbolTable projectLevelSymbolTable() {
6062
return projectLevelSymbolTable;
6163
}
6264

65+
public ProjectLevelTypeTable projectLevelTypeTable() {
66+
return projectLevelTypeTable;
67+
}
6368

6469
public String packageName(PythonInputFile inputFile) {
6570
if (!packageNames.containsKey(inputFile.wrappedFile().uri())) {

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

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -28,72 +28,87 @@
2828
import org.sonar.plugins.python.api.caching.CacheContext;
2929
import org.sonar.plugins.python.api.tree.FileInput;
3030
import org.sonar.plugins.python.api.types.v2.ModuleType;
31-
import org.sonar.python.types.v2.TypeChecker;
3231
import org.sonar.python.caching.CacheContextImpl;
3332
import org.sonar.python.semantic.ProjectLevelSymbolTable;
3433
import org.sonar.python.semantic.SymbolTableBuilder;
3534
import org.sonar.python.semantic.v2.ProjectLevelTypeTable;
3635
import org.sonar.python.semantic.v2.SymbolTableBuilderV2;
3736
import org.sonar.python.semantic.v2.TypeInferenceV2;
37+
import org.sonar.python.types.v2.TypeChecker;
3838

3939
public class PythonVisitorContext extends PythonInputFileContext {
4040

4141
private final FileInput rootTree;
4242
private final RecognitionException parsingException;
43-
private List<PreciseIssue> issues = new ArrayList<>();
4443
private final TypeChecker typeChecker;
4544
private ModuleType moduleType = null;
45+
private final List<PreciseIssue> issues;
4646

4747
public PythonVisitorContext(FileInput rootTree, PythonFile pythonFile, @Nullable File workingDirectory, String packageName) {
4848
super(pythonFile, workingDirectory, CacheContextImpl.dummyCache(), ProjectLevelSymbolTable.empty());
49-
this.rootTree = rootTree;
50-
this.parsingException = null;
49+
5150
SymbolTableBuilder symbolTableBuilder = new SymbolTableBuilder(packageName, pythonFile);
5251
symbolTableBuilder.visitFileInput(rootTree);
5352
var symbolTable = new SymbolTableBuilderV2(rootTree).build();
5453
var projectLevelTypeTable = new ProjectLevelTypeTable(ProjectLevelSymbolTable.empty());
54+
55+
this.rootTree = rootTree;
56+
this.parsingException = null;
5557
this.moduleType = new TypeInferenceV2(projectLevelTypeTable, pythonFile, symbolTable, packageName).inferModuleType(rootTree);
5658
this.typeChecker = new TypeChecker(projectLevelTypeTable);
59+
this.issues = new ArrayList<>();
5760
}
5861

5962
public PythonVisitorContext(FileInput rootTree, PythonFile pythonFile, @Nullable File workingDirectory, String packageName,
6063
ProjectLevelSymbolTable projectLevelSymbolTable, CacheContext cacheContext) {
6164
super(pythonFile, workingDirectory, cacheContext, projectLevelSymbolTable);
65+
66+
var symbolTableBuilder = new SymbolTableBuilder(packageName, pythonFile, projectLevelSymbolTable);
67+
symbolTableBuilder.visitFileInput(rootTree);
68+
var symbolTable = new SymbolTableBuilderV2(rootTree).build();
69+
var projectLevelTypeTable = new ProjectLevelTypeTable(projectLevelSymbolTable);
70+
6271
this.rootTree = rootTree;
6372
this.parsingException = null;
64-
new SymbolTableBuilder(packageName, pythonFile, projectLevelSymbolTable).visitFileInput(rootTree);
65-
var symbolTable = new SymbolTableBuilderV2(rootTree)
66-
.build();
67-
var projectLevelTypeTable = new ProjectLevelTypeTable(projectLevelSymbolTable);
6873
this.moduleType = new TypeInferenceV2(projectLevelTypeTable, pythonFile, symbolTable, packageName).inferModuleType(rootTree);
6974
this.typeChecker = new TypeChecker(projectLevelTypeTable);
75+
this.issues = new ArrayList<>();
7076
}
7177

7278
public PythonVisitorContext(FileInput rootTree, PythonFile pythonFile, @Nullable File workingDirectory, String packageName,
7379
ProjectLevelSymbolTable projectLevelSymbolTable, CacheContext cacheContext, SonarProduct sonarProduct) {
80+
this(rootTree, pythonFile, workingDirectory, packageName, projectLevelSymbolTable, new ProjectLevelTypeTable(projectLevelSymbolTable), cacheContext, sonarProduct);
81+
}
82+
83+
public PythonVisitorContext(FileInput rootTree, PythonFile pythonFile, @Nullable File workingDirectory, String packageName,
84+
ProjectLevelSymbolTable projectLevelSymbolTable, ProjectLevelTypeTable projectLevelTypeTable, CacheContext cacheContext, SonarProduct sonarProduct) {
7485
super(pythonFile, workingDirectory, cacheContext, sonarProduct, projectLevelSymbolTable);
75-
this.rootTree = rootTree;
76-
this.parsingException = null;
77-
new SymbolTableBuilder(packageName, pythonFile, projectLevelSymbolTable).visitFileInput(rootTree);
78-
var symbolTable = new SymbolTableBuilderV2(rootTree)
79-
.build();
80-
var projectLevelTypeTable = new ProjectLevelTypeTable(projectLevelSymbolTable);
86+
87+
var symbolTableBuilderV2 = new SymbolTableBuilderV2(rootTree);
88+
var symbolTable = symbolTableBuilderV2.build();
89+
var symbolTableBuilder = new SymbolTableBuilder(packageName, pythonFile, projectLevelSymbolTable);
90+
symbolTableBuilder.visitFileInput(rootTree);
8191
this.moduleType = new TypeInferenceV2(projectLevelTypeTable, pythonFile, symbolTable, packageName).inferModuleType(rootTree);
8292
this.typeChecker = new TypeChecker(projectLevelTypeTable);
93+
this.rootTree = rootTree;
94+
this.parsingException = null;
95+
this.issues = new ArrayList<>();
8396
}
8497

8598
public PythonVisitorContext(PythonFile pythonFile, RecognitionException parsingException) {
8699
super(pythonFile, null, CacheContextImpl.dummyCache(), ProjectLevelSymbolTable.empty());
87100
this.rootTree = null;
88101
this.parsingException = parsingException;
89102
this.typeChecker = new TypeChecker(new ProjectLevelTypeTable(ProjectLevelSymbolTable.empty()));
103+
this.issues = new ArrayList<>();
90104
}
91105

92106
public PythonVisitorContext(PythonFile pythonFile, RecognitionException parsingException, SonarProduct sonarProduct) {
93107
super(pythonFile, null, CacheContextImpl.dummyCache(), sonarProduct, ProjectLevelSymbolTable.empty());
94108
this.rootTree = null;
95109
this.parsingException = parsingException;
96110
this.typeChecker = new TypeChecker(new ProjectLevelTypeTable(ProjectLevelSymbolTable.empty()));
111+
this.issues = new ArrayList<>();
97112
}
98113

99114
public FileInput rootTree() {

python-frontend/src/main/java/org/sonar/python/semantic/v2/ProjectLevelTypeTable.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
public class ProjectLevelTypeTable implements TypeTable {
3030

3131
private final SymbolsModuleTypeProvider symbolsModuleTypeProvider;
32-
private final ModuleType rootModule;
32+
private final PythonType rootModule;
3333
private final LazyTypesContext lazyTypesContext;
3434

3535
public ProjectLevelTypeTable(ProjectLevelSymbolTable projectLevelSymbolTable) {
@@ -55,7 +55,7 @@ public PythonType getType(String... typeFqnParts) {
5555

5656
@Override
5757
public PythonType getType(List<String> typeFqnParts) {
58-
var parent = (PythonType) rootModule;
58+
var parent = rootModule;
5959
for (int i = 0; i < typeFqnParts.size(); i++) {
6060
var part = typeFqnParts.get(i);
6161
var moduleFqnParts = IntStream.rangeClosed(0, i)
@@ -104,7 +104,7 @@ private static boolean shouldResolveImmediately(LazyTypeWrapper lazyTypeWrapper,
104104
*/
105105
@Override
106106
public PythonType getModuleType(List<String> typeFqnParts) {
107-
var parent = (PythonType) rootModule;
107+
var parent = rootModule;
108108
for (int i = 0; i < typeFqnParts.size(); i++) {
109109
var part = typeFqnParts.get(i);
110110
var moduleFqnParts = IntStream.rangeClosed(0, i)

0 commit comments

Comments
 (0)