PY-18096 Fixed: False positive "Type doesn't have expected attributes" for namedtuple

Introduce PyClassLikeType.getMemberNames(boolean, TypeEvalContext). This method returns all members including dynamically ones (e.g. fields of namedtuple)
This commit is contained in:
Semyon Proshev
2016-03-09 19:06:52 +03:00
parent 646e78521d
commit 8d78d16800
9 changed files with 156 additions and 82 deletions
@@ -31,9 +31,7 @@ import com.jetbrains.python.psi.types.TypeEvalContext;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.*;
/**
* @author yole
@@ -49,7 +47,7 @@ public class PyJavaClassType implements PyClassLikeType {
@Nullable
public List<? extends RatedResolveResult> resolveMember(@NotNull final String name,
PyExpression location,
@Nullable PyExpression location,
@NotNull AccessDirection direction,
@NotNull PyResolveContext resolveContext) {
return resolveMember(name, location, direction, resolveContext, true);
@@ -156,6 +154,30 @@ public class PyJavaClassType implements PyClassLikeType {
// TODO: Implement
}
@NotNull
@Override
public Set<String> getMemberNames(boolean inherited, @NotNull TypeEvalContext context) {
final Set<String> result = new LinkedHashSet<>();
for (PsiMethod method : myClass.getAllMethods()) {
result.add(method.getName());
}
for (PsiField field : myClass.getAllFields()) {
result.add(field.getName());
}
if (inherited) {
for (PyClassLikeType type : getAncestorTypes(context)) {
if (type != null) {
result.addAll(type.getMemberNames(false, context));
}
}
}
return result;
}
@NotNull
@Override
public List<PyClassLikeType> getAncestorTypes(@NotNull final TypeEvalContext context) {