PY-13740: Django 1.7 QuerySet.as_manager() code completion support

This commit is contained in:
Ilya.Kazakevich
2014-10-06 21:37:51 +04:00
parent db32cae0c7
commit de5f5f0f76
38 changed files with 508 additions and 123 deletions
@@ -33,7 +33,7 @@ import javax.swing.*;
/**
* @author Dennis.Ushakov
*/
public class PyDynamicMember {
public class PyCustomMember {
private String myName;
private final boolean myResolveToInstance;
private final Function<PsiElement, PyType> myTypeCallback;
@@ -45,7 +45,7 @@ public class PyDynamicMember {
boolean myFunction = false;
public PyDynamicMember(@NotNull final String name, @Nullable final String type, final boolean resolveToInstance) {
public PyCustomMember(@NotNull final String name, @Nullable final String type, final boolean resolveToInstance) {
myName = name;
myResolveToInstance = resolveToInstance;
myTypeName = type;
@@ -54,7 +54,7 @@ public class PyDynamicMember {
myTypeCallback = null;
}
public PyDynamicMember(@NotNull final String name) {
public PyCustomMember(@NotNull final String name) {
myName = name;
myResolveToInstance = false;
myTypeName = null;
@@ -63,9 +63,9 @@ public class PyDynamicMember {
myTypeCallback = null;
}
public PyDynamicMember(@NotNull final String name,
@Nullable final String type,
final Function<PsiElement, PyType> typeCallback) {
public PyCustomMember(@NotNull final String name,
@Nullable final String type,
final Function<PsiElement, PyType> typeCallback) {
myName = name;
myResolveToInstance = false;
@@ -75,55 +75,58 @@ public class PyDynamicMember {
myTypeCallback = typeCallback;
}
public PyDynamicMember(@NotNull final String name, @Nullable final PsiElement target) {
public PyCustomMember(@NotNull final String name, @Nullable final PsiElement target, @Nullable String typeName) {
myName = name;
myTarget = target;
myResolveToInstance = false;
myTypeName = null;
myTypeName = typeName;
myTypeCallback = null;
}
public PyCustomMember(@NotNull final String name, @Nullable final PsiElement target) {
this(name, target, null);
}
public PyDynamicMember resolvesTo(String moduleQName) {
public PyCustomMember resolvesTo(String moduleQName) {
myPsiPath = new PyPsiPath.ToFile(moduleQName);
return this;
}
public PyDynamicMember resolvesToClass(String classQName) {
public PyCustomMember resolvesToClass(String classQName) {
myPsiPath = new PyPsiPath.ToClassQName(classQName);
return this;
}
public PyDynamicMember toClass(String name) {
public PyCustomMember toClass(String name) {
myPsiPath = new PyPsiPath.ToClass(myPsiPath, name);
return this;
}
public PyDynamicMember toFunction(String name) {
public PyCustomMember toFunction(String name) {
myPsiPath = new PyPsiPath.ToFunction(myPsiPath, name);
return this;
}
public PyDynamicMember toFunctionRecursive(String name) {
public PyCustomMember toFunctionRecursive(String name) {
myPsiPath = new PyPsiPath.ToFunctionRecursive(myPsiPath, name);
return this;
}
public PyDynamicMember toClassAttribute(String name) {
public PyCustomMember toClassAttribute(String name) {
myPsiPath = new PyPsiPath.ToClassAttribute(myPsiPath, name);
return this;
}
public PyDynamicMember toCall(String name, String... args) {
public PyCustomMember toCall(String name, String... args) {
myPsiPath = new PyPsiPath.ToCall(myPsiPath, name, args);
return this;
}
public PyDynamicMember toAssignment(String assignee) {
public PyCustomMember toAssignment(String assignee) {
myPsiPath = new PyPsiPath.ToAssignment(myPsiPath, assignee);
return this;
}
public PyDynamicMember toPsiElement(final PsiElement psiElement) {
public PyCustomMember toPsiElement(final PsiElement psiElement) {
myPsiPath = new PyPsiPath() {
@Override
@@ -179,7 +182,7 @@ public class PyDynamicMember {
return myTypeName.substring(pos + 1);
}
public PyDynamicMember asFunction() {
public PyCustomMember asFunction() {
myFunction = true;
return this;
}
@@ -110,8 +110,12 @@ public interface PyClass extends PsiNameIdentifierOwner, PyStatement, NameDefine
@NotNull
PyExpression[] getSuperClassExpressions();
/**
* @param inherited return inherited (parent) methods as well
* @return class methods
*/
@NotNull
PyFunction[] getMethods();
PyFunction[] getMethods(boolean inherited);
/**
* Get class properties.
@@ -243,4 +247,12 @@ public interface PyClass extends PsiNameIdentifierOwner, PyStatement, NameDefine
*/
@Nullable
PyExpression getMetaClassExpression();
/**
*
* @param context eval context
* @return {@link com.jetbrains.python.psi.types.PyType} casted if it has right type
*/
@Nullable
PyClassLikeType getType(@NotNull TypeEvalContext context);
}
@@ -26,6 +26,8 @@ import com.jetbrains.python.psi.types.PyType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
/**
* Function declaration in source (the <code>def</code> and everything within).
*
@@ -101,4 +103,48 @@ extends
@Nullable
PyAnnotation getAnnotation();
// TODO: Doc
//
/**
* Searches for function attributes.
* See <a href="http://legacy.python.org/dev/peps/pep-0232/">PEP-0232</a>
* @return assignment statements for function attributes
*/
@NotNull
List<PyAssignmentStatement> findAttributes();
/**
* @return function protection level (underscore based)
*/
@NotNull
ProtectionLevel getProtectionLevel();
enum ProtectionLevel {
/**
* public members
*/
PUBLIC(0),
/**
* _protected_memebers
*/
PROTECTED(1),
/**
* __private_memebrs
*/
PRIVATE(2);
private final int myUnderscoreLevel;
ProtectionLevel(final int underscoreLevel) {
myUnderscoreLevel = underscoreLevel;
}
/**
* @return number of underscores
*/
public int getUnderscoreLevel() {
return myUnderscoreLevel;
}
}
}
@@ -17,7 +17,7 @@ package com.jetbrains.python.psi.types;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.psi.PsiElement;
import com.jetbrains.python.codeInsight.PyDynamicMember;
import com.jetbrains.python.codeInsight.PyCustomMember;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -30,7 +30,7 @@ public interface PyClassMembersProvider {
ExtensionPointName<PyClassMembersProvider> EP_NAME = ExtensionPointName.create("Pythonid.pyClassMembersProvider");
@NotNull
Collection<PyDynamicMember> getMembers(PyClassType clazz, @Nullable PsiElement location);
Collection<PyCustomMember> getMembers(PyClassType clazz, @Nullable PsiElement location);
@Nullable
PsiElement resolveMember(PyClassType clazz, String name, @Nullable PsiElement location);
@@ -16,7 +16,7 @@
package com.jetbrains.python.psi.types;
import com.intellij.psi.PsiElement;
import com.jetbrains.python.codeInsight.PyDynamicMember;
import com.jetbrains.python.codeInsight.PyCustomMember;
import com.jetbrains.python.psi.PyClass;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -30,22 +30,22 @@ import java.util.Collections;
public class PyClassMembersProviderBase implements PyClassMembersProvider {
@NotNull
@Override
public Collection<PyDynamicMember> getMembers(PyClassType clazz, PsiElement location) {
public Collection<PyCustomMember> getMembers(PyClassType clazz, PsiElement location) {
return Collections.emptyList();
}
@Override
public PsiElement resolveMember(PyClassType clazz, String name, PsiElement location) {
final Collection<PyDynamicMember> members = getMembers(clazz, location);
final Collection<PyCustomMember> members = getMembers(clazz, location);
return resolveMemberByName(members, clazz, name);
}
@Nullable
public static PsiElement resolveMemberByName(Collection<PyDynamicMember> members,
public static PsiElement resolveMemberByName(Collection<PyCustomMember> members,
PyClassType clazz,
String name) {
final PyClass pyClass = clazz.getPyClass();
for (PyDynamicMember member : members) {
for (PyCustomMember member : members) {
if (member.getName().equals(name)) {
return member.resolve(pyClass);
}
@@ -18,7 +18,7 @@ package com.jetbrains.python.psi.types;
import com.intellij.openapi.extensions.ExtensionPointName;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.jetbrains.python.codeInsight.PyDynamicMember;
import com.jetbrains.python.codeInsight.PyCustomMember;
import com.jetbrains.python.psi.PyFile;
import com.jetbrains.python.psi.PyPsiFacade;
import com.jetbrains.python.psi.resolve.PointInImport;
@@ -33,7 +33,7 @@ import java.util.Collections;
public abstract class PyModuleMembersProvider {
public static final ExtensionPointName<PyModuleMembersProvider> EP_NAME = ExtensionPointName.create("Pythonid.pyModuleMembersProvider");
public Collection<PyDynamicMember> getMembers(PyFile module, PointInImport point) {
public Collection<PyCustomMember> getMembers(PyFile module, PointInImport point) {
final VirtualFile vFile = module.getVirtualFile();
if (vFile != null) {
final String qName = PyPsiFacade.getInstance(module.getProject()).findShortestImportableName(vFile, module);
@@ -46,7 +46,7 @@ public abstract class PyModuleMembersProvider {
@Nullable
public PsiElement resolveMember(PyFile module, String name) {
for (PyDynamicMember o : getMembers(module, PointInImport.NONE)) {
for (PyCustomMember o : getMembers(module, PointInImport.NONE)) {
if (o.getName().equals(name)) {
return o.resolve(module);
}
@@ -54,5 +54,5 @@ public abstract class PyModuleMembersProvider {
return null;
}
protected abstract Collection<PyDynamicMember> getMembersByQName(PyFile module, String qName);
protected abstract Collection<PyCustomMember> getMembersByQName(PyFile module, String qName);
}
@@ -47,8 +47,8 @@ public interface PyType {
* or a list of elements that define the name, a la multiResolve().
*/
@Nullable
List<? extends RatedResolveResult> resolveMember(@NotNull final String name, @Nullable PyExpression location,
@NotNull AccessDirection direction, @NotNull PyResolveContext resolveContext);
List<? extends RatedResolveResult> resolveMember(@NotNull String name, @Nullable final PyExpression location,
@NotNull final AccessDirection direction, @NotNull final PyResolveContext resolveContext);
/**
* Proposes completion variants from type's attributes.
@@ -80,6 +80,7 @@ public class PyTypeProviderBase implements PyTypeProvider {
}
};
@Nullable
@Override
public PyType getReferenceExpressionType(@NotNull PyReferenceExpression referenceExpression, @NotNull TypeEvalContext context) {
return null;
@@ -15,7 +15,7 @@
*/
package com.jetbrains.numpy.codeInsight;
import com.jetbrains.python.codeInsight.PyDynamicMember;
import com.jetbrains.python.codeInsight.PyCustomMember;
import com.jetbrains.python.psi.PyFile;
import com.jetbrains.python.psi.types.PyModuleMembersProvider;
@@ -39,11 +39,11 @@ public class NumpyModuleMembersProvider extends PyModuleMembersProvider {
};
@Override
protected Collection<PyDynamicMember> getMembersByQName(PyFile module, String qName) {
protected Collection<PyCustomMember> getMembersByQName(PyFile module, String qName) {
if ("numpy".equals(qName)) {
final List<PyDynamicMember> members = new ArrayList<PyDynamicMember>();
final List<PyCustomMember> members = new ArrayList<PyCustomMember>();
for (String type : NUMERIC_TYPES) {
members.add(new PyDynamicMember(type, "numpy.core.multiarray.dtype", false));
members.add(new PyCustomMember(type, "numpy.core.multiarray.dtype", false));
}
return members;
}
@@ -846,4 +846,8 @@ remote.interpreter.default.interpreter.path=/usr/bin/python
remote.interpreter.unspecified.interpreter.path=Specify Python interpreter path
remote.interpreter.unspecified.temp.files.path=Specify path for PyCharm helpers
remote.interpreter.configure.path.label=Python interpreter path:
remote.interpreter.configure.temp.files.path.label=PyCharm helpers path:
remote.interpreter.configure.temp.files.path.label=PyCharm helpers path:
# Message we display for inspection if user uses custom class type members that do not exist
custom.type.name=Dynamic class
custom.type.mimic.name=Dynamic class based on {0}
@@ -0,0 +1,189 @@
package com.jetbrains.python;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.psi.PsiElement;
import com.intellij.util.ArrayUtil;
import com.intellij.util.ProcessingContext;
import com.jetbrains.python.codeInsight.PyCustomMember;
import com.jetbrains.python.codeInsight.PyCustomMemberUtils;
import com.jetbrains.python.psi.AccessDirection;
import com.jetbrains.python.psi.PyCallSiteExpression;
import com.jetbrains.python.psi.PyExpression;
import com.jetbrains.python.psi.resolve.PyResolveContext;
import com.jetbrains.python.psi.resolve.RatedResolveResult;
import com.jetbrains.python.psi.types.*;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
/**
* Custom (aka dynamic) type that has some members you pass to it. To be used for cases like "type()"
* This class can also mimic any other class (optionally). When mimics, it has all methods from this class and its own.
* @author Ilya.Kazakevich
*/
public class PyCustomMembersType implements PyClassLikeType {
@NotNull
private final Map<String, PyCustomMember> myMembers;
@Nullable
private final PyClassType myTypeToMimic;
/**
* @param typeToMimic this type may mimic some other class-based type. Pass it to have all members from this class + custom.
* Check class manual for more info.
* @param members custom members
*/
public PyCustomMembersType(@Nullable final PyClassType typeToMimic, @NotNull final PyCustomMember... members) {
myTypeToMimic = typeToMimic;
myMembers = new HashMap<String, PyCustomMember>(members.length);
for (final PyCustomMember member : members) {
myMembers.put(member.getName(), member);
}
}
/**
* @return class we mimic (if any). Check class manual for more info.
*/
@Nullable
public PyClassType getTypeToMimic() {
return myTypeToMimic;
}
@Override
public boolean isDefinition() {
return false;
}
@Override
public PyClassLikeType toInstance() {
return this;
}
@Nullable
@Override
public String getClassQName() {
return null;
}
@NotNull
@Override
public List<PyClassLikeType> getSuperClassTypes(@NotNull TypeEvalContext context) {
return Collections.emptyList();
}
@Nullable
@Override
public List<? extends RatedResolveResult> resolveMember(@NotNull final String name,
@Nullable final PyExpression location,
@NotNull final AccessDirection direction,
@NotNull final PyResolveContext resolveContext,
final boolean inherited) {
if (myMembers.containsKey(name)) {
PsiElement context = null;
if (location != null) {
context = location;
}
if (context == null) {
context = resolveContext.getTypeEvalContext().getOrigin();
}
if (context != null) {
final PsiElement resolveResult = myMembers.get(name).resolve(context);
if (resolveResult != null) {
return Collections.singletonList(new RatedResolveResult(0, resolveResult));
}
}
}
if (myTypeToMimic != null) {
return myTypeToMimic.resolveMember(name, location, direction, resolveContext, inherited);
}
return null;
}
@Override
public boolean isValid() {
return true;
}
@Nullable
@Override
public PyClassLikeType getMetaClassType(@NotNull TypeEvalContext context, boolean inherited) {
return null;
}
@Override
public boolean isCallable() {
return true;
}
@Nullable
@Override
public PyType getReturnType(@NotNull TypeEvalContext context) {
return null;
}
@Nullable
@Override
public PyType getCallType(@NotNull TypeEvalContext context, @NotNull PyCallSiteExpression callSite) {
return this;
}
@Nullable
@Override
public List<PyCallableParameter> getParameters(@NotNull TypeEvalContext context) {
return null;
}
@Nullable
@Override
public List<? extends RatedResolveResult> resolveMember(@NotNull final String name,
@Nullable final PyExpression location,
@NotNull final AccessDirection direction,
@NotNull final PyResolveContext resolveContext) {
return resolveMember(name, location, direction, resolveContext, true);
}
@Override
public Object[] getCompletionVariants(final String completionPrefix, final PsiElement location, final ProcessingContext context) {
final Collection<LookupElement> lookupElements = new ArrayList<LookupElement>(myMembers.size());
for (final PyCustomMember member : myMembers.values()) {
lookupElements.add(PyCustomMemberUtils.toLookUpElement(member, member.getShortType()));
}
return ArrayUtil.mergeArrays(ArrayUtil.toObjectArray(lookupElements),
((myTypeToMimic != null)
? myTypeToMimic.getCompletionVariants(completionPrefix, location, context)
: PsiElement.EMPTY_ARRAY));
}
@Nullable
@Override
public String getName() {
String mimicName = null;
if (myTypeToMimic != null) {
mimicName = myTypeToMimic.getName();
}
if (mimicName != null) {
return PyBundle.message("custom.type.mimic.name", mimicName);
}
return PyBundle.message("custom.type.name");
}
@Override
public boolean isBuiltin() {
return false;
}
@Override
public void assertValid(final String message) {
}
/**
* @param name name to check
* @return True if this class (not the one it mimics!) has member with passed name
*/
public boolean hasMember(@NotNull final String name) {
return myMembers.containsKey(name);
}
}
@@ -0,0 +1,34 @@
package com.jetbrains.python.codeInsight;
import com.intellij.codeInsight.completion.util.ParenthesesInsertHandler;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
/**
* TODO: Move methods to {@link com.jetbrains.python.codeInsight.PyCustomMember}. Only dependency hell prevents me from doing it
*/
public final class PyCustomMemberUtils {
private PyCustomMemberUtils() {
}
/**
* Creates {@link com.intellij.codeInsight.lookup.LookupElement} to be used in cases like {@link com.jetbrains.python.psi.types.PyType#getCompletionVariants(String, com.intellij.psi.PsiElement, com.intellij.util.ProcessingContext)}
* This method should be in {@link com.jetbrains.python.codeInsight.PyCustomMember} but it does not. We need to move it.
*
* @param member custom member
* @param typeText type text (if any)
* @return lookup element
*/
@NotNull
public static LookupElementBuilder toLookUpElement(@NotNull final PyCustomMember member, @Nullable final String typeText) {
LookupElementBuilder lookupElementBuilder = LookupElementBuilder.create(member.getName())
.withIcon(member.getIcon())
.withTypeText(typeText);
if (member.isFunction()) {
lookupElementBuilder = lookupElementBuilder.withInsertHandler(ParenthesesInsertHandler.NO_PARAMETERS).withLookupString("()");
}
return lookupElementBuilder;
}
}
@@ -54,7 +54,7 @@ public class PyMethodNavigationOffsetProvider implements MethodNavigationOffsetP
array.add(psiElement);
}
else if (psiElement instanceof PyClass) {
Collections.addAll(array, ((PyClass)psiElement).getMethods());
Collections.addAll(array, ((PyClass)psiElement).getMethods(false));
}
}
}
@@ -57,13 +57,13 @@ public class PySuperMethodCompletionContributor extends CompletionContributor {
return;
}
Set<String> seenNames = new HashSet<String>();
for (PyFunction function : containingClass.getMethods()) {
for (PyFunction function : containingClass.getMethods(false)) {
seenNames.add(function.getName());
}
LanguageLevel languageLevel = LanguageLevel.forElement(parameters.getOriginalFile());
seenNames.addAll(PyNames.getBuiltinMethods(languageLevel).keySet());
for (PyClass ancestor : containingClass.getAncestorClasses()) {
for (PyFunction superMethod : ancestor.getMethods()) {
for (PyFunction superMethod : ancestor.getMethods(false)) {
if (!seenNames.contains(superMethod.getName())) {
String text = superMethod.getName() + superMethod.getParameterList().getText();
LookupElementBuilder element = LookupElementBuilder.create(text);
@@ -281,7 +281,7 @@ public class PyOverrideImplementUtil {
public static Collection<PyFunction> getAllSuperFunctions(@NotNull final PyClass pyClass) {
final Map<String, PyFunction> superFunctions = new HashMap<String, PyFunction>();
for (PyClass aClass : pyClass.getAncestorClasses()) {
for (PyFunction function : aClass.getMethods()) {
for (PyFunction function : aClass.getMethods(false)) {
if (!superFunctions.containsKey(function.getName())) {
superFunctions.put(function.getName(), function);
}
@@ -17,7 +17,7 @@ package com.jetbrains.python.codeInsight.stdlib;
import com.intellij.openapi.util.Key;
import com.intellij.psi.PsiElement;
import com.jetbrains.python.codeInsight.PyDynamicMember;
import com.jetbrains.python.codeInsight.PyCustomMember;
import com.jetbrains.python.psi.PyClass;
import com.jetbrains.python.psi.PyFile;
import com.jetbrains.python.psi.PyTargetExpression;
@@ -35,16 +35,16 @@ import java.util.List;
* @author yole
*/
public class PyStdlibClassMembersProvider extends PyClassMembersProviderBase {
private Key<List<PyDynamicMember>> mySocketMembersKey = Key.create("socket.members");
private Key<List<PyCustomMember>> mySocketMembersKey = Key.create("socket.members");
@NotNull
@Override
public Collection<PyDynamicMember> getMembers(PyClassType classType, PsiElement location) {
public Collection<PyCustomMember> getMembers(PyClassType classType, PsiElement location) {
PyClass clazz = classType.getPyClass();
final String qualifiedName = clazz.getQualifiedName();
if ("socket._socketobject".equals(qualifiedName)) {
final PyFile socketFile = (PyFile)clazz.getContainingFile();
List<PyDynamicMember> socketMembers = socketFile.getUserData(mySocketMembersKey);
List<PyCustomMember> socketMembers = socketFile.getUserData(mySocketMembersKey);
if (socketMembers == null) {
socketMembers = calcSocketMembers(socketFile);
socketFile.putUserData(mySocketMembersKey, socketMembers);
@@ -54,20 +54,20 @@ public class PyStdlibClassMembersProvider extends PyClassMembersProviderBase {
return Collections.emptyList();
}
private static List<PyDynamicMember> calcSocketMembers(PyFile socketFile) {
List<PyDynamicMember> result = new ArrayList<PyDynamicMember>();
private static List<PyCustomMember> calcSocketMembers(PyFile socketFile) {
List<PyCustomMember> result = new ArrayList<PyCustomMember>();
addMethodsFromAttr(socketFile, result, "_socketmethods");
addMethodsFromAttr(socketFile, result, "_delegate_methods");
return result;
}
private static void addMethodsFromAttr(PyFile socketFile, List<PyDynamicMember> result, final String attrName) {
private static void addMethodsFromAttr(PyFile socketFile, List<PyCustomMember> result, final String attrName) {
final PyTargetExpression socketMethods = socketFile.findTopLevelAttribute(attrName);
if (socketMethods != null) {
final List<String> methods = PyUtil.getStringListFromTargetExpression(socketMethods);
if (methods != null) {
for (String name : methods) {
result.add(new PyDynamicMember(name).resolvesTo("_socket").toClass("SocketType").toFunction(name));
result.add(new PyCustomMember(name).resolvesTo("_socket").toClass("SocketType").toFunction(name));
}
}
}
@@ -18,7 +18,7 @@ package com.jetbrains.python.codeInsight.stdlib;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.psi.PsiElement;
import com.intellij.psi.util.QualifiedName;
import com.jetbrains.python.codeInsight.PyDynamicMember;
import com.jetbrains.python.codeInsight.PyCustomMember;
import com.jetbrains.python.psi.PyFile;
import com.jetbrains.python.psi.resolve.ResolveImportUtil;
import com.jetbrains.python.psi.types.PyModuleMembersProvider;
@@ -33,15 +33,15 @@ import java.util.List;
*/
public class PyStdlibModuleMembersProvider extends PyModuleMembersProvider {
@Override
protected Collection<PyDynamicMember> getMembersByQName(PyFile module, String qName) {
protected Collection<PyCustomMember> getMembersByQName(PyFile module, String qName) {
if (qName.equals("os")) {
final List<PyDynamicMember> results = new ArrayList<PyDynamicMember>();
final List<PyCustomMember> results = new ArrayList<PyCustomMember>();
PsiElement path = null;
if (module != null) {
final String pathModuleName = SystemInfo.isWindows ? "ntpath" : "posixpath";
path = ResolveImportUtil.resolveModuleInRoots(QualifiedName.fromDottedString(pathModuleName), module);
}
results.add(new PyDynamicMember("path", path));
results.add(new PyCustomMember("path", path));
return results;
}
return Collections.emptyList();
@@ -16,7 +16,7 @@
package com.jetbrains.python.codeInsight.userSkeletons;
import com.intellij.psi.PsiElement;
import com.jetbrains.python.codeInsight.PyDynamicMember;
import com.jetbrains.python.codeInsight.PyCustomMember;
import com.jetbrains.python.psi.PyClass;
import com.jetbrains.python.psi.PyFunction;
import com.jetbrains.python.psi.PyTargetExpression;
@@ -37,7 +37,7 @@ import java.util.List;
public class PyUserSkeletonsClassMembersProvider extends PyClassMembersProviderBase implements PyOverridingAncestorsClassMembersProvider {
@NotNull
@Override
public Collection<PyDynamicMember> getMembers(@NotNull PyClassType classType, PsiElement location) {
public Collection<PyCustomMember> getMembers(@NotNull PyClassType classType, PsiElement location) {
final PyClass cls = classType.getPyClass();
final PyClass skeleton = PyUserSkeletonsUtil.getUserSkeleton(cls);
if (skeleton != null) {
@@ -73,24 +73,24 @@ public class PyUserSkeletonsClassMembersProvider extends PyClassMembersProviderB
return null;
}
private static Collection<PyDynamicMember> getClassMembers(@NotNull PyClass cls) {
final List<PyDynamicMember> result = new ArrayList<PyDynamicMember>();
for (PyFunction function : cls.getMethods()) {
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 PyDynamicMember(name, function));
result.add(new PyCustomMember(name, function));
}
}
for (PyTargetExpression attribute : cls.getInstanceAttributes()) {
final String name = attribute.getName();
if (name != null) {
result.add(new PyDynamicMember(name, attribute));
result.add(new PyCustomMember(name, attribute));
}
}
for (PyTargetExpression attribute : cls.getClassAttributes()) {
final String name = attribute.getName();
if (name != null) {
result.add(new PyDynamicMember(name, attribute));
result.add(new PyCustomMember(name, attribute));
}
}
return result;
@@ -17,7 +17,7 @@ package com.jetbrains.python.codeInsight.userSkeletons;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFileSystemItem;
import com.jetbrains.python.codeInsight.PyDynamicMember;
import com.jetbrains.python.codeInsight.PyCustomMember;
import com.jetbrains.python.psi.PyElement;
import com.jetbrains.python.psi.PyFile;
import com.jetbrains.python.psi.types.PyModuleMembersProvider;
@@ -43,17 +43,17 @@ public class PyUserSkeletonsModuleMembersProvider extends PyModuleMembersProvide
}
@Override
protected Collection<PyDynamicMember> getMembersByQName(PyFile module, String qName) {
protected Collection<PyCustomMember> getMembersByQName(PyFile module, String qName) {
final PyFile moduleSkeleton = PyUserSkeletonsUtil.getUserSkeletonForModuleQName(qName, module);
if (moduleSkeleton != null) {
final List<PyDynamicMember> results = new ArrayList<PyDynamicMember>();
final List<PyCustomMember> results = new ArrayList<PyCustomMember>();
for (PyElement element : moduleSkeleton.iterateNames()) {
if (element instanceof PsiFileSystemItem) {
continue;
}
final String name = element.getName();
if (name != null) {
results.add(new PyDynamicMember(name, element));
results.add(new PyCustomMember(name, element));
}
}
return results;
@@ -74,7 +74,7 @@ public class PyOldStyleClassesInspection extends PyInspection {
registerProblem(attr, "Old-style class contains __slots__ definition", ProblemHighlightType.GENERIC_ERROR_OR_WARNING, null, quickFixes.toArray(new LocalQuickFix[quickFixes.size()]));
}
}
for (PyFunction attr : node.getMethods()) {
for (PyFunction attr : node.getMethods(false)) {
if ("__getattribute__".equals(attr.getName())) {
final ASTNode nameNode = attr.getNameNode();
assert nameNode != null;
@@ -166,7 +166,7 @@ public class AddFieldQuickFix implements LocalQuickFix {
appendToMethod(newInit, callback);
PsiElement addAnchor = null;
PyFunction[] meths = cls.getMethods();
PyFunction[] meths = cls.getMethods(false);
if (meths.length > 0) addAnchor = meths[0].getPrevSibling();
PyStatementList clsContent = cls.getStatementList();
newInit = (PyFunction) clsContent.addAfter(newInit, addAnchor);
@@ -33,9 +33,10 @@ import com.intellij.psi.util.QualifiedName;
import com.intellij.util.Consumer;
import com.intellij.util.PlatformUtils;
import com.jetbrains.python.PyBundle;
import com.jetbrains.python.PyCustomMembersType;
import com.jetbrains.python.PyNames;
import com.jetbrains.python.codeInsight.PyCodeInsightSettings;
import com.jetbrains.python.codeInsight.PyDynamicMember;
import com.jetbrains.python.codeInsight.PyCustomMember;
import com.jetbrains.python.codeInsight.controlflow.ScopeOwner;
import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil;
import com.jetbrains.python.codeInsight.imports.AutoImportHintAction;
@@ -462,7 +463,7 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
}
if (expr.isQualified()) {
final PyClassTypeImpl object_type = (PyClassTypeImpl)PyBuiltinCache.getInstance(node).getObjectType();
if ((object_type != null) && object_type.getPossibleInstanceMembers().contains(refName)){
if ((object_type != null) && object_type.getPossibleInstanceMembers().contains(refName)) {
return;
}
}
@@ -542,6 +543,10 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
}
markedQualified = true;
}
else if (isHasCustomMember(refName, type)) {
// We have dynamic members
return;
}
else {
description = PyBundle.message("INSP.cannot.find.$0.in.$1", refText, type.getName());
markedQualified = true;
@@ -605,6 +610,16 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
registerProblem(node, description, hl_type, null, rangeInElement, actions.toArray(new LocalQuickFix[actions.size()]));
}
/**
* Checks if type is custom-member based and has custom member with certain name
* @param refName name to check
* @param type type
* @return true if has one
*/
private static boolean isHasCustomMember(@NotNull final String refName, @NotNull final PyType type) {
return (type instanceof PyCustomMembersType) && ((PyCustomMembersType)type).hasMember(refName);
}
/**
* Return the canonical qualified name for a reference (even for an unresolved one).
*/
@@ -687,6 +702,13 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
return true;
}
}
if (type instanceof PyCustomMembersType) {
// Skip custom member types that mimics another class with fuzzy parents
PyClassType mimic = ((PyCustomMembersType)type).getTypeToMimic();
if (mimic != null && PyUtil.hasUnresolvedAncestors(mimic.getPyClass(), myTypeEvalContext)) {
return true;
}
}
if (type instanceof PyClassTypeImpl) {
PyClass cls = ((PyClassType)type).getPyClass();
if (overridesGetAttr(cls, myTypeEvalContext)) {
@@ -721,8 +743,8 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
PsiReference reference,
@NotNull final String name) {
for (PyClassMembersProvider provider : Extensions.getExtensions(PyClassMembersProvider.EP_NAME)) {
final Collection<PyDynamicMember> resolveResult = provider.getMembers(type, reference.getElement());
for (PyDynamicMember member : resolveResult) {
final Collection<PyCustomMember> resolveResult = provider.getMembers(type, reference.getElement());
for (PyCustomMember member : resolveResult) {
if (member.getName().equals(name)) return true;
}
}
@@ -810,7 +832,7 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
}
}
}
for (PyFunction method : containedClass.getMethods()) {
for (PyFunction method : containedClass.getMethods(false)) {
if (expr.getText().equals(method.getName())) {
actions.add(new UnresolvedReferenceAddSelfQuickFix(expr, qualifier));
}
@@ -50,7 +50,7 @@ public class PyElementNode extends BasePsiNode<PyElement> {
for (PyClass aClass : pyClass.getNestedClasses()) {
result.add(new PyElementNode(myProject, aClass, getSettings()));
}
for (PyFunction function : pyClass.getMethods()) {
for (PyFunction function : pyClass.getMethods(false)) {
result.add(new PyElementNode(myProject, function, getSettings()));
}
return result;
@@ -172,9 +172,7 @@ public class PsiQuery {
}
}
}
@SuppressWarnings("unchecked") // Type is preserved
final T[] array = (T[])result.toArray(new PsiElement[result.size()]);
return new PsiTypedQuery<T>(clazz, array);
return new PsiTypedQuery<T>(clazz, result);
}
@@ -309,14 +307,17 @@ public class PsiQuery {
* Filter elements by class
*/
@NotNull
public PsiQuery filter(@NotNull final Class<? extends PsiElement> clazz) {
public <T extends PsiElement> PsiTypedQuery<T> filter(@NotNull final Class<T> clazz) {
final Set<PsiElement> result = new HashSet<PsiElement>(Arrays.asList(myPsiElements));
for (final PsiElement element : myPsiElements) {
if (PyUtil.as(element, clazz) == null) {
if (!(clazz.isInstance(element))) {
result.remove(element);
}
}
return new PsiQuery(result.toArray(new PsiElement[result.size()]));
// We checked it in runtime
@SuppressWarnings("unchecked")
final List<T> toAdd = (List<T>)new ArrayList<PsiElement>(result);
return new PsiTypedQuery<T>(clazz, toAdd);
}
@@ -351,16 +352,16 @@ public class PsiQuery {
@NotNull
private final Class<T> myClass;
@NotNull
private final T[] myElements;
private final List<T> myElements;
/**
* @param clazz type
* @param elements elements
*/
private PsiTypedQuery(@NotNull final Class<T> clazz, @NotNull final T... elements) {
private PsiTypedQuery(@NotNull final Class<T> clazz, @NotNull final List<T> elements) {
super(elements);
myClass = clazz;
myElements = elements.clone();
myElements = elements;
}
/**
@@ -383,8 +384,8 @@ public class PsiQuery {
* @return All elements of certain type
*/
@NotNull
public T[] getElements() {
return myElements.clone();
public List<T> getElements() {
return Collections.unmodifiableList(myElements);
}
}
}
@@ -389,9 +389,34 @@ public class PyClassImpl extends PyBaseElementImpl<PyClassStub> implements PyCla
return result;
}
@Override
@NotNull
public PyFunction[] getMethods() {
return getClassChildren(PythonDialectsTokenSetProvider.INSTANCE.getFunctionDeclarationTokens(), PyFunction.ARRAY_FACTORY);
public PyFunction[] getMethods(final boolean inherited) {
final PyFunction[] thisClassFunctions =
getClassChildren(PythonDialectsTokenSetProvider.INSTANCE.getFunctionDeclarationTokens(), PyFunction.ARRAY_FACTORY);
if (!inherited) {
return thisClassFunctions;
}
// Map to get rid of duplicated (overwritten methods)
final Map<String, PyFunction> result = new HashMap<String, PyFunction>();
// We get classes in MRO order (hopefully), so last methods are last
for (final PyClass superClass : getSuperClasses()) {
for (final PyFunction function : superClass.getMethods(false)) {
final String functionName = function.getName();
if (functionName != null) {
result.put(functionName, function);
}
}
}
// We now need to add our own methods
for (final PyFunction function : thisClassFunctions) {
final String functionName = function.getName();
if (functionName != null) {
result.put(functionName, function);
}
}
final Collection<PyFunction> functionsToReturn = result.values();
return functionsToReturn.toArray(new PyFunction[functionsToReturn.size()]);
}
@Override
@@ -514,7 +539,7 @@ public class PyClassImpl extends PyBaseElementImpl<PyClassStub> implements PyCla
// look at @property decorators
Map<String, List<PyFunction>> grouped = new HashMap<String, List<PyFunction>>();
// group suitable same-named methods, each group defines a property
for (PyFunction method : getMethods()) {
for (PyFunction method : getMethods(false)) {
final String methodName = method.getName();
if (name == null || name.equals(methodName)) {
List<PyFunction> bucket = grouped.get(methodName);
@@ -826,7 +851,7 @@ public class PyClassImpl extends PyBaseElementImpl<PyClassStub> implements PyCla
public boolean visitMethods(Processor<PyFunction> processor,
boolean inherited,
boolean skipClassObj) {
PyFunction[] methods = getMethods();
PyFunction[] methods = getMethods(false);
if (!ContainerUtil.process(methods, processor)) return false;
if (inherited) {
for (PyClass ancestor : getAncestorClasses()) {
@@ -932,7 +957,7 @@ public class PyClassImpl extends PyBaseElementImpl<PyClassStub> implements PyCla
collectInstanceAttributes(initMethod, result);
}
Set<String> namesInInit = new HashSet<String>(result.keySet());
final PyFunction[] methods = getMethods();
final PyFunction[] methods = getMethods(false);
for (PyFunction method : methods) {
if (!PyNames.INIT.equals(method.getName())) {
collectInstanceAttributes(method, result, namesInInit);
@@ -981,7 +1006,8 @@ public class PyClassImpl extends PyBaseElementImpl<PyClassStub> implements PyCla
final List<PyTargetExpression> result = new ArrayList<PyTargetExpression>();
statementList.accept(new PyRecursiveElementVisitor() {
@Override
public void visitPyClass(PyClass node) {}
public void visitPyClass(PyClass node) {
}
public void visitPyAssignmentStatement(final PyAssignmentStatement node) {
for (PyExpression expression : node.getTargets()) {
@@ -1338,4 +1364,10 @@ public class PyClassImpl extends PyBaseElementImpl<PyClassStub> implements PyCla
}
return null;
}
@Nullable
@Override
public PyClassLikeType getType(@NotNull TypeEvalContext context) {
return PyUtil.as(context.getType(this), PyClassLikeType.class);
}
}
@@ -65,6 +65,15 @@ public class PyEvaluator {
if (expr instanceof PySequenceExpression) {
return evaluateSequenceExpression((PySequenceExpression)expr);
}
if (expr instanceof PyQualifiedExpression) { // support bool
final String referencedName = ((PyQualifiedExpression)expr).getReferencedName();
if (PyNames.TRUE.equals(referencedName)) {
return true;
}
if (PyNames.FALSE.equals(referencedName)) {
return true;
}
}
if (expr instanceof PyCallExpression) {
return evaluateCall((PyCallExpression)expr);
}
@@ -23,6 +23,7 @@ import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import com.intellij.psi.StubBasedPsiElement;
import com.intellij.psi.search.LocalSearchScope;
import com.intellij.psi.search.SearchScope;
@@ -699,4 +700,39 @@ public class PyFunctionImpl extends PyBaseElementImpl<PyFunctionStub> implements
public String getQualifiedName() {
return QualifiedNameFinder.getQualifiedName(this);
}
@NotNull
@Override
public List<PyAssignmentStatement> findAttributes() {
final List<PyAssignmentStatement> result = new ArrayList<PyAssignmentStatement>();
for (final PyAssignmentStatement statement : new PsiQuery(this).siblings(PyAssignmentStatement.class).getElements()) {
for (final PyQualifiedExpression targetExpression : new PsiQuery(statement.getTargets()).filter(PyQualifiedExpression.class)
.getElements()) {
final PyExpression qualifier = targetExpression.getQualifier();
if (qualifier == null) {
continue;
}
final PsiReference qualifierReference = qualifier.getReference();
if (qualifierReference == null) {
continue;
}
if (qualifierReference.isReferenceTo(this)) {
result.add(statement);
}
}
}
return result;
}
@NotNull
@Override
public ProtectionLevel getProtectionLevel() {
final int underscoreLevels = PyUtil.getInitialUnderscores(getName());
for (final ProtectionLevel level : ProtectionLevel.values()) {
if (level.getUnderscoreLevel() == underscoreLevels) {
return level;
}
}
return ProtectionLevel.PRIVATE;
}
}
@@ -16,7 +16,6 @@
package com.jetbrains.python.psi.types;
import com.intellij.codeInsight.completion.CompletionUtil;
import com.intellij.codeInsight.completion.util.ParenthesesInsertHandler;
import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.openapi.extensions.Extensions;
@@ -33,7 +32,8 @@ import com.intellij.util.ArrayUtil;
import com.intellij.util.ProcessingContext;
import com.intellij.util.containers.ContainerUtil;
import com.jetbrains.python.PyNames;
import com.jetbrains.python.codeInsight.PyDynamicMember;
import com.jetbrains.python.codeInsight.PyCustomMember;
import com.jetbrains.python.codeInsight.PyCustomMemberUtils;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.impl.PyBuiltinCache;
import com.jetbrains.python.psi.impl.ResolveResultList;
@@ -151,7 +151,8 @@ public class PyClassTypeImpl extends UserDataHolderBase implements PyClassType {
@NotNull PyResolveContext resolveContext,
boolean inherited) {
final TypeEvalContext context = resolveContext.getTypeEvalContext();
PsiElement classMember = resolveByOverridingMembersProviders(this, name, location); //overriding members provers have priority to normal resolve
PsiElement classMember =
resolveByOverridingMembersProviders(this, name, location); //overriding members provers have priority to normal resolve
if (classMember != null) {
return ResolveResultList.to(classMember);
}
@@ -219,7 +220,8 @@ public class PyClassTypeImpl extends UserDataHolderBase implements PyClassType {
}
if (inherited) {
classMember = resolveByMembersProviders(this, name, location); //ask providers after real class introspection as providers have less priority
classMember =
resolveByMembersProviders(this, name, location); //ask providers after real class introspection as providers have less priority
}
if (classMember != null) {
@@ -414,16 +416,11 @@ public class PyClassTypeImpl extends UserDataHolderBase implements PyClassType {
addInheritedMembers(prefix, location, namesAlready, context, ret, typeEvalContext);
// from providers
for (PyClassMembersProvider provider : Extensions.getExtensions(PyClassMembersProvider.EP_NAME)) {
for (PyDynamicMember member : provider.getMembers(this, location)) {
for (final PyClassMembersProvider provider : Extensions.getExtensions(PyClassMembersProvider.EP_NAME)) {
for (final PyCustomMember member : provider.getMembers(this, location)) {
final String name = member.getName();
if (!namesAlready.contains(name)) {
LookupElementBuilder lookupElementBuilder = LookupElementBuilder.create(name).withIcon(member.getIcon()).withTypeText(getName());
if (member.isFunction()) {
lookupElementBuilder = lookupElementBuilder.withInsertHandler(ParenthesesInsertHandler.NO_PARAMETERS);
lookupElementBuilder.withTailText("()");
}
ret.add(lookupElementBuilder);
ret.add(PyCustomMemberUtils.toLookUpElement(member, getName()));
}
}
}
@@ -30,7 +30,7 @@ import com.intellij.psi.scope.PsiScopeProcessor;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.ProcessingContext;
import com.jetbrains.python.PyNames;
import com.jetbrains.python.codeInsight.PyDynamicMember;
import com.jetbrains.python.codeInsight.PyCustomMember;
import com.jetbrains.python.codeInsight.controlflow.ScopeOwner;
import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil;
import com.jetbrains.python.psi.*;
@@ -289,7 +289,7 @@ public class PyModuleType implements PyType { // Modules don't descend from obje
Set<String> namesAlready = context.get(CTX_NAMES);
PointInImport point = ResolveImportUtil.getPointInImport(location);
for (PyModuleMembersProvider provider : Extensions.getExtensions(PyModuleMembersProvider.EP_NAME)) {
for (PyDynamicMember member : provider.getMembers(myModule, point)) {
for (PyCustomMember member : provider.getMembers(myModule, point)) {
final String name = member.getName();
if (namesAlready != null) {
namesAlready.add(name);
@@ -44,7 +44,7 @@ class MethodsManager extends MembersManager<PyFunction> {
@Override
public boolean hasConflict(@NotNull final PyFunction member, @NotNull final PyClass aClass) {
return NamePredicate.hasElementWithSameName(member, Arrays.asList(aClass.getMethods()));
return NamePredicate.hasElementWithSameName(member, Arrays.asList(aClass.getMethods(false)));
}
@NotNull
@@ -64,7 +64,7 @@ class MethodsManager extends MembersManager<PyFunction> {
@NotNull
@Override
protected List<? extends PyElement> getMembersCouldBeMoved(@NotNull final PyClass pyClass) {
return FluentIterable.from(Arrays.asList(pyClass.getMethods())).filter(new NamelessFilter<PyFunction>()).filter(NO_PROPERTIES).toList();
return FluentIterable.from(Arrays.asList(pyClass.getMethods(false))).filter(new NamelessFilter<PyFunction>()).filter(NO_PROPERTIES).toList();
}
@Override
@@ -181,7 +181,7 @@ public class PyExtractMethodUtil {
scope.add(owner);
final PyClass containingClass = ((PyFunction)owner).getContainingClass();
if (containingClass != null) {
for (PyFunction function : containingClass.getMethods()) {
for (PyFunction function : containingClass.getMethods(false)) {
if (!function.equals(owner) && !function.equals(generatedMethod))
scope.add(function);
}
@@ -60,7 +60,7 @@ public class PythonAtTestConfigurationProducer extends
}
private static boolean hasTestFunction(@NotNull final PyClass pyClass) {
PyFunction[] methods = pyClass.getMethods();
PyFunction[] methods = pyClass.getMethods(false);
for (PyFunction function : methods) {
PyDecoratorList decorators = function.getDecoratorList();
if (decorators == null) continue;
@@ -58,7 +58,7 @@ public class PythonDocTestUtil {
}
public static boolean isDocTestClass(PyClass pyClass) {
for (PyFunction cls : pyClass.getMethods()) {
for (PyFunction cls : pyClass.getMethods(false)) {
if (isDocTestFunction(cls)) {
return true;
}
@@ -80,7 +80,7 @@ public class PyTestUtil {
if (className == null) return false;
final String name = className.toLowerCase();
if (name.startsWith("test")) {
for (PyFunction cls : pyClass.getMethods()) {
for (PyFunction cls : pyClass.getMethods(false)) {
if (isPyTestFunction(cls)) {
return true;
}
@@ -205,7 +205,7 @@ public class PyControlFlowBuilderTest extends LightMarkedTestCase {
configureByFile(testName + ".py");
final String fullPath = getTestDataPath() + testName + ".txt";
final PyClass pyClass = ((PyFile) myFile).getTopLevelClasses().get(0);
final ControlFlow flow = ControlFlowCache.getControlFlow(pyClass.getMethods()[0]);
final ControlFlow flow = ControlFlowCache.getControlFlow(pyClass.getMethods(false)[0]);
check(fullPath, flow);
}
@@ -214,7 +214,7 @@ public class PyControlFlowBuilderTest extends LightMarkedTestCase {
configureByFile(testName + ".py");
final String fullPath = getTestDataPath() + testName + ".txt";
final PyClass pyClass = ((PyFile) myFile).getTopLevelClasses().get(0);
final ControlFlow flow = ControlFlowCache.getControlFlow(pyClass.getMethods()[0]);
final ControlFlow flow = ControlFlowCache.getControlFlow(pyClass.getMethods(false)[0]);
check(fullPath, flow);
}
@@ -35,7 +35,7 @@ import java.util.Collections;
public class PyOverrideTest extends PyTestCase {
private void doTest() {
myFixture.configureByFile("override/" + getTestName(true) + ".py");
PyFunction toOverride = getTopLevelClass(0).getMethods() [0];
PyFunction toOverride = getTopLevelClass(0).getMethods(false) [0];
PyOverrideImplementUtil.overrideMethods(myFixture.getEditor(), getTopLevelClass(1),
Collections.singletonList(new PyMethodMember(toOverride)), false);
myFixture.checkResultByFile("override/" + getTestName(true) + "_after.py", true);
@@ -86,7 +86,7 @@ public class PyOverrideTest extends PyTestCase {
public void testInnerClass() { // PY-10976
myFixture.configureByFile("override/" + getTestName(true) + ".py");
PyFunction toOverride = getTopLevelClass(0).getMethods()[0];
PyFunction toOverride = getTopLevelClass(0).getMethods(false)[0];
PyClass pyClass = getTopLevelClass(1).getNestedClasses()[0];
PyOverrideImplementUtil.overrideMethods(myFixture.getEditor(), pyClass,
Collections.singletonList(new PyMethodMember(toOverride)), false);
@@ -95,7 +95,7 @@ public class PyOverrideTest extends PyTestCase {
public void testInnerFunctionClass() {
myFixture.configureByFile("override/" + getTestName(true) + ".py");
PyFunction toOverride = getTopLevelClass(0).getMethods()[0];
PyFunction toOverride = getTopLevelClass(0).getMethods(false)[0];
final PsiElement element = myFixture.getElementAtCaret();
PyOverrideImplementUtil.overrideMethods(myFixture.getEditor(), PsiTreeUtil.getParentOfType(element, PyClass.class, false),
Collections.singletonList(new PyMethodMember(toOverride)), false);
@@ -115,7 +115,7 @@ public class PyOverrideTest extends PyTestCase {
public void testImplement() {
myFixture.configureByFile("override/" + getTestName(true) + ".py");
PyFunction toImplement = getTopLevelClass(0).getMethods()[1];
PyFunction toImplement = getTopLevelClass(0).getMethods(false)[1];
PyOverrideImplementUtil.overrideMethods(myFixture.getEditor(), getTopLevelClass(1),
Collections.singletonList(new PyMethodMember(toImplement)), true);
myFixture.checkResultByFile("override/" + getTestName(true) + "_after.py", true);
@@ -75,7 +75,7 @@ public class PyStubsTest extends PyTestCase {
assertEquals("staticField", attrs.get(0).getName());
assertTrue(attrs.get(0).getAssignedQName().matches("deco"));
final PyFunction[] methods = pyClass.getMethods();
final PyFunction[] methods = pyClass.getMethods(false);
assertEquals(2, methods.length);
assertEquals("__init__", methods [0].getName());
assertEquals("fooFunction", methods [1].getName());
@@ -122,7 +122,7 @@ public class PyStubsTest extends PyTestCase {
Property prop = pyClass.findProperty("value", true);
Maybe<Callable> maybe_function = prop.getGetter();
assertTrue(maybe_function.isDefined());
assertEquals(pyClass.getMethods()[0], maybe_function.value());
assertEquals(pyClass.getMethods(false)[0], maybe_function.value());
Property setvalueProp = pyClass.findProperty("setvalue", true);
Maybe<Callable> setter = setvalueProp.getSetter();
@@ -135,10 +135,10 @@ public class PyStubsTest extends PyTestCase {
prop = pyClass.findProperty("x", true);
maybe_function = prop.getGetter();
assertTrue(maybe_function.isDefined());
assertEquals(pyClass.getMethods()[0], maybe_function.value());
assertEquals(pyClass.getMethods(false)[0], maybe_function.value());
maybe_function = prop.getSetter();
assertTrue(maybe_function.isDefined());
assertEquals(pyClass.getMethods()[1], maybe_function.value());
assertEquals(pyClass.getMethods(false)[1], maybe_function.value());
// ...and the juice:
assertNotParsed(file);
@@ -342,7 +342,7 @@ public class PyStubsTest extends PyTestCase {
public void testWrappedStaticMethod() {
final PyFileImpl file = (PyFileImpl) getTestFile();
final PyClass pyClass = file.getTopLevelClasses().get(0);
final PyFunction[] methods = pyClass.getMethods();
final PyFunction[] methods = pyClass.getMethods(false);
assertEquals(1, methods.length);
final PyFunction.Modifier modifier = methods[0].getModifier();
assertEquals(PyFunction.Modifier.STATICMETHOD, modifier);
@@ -1,7 +1,6 @@
package com.jetbrains.python.refactoring.classes;
import com.intellij.psi.PsiElement;
import com.intellij.util.text.Matcher;
import com.jetbrains.python.fixtures.PyTestCase;
import com.jetbrains.python.psi.*;
import org.hamcrest.Matchers;
@@ -23,7 +22,7 @@ public class PyDependenciesComparatorTest extends PyTestCase {
@SuppressWarnings("ConstantConditions") // Can't be null (class has docstring)
PsiElement docStringExpression = clazz.getDocStringExpression().getParent();
PyFunction method = clazz.getMethods()[0];
PyFunction method = clazz.getMethods(false)[0];
PsiElement classField = clazz.getClassAttributes().get(0).getParent();
final List<PyStatement> elementList = new ArrayList<PyStatement>();