PY-24990 Initial attempt to support generic types for self and cls

by including the mapping for these special parameters in PyArgumentsMapping
This commit is contained in:
Mikhail Golubev
2017-12-15 15:14:12 +03:00
parent e7ebd7eaf1
commit b25fc9d6c9
2 changed files with 74 additions and 1 deletions
@@ -802,13 +802,22 @@ public class PyCallExpressionHelper {
filterExplicitParameters(parameters, callable, callSite, resolveContext);
final ArgumentMappingResults mappingResults = analyzeArguments(arguments, explicitParameters);
final Map<PyExpression, PyCallableParameter> mapped = new LinkedHashMap<>();
final PyExpression receiver = callSite.getReceiver(callable);
if (receiver != null && !explicitParameters.equals(parameters)) {
final PyCallableParameter first = ContainerUtil.getFirstItem(parameters);
if (first != null && first.getParameter() != null && first.getParameter().isSelf()) {
mapped.put(receiver, first);
}
}
mapped.putAll(mappingResults.getMappedParameters());
final PyCallExpression.PyMarkedCallee markedCallee =
new PyCallExpression.PyMarkedCallee(callableType, callable, null, 0, false, RatedResolveResult.RATE_NORMAL);
return new PyCallExpression.PyArgumentsMapping(callSite,
markedCallee,
mappingResults.getMappedParameters(),
mapped,
mappingResults.getUnmappedParameters(),
mappingResults.getUnmappedArguments(),
mappingResults.getParametersMappedToVariadicPositionalArguments(),
@@ -1083,6 +1083,70 @@ public class PyTypingTest extends PyTestCase {
"expr = C().attr");
}
// PY-24990
public void testSelfAnnotationSameClassInstance() {
doTest("C",
"from typing import TypeVar\n" +
"\n" +
"T = TypeVar('T')\n" +
"\n" +
"class C:\n" +
" def method(self: T) -> T:\n" +
" pass\n" +
"\n" +
"expr = C().method()");
}
// PY-24990
public void testSelfAnnotationSubclassInstance() {
doTest("D",
"from typing import TypeVar\n" +
"\n" +
"T = TypeVar('T')\n" +
"\n" +
"class C:\n" +
" def method(self: T) -> T:\n" +
" pass\n" +
"\n" +
"class D(C):\n" +
" pass\n" +
"\n" +
"expr = D().method()");
}
// PY-24990
public void testClsAnnotationSameClassInstance() {
doTest("C",
"from typing import TypeVar, Type\n" +
"\n" +
"T = TypeVar('T')\n" +
"\n" +
"class C:\n" +
" @classmethod\n" +
" def factory(cls: Type[T]) -> T:\n" +
" pass\n" +
"\n" +
"expr = C.factory()");
}
// PY-24990
public void testClsAnnotationSubclassInstance() {
doTest("D",
"from typing import TypeVar, Type\n" +
"\n" +
"T = TypeVar('T')\n" +
"\n" +
"class C:\n" +
" @classmethod\n" +
" def factory(cls: Type[T]) -> T:\n" +
" pass\n" +
"\n" +
"class D(C): \n" +
" pass\n" +
"\n" +
"expr = D.factory()");
}
private void doTestNoInjectedText(@NotNull String text) {
myFixture.configureByText(PythonFileType.INSTANCE, text);
final InjectedLanguageManager languageManager = InjectedLanguageManager.getInstance(myFixture.getProject());