mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Fix collecting generics and type substituting for homogeneous tuples
This commit is contained in:
committed by
Semyon Proshev
parent
a93b24d7e6
commit
8349f69f4b
@@ -303,7 +303,7 @@ public class PyTypeChecker {
|
||||
}
|
||||
else if (type instanceof PyTupleType) {
|
||||
final PyTupleType tuple = (PyTupleType)type;
|
||||
final int n = tuple.getElementCount();
|
||||
final int n = tuple.isHomogeneous() ? 1 : tuple.getElementCount();
|
||||
for (int i = 0; i < n; i++) {
|
||||
collectGenerics(tuple.getElementType(i), context, collected, visited);
|
||||
}
|
||||
@@ -349,13 +349,19 @@ public class PyTypeChecker {
|
||||
}
|
||||
else if (type instanceof PyTupleType) {
|
||||
final PyTupleType tuple = (PyTupleType)type;
|
||||
final int n = tuple.getElementCount();
|
||||
final List<PyType> results = new ArrayList<>();
|
||||
for (int i = 0; i < n; i++) {
|
||||
final PyType subst = substitute(tuple.getElementType(i), substitutions, context);
|
||||
results.add(subst);
|
||||
|
||||
if (tuple.isHomogeneous()) {
|
||||
return PyTupleType.createHomogeneous(tuple.getPyClass(), substitute(tuple.getElementType(0), substitutions, context));
|
||||
} else {
|
||||
final int elementCount = tuple.getElementCount();
|
||||
final PyType[] elementTypes = new PyType[elementCount];
|
||||
|
||||
for (int i = 0; i < elementCount; i++) {
|
||||
elementTypes[i] = substitute(tuple.getElementType(i), substitutions, context);
|
||||
}
|
||||
|
||||
return PyTupleType.create(tuple.getPyClass(), elementTypes);
|
||||
}
|
||||
return new PyTupleType((PyTupleType)type, results.toArray(new PyType[results.size()]));
|
||||
}
|
||||
else if (type instanceof PyCallableType) {
|
||||
final PyCallableType callable = (PyCallableType)type;
|
||||
@@ -465,7 +471,7 @@ public class PyTypeChecker {
|
||||
if (callSite instanceof PyCallExpression) {
|
||||
final PyCallExpression callExpr = (PyCallExpression)callSite;
|
||||
final PyCallExpression.PyMarkedCallee callee = callExpr.resolveCallee(resolveContext);
|
||||
return callee != null ? Collections.singletonList(callee.getCallable()) : Collections.<PyCallable>emptyList();
|
||||
return callee != null ? Collections.singletonList(callee.getCallable()) : Collections.emptyList();
|
||||
}
|
||||
else if (callSite instanceof PySubscriptionExpression || callSite instanceof PyBinaryExpression) {
|
||||
final List<PyCallable> results = new ArrayList<>();
|
||||
@@ -484,7 +490,7 @@ public class PyTypeChecker {
|
||||
}
|
||||
resolvedToUnknownResult = true;
|
||||
}
|
||||
return resolvedToUnknownResult ? Collections.<PyCallable>emptyList() : results;
|
||||
return resolvedToUnknownResult ? Collections.emptyList() : results;
|
||||
}
|
||||
else {
|
||||
return Collections.emptyList();
|
||||
|
||||
@@ -886,6 +886,44 @@ public class PyTypeTest extends PyTestCase {
|
||||
" expr, foo = xs\n");
|
||||
}
|
||||
|
||||
public void testHomogeneousTupleSubstitution() {
|
||||
runWithLanguageLevel(
|
||||
LanguageLevel.PYTHON35,
|
||||
() -> {
|
||||
myFixture.copyDirectoryToProject("typing", "");
|
||||
|
||||
doTest("Tuple[int, ...]",
|
||||
"from typing import TypeVar, Tuple\n" +
|
||||
"T = TypeVar('T')\n" +
|
||||
"def foo(i: T) -> Tuple[T, ...]:\n" +
|
||||
" pass\n" +
|
||||
"expr = foo(5)");
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
public void testHeterogeneousTupleSubstitution() {
|
||||
doTest("tuple[int, int]",
|
||||
"def foo(i):\n" +
|
||||
" \"\"\"\n" +
|
||||
" :type i: T\n" +
|
||||
" :rtype: tuple[T, T]\n" +
|
||||
" \"\"\"\n" +
|
||||
" pass\n" +
|
||||
"expr = foo(5)");
|
||||
}
|
||||
|
||||
public void testUnknownTupleSubstitution() {
|
||||
doTest("tuple",
|
||||
"def foo(i):\n" +
|
||||
" \"\"\"\n" +
|
||||
" :type i: T\n" +
|
||||
" :rtype: tuple\n" +
|
||||
" \"\"\"\n" +
|
||||
" pass\n" +
|
||||
"expr = foo(5)");
|
||||
}
|
||||
|
||||
public void testTupleIterationType() {
|
||||
doTest("Union[int, str]",
|
||||
"xs = (1, 'a')\n" +
|
||||
|
||||
Reference in New Issue
Block a user