mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Support six.add_metaclass decorator
This commit is contained in:
@@ -1455,9 +1455,58 @@ public class PyClassImpl extends PyBaseElementImpl<PyClassStub> implements PyCla
|
||||
}
|
||||
}
|
||||
|
||||
final PyDecoratorList decoratorList = getDecoratorList();
|
||||
if (decoratorList != null) {
|
||||
for (PyDecorator decorator : decoratorList.getDecorators()) {
|
||||
if (isSixAddMetaclass(decorator)) {
|
||||
final PyExpression[] arguments = decorator.getArguments();
|
||||
if (arguments.length != 0) {
|
||||
return arguments[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static boolean isSixAddMetaclass(@NotNull PyDecorator decorator) {
|
||||
final PyExpression callee = decorator.getCallee();
|
||||
if (callee != null && "add_metaclass".equals(callee.getName())) {
|
||||
// SUPPORTED CASES:
|
||||
|
||||
// import six
|
||||
// six.add_metaclass(...)
|
||||
|
||||
// from six import add_metaclass
|
||||
// add_metaclass(...)
|
||||
return true;
|
||||
}
|
||||
|
||||
if (callee instanceof PyReferenceExpression) {
|
||||
// SUPPORTED CASES:
|
||||
|
||||
// from six import add_metaclass as a_m
|
||||
// a_m(...)
|
||||
|
||||
final boolean importedAddMetaclass = StreamEx
|
||||
.of(PyResolveUtil.resolveLocally((PyReferenceExpression)callee))
|
||||
.select(PyImportElement.class)
|
||||
.map(PyImportElement::getImportedQName)
|
||||
.nonNull()
|
||||
.map(QualifiedName::getLastComponent)
|
||||
.nonNull()
|
||||
.findAny("add_metaclass"::equals)
|
||||
.isPresent();
|
||||
|
||||
if (importedAddMetaclass) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private List<PyClassLikeType> getMROAncestorTypes(@NotNull TypeEvalContext context) throws MROException {
|
||||
PyPsiUtils.assertValid(this);
|
||||
|
||||
@@ -1076,6 +1076,34 @@ public class PythonCompletionTest extends PyTestCase {
|
||||
});
|
||||
}
|
||||
|
||||
public void testSixAddMetaclass() {
|
||||
final List<String> suggested = doTestByText("import six\n" +
|
||||
"class M(type):\n" +
|
||||
" def baz(self):\n" +
|
||||
" pass\n" +
|
||||
"@six.add_metaclass(M)\n" +
|
||||
"class C(object):\n" +
|
||||
" def foo(self):\n" +
|
||||
" C.ba<caret>()");
|
||||
|
||||
assertNotNull(suggested);
|
||||
assertContainsElements(suggested, "baz");
|
||||
}
|
||||
|
||||
public void testSixAddMetaclassWithAs() {
|
||||
final List<String> suggested = doTestByText("from six import add_metaclass as a_m\n" +
|
||||
"class M(type):\n" +
|
||||
" def baz(self):\n" +
|
||||
" pass\n" +
|
||||
"@a_m(M)\n" +
|
||||
"class C(object):\n" +
|
||||
" def foo(self):\n" +
|
||||
" C.ba<caret>()");
|
||||
|
||||
assertNotNull(suggested);
|
||||
assertContainsElements(suggested, "baz");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getTestDataPath() {
|
||||
return super.getTestDataPath() + "/completion";
|
||||
|
||||
Reference in New Issue
Block a user