mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-10-01 19:02:13 +07:00
Merge branch 'python-fixes'
This commit is contained in:
+24
-13
@@ -20,6 +20,7 @@ import com.jetbrains.python.codeInsight.PyCustomMember;
|
||||
import com.jetbrains.python.psi.PyClass;
|
||||
import com.jetbrains.python.psi.PyFunction;
|
||||
import com.jetbrains.python.psi.PyTargetExpression;
|
||||
import com.jetbrains.python.psi.PyUtil;
|
||||
import com.jetbrains.python.psi.types.PyClassMembersProviderBase;
|
||||
import com.jetbrains.python.psi.types.PyClassType;
|
||||
import com.jetbrains.python.psi.types.PyOverridingAncestorsClassMembersProvider;
|
||||
@@ -42,7 +43,7 @@ public class PyUserSkeletonsClassMembersProvider extends PyClassMembersProviderB
|
||||
final PyClass cls = classType.getPyClass();
|
||||
final PyClass skeleton = PyUserSkeletonsUtil.getUserSkeleton(cls);
|
||||
if (skeleton != null) {
|
||||
return getClassMembers(skeleton);
|
||||
return getClassMembers(skeleton, classType.isDefinition());
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
@@ -53,19 +54,25 @@ public class PyUserSkeletonsClassMembersProvider extends PyClassMembersProviderB
|
||||
final PyClass cls = classType.getPyClass();
|
||||
final PyClass skeleton = PyUserSkeletonsUtil.getUserSkeleton(cls);
|
||||
if (skeleton != null) {
|
||||
return findClassMember(skeleton, name);
|
||||
return findClassMember(skeleton, name, classType.isDefinition());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static PsiElement findClassMember(@NotNull PyClass cls, @NotNull String name) {
|
||||
public static PsiElement findClassMember(@NotNull PyClass cls, @NotNull String name, boolean isDefinition) {
|
||||
final PyFunction function = cls.findMethodByName(name, false);
|
||||
if (function != null) {
|
||||
return function;
|
||||
final PyUtil.MethodFlags methodFlags = PyUtil.MethodFlags.of(function);
|
||||
final boolean instanceMethod = methodFlags == null || methodFlags.isInstanceMethod();
|
||||
if (isDefinition ^ instanceMethod) {
|
||||
return function;
|
||||
}
|
||||
}
|
||||
final PyTargetExpression instanceAttribute = cls.findInstanceAttribute(name, false);
|
||||
if (instanceAttribute != null) {
|
||||
return instanceAttribute;
|
||||
if (!isDefinition) {
|
||||
final PyTargetExpression instanceAttribute = cls.findInstanceAttribute(name, false);
|
||||
if (instanceAttribute != null) {
|
||||
return instanceAttribute;
|
||||
}
|
||||
}
|
||||
final PyTargetExpression classAttribute = cls.findClassAttribute(name, false);
|
||||
if (classAttribute != null) {
|
||||
@@ -74,18 +81,22 @@ public class PyUserSkeletonsClassMembersProvider extends PyClassMembersProviderB
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Collection<PyCustomMember> getClassMembers(@NotNull PyClass cls) {
|
||||
public static Collection<PyCustomMember> getClassMembers(@NotNull PyClass cls, boolean isDefinition) {
|
||||
final List<PyCustomMember> result = new ArrayList<PyCustomMember>();
|
||||
for (PyFunction function : cls.getMethods(false)) {
|
||||
final String name = function.getName();
|
||||
if (name != null) {
|
||||
final PyUtil.MethodFlags methodFlags = PyUtil.MethodFlags.of(function);
|
||||
final boolean instanceMethod = methodFlags == null || methodFlags.isInstanceMethod();
|
||||
if (name != null && (isDefinition ^ instanceMethod)) {
|
||||
result.add(new PyCustomMember(name, function));
|
||||
}
|
||||
}
|
||||
for (PyTargetExpression attribute : cls.getInstanceAttributes()) {
|
||||
final String name = attribute.getName();
|
||||
if (name != null) {
|
||||
result.add(new PyCustomMember(name, attribute));
|
||||
if (!isDefinition) {
|
||||
for (PyTargetExpression attribute : cls.getInstanceAttributes()) {
|
||||
final String name = attribute.getName();
|
||||
if (name != null) {
|
||||
result.add(new PyCustomMember(name, attribute));
|
||||
}
|
||||
}
|
||||
}
|
||||
for (PyTargetExpression attribute : cls.getClassAttributes()) {
|
||||
|
||||
@@ -214,7 +214,7 @@ public class PyTypeChecker {
|
||||
|
||||
@NotNull
|
||||
public static Set<String> getClassTypeAttributes(@NotNull PyClassType type, boolean inherited, @NotNull TypeEvalContext context) {
|
||||
final Set<String> attributes = getClassAttributes(type.getPyClass(), inherited, context);
|
||||
final Set<String> attributes = getClassAttributes(type.getPyClass(), inherited, type.isDefinition(), context);
|
||||
for (PyClassMembersProvider provider : Extensions.getExtensions(PyClassMembersProvider.EP_NAME)) {
|
||||
final Collection<PyCustomMember> members = provider.getMembers(type, null);
|
||||
for (PyCustomMember member : members) {
|
||||
@@ -225,7 +225,10 @@ public class PyTypeChecker {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static Set<String> getClassAttributes(@NotNull PyClass cls, boolean inherited, @NotNull TypeEvalContext context) {
|
||||
private static Set<String> getClassAttributes(@NotNull PyClass cls,
|
||||
boolean inherited,
|
||||
boolean isDefinition,
|
||||
@NotNull TypeEvalContext context) {
|
||||
final Set<String> attributes = new HashSet<String>();
|
||||
for (PyFunction function : cls.getMethods(false)) {
|
||||
attributes.add(function.getName());
|
||||
@@ -239,8 +242,11 @@ public class PyTypeChecker {
|
||||
if (inherited) {
|
||||
for (PyClass ancestor : cls.getAncestorClasses(null)) {
|
||||
final PyType ancestorType = context.getType(ancestor);
|
||||
if (ancestorType instanceof PyClassType) {
|
||||
attributes.addAll(getClassTypeAttributes((PyClassType)ancestorType, false, context));
|
||||
if (ancestorType instanceof PyClassLikeType) {
|
||||
final PyClassLikeType classType = isDefinition ? (PyClassLikeType)ancestorType : ((PyClassLikeType)ancestorType).toInstance();
|
||||
if (classType instanceof PyClassType) {
|
||||
attributes.addAll(getClassTypeAttributes((PyClassType)classType, false, context));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,9 +17,8 @@ package com.jetbrains.python.pyi;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.jetbrains.python.codeInsight.PyCustomMember;
|
||||
import com.jetbrains.python.codeInsight.userSkeletons.PyUserSkeletonsClassMembersProvider;
|
||||
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 com.jetbrains.python.psi.types.PyOverridingAncestorsClassMembersProvider;
|
||||
@@ -27,10 +26,8 @@ import com.jetbrains.python.psi.types.TypeEvalContext;
|
||||
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
|
||||
@@ -42,7 +39,7 @@ public class PyiClassMembersProvider extends PyClassMembersProviderBase implemen
|
||||
final PyClass cls = classType.getPyClass();
|
||||
final PsiElement pythonStub = PyiUtil.getPythonStub(cls);
|
||||
if (pythonStub instanceof PyClass) {
|
||||
return getClassMembers((PyClass)pythonStub);
|
||||
return PyUserSkeletonsClassMembersProvider.getClassMembers((PyClass)pythonStub, classType.isDefinition());
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
@@ -54,47 +51,8 @@ public class PyiClassMembersProvider extends PyClassMembersProviderBase implemen
|
||||
final PyClass cls = classType.getPyClass();
|
||||
final PsiElement pythonStub = PyiUtil.getPythonStub(cls);
|
||||
if (pythonStub instanceof PyClass) {
|
||||
return findClassMember((PyClass)pythonStub, name);
|
||||
return PyUserSkeletonsClassMembersProvider.findClassMember((PyClass)pythonStub, name, classType.isDefinition());
|
||||
}
|
||||
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<PyCustomMember> getClassMembers(@NotNull PyClass cls) {
|
||||
final List<PyCustomMember> result = new ArrayList<PyCustomMember>();
|
||||
for (PyFunction function : cls.getMethods(false)) {
|
||||
final String name = function.getName();
|
||||
if (name != null) {
|
||||
result.add(new PyCustomMember(name, function));
|
||||
}
|
||||
}
|
||||
for (PyTargetExpression attribute : cls.getInstanceAttributes()) {
|
||||
final String name = attribute.getName();
|
||||
if (name != null) {
|
||||
result.add(new PyCustomMember(name, attribute));
|
||||
}
|
||||
}
|
||||
for (PyTargetExpression attribute : cls.getClassAttributes()) {
|
||||
final String name = attribute.getName();
|
||||
if (name != null) {
|
||||
result.add(new PyCustomMember(name, attribute));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
x = list<warning descr="Class 'type' does not define '__getitem__', so the '[]' operator cannot be used on its instances">[</warning>int]
|
||||
x = [][0]
|
||||
+4
@@ -515,6 +515,10 @@ public class PyUnresolvedReferencesInspectionTest extends PyInspectionTestCase {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testBuiltinListGetItem() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected Class<? extends PyInspection> getInspectionClass() {
|
||||
|
||||
Reference in New Issue
Block a user