diff --git a/python/src/com/jetbrains/python/psi/PyCallExpression.java b/python/src/com/jetbrains/python/psi/PyCallExpression.java index 87ff29572b8a..bb15d91f26ce 100644 --- a/python/src/com/jetbrains/python/psi/PyCallExpression.java +++ b/python/src/com/jetbrains/python/psi/PyCallExpression.java @@ -26,7 +26,7 @@ import org.jetbrains.annotations.Nullable; * To change this template use File | Settings | File Templates. */ public interface PyCallExpression extends PyExpression { - PyReferenceExpression getCalledFunctionReference(); + PyExpression getCallee(); PyArgumentList getArgumentList(); void addArgument(PyExpression expression); diff --git a/python/src/com/jetbrains/python/psi/impl/PyCallExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyCallExpressionImpl.java index 65a9817d6ebf..742c9a40e58c 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyCallExpressionImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyCallExpressionImpl.java @@ -42,8 +42,9 @@ public class PyCallExpressionImpl extends PyElementImpl implements PyCallExpress } @PsiCached - public PyReferenceExpression getCalledFunctionReference() { - return PsiTreeUtil.getChildOfType(this, PyReferenceExpression.class); + public PyExpression getCallee() { + //return PsiTreeUtil.getChildOfType(this, PyReferenceExpression.class); what we call can be whatever expr, not always a ref + return (PyExpression)getFirstChild(); } @PsiCached @@ -63,21 +64,24 @@ public class PyCallExpressionImpl extends PyElementImpl implements PyCallExpress } public PyElement resolveCallee() { - PyReferenceExpression calleeReference = getCalledFunctionReference(); + PyExpression calleeReference = getCallee(); return (PyElement) calleeReference.getReference().resolve(); } @Override public String toString() { - return "PyCallExpression: " + getCalledFunctionReference().getReferencedName(); + return "PyCallExpression: " + PyResolveUtil.getReadableRepr(getCallee()); //getCalledFunctionReference().getReferencedName(); } public PyType getType() { - PyReferenceExpression callee = getCalledFunctionReference(); - PsiElement target = callee.resolve(); - if (target instanceof PyClass) { - return new PyClassType((PyClass) target); + PyExpression callee = getCallee(); + if (callee instanceof PyReferenceExpression) { + PsiElement target = ((PyReferenceExpression)callee).resolve(); + if (target instanceof PyClass) { + return new PyClassType((PyClass) target); + } + return PyReferenceExpressionImpl.getReferenceTypeFromProviders(target); } - return PyReferenceExpressionImpl.getReferenceTypeFromProviders(target); + return callee.getType(); } } diff --git a/python/testData/psi/WithStatement2.txt b/python/testData/psi/WithStatement2.txt index 19489c4f4e2e..4f29c7dea2d3 100644 --- a/python/testData/psi/WithStatement2.txt +++ b/python/testData/psi/WithStatement2.txt @@ -37,7 +37,7 @@ PyFile:WithStatement2.py PsiElement(Py:WITH_KEYWORD)('with') PsiWhiteSpace(' ') PySubscriptionExpression - PyCallExpression: y + PyCallExpression: x.y PyReferenceExpression: y PyReferenceExpression: x PsiElement(Py:IDENTIFIER)('x') diff --git a/python/testData/resolve/ComplexCallee.py b/python/testData/resolve/ComplexCallee.py new file mode 100644 index 000000000000..d92834dd611f --- /dev/null +++ b/python/testData/resolve/ComplexCallee.py @@ -0,0 +1,2 @@ +x = method_table[method]() +x diff --git a/python/testSrc/com/jetbrains/python/PyResolveTest.java b/python/testSrc/com/jetbrains/python/PyResolveTest.java index f65a8820022b..67c939d0e1ed 100644 --- a/python/testSrc/com/jetbrains/python/PyResolveTest.java +++ b/python/testSrc/com/jetbrains/python/PyResolveTest.java @@ -26,6 +26,15 @@ public class PyResolveTest extends ResolveTestCase { assertTrue(targetElement instanceof PyFunction); } + // NOTE: maybe this test does not belong exactly here; still it's the best place currently. + public void testComplexCallee() throws Exception { + PsiElement targetElement = resolve(); + PyExpression assigned = ((PyAssignmentStatement) targetElement.getContext()).getAssignedValue(); + assertTrue(assigned instanceof PyCallExpression); + PsiElement callee = ((PyCallExpression)assigned).getCallee(); + assertTrue(callee instanceof PySubscriptionExpression); + } + public void testVar() throws Exception { PsiElement targetElement = resolve(); assertTrue(targetElement instanceof PyTargetExpression);