Skip to content

Commit 33ea204

Browse files
authored
SONARPY-2346 Remove usage of old ProjectLevelSymbolTable#from using V1 symbols (#2199)
1 parent efcd828 commit 33ea204

File tree

10 files changed

+158
-289
lines changed

10 files changed

+158
-289
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ public static PythonVisitorContext createNotebookContext(File file, Map<Integer,
8181
}
8282

8383
public static ProjectLevelSymbolTable globalSymbols(List<File> files, File baseDir) {
84-
ProjectLevelSymbolTable projectLevelSymbolTable = new ProjectLevelSymbolTable();
84+
ProjectLevelSymbolTable projectLevelSymbolTable = ProjectLevelSymbolTable.empty();
8585
for (File file : files) {
8686
var pythonFile = new TestPythonFile(file);
8787
if (pythonFile.isIPython()) {

python-frontend/src/main/java/org/sonar/python/index/DescriptorUtils.java

Lines changed: 0 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,10 @@
1919
import java.util.Collections;
2020
import java.util.HashMap;
2121
import java.util.HashSet;
22-
import java.util.List;
2322
import java.util.Map;
24-
import java.util.Objects;
2523
import java.util.Set;
2624
import java.util.stream.Collectors;
2725
import javax.annotation.Nullable;
28-
import org.sonar.plugins.python.api.symbols.AmbiguousSymbol;
29-
import org.sonar.plugins.python.api.symbols.ClassSymbol;
30-
import org.sonar.plugins.python.api.symbols.FunctionSymbol;
3126
import org.sonar.plugins.python.api.symbols.Symbol;
3227
import org.sonar.plugins.python.api.types.InferredType;
3328
import org.sonar.python.semantic.AmbiguousSymbolImpl;
@@ -45,76 +40,6 @@ public class DescriptorUtils {
4540

4641
private DescriptorUtils() {}
4742

48-
public static Descriptor descriptor(Symbol symbol) {
49-
switch (symbol.kind()) {
50-
case FUNCTION:
51-
return functionDescriptor(((FunctionSymbol) symbol));
52-
case CLASS:
53-
return classDescriptor((ClassSymbol) symbol);
54-
case AMBIGUOUS:
55-
return ambiguousDescriptor((AmbiguousSymbol) symbol);
56-
default:
57-
return new VariableDescriptor(symbol.name(), symbol.fullyQualifiedName(), symbol.annotatedTypeName());
58-
}
59-
}
60-
61-
private static ClassDescriptor classDescriptor(ClassSymbol classSymbol) {
62-
ClassDescriptor.ClassDescriptorBuilder classDescriptor = new ClassDescriptor.ClassDescriptorBuilder()
63-
.withName(classSymbol.name())
64-
.withFullyQualifiedName(classSymbol.fullyQualifiedName())
65-
.withMembers(classSymbol.declaredMembers().stream().map(DescriptorUtils::descriptor).collect(Collectors.toSet()))
66-
.withSuperClasses(classSymbol.superClasses().stream().map(Symbol::fullyQualifiedName).filter(Objects::nonNull).toList())
67-
.withDefinitionLocation(classSymbol.definitionLocation())
68-
.withHasMetaClass(((ClassSymbolImpl) classSymbol).hasMetaClass())
69-
.withHasSuperClassWithoutDescriptor(((ClassSymbolImpl) classSymbol).hasSuperClassWithoutSymbol() ||
70-
// Setting hasSuperClassWithoutDescriptor if a parent has a null FQN as it would be impossible to retrieve it without one, even if the parent exists.
71-
classSymbol.superClasses().stream().anyMatch(s -> s.fullyQualifiedName() == null))
72-
.withMetaclassFQN(((ClassSymbolImpl) classSymbol).metaclassFQN())
73-
.withHasDecorators(classSymbol.hasDecorators())
74-
.withSupportsGenerics(((ClassSymbolImpl) classSymbol).supportsGenerics());
75-
76-
return classDescriptor.build();
77-
}
78-
79-
private static FunctionDescriptor functionDescriptor(FunctionSymbol functionSymbol) {
80-
return new FunctionDescriptor.FunctionDescriptorBuilder()
81-
.withName(functionSymbol.name())
82-
.withFullyQualifiedName(functionSymbol.fullyQualifiedName())
83-
.withParameters(parameters(functionSymbol.parameters()))
84-
.withHasDecorators(functionSymbol.hasDecorators())
85-
.withDecorators(functionSymbol.decorators())
86-
.withIsAsynchronous(functionSymbol.isAsynchronous())
87-
.withIsInstanceMethod(functionSymbol.isInstanceMethod())
88-
.withAnnotatedReturnTypeName(functionSymbol.annotatedReturnTypeName())
89-
.withDefinitionLocation(functionSymbol.definitionLocation())
90-
.build();
91-
}
92-
93-
private static AmbiguousDescriptor ambiguousDescriptor(AmbiguousSymbol ambiguousSymbol) {
94-
return ambiguousDescriptor(ambiguousSymbol, null);
95-
}
96-
97-
public static AmbiguousDescriptor ambiguousDescriptor(AmbiguousSymbol ambiguousSymbol, @Nullable String overriddenFQN) {
98-
String fullyQualifiedName = overriddenFQN != null ? overriddenFQN : ambiguousSymbol.fullyQualifiedName();
99-
Set<Descriptor> alternatives = ambiguousSymbol.alternatives().stream()
100-
.map(DescriptorUtils::descriptor)
101-
.collect(Collectors.toSet());
102-
return new AmbiguousDescriptor(ambiguousSymbol.name(), fullyQualifiedName, alternatives);
103-
}
104-
105-
private static List<FunctionDescriptor.Parameter> parameters(List<FunctionSymbol.Parameter> parameters) {
106-
return parameters.stream().map(parameter -> new FunctionDescriptor.Parameter(
107-
parameter.name(),
108-
((FunctionSymbolImpl.ParameterImpl) parameter).annotatedTypeName(),
109-
parameter.hasDefaultValue(),
110-
parameter.isKeywordOnly(),
111-
parameter.isPositionalOnly(),
112-
parameter.isPositionalVariadic(),
113-
parameter.isKeywordVariadic(),
114-
parameter.location()
115-
)).toList();
116-
}
117-
11843
// TODO SONARPY-958: Cleanup the symbol construction from descriptors by extracting this logic in a builder class
11944
public static Symbol symbolFromDescriptor(Descriptor descriptor, ProjectLevelSymbolTable projectLevelSymbolTable,
12045
@Nullable String localSymbolName, Map<Descriptor, Symbol> createdSymbolsByDescriptor, Map<String, Symbol> createdSymbolsByFqn) {

python-frontend/src/main/java/org/sonar/python/semantic/ProjectLevelSymbolTable.java

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -61,25 +61,22 @@ public class ProjectLevelSymbolTable {
6161
private TypeShedDescriptorsProvider typeShedDescriptorsProvider = null;
6262

6363
public static ProjectLevelSymbolTable empty() {
64-
return new ProjectLevelSymbolTable(Collections.emptyMap());
64+
return new ProjectLevelSymbolTable();
6565
}
6666

67-
public static ProjectLevelSymbolTable from(Map<String, Set<Symbol>> globalSymbolsByModuleName) {
68-
return new ProjectLevelSymbolTable(globalSymbolsByModuleName);
69-
}
67+
public static ProjectLevelSymbolTable from(Map<String, Set<Descriptor>> globalDescriptorsByModuleName) {
68+
var projectLevelSymbolTable = ProjectLevelSymbolTable.empty();
7069

71-
public ProjectLevelSymbolTable() {
72-
this.globalDescriptorsByModuleName = new HashMap<>();
70+
for (var entry : globalDescriptorsByModuleName.entrySet()) {
71+
var descriptors = entry.getValue();
72+
projectLevelSymbolTable.globalDescriptorsByModuleName.put(entry.getKey(), descriptors);
73+
}
74+
75+
return projectLevelSymbolTable;
7376
}
7477

75-
private ProjectLevelSymbolTable(Map<String, Set<Symbol>> globalSymbolsByModuleName) {
78+
private ProjectLevelSymbolTable() {
7679
this.globalDescriptorsByModuleName = new HashMap<>();
77-
globalSymbolsByModuleName.entrySet().forEach(entry -> {
78-
String moduleName = entry.getKey();
79-
Set<Symbol> symbols = entry.getValue();
80-
Set<Descriptor> globalDescriptors = symbols.stream().map(DescriptorUtils::descriptor).collect(Collectors.toSet());
81-
globalDescriptorsByModuleName.put(moduleName, globalDescriptors);
82-
});
8380
}
8481

8582
public void removeModule(String packageName, String fileName) {

python-frontend/src/test/java/org/sonar/plugins/python/api/PythonVisitorContextTest.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,7 @@
1818

1919
import com.sonar.sslr.api.RecognitionException;
2020
import java.io.File;
21-
import java.util.Arrays;
2221
import java.util.Collections;
23-
import java.util.HashSet;
24-
import java.util.List;
2522
import java.util.Map;
2623
import java.util.Set;
2724
import org.junit.jupiter.api.Test;
@@ -33,9 +30,10 @@
3330
import org.sonar.plugins.python.api.tree.Tree;
3431
import org.sonar.python.PythonTestUtils;
3532
import org.sonar.python.caching.CacheContextImpl;
33+
import org.sonar.python.index.Descriptor;
34+
import org.sonar.python.index.VariableDescriptor;
3635
import org.sonar.python.parser.PythonParser;
3736
import org.sonar.python.semantic.ProjectLevelSymbolTable;
38-
import org.sonar.python.semantic.SymbolImpl;
3937
import org.sonar.python.tree.FileInputImpl;
4038
import org.sonar.python.tree.PythonTreeMaker;
4139

@@ -82,9 +80,11 @@ void globalSymbols() {
8280
String code = "from mod import a, b";
8381
FileInput fileInput = new PythonTreeMaker().fileInput(PythonParser.create().parse(code));
8482
PythonFile pythonFile = pythonFile("my_module.py");
85-
List<Symbol> modSymbols = Arrays.asList(new SymbolImpl("a", null), new SymbolImpl("b", null));
86-
Map<String, Set<Symbol>> globalSymbols = Collections.singletonMap("mod", new HashSet<>(modSymbols));
87-
new PythonVisitorContext(fileInput, pythonFile, null, "my_package", ProjectLevelSymbolTable.from(globalSymbols), null);
83+
84+
Set<Descriptor> descriptors = Set.of(new VariableDescriptor("a", "mod.a", null), new VariableDescriptor("b", "mod.b", null));
85+
Map<String, Set<Descriptor>> globalDescriptors = Collections.singletonMap("mod", descriptors);
86+
87+
new PythonVisitorContext(fileInput, pythonFile, null, "my_package", ProjectLevelSymbolTable.from(globalDescriptors), CacheContextImpl.dummyCache());
8888
assertThat(fileInput.globalVariables()).extracting(Symbol::name).containsExactlyInAnyOrder("a", "b");
8989
}
9090

python-frontend/src/test/java/org/sonar/python/index/AmbiguousDescriptorTest.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
import java.util.Set;
2121
import org.junit.jupiter.api.Test;
2222
import org.sonar.plugins.python.api.tree.Name;
23-
import org.sonar.python.semantic.SymbolImpl;
2423
import org.sonar.python.semantic.v2.SymbolV2;
2524
import org.sonar.python.semantic.v2.converter.PythonTypeToDescriptorConverter;
2625
import org.sonar.python.types.v2.PythonType;
@@ -30,7 +29,6 @@
3029
import static org.assertj.core.api.Assertions.assertThatThrownBy;
3130
import static org.sonar.python.index.ClassDescriptorTest.lastClassDescriptor;
3231
import static org.sonar.python.index.DescriptorToProtobufTestUtils.assertDescriptorToProtobuf;
33-
import static org.sonar.python.index.DescriptorUtils.descriptor;
3432
import static org.sonar.python.index.FunctionDescriptorTest.lastFunctionDescriptor;
3533
import static org.sonar.python.types.v2.TypesTestUtils.lastName;
3634

@@ -110,10 +108,8 @@ void test_different_names_illegal_argument() {
110108

111109
@Test
112110
void ambiguous_descriptor_creation_different_name_same_fqn() {
113-
SymbolImpl foo = new SymbolImpl("foo", "mod.bar");
114-
SymbolImpl bar = new SymbolImpl("bar", "mod.bar");
115-
Descriptor fooDesc = descriptor(foo);
116-
Descriptor barDesc = descriptor(bar);
111+
Descriptor fooDesc = new VariableDescriptor("foo", "mod.bar", null, false);
112+
Descriptor barDesc = new VariableDescriptor("bar", "mod.bar", null, false);
117113
assertThatThrownBy(() -> AmbiguousDescriptor.create(fooDesc, barDesc)).isInstanceOf(IllegalArgumentException.class);
118114
}
119115

0 commit comments

Comments
 (0)