mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
provide type, and therefore completion, for function decorated with @property (PY-5951)
This commit is contained in:
@@ -306,14 +306,18 @@ public class PyReferenceExpressionImpl extends PyElementImpl implements PyRefere
|
||||
PsiFile file = ((PsiDirectory)target).findFile(PyNames.INIT_DOT_PY);
|
||||
if (file != null) return getTypeFromTarget(file, context, anchor);
|
||||
}
|
||||
if (target instanceof PyFunction) {
|
||||
final PyDecoratorList decoratorList = ((PyFunction)target).getDecoratorList();
|
||||
if (decoratorList != null) {
|
||||
final PyDecorator decorator = decoratorList.findDecorator(PyNames.PROPERTY);
|
||||
if (decorator != null) {
|
||||
return PyBuiltinCache.getInstance(target).getObjectType(PyNames.PROPERTY);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PyType getTypeIfExpr(PyElement def, TypeEvalContext context) {
|
||||
return def instanceof PyExpression ? context.getType((PyExpression)def) : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static PyType getReferenceTypeFromProviders(@NotNull final PsiElement target,
|
||||
TypeEvalContext context,
|
||||
|
||||
@@ -8,9 +8,11 @@ import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.PlatformIcons;
|
||||
import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.codeInsight.completion.PyClassInsertHandler;
|
||||
import com.jetbrains.python.codeInsight.completion.PyFunctionInsertHandler;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.impl.PyBuiltinCache;
|
||||
import com.jetbrains.python.psi.types.PyType;
|
||||
import com.jetbrains.python.psi.types.TypeEvalContext;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -65,6 +67,13 @@ public class CompletionVariantsProcessor extends VariantsProcessor {
|
||||
}
|
||||
|
||||
private static boolean isSingleArgDecoratorCall(PsiElement elementInCall, PyFunction callee) {
|
||||
// special case hack to avoid the need of patching generator3.py
|
||||
PyClass containingClass = callee.getContainingClass();
|
||||
if (containingClass != null && PyNames.PROPERTY.equals(containingClass.getName()) &&
|
||||
PyBuiltinCache.getInstance(elementInCall).hasInBuiltins(containingClass)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (callee.getParameterList().getParameters().length > 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
class C(object):
|
||||
def __init__(self):
|
||||
self._x = None
|
||||
|
||||
@property
|
||||
def x(self):
|
||||
return self._x
|
||||
|
||||
@x.setter
|
||||
@@ -0,0 +1,9 @@
|
||||
class C(object):
|
||||
def __init__(self):
|
||||
self._x = None
|
||||
|
||||
@property
|
||||
def x(self):
|
||||
return self._x
|
||||
|
||||
@x.set<caret>
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.jetbrains.python;
|
||||
|
||||
import com.intellij.testFramework.LightProjectDescriptor;
|
||||
import com.jetbrains.python.fixtures.PyTestCase;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public class Py3CompletionTest extends PyTestCase {
|
||||
@Override
|
||||
protected LightProjectDescriptor getProjectDescriptor() {
|
||||
return ourPy3Descriptor;
|
||||
}
|
||||
|
||||
public void testPropertyDecorator() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
private void doTest() {
|
||||
final String testName = "completion/" + getTestName(true);
|
||||
myFixture.configureByFile(testName + ".py");
|
||||
myFixture.completeBasic();
|
||||
myFixture.checkResultByFile(testName + ".after.py");
|
||||
}
|
||||
}
|
||||
@@ -39,6 +39,7 @@ public class PythonAllTestsSuite {
|
||||
CythonResolveTest.class,
|
||||
PyAssignmentMappingTest.class,
|
||||
PythonCompletionTest.class,
|
||||
Py3CompletionTest.class,
|
||||
PyInheritorsSearchTest.class,
|
||||
PyParameterInfoTest.class,
|
||||
PyDecoratorTest.class,
|
||||
|
||||
Reference in New Issue
Block a user