mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Search for missing class attributes in user skeletons (PY-9011)
This commit is contained in:
@@ -558,6 +558,7 @@
|
||||
|
||||
<!-- User skeletons -->
|
||||
<pyModuleMembersProvider implementation="com.jetbrains.python.codeInsight.userSkeletons.PyUserSkeletonsModuleMembersProvider"/>
|
||||
<pyClassMembersProvider implementation="com.jetbrains.python.codeInsight.userSkeletons.PyUserSkeletonsClassMembersProvider"/>
|
||||
<typeProvider implementation="com.jetbrains.python.codeInsight.userSkeletons.PyUserSkeletonsTypeProvider"/>
|
||||
|
||||
<typeProvider implementation="com.jetbrains.python.debugger.PyCallSignatureTypeProvider"/>
|
||||
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
package com.jetbrains.python.codeInsight.userSkeletons;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.jetbrains.python.codeInsight.PyDynamicMember;
|
||||
import com.jetbrains.python.psi.PyClass;
|
||||
import com.jetbrains.python.psi.PyFunction;
|
||||
import com.jetbrains.python.psi.PyTargetExpression;
|
||||
import com.jetbrains.python.psi.types.PyClassMembersProviderBase;
|
||||
import com.jetbrains.python.psi.types.PyClassType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author vlan
|
||||
*/
|
||||
public class PyUserSkeletonsClassMembersProvider extends PyClassMembersProviderBase {
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<PyDynamicMember> getMembers(@NotNull PyClassType classType, PsiElement location) {
|
||||
final PyClass cls = classType.getPyClass();
|
||||
final PyClass skeleton = PyUserSkeletonsUtil.getUserSkeleton(cls);
|
||||
if (skeleton != null) {
|
||||
return getClassMembers(skeleton);
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiElement resolveMember(@NotNull PyClassType classType, @NotNull String name, PsiElement location) {
|
||||
final PyClass cls = classType.getPyClass();
|
||||
final PyClass skeleton = PyUserSkeletonsUtil.getUserSkeleton(cls);
|
||||
if (skeleton != null) {
|
||||
return findClassMember(skeleton, name);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static PsiElement findClassMember(@NotNull PyClass cls, @NotNull String name) {
|
||||
final PyFunction function = cls.findMethodByName(name, false);
|
||||
if (function != null) {
|
||||
return function;
|
||||
}
|
||||
final PyTargetExpression instanceAttribute = cls.findInstanceAttribute(name, false);
|
||||
if (instanceAttribute != null) {
|
||||
return instanceAttribute;
|
||||
}
|
||||
final PyTargetExpression classAttribute = cls.findClassAttribute(name, false);
|
||||
if (classAttribute != null) {
|
||||
return classAttribute;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Collection<PyDynamicMember> getClassMembers(@NotNull PyClass cls) {
|
||||
final List<PyDynamicMember> result = new ArrayList<PyDynamicMember>();
|
||||
for (PyFunction function : cls.getMethods()) {
|
||||
final String name = function.getName();
|
||||
if (name != null) {
|
||||
result.add(new PyDynamicMember(name, function));
|
||||
}
|
||||
}
|
||||
for (PyTargetExpression attribute : cls.getInstanceAttributes()) {
|
||||
final String name = attribute.getName();
|
||||
if (name != null) {
|
||||
result.add(new PyDynamicMember(name, attribute));
|
||||
}
|
||||
}
|
||||
for (PyTargetExpression attribute : cls.getClassAttributes()) {
|
||||
final String name = attribute.getName();
|
||||
if (name != null) {
|
||||
result.add(new PyDynamicMember(name, attribute));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
from datetime import date
|
||||
|
||||
print(date.today)
|
||||
print(date.max)
|
||||
print(date.<warning descr="Unresolved attribute reference 'foo' for class 'date'">foo</warning>)
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
class date(object):
|
||||
@classmethod
|
||||
def today(cls):
|
||||
return date(0, 0, 0)
|
||||
+5
@@ -58,6 +58,11 @@ public class Py3UnresolvedReferencesInspectionTest extends PyTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
// PY-9011
|
||||
public void testDatetimeDateAttributesOutsideClass() {
|
||||
doMultiFileTest("a.py");
|
||||
}
|
||||
|
||||
public void testObjectNewAttributes() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user