Skip to content

Commit d94d0e1

Browse files
SONARPY-1889 implementation of type shed to symbol conversion for v2 type inference
1 parent 8324a5a commit d94d0e1

File tree

3 files changed

+908
-5
lines changed

3 files changed

+908
-5
lines changed

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

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,17 @@
2525
import java.util.Map;
2626
import java.util.Optional;
2727
import java.util.Set;
28+
import java.util.function.Function;
2829
import java.util.function.Predicate;
2930
import java.util.stream.Collectors;
3031
import javax.annotation.Nullable;
3132
import org.sonar.plugins.python.api.symbols.AmbiguousSymbol;
3233
import org.sonar.plugins.python.api.symbols.ClassSymbol;
3334
import org.sonar.plugins.python.api.symbols.FunctionSymbol;
3435
import org.sonar.plugins.python.api.symbols.Symbol;
36+
import org.sonar.python.semantic.ClassSymbolImpl;
3537
import org.sonar.python.semantic.ProjectLevelSymbolTable;
36-
import org.sonar.python.types.TypeShed;
38+
import org.sonar.python.semantic.SymbolImpl;
3739
import org.sonar.python.types.v2.ClassType;
3840
import org.sonar.python.types.v2.FunctionType;
3941
import org.sonar.python.types.v2.Member;
@@ -44,13 +46,15 @@
4446

4547
public class SymbolsModuleTypeProvider {
4648
private final ProjectLevelSymbolTable projectLevelSymbolTable;
49+
private final TypeShed typeShed;
4750

4851
public SymbolsModuleTypeProvider(ProjectLevelSymbolTable projectLevelSymbolTable) {
4952
this.projectLevelSymbolTable = projectLevelSymbolTable;
53+
typeShed = new TypeShed();
5054
}
5155

5256
public ModuleType createBuiltinModule() {
53-
return createModuleFromSymbols(null, null, TypeShed.builtinSymbols().values());
57+
return createModuleFromSymbols(null, null, typeShed.builtinSymbols().values());
5458
}
5559

5660
public ModuleType createModuleType(List<String> moduleFqn, ModuleType parent) {
@@ -71,7 +75,7 @@ private Optional<ModuleType> createModuleTypeFromProjectLevelSymbolTable(String
7175
}
7276

7377
private Optional<ModuleType> createModuleTypeFromTypeShed(String moduleName, String moduleFqn, ModuleType parent) {
74-
return Optional.ofNullable(TypeShed.symbolsForModuleWithoutStoreInCache(moduleFqn))
78+
return Optional.ofNullable(typeShed.symbolsForModule(moduleFqn))
7579
.filter(Predicate.not(Map::isEmpty))
7680
.map(typeShedModuleSymbols -> createModuleFromSymbols(moduleName, parent, typeShedModuleSymbols.values()));
7781
}
@@ -143,11 +147,32 @@ private PythonType convertToClassType(ClassSymbol symbol, Map<Symbol, PythonType
143147
Set<Member> members =
144148
symbol.declaredMembers().stream().map(m -> new Member(m.name(), convertToType(m, createdTypesBySymbol))).collect(Collectors.toSet());
145149
classType.members().addAll(members);
146-
List<PythonType> superClasses = symbol.superClasses().stream().map(s -> convertToType(s, createdTypesBySymbol)).toList();
147-
classType.superClasses().addAll(superClasses);
150+
151+
152+
Optional.of(symbol)
153+
.filter(ClassSymbolImpl.class::isInstance)
154+
.map(ClassSymbolImpl.class::cast)
155+
.filter(ClassSymbolImpl::shouldSearchHierarchyInTypeshed)
156+
.map(ClassSymbol::superClassesFqn)
157+
.map(fqns -> fqns.stream().map(this::typeshedSymbolWithFQN))
158+
.or(() -> Optional.of(symbol)
159+
.map(ClassSymbol::superClasses)
160+
.map(Collection::stream))
161+
.stream()
162+
.flatMap(Function.identity())
163+
.map(s -> convertToType(s, createdTypesBySymbol))
164+
.forEach(classType.superClasses()::add);
165+
148166
return classType;
149167
}
150168

169+
private Symbol typeshedSymbolWithFQN(String fullyQualifiedName) {
170+
String[] fqnSplitByDot = fullyQualifiedName.split("\\.");
171+
String localName = fqnSplitByDot[fqnSplitByDot.length - 1];
172+
Symbol symbol = typeShed.symbolWithFQN(fullyQualifiedName);
173+
return symbol == null ? new SymbolImpl(localName, fullyQualifiedName) : ((SymbolImpl) symbol).copyWithoutUsages();
174+
}
175+
151176
private PythonType convertToUnionType(AmbiguousSymbol ambiguousSymbol, Map<Symbol, PythonType> createdTypesBySymbol) {
152177
Set<PythonType> pythonTypes = ambiguousSymbol.alternatives().stream().map(a -> convertToType(a, createdTypesBySymbol)).collect(Collectors.toSet());
153178
return new UnionType(pythonTypes);

0 commit comments

Comments
 (0)