PY-27241 + improvements: do not check ancestors in classMemberProvider

ClassMemberProvider should not access ancestors, it should be done by getMembers client.
This commit is contained in:
Ilya.Kazakevich
2017-12-04 20:44:40 +03:00
parent cb0cc5dfd5
commit 0f318a60f5
2 changed files with 17 additions and 4 deletions
@@ -15,6 +15,10 @@ import java.util.Collections;
* @author yole
*/
public class PyClassMembersProviderBase implements PyClassMembersProvider {
/**
* Get members for this class type only: no need to read its ancestors since it is duty of this method client
*/
@NotNull
@Override
public Collection<PyCustomMember> getMembers(PyClassType clazz, PsiElement location, @NotNull TypeEvalContext context) {
@@ -1,6 +1,7 @@
// Copyright 2000-2017 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.jetbrains.python.inspections.unresolvedReference;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.intellij.codeInsight.controlflow.ControlFlow;
@@ -824,12 +825,20 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
private static boolean hasUnresolvedDynamicMember(@NotNull final PyClassType type,
PsiReference reference,
@NotNull final String name, TypeEvalContext typeEvalContext) {
for (PyClassMembersProvider provider : Extensions.getExtensions(PyClassMembersProvider.EP_NAME)) {
final Collection<PyCustomMember> resolveResult = provider.getMembers(type, reference.getElement(), typeEvalContext);
for (PyCustomMember member : resolveResult) {
if (member.getName().equals(name)) return true;
final List<PyClassType> types = new ArrayList<>(Collections.singletonList(type));
types.addAll(FluentIterable.from(type.getAncestorTypes(typeEvalContext)).filter(PyClassType.class).toList());
for (final PyClassType typeToCheck : types) {
for (PyClassMembersProvider provider : Extensions.getExtensions(PyClassMembersProvider.EP_NAME)) {
final Collection<PyCustomMember> resolveResult = provider.getMembers(typeToCheck, reference.getElement(), typeEvalContext);
for (PyCustomMember member : resolveResult) {
if (member.getName().equals(name)) return true;
}
}
}
return false;
}