mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Update PyTypeChecker to pass PyTypeTest.testDictFromTuple.
If actual is union of tuples and expected is tuple then convert actual to tuple of unions and match it
This commit is contained in:
committed by
Semyon Proshev
parent
bfeaf9fe24
commit
d7f1990910
@@ -25,6 +25,7 @@ import com.jetbrains.python.psi.impl.PyBuiltinCache;
|
||||
import com.jetbrains.python.psi.impl.PyCallExpressionHelper;
|
||||
import com.jetbrains.python.psi.resolve.PyResolveContext;
|
||||
import com.jetbrains.python.psi.resolve.RatedResolveResult;
|
||||
import one.util.streamex.StreamEx;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
@@ -99,7 +100,18 @@ public class PyTypeChecker {
|
||||
return true;
|
||||
}
|
||||
if (actual instanceof PyUnionType) {
|
||||
for (PyType m : ((PyUnionType)actual).getMembers()) {
|
||||
final PyUnionType actualUnionType = (PyUnionType)actual;
|
||||
|
||||
if (expected instanceof PyTupleType) {
|
||||
final PyTupleType expectedTupleType = (PyTupleType)expected;
|
||||
final int elementCount = expectedTupleType.getElementCount();
|
||||
|
||||
if (!expectedTupleType.isHomogeneous() && consistsOfSameElementNumberTuples(actualUnionType, elementCount)) {
|
||||
return substituteExpectedElementsWithUnions(expectedTupleType, elementCount, actualUnionType, context, substitutions, recursive);
|
||||
}
|
||||
}
|
||||
|
||||
for (PyType m : actualUnionType.getMembers()) {
|
||||
if (match(expected, m, context, substitutions, recursive)) {
|
||||
return true;
|
||||
}
|
||||
@@ -244,6 +256,48 @@ public class PyTypeChecker {
|
||||
return matchNumericTypes(expected, actual);
|
||||
}
|
||||
|
||||
private static boolean consistsOfSameElementNumberTuples(@NotNull PyUnionType unionType, int elementCount) {
|
||||
for (PyType type : unionType.getMembers()) {
|
||||
if (type instanceof PyTupleType) {
|
||||
final PyTupleType tupleType = (PyTupleType)type;
|
||||
|
||||
if (!tupleType.isHomogeneous() && elementCount != tupleType.getElementCount()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean substituteExpectedElementsWithUnions(@NotNull PyTupleType expected,
|
||||
int elementCount,
|
||||
@NotNull PyUnionType actual,
|
||||
@NotNull TypeEvalContext context,
|
||||
@Nullable Map<PyGenericType, PyType> substitutions,
|
||||
boolean recursive) {
|
||||
for (int i = 0; i < elementCount; i++) {
|
||||
final int currentIndex = i;
|
||||
|
||||
final PyType elementType = PyUnionType.union(
|
||||
StreamEx
|
||||
.of(actual.getMembers())
|
||||
.select(PyTupleType.class)
|
||||
.map(type -> type.getElementType(currentIndex))
|
||||
.toList()
|
||||
);
|
||||
|
||||
if (!match(expected.getElementType(i), elementType, context, substitutions, recursive)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean matchNumericTypes(PyType expected, PyType actual) {
|
||||
final String superName = expected.getName();
|
||||
final String subName = actual.getName();
|
||||
|
||||
Reference in New Issue
Block a user