Merge branch 'python-fixes'

This commit is contained in:
Andrey Vlasovskikh
2013-07-29 20:24:50 +04:00
6 changed files with 49 additions and 21 deletions
@@ -100,8 +100,8 @@ public class PythonDocumentationProvider extends AbstractDocumentationProvider i
return describeDecorators(cls, LSame2, ", ", LSame1).add(describeClass(cls, LSame2, false, false)).toString() + "\n" + summary;
}
else if (element instanceof PyTargetExpression || element instanceof PyNamedParameter) {
return describeExpression((PyExpression)element);
else if (element instanceof PyExpression) {
return describeExpression((PyExpression)element, originalElement);
}
return null;
}
@@ -131,7 +131,7 @@ public class PythonDocumentationProvider extends AbstractDocumentationProvider i
}
@Nullable
private static String describeExpression(PyExpression expr) {
private static String describeExpression(@NotNull PyExpression expr, @NotNull PsiElement originalElement) {
final String name = expr.getName();
if (name != null) {
StringBuilder result = new StringBuilder((expr instanceof PyNamedParameter) ? "parameter" : "variable");
@@ -143,15 +143,17 @@ public class PythonDocumentationProvider extends AbstractDocumentationProvider i
result.append(String.format(" \"%s\"", function.getName()));
}
}
result.append("\n").append(describeExpressionType(expr));
if (originalElement instanceof PyTypedElement) {
result.append("\n").append(describeType((PyTypedElement)originalElement));
}
return result.toString();
}
return null;
}
static String describeExpressionType(PyExpression expr) {
final TypeEvalContext context = TypeEvalContext.userInitiated(expr.getContainingFile());
return String.format("Inferred type: %s", getTypeName(context.getType(expr), context));
static String describeType(@NotNull PyTypedElement element) {
final TypeEvalContext context = TypeEvalContext.userInitiated(element.getContainingFile());
return String.format("Inferred type: %s", getTypeName(context.getType(element), context));
}
public static String getTypeDescription(@NotNull PyFunction fun) {
@@ -400,23 +400,26 @@ public class PyFunctionImpl extends PyPresentableElementImpl<PyFunctionStub> imp
@Nullable
private String extractReturnType() {
final String ARROW = "->";
final StructuredDocString structuredDocString = getStructuredDocString();
if (structuredDocString != null) {
return structuredDocString.getReturnType();
}
final String docString = getDocStringValue();
if (docString == null) {
return null;
}
final List<String> lines = StringUtil.split(docString, "\n");
while (lines.size() > 0 && lines.get(0).trim().length() == 0) {
lines.remove(0);
}
if (lines.size() > 1 && lines.get(1).trim().length() == 0) {
String firstLine = lines.get(0);
int pos = firstLine.lastIndexOf("->");
if (pos >= 0) {
return firstLine.substring(pos + 2).trim();
if (docString != null && docString.contains(ARROW)) {
final List<String> lines = StringUtil.split(docString, "\n");
while (lines.size() > 0 && lines.get(0).trim().length() == 0) {
lines.remove(0);
}
if (lines.size() > 1 && lines.get(1).trim().length() == 0) {
String firstLine = lines.get(0);
int pos = firstLine.lastIndexOf(ARROW);
if (pos >= 0) {
return firstLine.substring(pos + 2).trim();
}
}
}
final StructuredDocString structuredDocString = getStructuredDocString();
return structuredDocString != null ? structuredDocString.getReturnType() : null;
return null;
}
private static class ReturnVisitor extends PyRecursiveElementVisitor {
@@ -0,0 +1,2 @@
variable "x"
Inferred type: one of (str, int)
@@ -0,0 +1,6 @@
def foo(c):
if c:
x = 'foo'
else:
x = 1
return <the_ref>x
@@ -216,4 +216,8 @@ public class PyQuickDocTest extends LightMarkedTestCase {
public void testHoverOverParameter() {
checkHover();
}
public void testHoverOverControlFlowUnion() {
checkHover();
}
}
@@ -629,6 +629,17 @@ public class PyTypeTest extends PyTestCase {
assertTrue(PyTypeChecker.isUnknown(type));
}
public void testParameterOfFunctionTypeAndReturnValue() {
doTest("int",
"def func(f):\n" +
" '''\n" +
" :type f: (unknown) -> str\n" +
" '''\n" +
" return 1\n" +
"\n" +
"expr = func(foo)\n");
}
private static TypeEvalContext getTypeEvalContext(@NotNull PyExpression element) {
return TypeEvalContext.userInitiated(element.getContainingFile()).withTracing();
}