Skip to content

Commit 9a2f999

Browse files
andreaguarinoguillaume-dequenne
authored andcommitted
SONARPY-728 Introduce InferredTypes#typeSymbols internal API
1 parent 3922032 commit 9a2f999

3 files changed

Lines changed: 33 additions & 0 deletions

File tree

python-frontend/src/main/java/org/sonar/python/types/InferredTypes.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,13 @@
1919
*/
2020
package org.sonar.python.types;
2121

22+
import java.util.Collection;
2223
import java.util.Collections;
2324
import java.util.HashMap;
25+
import java.util.HashSet;
2426
import java.util.List;
2527
import java.util.Map;
28+
import java.util.Set;
2629
import java.util.stream.Stream;
2730
import javax.annotation.Nullable;
2831
import org.sonar.plugins.python.api.symbols.AmbiguousSymbol;
@@ -149,4 +152,16 @@ private static InferredType optionalDeclaredType(List<Expression> subscripts, Ma
149152
InferredType noneType = InferredTypes.runtimeType(builtinSymbols.get(BuiltinTypes.NONE_TYPE));
150153
return InferredTypes.or(declaredType(subscripts.get(0), builtinSymbols), noneType);
151154
}
155+
156+
public static Collection<ClassSymbol> typeSymbols(InferredType inferredType) {
157+
if (inferredType instanceof RuntimeType) {
158+
return Collections.singleton(((RuntimeType) inferredType).getTypeClass());
159+
}
160+
if (inferredType instanceof UnionType) {
161+
Set<ClassSymbol> typeClasses = new HashSet<>();
162+
((UnionType) inferredType).types().forEach(type -> typeClasses.addAll(typeSymbols(type)));
163+
return typeClasses;
164+
}
165+
return Collections.emptySet();
166+
}
152167
}

python-frontend/src/main/java/org/sonar/python/types/RuntimeType.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,4 +131,8 @@ public int hashCode() {
131131
public String toString() {
132132
return "RuntimeType(" + typeClass.fullyQualifiedName() + ')';
133133
}
134+
135+
public ClassSymbol getTypeClass() {
136+
return typeClass;
137+
}
134138
}

python-frontend/src/test/java/org/sonar/python/types/InferredTypesTest.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,12 @@
3232
import org.sonar.python.semantic.SymbolImpl;
3333

3434
import static org.assertj.core.api.Assertions.assertThat;
35+
import static org.sonar.python.types.InferredTypes.INT;
36+
import static org.sonar.python.types.InferredTypes.STR;
3537
import static org.sonar.python.types.InferredTypes.anyType;
3638
import static org.sonar.python.types.InferredTypes.or;
3739
import static org.sonar.python.types.InferredTypes.runtimeType;
40+
import static org.sonar.python.types.TypeShed.typeShedClass;
3841

3942
public class InferredTypesTest {
4043

@@ -123,6 +126,17 @@ public void test_optional_type_annotations() {
123126
assertThat(InferredTypes.declaredType(typeAnnotation)).isEqualTo(InferredTypes.anyType());
124127
}
125128

129+
@Test
130+
public void test_typeSymbol() {
131+
assertThat(InferredTypes.typeSymbols(STR)).containsExactly(typeShedClass("str"));
132+
133+
ClassSymbol a = new ClassSymbolImpl("A", "mod.A");
134+
assertThat(InferredTypes.typeSymbols(new RuntimeType(a))).containsExactly(a);
135+
136+
assertThat(InferredTypes.typeSymbols(or(STR, INT))).containsExactlyInAnyOrder(typeShedClass("str"), typeShedClass("int"));
137+
assertThat(InferredTypes.typeSymbols(InferredTypes.anyType())).isEmpty();
138+
}
139+
126140
private TypeAnnotation typeAnnotation(String... code) {
127141
return PythonTestUtils.getLastDescendant(PythonTestUtils.parse(code), tree -> tree.is(Tree.Kind.VARIABLE_TYPE_ANNOTATION));
128142
}

0 commit comments

Comments
 (0)