mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
PY-18726 Parse list of parameter type in square brackets inside typing.Callable
This commit is contained in:
committed by
Andrey Vlasovskikh
parent
6ee2663efe
commit
a30ecb2baf
@@ -355,7 +355,14 @@ public class PyTypingTypeProvider extends PyTypeProviderBase {
|
||||
return PyUnionType.union(elementTypes.get(0), PyNoneType.INSTANCE);
|
||||
}
|
||||
if ("typing.Callable".equals(qualifiedName) && elementTypes.size() == 2) {
|
||||
return new PyCallableTypeImpl(null, elementTypes.get(1));
|
||||
final List<PyCallableParameter> paramTypes = new ArrayList<>();
|
||||
final PyTupleType firstType = as(elementTypes.get(0), PyTupleType.class);
|
||||
if (firstType != null) {
|
||||
for (int i = 0; i < firstType.getElementCount(); i++) {
|
||||
paramTypes.add(new PyCallableParameterImpl(null, firstType.getElementType(i)));
|
||||
}
|
||||
return new PyCallableTypeImpl(paramTypes, elementTypes.get(1));
|
||||
}
|
||||
}
|
||||
if ("typing.Tuple".equals(qualifiedName)) {
|
||||
return PyTupleType.create(resolved, elementTypes.toArray(new PyType[elementTypes.size()]));
|
||||
|
||||
@@ -23,6 +23,7 @@ import com.intellij.psi.PsiDirectory;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.util.QualifiedName;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.hash.HashMap;
|
||||
import com.jetbrains.python.PyNames;
|
||||
@@ -325,14 +326,33 @@ public class PyTypeParser {
|
||||
.cached()
|
||||
.named("class-type");
|
||||
|
||||
final FunctionalParser<ParseResult, PyElementType> typeList =
|
||||
op("[").skipThen(maybe(typeExpr.then(many(op(",").skipThen(typeExpr))))).thenSkip(op("]"))
|
||||
.map(pair -> {
|
||||
if (pair != null) {
|
||||
final List<PyType> itemTypes = new ArrayList<>();
|
||||
ParseResult result = pair.getFirst();
|
||||
itemTypes.add(pair.getFirst().getType());
|
||||
for (ParseResult r : pair.getSecond()) {
|
||||
result = result.merge(r);
|
||||
itemTypes.add(r.getType());
|
||||
}
|
||||
final PyTupleType tupleType = PyTupleType.create(anchor, ArrayUtil.toObjectArray(itemTypes, PyType.class));
|
||||
return result.withType(tupleType);
|
||||
}
|
||||
return EMPTY_RESULT.withType(PyTupleType.create(anchor, new PyType[0]));
|
||||
});
|
||||
|
||||
final FunctionalParser<ParseResult, PyElementType> typeParam = typeExpr.or(typeList);
|
||||
|
||||
final FunctionalParser<ParseResult, PyElementType> paramExpr =
|
||||
classType.thenSkip(op("[")).then(typeExpr).then(many(op(",").skipThen(typeExpr))).thenSkip(op("]"))
|
||||
classType.thenSkip(op("[")).then(typeParam).then(many(op(",").skipThen(typeParam))).thenSkip(op("]"))
|
||||
.map(value -> {
|
||||
final Pair<ParseResult, ParseResult> firstPair = value.getFirst();
|
||||
final ParseResult first = firstPair.getFirst();
|
||||
final ParseResult second = firstPair.getSecond();
|
||||
final List<ParseResult> third = value.getSecond();
|
||||
final List<PyType> typesInBrackets = new ArrayList<PyType>();
|
||||
final List<PyType> typesInBrackets = new ArrayList<>();
|
||||
typesInBrackets.add(second.getType());
|
||||
ParseResult result = first;
|
||||
result = result.merge(second);
|
||||
@@ -352,13 +372,9 @@ public class PyTypeParser {
|
||||
})
|
||||
.named("param-expr");
|
||||
|
||||
final FunctionalParser<ParseResult, PyElementType> singleExpr =
|
||||
typeExpr.define(
|
||||
paramExpr
|
||||
.or(classType)
|
||||
.named("single-expr");
|
||||
|
||||
typeExpr
|
||||
.define(singleExpr)
|
||||
.or(classType))
|
||||
.named("type-expr");
|
||||
|
||||
final FunctionalParser<ParseResult, PyElementType> argExpr =
|
||||
|
||||
@@ -472,6 +472,16 @@ public class PyTypingTest extends PyTestCase {
|
||||
|
||||
}
|
||||
|
||||
// PY-18726
|
||||
public void testFunctionTypeCommentCallableParameter() {
|
||||
doTest("(bool, str) -> int",
|
||||
"from typing import Callable\n" +
|
||||
"\n" +
|
||||
"def f(cb):\n" +
|
||||
" # type: (Callable[[bool, str], int]) -> None\n" +
|
||||
" expr = cb");
|
||||
}
|
||||
|
||||
// PY-18386
|
||||
public void testRecursiveType() {
|
||||
doTest("Union[int, Any]",
|
||||
|
||||
Reference in New Issue
Block a user