Update PyDocumentationBuilder to use type evaluation context while resolving docstring owner.

This commit is contained in:
Semyon Proshev
2017-06-15 14:40:48 +03:00
parent 804354727e
commit dbff481450
4 changed files with 17 additions and 9 deletions

View File

@@ -87,7 +87,7 @@ public class PyDocumentationBuilder {
final TypeEvalContext context = TypeEvalContext.userInitiated(myElement.getProject(), myElement.getContainingFile());
final PsiElement outerElement = myOriginalElement != null ? myOriginalElement.getParent() : null;
final PsiElement elementDefinition = resolveToDocStringOwner();
final PsiElement elementDefinition = resolveToDocStringOwner(context);
final boolean isProperty = buildFromProperty(elementDefinition, outerElement, context);
if (myProlog.isEmpty() && !isProperty && !isAttribute()) {
@@ -311,14 +311,14 @@ public class PyDocumentationBuilder {
}
@Nullable
private PsiElement resolveToDocStringOwner() {
private PsiElement resolveToDocStringOwner(@NotNull TypeEvalContext context) {
// here the ^Q target is already resolved; the resolved element may point to intermediate assignments
if (myElement instanceof PyTargetExpression) {
final String targetName = myElement.getText();
myReassignmentChain.addWith(TagSmall, $(PyBundle.message("QDOC.assigned.to.$0", targetName)).addItem(BR));
final PyExpression assignedValue = ((PyTargetExpression)myElement).findAssignedValue();
if (assignedValue instanceof PyReferenceExpression) {
final PsiElement resolved = resolveWithoutImplicits((PyReferenceExpression)assignedValue);
final PsiElement resolved = resolveWithoutImplicits((PyReferenceExpression)assignedValue, context);
if (resolved != null) {
return resolved;
}
@@ -327,7 +327,7 @@ public class PyDocumentationBuilder {
}
if (myElement instanceof PyReferenceExpression) {
myReassignmentChain.addWith(TagSmall, $(PyBundle.message("QDOC.assigned.to.$0", myElement.getText())).addItem(BR));
return resolveWithoutImplicits((PyReferenceExpression)myElement);
return resolveWithoutImplicits((PyReferenceExpression)myElement, context);
}
// it may be a call to a standard wrapper
if (myElement instanceof PyCallExpression) {
@@ -343,8 +343,10 @@ public class PyDocumentationBuilder {
return myElement;
}
private static PsiElement resolveWithoutImplicits(@NotNull PyReferenceExpression element) {
final QualifiedResolveResult resolveResult = element.followAssignmentsChain(PyResolveContext.noImplicits());
@Nullable
private static PsiElement resolveWithoutImplicits(@NotNull PyReferenceExpression element, @NotNull TypeEvalContext context) {
final PyResolveContext resolveContext = PyResolveContext.noImplicits().withTypeEvalContext(context);
final QualifiedResolveResult resolveResult = element.followAssignmentsChain(resolveContext);
return resolveResult.isImplicit() ? null : resolveResult.getElement();
}

View File

@@ -0,0 +1 @@
<html><body><small>Assigned to <code>c1</code><br></small><code><small>class <a href="psi_element://#class#">list</a>()</small><br><br>def <b>count</b>(self,&nbsp;object:&nbsp;_T)<br>Inferred&nbsp;type:&nbsp;(self:&nbsp;<a href="psi_element://#typename#list">list</a>,&nbsp;object:&nbsp;TypeVar('_T'))&nbsp;-&gt;&nbsp;<a href="psi_element://#typename#int">int</a><br><br>L.count(value)&nbsp;-&gt;&nbsp;integer&nbsp;--&nbsp;return&nbsp;number&nbsp;of&nbsp;occurrences&nbsp;of&nbsp;value&nbsp;</code></body></html>

View File

@@ -0,0 +1,3 @@
my_list = [1, 2, 2, 3, 3]
c1 = my_list.count
print(<the_ref>c1)

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
* Copyright 2000-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -279,13 +279,11 @@ public class PyQuickDocTest extends LightMarkedTestCase {
}
public void testTypeVars() {
myFixture.copyDirectoryToProject("typing", "");
runWithLanguageLevel(LanguageLevel.PYTHON35, this::checkHTMLOnly);
}
// PY-22730
public void testOptionalAndUnionTypesContainingTypeVars() {
myFixture.copyDirectoryToProject("typing", "");
runWithLanguageLevel(LanguageLevel.PYTHON36, this::checkHTMLOnly);
}
@@ -293,4 +291,8 @@ public class PyQuickDocTest extends LightMarkedTestCase {
public void testBuiltinLen() {
checkHTMLOnly();
}
public void testReferenceToMethodQualifiedWithInstance() {
checkHTMLOnly();
}
}