From 6185917f904a995733c00e52c8392ebc6582fddd Mon Sep 17 00:00:00 2001 From: "Ilya.Kazakevich" Date: Fri, 3 Oct 2014 17:27:46 +0400 Subject: [PATCH 01/12] PY-13740 Django 1.7 QuerySet.as_manager() code completion support: PyDynamicMember renamed --- ...DynamicMember.java => PyCustomMember.java} | 34 +++++++++---------- .../psi/types/PyClassMembersProvider.java | 4 +-- .../psi/types/PyClassMembersProviderBase.java | 10 +++--- .../psi/types/PyModuleMembersProvider.java | 8 ++--- .../NumpyModuleMembersProvider.java | 8 ++--- .../stdlib/PyStdlibClassMembersProvider.java | 16 ++++----- .../stdlib/PyStdlibModuleMembersProvider.java | 8 ++--- .../PyUserSkeletonsClassMembersProvider.java | 14 ++++---- .../PyUserSkeletonsModuleMembersProvider.java | 8 ++--- .../PyUnresolvedReferencesInspection.java | 6 ++-- .../python/psi/types/PyClassTypeImpl.java | 4 +-- .../python/psi/types/PyModuleType.java | 4 +-- 12 files changed, 62 insertions(+), 62 deletions(-) rename python/psi-api/src/com/jetbrains/python/codeInsight/{PyDynamicMember.java => PyCustomMember.java} (82%) diff --git a/python/psi-api/src/com/jetbrains/python/codeInsight/PyDynamicMember.java b/python/psi-api/src/com/jetbrains/python/codeInsight/PyCustomMember.java similarity index 82% rename from python/psi-api/src/com/jetbrains/python/codeInsight/PyDynamicMember.java rename to python/psi-api/src/com/jetbrains/python/codeInsight/PyCustomMember.java index a344e892588c..12b81805822d 100644 --- a/python/psi-api/src/com/jetbrains/python/codeInsight/PyDynamicMember.java +++ b/python/psi-api/src/com/jetbrains/python/codeInsight/PyCustomMember.java @@ -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 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 typeCallback) { + public PyCustomMember(@NotNull final String name, + @Nullable final String type, + final Function typeCallback) { myName = name; myResolveToInstance = false; @@ -75,7 +75,7 @@ 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) { myName = name; myTarget = target; myResolveToInstance = false; @@ -83,47 +83,47 @@ public class PyDynamicMember { myTypeCallback = 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 +179,7 @@ public class PyDynamicMember { return myTypeName.substring(pos + 1); } - public PyDynamicMember asFunction() { + public PyCustomMember asFunction() { myFunction = true; return this; } diff --git a/python/psi-api/src/com/jetbrains/python/psi/types/PyClassMembersProvider.java b/python/psi-api/src/com/jetbrains/python/psi/types/PyClassMembersProvider.java index e051b48fbfaa..6a61de999abc 100644 --- a/python/psi-api/src/com/jetbrains/python/psi/types/PyClassMembersProvider.java +++ b/python/psi-api/src/com/jetbrains/python/psi/types/PyClassMembersProvider.java @@ -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 EP_NAME = ExtensionPointName.create("Pythonid.pyClassMembersProvider"); @NotNull - Collection getMembers(PyClassType clazz, @Nullable PsiElement location); + Collection getMembers(PyClassType clazz, @Nullable PsiElement location); @Nullable PsiElement resolveMember(PyClassType clazz, String name, @Nullable PsiElement location); diff --git a/python/psi-api/src/com/jetbrains/python/psi/types/PyClassMembersProviderBase.java b/python/psi-api/src/com/jetbrains/python/psi/types/PyClassMembersProviderBase.java index a7d66499cf52..6ec96559911a 100644 --- a/python/psi-api/src/com/jetbrains/python/psi/types/PyClassMembersProviderBase.java +++ b/python/psi-api/src/com/jetbrains/python/psi/types/PyClassMembersProviderBase.java @@ -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 getMembers(PyClassType clazz, PsiElement location) { + public Collection getMembers(PyClassType clazz, PsiElement location) { return Collections.emptyList(); } @Override public PsiElement resolveMember(PyClassType clazz, String name, PsiElement location) { - final Collection members = getMembers(clazz, location); + final Collection members = getMembers(clazz, location); return resolveMemberByName(members, clazz, name); } @Nullable - public static PsiElement resolveMemberByName(Collection members, + public static PsiElement resolveMemberByName(Collection 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); } diff --git a/python/psi-api/src/com/jetbrains/python/psi/types/PyModuleMembersProvider.java b/python/psi-api/src/com/jetbrains/python/psi/types/PyModuleMembersProvider.java index 696dcaee6623..60d13fde976e 100644 --- a/python/psi-api/src/com/jetbrains/python/psi/types/PyModuleMembersProvider.java +++ b/python/psi-api/src/com/jetbrains/python/psi/types/PyModuleMembersProvider.java @@ -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 EP_NAME = ExtensionPointName.create("Pythonid.pyModuleMembersProvider"); - public Collection getMembers(PyFile module, PointInImport point) { + public Collection 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 getMembersByQName(PyFile module, String qName); + protected abstract Collection getMembersByQName(PyFile module, String qName); } diff --git a/python/src/com/jetbrains/numpy/codeInsight/NumpyModuleMembersProvider.java b/python/src/com/jetbrains/numpy/codeInsight/NumpyModuleMembersProvider.java index 1fd2e3afd58f..fadf38916d0b 100644 --- a/python/src/com/jetbrains/numpy/codeInsight/NumpyModuleMembersProvider.java +++ b/python/src/com/jetbrains/numpy/codeInsight/NumpyModuleMembersProvider.java @@ -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 getMembersByQName(PyFile module, String qName) { + protected Collection getMembersByQName(PyFile module, String qName) { if ("numpy".equals(qName)) { - final List members = new ArrayList(); + final List members = new ArrayList(); 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; } diff --git a/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibClassMembersProvider.java b/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibClassMembersProvider.java index b0b8c06c92de..334552aaf8c0 100644 --- a/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibClassMembersProvider.java +++ b/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibClassMembersProvider.java @@ -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> mySocketMembersKey = Key.create("socket.members"); + private Key> mySocketMembersKey = Key.create("socket.members"); @NotNull @Override - public Collection getMembers(PyClassType classType, PsiElement location) { + public Collection 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 socketMembers = socketFile.getUserData(mySocketMembersKey); + List 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 calcSocketMembers(PyFile socketFile) { - List result = new ArrayList(); + private static List calcSocketMembers(PyFile socketFile) { + List result = new ArrayList(); addMethodsFromAttr(socketFile, result, "_socketmethods"); addMethodsFromAttr(socketFile, result, "_delegate_methods"); return result; } - private static void addMethodsFromAttr(PyFile socketFile, List result, final String attrName) { + private static void addMethodsFromAttr(PyFile socketFile, List result, final String attrName) { final PyTargetExpression socketMethods = socketFile.findTopLevelAttribute(attrName); if (socketMethods != null) { final List 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)); } } } diff --git a/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibModuleMembersProvider.java b/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibModuleMembersProvider.java index 80d3627ac083..a724b7808a75 100644 --- a/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibModuleMembersProvider.java +++ b/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibModuleMembersProvider.java @@ -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 getMembersByQName(PyFile module, String qName) { + protected Collection getMembersByQName(PyFile module, String qName) { if (qName.equals("os")) { - final List results = new ArrayList(); + final List results = new ArrayList(); 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(); diff --git a/python/src/com/jetbrains/python/codeInsight/userSkeletons/PyUserSkeletonsClassMembersProvider.java b/python/src/com/jetbrains/python/codeInsight/userSkeletons/PyUserSkeletonsClassMembersProvider.java index 5ac7fc10751c..104aceb861c0 100644 --- a/python/src/com/jetbrains/python/codeInsight/userSkeletons/PyUserSkeletonsClassMembersProvider.java +++ b/python/src/com/jetbrains/python/codeInsight/userSkeletons/PyUserSkeletonsClassMembersProvider.java @@ -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 getMembers(@NotNull PyClassType classType, PsiElement location) { + public Collection 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 getClassMembers(@NotNull PyClass cls) { - final List result = new ArrayList(); + private static Collection getClassMembers(@NotNull PyClass cls) { + final List result = new ArrayList(); for (PyFunction function : cls.getMethods()) { 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; diff --git a/python/src/com/jetbrains/python/codeInsight/userSkeletons/PyUserSkeletonsModuleMembersProvider.java b/python/src/com/jetbrains/python/codeInsight/userSkeletons/PyUserSkeletonsModuleMembersProvider.java index ad876ee4ec91..c42d15c6f463 100644 --- a/python/src/com/jetbrains/python/codeInsight/userSkeletons/PyUserSkeletonsModuleMembersProvider.java +++ b/python/src/com/jetbrains/python/codeInsight/userSkeletons/PyUserSkeletonsModuleMembersProvider.java @@ -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 getMembersByQName(PyFile module, String qName) { + protected Collection getMembersByQName(PyFile module, String qName) { final PyFile moduleSkeleton = PyUserSkeletonsUtil.getUserSkeletonForModuleQName(qName, module); if (moduleSkeleton != null) { - final List results = new ArrayList(); + final List results = new ArrayList(); 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; diff --git a/python/src/com/jetbrains/python/inspections/unresolvedReference/PyUnresolvedReferencesInspection.java b/python/src/com/jetbrains/python/inspections/unresolvedReference/PyUnresolvedReferencesInspection.java index 8049546a6e92..0e2491134d5c 100644 --- a/python/src/com/jetbrains/python/inspections/unresolvedReference/PyUnresolvedReferencesInspection.java +++ b/python/src/com/jetbrains/python/inspections/unresolvedReference/PyUnresolvedReferencesInspection.java @@ -35,7 +35,7 @@ import com.intellij.util.PlatformUtils; import com.jetbrains.python.PyBundle; 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; @@ -721,8 +721,8 @@ public class PyUnresolvedReferencesInspection extends PyInspection { PsiReference reference, @NotNull final String name) { for (PyClassMembersProvider provider : Extensions.getExtensions(PyClassMembersProvider.EP_NAME)) { - final Collection resolveResult = provider.getMembers(type, reference.getElement()); - for (PyDynamicMember member : resolveResult) { + final Collection resolveResult = provider.getMembers(type, reference.getElement()); + for (PyCustomMember member : resolveResult) { if (member.getName().equals(name)) return true; } } diff --git a/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java b/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java index 34a92e16bf01..9a7f2f107ee8 100644 --- a/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java +++ b/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java @@ -33,7 +33,7 @@ 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.psi.*; import com.jetbrains.python.psi.impl.PyBuiltinCache; import com.jetbrains.python.psi.impl.ResolveResultList; @@ -415,7 +415,7 @@ public class PyClassTypeImpl extends UserDataHolderBase implements PyClassType { // from providers for (PyClassMembersProvider provider : Extensions.getExtensions(PyClassMembersProvider.EP_NAME)) { - for (PyDynamicMember member : provider.getMembers(this, location)) { + for (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()); diff --git a/python/src/com/jetbrains/python/psi/types/PyModuleType.java b/python/src/com/jetbrains/python/psi/types/PyModuleType.java index db5a9ba3f1ae..0aec8612c989 100644 --- a/python/src/com/jetbrains/python/psi/types/PyModuleType.java +++ b/python/src/com/jetbrains/python/psi/types/PyModuleType.java @@ -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 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); From 679ef3e9760d7c4197387309ef6b9bcfdec0c419 Mon Sep 17 00:00:00 2001 From: "Ilya.Kazakevich" Date: Sat, 4 Oct 2014 01:14:41 +0400 Subject: [PATCH 02/12] PY-13740 Django 1.7 QuerySet.as_manager() code completion support: TODO: * Add tests * Check performance --- .../python/codeInsight/PyCustomMember.java | 7 +- .../src/com/jetbrains/python/psi/PyClass.java | 14 +- .../com/jetbrains/python/psi/PyFunction.java | 46 +++++ .../jetbrains/python/psi/types/PyType.java | 4 +- .../python/psi/types/PyTypeProviderBase.java | 1 + .../com/jetbrains/python/PyBundle.properties | 6 +- .../jetbrains/python/PyCustomMembersType.java | 189 ++++++++++++++++++ .../codeInsight/PyCustomMemberUtils.java | 34 ++++ .../PyMethodNavigationOffsetProvider.java | 2 +- .../PySuperMethodCompletionContributor.java | 4 +- .../override/PyOverrideImplementUtil.java | 2 +- .../PyUserSkeletonsClassMembersProvider.java | 2 +- .../PyOldStyleClassesInspection.java | 2 +- .../quickfix/AddFieldQuickFix.java | 2 +- .../PyUnresolvedReferencesInspection.java | 26 ++- .../python/projectView/PyElementNode.java | 2 +- .../com/jetbrains/python/psi/PsiQuery.java | 23 ++- .../python/psi/impl/PyClassImpl.java | 44 +++- .../python/psi/impl/PyEvaluator.java | 9 + .../python/psi/impl/PyFunctionImpl.java | 36 ++++ .../python/psi/types/PyClassTypeImpl.java | 19 +- .../membersManager/MethodsManager.java | 4 +- .../extractmethod/PyExtractMethodUtil.java | 2 +- .../PythonAtTestConfigurationProducer.java | 2 +- .../testing/doctest/PythonDocTestUtil.java | 2 +- .../python/testing/pytest/PyTestUtil.java | 2 +- .../python/PyControlFlowBuilderTest.java | 4 +- .../com/jetbrains/python/PyOverrideTest.java | 8 +- .../com/jetbrains/python/PyStubsTest.java | 10 +- .../classes/PyDependenciesComparatorTest.java | 3 +- 30 files changed, 448 insertions(+), 63 deletions(-) create mode 100644 python/src/com/jetbrains/python/PyCustomMembersType.java create mode 100644 python/src/com/jetbrains/python/codeInsight/PyCustomMemberUtils.java diff --git a/python/psi-api/src/com/jetbrains/python/codeInsight/PyCustomMember.java b/python/psi-api/src/com/jetbrains/python/codeInsight/PyCustomMember.java index 12b81805822d..ffc846796806 100644 --- a/python/psi-api/src/com/jetbrains/python/codeInsight/PyCustomMember.java +++ b/python/psi-api/src/com/jetbrains/python/codeInsight/PyCustomMember.java @@ -75,13 +75,16 @@ public class PyCustomMember { myTypeCallback = typeCallback; } - public PyCustomMember(@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 PyCustomMember resolvesTo(String moduleQName) { myPsiPath = new PyPsiPath.ToFile(moduleQName); diff --git a/python/psi-api/src/com/jetbrains/python/psi/PyClass.java b/python/psi-api/src/com/jetbrains/python/psi/PyClass.java index a988714c144a..b6a26fc35539 100644 --- a/python/psi-api/src/com/jetbrains/python/psi/PyClass.java +++ b/python/psi-api/src/com/jetbrains/python/psi/PyClass.java @@ -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); } diff --git a/python/psi-api/src/com/jetbrains/python/psi/PyFunction.java b/python/psi-api/src/com/jetbrains/python/psi/PyFunction.java index e70a7ad12a51..0f7031b85dc2 100644 --- a/python/psi-api/src/com/jetbrains/python/psi/PyFunction.java +++ b/python/psi-api/src/com/jetbrains/python/psi/PyFunction.java @@ -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 def and everything within). * @@ -101,4 +103,48 @@ extends @Nullable PyAnnotation getAnnotation(); + + // TODO: Doc + // + + /** + * Searches for function attributes. + * See PEP-0232 + * @return assignment statements for function attributes + */ + @NotNull + List 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; + } + } } diff --git a/python/psi-api/src/com/jetbrains/python/psi/types/PyType.java b/python/psi-api/src/com/jetbrains/python/psi/types/PyType.java index 67ba765bbf81..4640fceb324d 100644 --- a/python/psi-api/src/com/jetbrains/python/psi/types/PyType.java +++ b/python/psi-api/src/com/jetbrains/python/psi/types/PyType.java @@ -47,8 +47,8 @@ public interface PyType { * or a list of elements that define the name, a la multiResolve(). */ @Nullable - List resolveMember(@NotNull final String name, @Nullable PyExpression location, - @NotNull AccessDirection direction, @NotNull PyResolveContext resolveContext); + List resolveMember(@NotNull String name, @Nullable final PyExpression location, + @NotNull final AccessDirection direction, @NotNull final PyResolveContext resolveContext); /** * Proposes completion variants from type's attributes. diff --git a/python/psi-api/src/com/jetbrains/python/psi/types/PyTypeProviderBase.java b/python/psi-api/src/com/jetbrains/python/psi/types/PyTypeProviderBase.java index 0c60e6555b59..320397c4c12a 100644 --- a/python/psi-api/src/com/jetbrains/python/psi/types/PyTypeProviderBase.java +++ b/python/psi-api/src/com/jetbrains/python/psi/types/PyTypeProviderBase.java @@ -80,6 +80,7 @@ public class PyTypeProviderBase implements PyTypeProvider { } }; + @Nullable @Override public PyType getReferenceExpressionType(@NotNull PyReferenceExpression referenceExpression, @NotNull TypeEvalContext context) { return null; diff --git a/python/src/com/jetbrains/python/PyBundle.properties b/python/src/com/jetbrains/python/PyBundle.properties index d82e9a6fde62..9e9c68f64a69 100644 --- a/python/src/com/jetbrains/python/PyBundle.properties +++ b/python/src/com/jetbrains/python/PyBundle.properties @@ -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: \ No newline at end of file +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} \ No newline at end of file diff --git a/python/src/com/jetbrains/python/PyCustomMembersType.java b/python/src/com/jetbrains/python/PyCustomMembersType.java new file mode 100644 index 000000000000..7e6b3b07f727 --- /dev/null +++ b/python/src/com/jetbrains/python/PyCustomMembersType.java @@ -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 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(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 getSuperClassTypes(@NotNull TypeEvalContext context) { + return Collections.emptyList(); + } + + @Nullable + @Override + public List 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 getParameters(@NotNull TypeEvalContext context) { + return null; + } + + @Nullable + @Override + public List 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 lookupElements = new ArrayList(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); + } +} diff --git a/python/src/com/jetbrains/python/codeInsight/PyCustomMemberUtils.java b/python/src/com/jetbrains/python/codeInsight/PyCustomMemberUtils.java new file mode 100644 index 000000000000..86da6a9326f5 --- /dev/null +++ b/python/src/com/jetbrains/python/codeInsight/PyCustomMemberUtils.java @@ -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; + } +} diff --git a/python/src/com/jetbrains/python/codeInsight/PyMethodNavigationOffsetProvider.java b/python/src/com/jetbrains/python/codeInsight/PyMethodNavigationOffsetProvider.java index 045bdc1307b3..a00366ab5d7d 100644 --- a/python/src/com/jetbrains/python/codeInsight/PyMethodNavigationOffsetProvider.java +++ b/python/src/com/jetbrains/python/codeInsight/PyMethodNavigationOffsetProvider.java @@ -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)); } } } diff --git a/python/src/com/jetbrains/python/codeInsight/completion/PySuperMethodCompletionContributor.java b/python/src/com/jetbrains/python/codeInsight/completion/PySuperMethodCompletionContributor.java index 04ad5ae8e958..4778c6db1ccc 100644 --- a/python/src/com/jetbrains/python/codeInsight/completion/PySuperMethodCompletionContributor.java +++ b/python/src/com/jetbrains/python/codeInsight/completion/PySuperMethodCompletionContributor.java @@ -57,13 +57,13 @@ public class PySuperMethodCompletionContributor extends CompletionContributor { return; } Set seenNames = new HashSet(); - 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); diff --git a/python/src/com/jetbrains/python/codeInsight/override/PyOverrideImplementUtil.java b/python/src/com/jetbrains/python/codeInsight/override/PyOverrideImplementUtil.java index 5a6caf0a8941..634eaf9a59c9 100644 --- a/python/src/com/jetbrains/python/codeInsight/override/PyOverrideImplementUtil.java +++ b/python/src/com/jetbrains/python/codeInsight/override/PyOverrideImplementUtil.java @@ -281,7 +281,7 @@ public class PyOverrideImplementUtil { public static Collection getAllSuperFunctions(@NotNull final PyClass pyClass) { final Map superFunctions = new HashMap(); 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); } diff --git a/python/src/com/jetbrains/python/codeInsight/userSkeletons/PyUserSkeletonsClassMembersProvider.java b/python/src/com/jetbrains/python/codeInsight/userSkeletons/PyUserSkeletonsClassMembersProvider.java index 104aceb861c0..bcc39aab9010 100644 --- a/python/src/com/jetbrains/python/codeInsight/userSkeletons/PyUserSkeletonsClassMembersProvider.java +++ b/python/src/com/jetbrains/python/codeInsight/userSkeletons/PyUserSkeletonsClassMembersProvider.java @@ -75,7 +75,7 @@ public class PyUserSkeletonsClassMembersProvider extends PyClassMembersProviderB private static Collection getClassMembers(@NotNull PyClass cls) { final List result = new ArrayList(); - for (PyFunction function : cls.getMethods()) { + for (PyFunction function : cls.getMethods(false)) { final String name = function.getName(); if (name != null) { result.add(new PyCustomMember(name, function)); diff --git a/python/src/com/jetbrains/python/inspections/PyOldStyleClassesInspection.java b/python/src/com/jetbrains/python/inspections/PyOldStyleClassesInspection.java index a253be86344f..0ea757dbebc1 100644 --- a/python/src/com/jetbrains/python/inspections/PyOldStyleClassesInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyOldStyleClassesInspection.java @@ -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; diff --git a/python/src/com/jetbrains/python/inspections/quickfix/AddFieldQuickFix.java b/python/src/com/jetbrains/python/inspections/quickfix/AddFieldQuickFix.java index 8ecd8a5d9b03..367f22b0540c 100644 --- a/python/src/com/jetbrains/python/inspections/quickfix/AddFieldQuickFix.java +++ b/python/src/com/jetbrains/python/inspections/quickfix/AddFieldQuickFix.java @@ -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); diff --git a/python/src/com/jetbrains/python/inspections/unresolvedReference/PyUnresolvedReferencesInspection.java b/python/src/com/jetbrains/python/inspections/unresolvedReference/PyUnresolvedReferencesInspection.java index 0e2491134d5c..10b4c6f8705a 100644 --- a/python/src/com/jetbrains/python/inspections/unresolvedReference/PyUnresolvedReferencesInspection.java +++ b/python/src/com/jetbrains/python/inspections/unresolvedReference/PyUnresolvedReferencesInspection.java @@ -33,6 +33,7 @@ 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.PyCustomMember; @@ -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)) { @@ -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)); } diff --git a/python/src/com/jetbrains/python/projectView/PyElementNode.java b/python/src/com/jetbrains/python/projectView/PyElementNode.java index 6ec347236773..3ef8ddd71a6b 100644 --- a/python/src/com/jetbrains/python/projectView/PyElementNode.java +++ b/python/src/com/jetbrains/python/projectView/PyElementNode.java @@ -50,7 +50,7 @@ public class PyElementNode extends BasePsiNode { 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; diff --git a/python/src/com/jetbrains/python/psi/PsiQuery.java b/python/src/com/jetbrains/python/psi/PsiQuery.java index d41f6ba68a2c..3e1e26de12c3 100644 --- a/python/src/com/jetbrains/python/psi/PsiQuery.java +++ b/python/src/com/jetbrains/python/psi/PsiQuery.java @@ -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(clazz, array); + return new PsiTypedQuery(clazz, result); } @@ -309,14 +307,17 @@ public class PsiQuery { * Filter elements by class */ @NotNull - public PsiQuery filter(@NotNull final Class clazz) { + public PsiTypedQuery filter(@NotNull final Class clazz) { final Set result = new HashSet(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 toAdd = (List)new ArrayList(result); + return new PsiTypedQuery(clazz, toAdd); } @@ -351,16 +352,16 @@ public class PsiQuery { @NotNull private final Class myClass; @NotNull - private final T[] myElements; + private final List myElements; /** * @param clazz type * @param elements elements */ - private PsiTypedQuery(@NotNull final Class clazz, @NotNull final T... elements) { + private PsiTypedQuery(@NotNull final Class clazz, @NotNull final List 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 getElements() { + return Collections.unmodifiableList(myElements); } } } diff --git a/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java b/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java index 611cbc84ad2e..c7f2173973c0 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java @@ -389,9 +389,34 @@ public class PyClassImpl extends PyBaseElementImpl 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 result = new HashMap(); + // 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 functionsToReturn = result.values(); + return functionsToReturn.toArray(new PyFunction[functionsToReturn.size()]); } @Override @@ -514,7 +539,7 @@ public class PyClassImpl extends PyBaseElementImpl implements PyCla // look at @property decorators Map> grouped = new HashMap>(); // 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 bucket = grouped.get(methodName); @@ -826,7 +851,7 @@ public class PyClassImpl extends PyBaseElementImpl implements PyCla public boolean visitMethods(Processor 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 implements PyCla collectInstanceAttributes(initMethod, result); } Set namesInInit = new HashSet(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 implements PyCla final List result = new ArrayList(); 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 implements PyCla } return null; } + + @Nullable + @Override + public PyClassLikeType getType(@NotNull TypeEvalContext context) { + return PyUtil.as(context.getType(this), PyClassLikeType.class); + } } diff --git a/python/src/com/jetbrains/python/psi/impl/PyEvaluator.java b/python/src/com/jetbrains/python/psi/impl/PyEvaluator.java index dea9296f12c6..3f948c496592 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyEvaluator.java +++ b/python/src/com/jetbrains/python/psi/impl/PyEvaluator.java @@ -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); } diff --git a/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java index 2c1842f3337f..9f6afb5e43f7 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java @@ -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 implements public String getQualifiedName() { return QualifiedNameFinder.getQualifiedName(this); } + + @NotNull + @Override + public List findAttributes() { + final List result = new ArrayList(); + 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; + } } diff --git a/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java b/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java index 9a7f2f107ee8..d9b69121aa50 100644 --- a/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java +++ b/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java @@ -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; @@ -34,6 +33,7 @@ import com.intellij.util.ProcessingContext; import com.intellij.util.containers.ContainerUtil; import com.jetbrains.python.PyNames; 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 (PyCustomMember 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())); } } } diff --git a/python/src/com/jetbrains/python/refactoring/classes/membersManager/MethodsManager.java b/python/src/com/jetbrains/python/refactoring/classes/membersManager/MethodsManager.java index 52c32d95d38d..56bd80ca3077 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/membersManager/MethodsManager.java +++ b/python/src/com/jetbrains/python/refactoring/classes/membersManager/MethodsManager.java @@ -44,7 +44,7 @@ class MethodsManager extends MembersManager { @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 { @NotNull @Override protected List getMembersCouldBeMoved(@NotNull final PyClass pyClass) { - return FluentIterable.from(Arrays.asList(pyClass.getMethods())).filter(new NamelessFilter()).filter(NO_PROPERTIES).toList(); + return FluentIterable.from(Arrays.asList(pyClass.getMethods(false))).filter(new NamelessFilter()).filter(NO_PROPERTIES).toList(); } @Override diff --git a/python/src/com/jetbrains/python/refactoring/extractmethod/PyExtractMethodUtil.java b/python/src/com/jetbrains/python/refactoring/extractmethod/PyExtractMethodUtil.java index d16712dea6c7..a396a354a381 100644 --- a/python/src/com/jetbrains/python/refactoring/extractmethod/PyExtractMethodUtil.java +++ b/python/src/com/jetbrains/python/refactoring/extractmethod/PyExtractMethodUtil.java @@ -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); } diff --git a/python/src/com/jetbrains/python/testing/attest/PythonAtTestConfigurationProducer.java b/python/src/com/jetbrains/python/testing/attest/PythonAtTestConfigurationProducer.java index d0a6d19e19e2..006749a25e96 100644 --- a/python/src/com/jetbrains/python/testing/attest/PythonAtTestConfigurationProducer.java +++ b/python/src/com/jetbrains/python/testing/attest/PythonAtTestConfigurationProducer.java @@ -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; diff --git a/python/src/com/jetbrains/python/testing/doctest/PythonDocTestUtil.java b/python/src/com/jetbrains/python/testing/doctest/PythonDocTestUtil.java index fd6e9ef357af..b0889b72c46d 100644 --- a/python/src/com/jetbrains/python/testing/doctest/PythonDocTestUtil.java +++ b/python/src/com/jetbrains/python/testing/doctest/PythonDocTestUtil.java @@ -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; } diff --git a/python/src/com/jetbrains/python/testing/pytest/PyTestUtil.java b/python/src/com/jetbrains/python/testing/pytest/PyTestUtil.java index b6f463b15706..357227532727 100644 --- a/python/src/com/jetbrains/python/testing/pytest/PyTestUtil.java +++ b/python/src/com/jetbrains/python/testing/pytest/PyTestUtil.java @@ -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; } diff --git a/python/testSrc/com/jetbrains/python/PyControlFlowBuilderTest.java b/python/testSrc/com/jetbrains/python/PyControlFlowBuilderTest.java index 203b462c5a44..c5e489c06485 100644 --- a/python/testSrc/com/jetbrains/python/PyControlFlowBuilderTest.java +++ b/python/testSrc/com/jetbrains/python/PyControlFlowBuilderTest.java @@ -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); } diff --git a/python/testSrc/com/jetbrains/python/PyOverrideTest.java b/python/testSrc/com/jetbrains/python/PyOverrideTest.java index d80dc06182e7..fddb9e26c905 100644 --- a/python/testSrc/com/jetbrains/python/PyOverrideTest.java +++ b/python/testSrc/com/jetbrains/python/PyOverrideTest.java @@ -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); diff --git a/python/testSrc/com/jetbrains/python/PyStubsTest.java b/python/testSrc/com/jetbrains/python/PyStubsTest.java index 0904b4c3d7d0..2a58613f1668 100644 --- a/python/testSrc/com/jetbrains/python/PyStubsTest.java +++ b/python/testSrc/com/jetbrains/python/PyStubsTest.java @@ -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 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 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); diff --git a/python/testSrc/com/jetbrains/python/refactoring/classes/PyDependenciesComparatorTest.java b/python/testSrc/com/jetbrains/python/refactoring/classes/PyDependenciesComparatorTest.java index 9ebe01b127dc..b3be3825f970 100644 --- a/python/testSrc/com/jetbrains/python/refactoring/classes/PyDependenciesComparatorTest.java +++ b/python/testSrc/com/jetbrains/python/refactoring/classes/PyDependenciesComparatorTest.java @@ -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 elementList = new ArrayList(); From db41dda5cadd8b681845aef159cd953095ff880b Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Fri, 3 Oct 2014 20:47:45 +0400 Subject: [PATCH 03/12] cleanup --- .../com/intellij/ui/EditorTextFieldCellRenderer.java | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/platform/platform-impl/src/com/intellij/ui/EditorTextFieldCellRenderer.java b/platform/platform-impl/src/com/intellij/ui/EditorTextFieldCellRenderer.java index 5c3fa9143ae4..568e8c0cf7ef 100644 --- a/platform/platform-impl/src/com/intellij/ui/EditorTextFieldCellRenderer.java +++ b/platform/platform-impl/src/com/intellij/ui/EditorTextFieldCellRenderer.java @@ -29,14 +29,12 @@ import com.intellij.openapi.editor.impl.EditorImpl; import com.intellij.openapi.editor.impl.LineSet; import com.intellij.openapi.editor.impl.RangeMarkerTree; import com.intellij.openapi.fileTypes.FileTypes; -import com.intellij.openapi.util.Comparing; -import com.intellij.openapi.util.Disposer; -import com.intellij.openapi.util.TextRange; -import com.intellij.openapi.util.UserDataHolderBase; +import com.intellij.openapi.util.*; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.ArrayUtil; import com.intellij.util.ObjectUtils; import com.intellij.util.Processor; +import com.intellij.util.ui.UIUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -52,7 +50,7 @@ import java.util.List; */ public abstract class EditorTextFieldCellRenderer implements TableCellRenderer, Disposable { - private static final String MY_PANEL_PROPERTY = "EditorTextFieldCellRenderer.MyEditorPanel"; + private static final Key MY_PANEL_PROPERTY = Key.create("EditorTextFieldCellRenderer.MyEditorPanel"); public EditorTextFieldCellRenderer(Disposable parent) { Disposer.register(parent, this); @@ -96,7 +94,7 @@ public abstract class EditorTextFieldCellRenderer implements TableCellRenderer, @NotNull private MyPanel getEditorPanel(JTable table) { - MyPanel panel = (MyPanel)table.getClientProperty(MY_PANEL_PROPERTY); + MyPanel panel = UIUtil.getClientProperty(table, MY_PANEL_PROPERTY); if (panel != null) { EditorColorsScheme scheme = panel.myEditor.getColorsScheme(); if (scheme instanceof DelegateColorScheme) { From 76e6928bacac817269f0061f0d9502f6df4f71a4 Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Fri, 3 Oct 2014 22:54:27 +0400 Subject: [PATCH 04/12] LanguageUtil: introduce isFileLanguage & getFileLanguages --- .../src/com/intellij/lang/LanguageUtil.java | 25 ++++++++++++- .../ide/scratch/NewScratchFileAction.java | 36 ++----------------- 2 files changed, 26 insertions(+), 35 deletions(-) diff --git a/platform/core-api/src/com/intellij/lang/LanguageUtil.java b/platform/core-api/src/com/intellij/lang/LanguageUtil.java index 96dae6f63f34..418d6931f86f 100644 --- a/platform/core-api/src/com/intellij/lang/LanguageUtil.java +++ b/platform/core-api/src/com/intellij/lang/LanguageUtil.java @@ -17,7 +17,9 @@ package com.intellij.lang; import com.intellij.lexer.Lexer; +import com.intellij.openapi.fileTypes.LanguageFileType; import com.intellij.openapi.util.Condition; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.FileViewProvider; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; @@ -26,6 +28,7 @@ import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Set; @@ -74,7 +77,7 @@ public final class LanguageUtil { return language instanceof TemplateLanguage; } - public static boolean isInjectableLanguage(Language language) { + public static boolean isInjectableLanguage(@NotNull Language language) { if (language == Language.ANY) { return false; } @@ -93,6 +96,26 @@ public final class LanguageUtil { return true; } + public static boolean isFileLanguage(@NotNull Language language) { + if (language instanceof DependentLanguage || language instanceof InjectableLanguage) return false; + LanguageFileType type = language.getAssociatedFileType(); + if (type == null || StringUtil.isEmpty(type.getDefaultExtension())) return false; + String name = language.getDisplayName(); + if (StringUtil.isEmpty(name) || name.startsWith("<") || name.startsWith("[")) return false; + return !StringUtil.isEmpty(type.getDefaultExtension()); + } + + @NotNull + public static List getFileLanguages() { + List result = ContainerUtil.newArrayList(); + for (Language language : Language.getRegisteredLanguages()) { + if (!isFileLanguage(language)) continue; + result.add(language); + } + Collections.sort(result, LANGUAGE_COMPARATOR); + return result; + } + @NotNull public static Language getRootLanguage(@NotNull PsiElement element) { final FileViewProvider provider = element.getContainingFile().getViewProvider(); diff --git a/platform/lang-impl/src/com/intellij/ide/scratch/NewScratchFileAction.java b/platform/lang-impl/src/com/intellij/ide/scratch/NewScratchFileAction.java index 11c7ff2efe14..0f4c4165cda7 100644 --- a/platform/lang-impl/src/com/intellij/ide/scratch/NewScratchFileAction.java +++ b/platform/lang-impl/src/com/intellij/ide/scratch/NewScratchFileAction.java @@ -16,9 +16,8 @@ package com.intellij.ide.scratch; import com.intellij.featureStatistics.FeatureUsageTracker; -import com.intellij.lang.DependentLanguage; -import com.intellij.lang.InjectableLanguage; import com.intellij.lang.Language; +import com.intellij.lang.LanguageUtil; import com.intellij.lang.StdLanguages; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; @@ -31,23 +30,18 @@ import com.intellij.openapi.ui.popup.ListPopup; import com.intellij.openapi.ui.popup.ListPopupStep; import com.intellij.openapi.ui.popup.PopupStep; import com.intellij.openapi.ui.popup.util.BaseListPopupStep; -import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.registry.Registry; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.util.Consumer; import com.intellij.util.ObjectUtils; -import com.intellij.util.containers.ContainerUtil; -import com.intellij.util.containers.ContainerUtilRt; import com.intellij.util.ui.EmptyIcon; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.awt.*; -import java.util.Comparator; import java.util.List; -import java.util.Set; /** * @author ignatov @@ -82,7 +76,7 @@ public class NewScratchFileAction extends AnAction implements DumbAware { @NotNull static ListPopup buildLanguagePopup(@Nullable Language previous, final Consumer onChoosen) { - List languages = getLanguages(); + List languages = LanguageUtil.getFileLanguages(); BaseListPopupStep step = new BaseListPopupStep("Choose Language", languages) { @NotNull @@ -128,30 +122,4 @@ public class NewScratchFileAction extends AnAction implements DumbAware { } return popup; } - - - @NotNull - private static List getLanguages() { - Set result = ContainerUtilRt.newTreeSet(new Comparator() { - @Override - public int compare(@NotNull Language l1, @NotNull Language l2) { - return l1.getDisplayName().compareTo(l2.getDisplayName()); - } - }); - for (Language lang : Language.getRegisteredLanguages()) { - if (!StringUtil.isEmpty(lang.getDisplayName())) result.add(lang); - for (Language dialect : lang.getDialects()) result.add(dialect); - } - return ContainerUtil.filter(result, new Condition() { - @Override - public boolean value(Language lang) { - if (lang instanceof DependentLanguage || lang instanceof InjectableLanguage) return false; - LanguageFileType type = lang.getAssociatedFileType(); - if (type == null) return false; - String name = lang.getDisplayName(); - if (StringUtil.startsWith(name, "<") || StringUtil.startsWith(name, "[") || StringUtil.isEmpty(name) || StringUtil.equalsIgnoreCase(name, "SQL")) return false; - return !StringUtil.isEmpty(type.getDefaultExtension()); - } - }); - } } \ No newline at end of file From 142bc8670e35affdee2d86ceef2b9f7efdb99f66 Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Fri, 3 Oct 2014 22:54:52 +0400 Subject: [PATCH 05/12] ScratchWidget: use language substitutors --- .../src/com/intellij/ide/scratch/ScratchWidget.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/ide/scratch/ScratchWidget.java b/platform/lang-impl/src/com/intellij/ide/scratch/ScratchWidget.java index 8dbeb7200a77..9a455cad2e4a 100644 --- a/platform/lang-impl/src/com/intellij/ide/scratch/ScratchWidget.java +++ b/platform/lang-impl/src/com/intellij/ide/scratch/ScratchWidget.java @@ -28,6 +28,7 @@ import com.intellij.openapi.wm.CustomStatusBarWidget; import com.intellij.openapi.wm.StatusBarWidget; import com.intellij.openapi.wm.impl.status.EditorBasedWidget; import com.intellij.openapi.wm.impl.status.TextPanel; +import com.intellij.psi.LanguageSubstitutors; import com.intellij.testFramework.LightVirtualFile; import com.intellij.ui.ClickListener; import com.intellij.ui.awt.RelativePoint; @@ -50,7 +51,7 @@ class ScratchWidget extends EditorBasedWidget implements CustomStatusBarWidget.M new ClickListener() { @Override public boolean onClick(@NotNull MouseEvent e, int clickCount) { - final Project project = getProject(); + Project project = getProject(); Editor editor = getEditor(); final LightVirtualFile selectedFile = getScratchFile(); if (project == null || editor == null || selectedFile == null) return false; @@ -58,7 +59,7 @@ class ScratchWidget extends EditorBasedWidget implements CustomStatusBarWidget.M ListPopup popup = NewScratchFileAction.buildLanguagePopup(selectedFile.getLanguage(), new Consumer() { @Override public void consume(Language language) { - selectedFile.setLanguage(language); + selectedFile.setLanguage(LanguageSubstitutors.INSTANCE.substituteLanguage(language, selectedFile, myProject)); FileContentUtilCore.reparseFiles(selectedFile); update(); } From 44be381c6f37a899bcd1bb41fdf4e6c995cea1a9 Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Fri, 3 Oct 2014 22:55:38 +0400 Subject: [PATCH 06/12] revert to "Scratch File" naming --- .../src/com/intellij/ide/scratch/NewScratchFileAction.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform/lang-impl/src/com/intellij/ide/scratch/NewScratchFileAction.java b/platform/lang-impl/src/com/intellij/ide/scratch/NewScratchFileAction.java index 0f4c4165cda7..29320e24f9a4 100644 --- a/platform/lang-impl/src/com/intellij/ide/scratch/NewScratchFileAction.java +++ b/platform/lang-impl/src/com/intellij/ide/scratch/NewScratchFileAction.java @@ -50,7 +50,7 @@ public class NewScratchFileAction extends AnAction implements DumbAware { public static final int MAX_VISIBLE_SIZE = 20; public NewScratchFileAction() { - super("New Scratch Pad...", null, null); + super("New Scratch File...", null, null); } @Override From 58ba717287ccb6c0f84f2706a6f4af88c96a0a06 Mon Sep 17 00:00:00 2001 From: "Gregory.Shrago" Date: Sat, 4 Oct 2014 01:54:04 +0400 Subject: [PATCH 07/12] ensure ParserDefinition is available --- platform/core-api/src/com/intellij/lang/LanguageUtil.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/platform/core-api/src/com/intellij/lang/LanguageUtil.java b/platform/core-api/src/com/intellij/lang/LanguageUtil.java index 418d6931f86f..6179acfabe7a 100644 --- a/platform/core-api/src/com/intellij/lang/LanguageUtil.java +++ b/platform/core-api/src/com/intellij/lang/LanguageUtil.java @@ -98,11 +98,12 @@ public final class LanguageUtil { public static boolean isFileLanguage(@NotNull Language language) { if (language instanceof DependentLanguage || language instanceof InjectableLanguage) return false; + if (LanguageParserDefinitions.INSTANCE.forLanguage(language) == null) return false; LanguageFileType type = language.getAssociatedFileType(); if (type == null || StringUtil.isEmpty(type.getDefaultExtension())) return false; String name = language.getDisplayName(); if (StringUtil.isEmpty(name) || name.startsWith("<") || name.startsWith("[")) return false; - return !StringUtil.isEmpty(type.getDefaultExtension()); + return StringUtil.isNotEmpty(type.getDefaultExtension()); } @NotNull From bd298abb73e99c9ce2d5a6108b4841ae9939b399 Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 3 Oct 2014 21:20:45 +0200 Subject: [PATCH 08/12] IDEA-130773 Shorten inferred org.jetbrains.annotations.Nullable/NotNull names in javadoc --- .../codeInsight/javadoc/JavaDocInfoGenerator.java | 12 +++++++++--- .../BytecodeAnalysisIntegrationTest.java | 2 +- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java b/java/java-psi-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java index 7d7d697d724e..18dbccb258c5 100644 --- a/java/java-psi-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java +++ b/java/java-psi-impl/src/com/intellij/codeInsight/javadoc/JavaDocInfoGenerator.java @@ -740,7 +740,11 @@ public class JavaDocInfoGenerator { if (inferred) buffer.append(""); final PsiClassType type = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory().createType(annotationType, PsiSubstitutor.EMPTY); buffer.append("@"); - generateType(buffer, type, owner, generateLink); + if (inferred && !generateLink) { + buffer.append(type.getPresentableText()); + } else { + generateType(buffer, type, owner, generateLink); + } final PsiNameValuePair[] attributes = annotation.getParameterList().getAttributes(); if (attributes.length > 0) { buffer.append("("); @@ -778,9 +782,11 @@ public class JavaDocInfoGenerator { } } else if (external) { if (inferred) buffer.append(""); - buffer.append(XmlStringUtil.escapeString(annotation.getText())); - buffer.append(" "); + String annoText = inferred ? "@" + annotation.getNameReferenceElement().getReferenceName() + annotation.getParameterList().getText() + : annotation.getText(); + buffer.append(XmlStringUtil.escapeString(annoText)); if (inferred) buffer.append(""); + buffer.append(" "); } else { buffer.append(""); diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisIntegrationTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisIntegrationTest.java index a12fbb51ddfb..b0f8ff27b8f8 100644 --- a/java/java-tests/testSrc/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisIntegrationTest.java +++ b/java/java-tests/testSrc/com/intellij/codeInspection/bytecodeAnalysis/BytecodeAnalysisIntegrationTest.java @@ -132,7 +132,7 @@ public class BytecodeAnalysisIntegrationTest extends JavaCodeInsightFixtureTestC public void testInferredAnnoGutter() { setUpLibraries(); openDecompiledClass("org.apache.velocity.util.ExceptionUtils"); - checkHasGutter("@org.jetbrains.annotations.Contract("null,_,_->null")"); + checkHasGutter("@Contract("null,_,_->null")"); } public void testExternalAnnoGutter() { From 544385ce69c87c6678cc21b16d4ddb7eadd6932a Mon Sep 17 00:00:00 2001 From: peter Date: Sat, 4 Oct 2014 09:43:52 +0200 Subject: [PATCH 09/12] IDEA-130745 Incorrect auto cast after completion * when merging dfa states, check that they're really equal after stripping complementary facts (there might be additional info in subclasses) * merge in separate groups in one go --- .../codeInspection/dataFlow/StateMerger.java | 154 +++++++++++------- ...ontCastPartiallyInstanceofedQualifier.java | 16 ++ .../completion/NormalCompletionDfaTest.groovy | 1 + 3 files changed, 114 insertions(+), 57 deletions(-) create mode 100644 java/java-tests/testData/codeInsight/completion/normal/DontCastPartiallyInstanceofedQualifier.java diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StateMerger.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StateMerger.java index 1fa65263de27..86c87a7af046 100644 --- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StateMerger.java +++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StateMerger.java @@ -20,9 +20,9 @@ import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.UnorderedPair; import com.intellij.psi.JavaTokenType; +import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.MultiMap; -import gnu.trove.THashSet; import org.jetbrains.annotations.Nullable; import java.util.*; @@ -56,32 +56,25 @@ class StateMerger { for (DfaMemoryStateImpl state : ContainerUtil.concat(statesByFact.get(fact), statesWithNegations)) { statesByUnrelatedFacts.putValue(getUnrelatedFacts(fact, state), state); } - - Set removedStates = ContainerUtil.newIdentityTroveSet(); - List result = ContainerUtil.newArrayList(); + + Replacements replacements = new Replacements(states); for (Set key : statesByUnrelatedFacts.keySet()) { - Collection group = statesByUnrelatedFacts.get(key); - if (group.size() > 1) { - DfaMemoryStateImpl copy = group.iterator().next().createCopy(); - fact.removeFromState(copy); - if (fact.myType == FactType.equality) { - restoreOtherInequalities(fact, group, copy); + final Collection group = statesByUnrelatedFacts.get(key); + final Set unknowns = getAllUnknownVariables(group); + replacements.stripAndMerge(group, new Function() { + @Override + public DfaMemoryStateImpl fun(DfaMemoryStateImpl original) { + DfaMemoryStateImpl copy = withUnknownVariables(original, unknowns); + fact.removeFromState(copy); + if (fact.myType == FactType.equality) { + restoreOtherInequalities(fact, group, copy); + } + return copy; } - mergeUnknowns(copy, group); - - removedStates.addAll(group); - result.add(copy); - } + }); } - if (!result.isEmpty()) { - for (DfaMemoryStateImpl state : states) { - if (!removedStates.contains(state)) { - result.add(state); - } - } - return result; - } + if (replacements.hasMerges()) return replacements.getMergeResult(); } return null; } @@ -129,26 +122,20 @@ class StateMerger { return otherInequalities; } - private static void mergeUnknowns(DfaMemoryStateImpl mergedState, Collection complementaryStates) { - for (DfaMemoryStateImpl removedState : complementaryStates) { - for (DfaVariableValue unknownVar : removedState.getUnknownVariables()) { - mergedState.doFlush(unknownVar, true); - } + private static Set getAllUnknownVariables(Collection complementary) { + final Set toFlush = ContainerUtil.newLinkedHashSet(); + for (DfaMemoryStateImpl removedState : complementary) { + toFlush.addAll(removedState.getUnknownVariables()); } + return toFlush; } - private static List getMergeResult(List statesBeforeMerge, - final THashSet mergedStates, - DfaMemoryStateImpl mergeResult) { - List result = ContainerUtil.newArrayList(); - result.add(mergeResult); - result.addAll(ContainerUtil.filter(statesBeforeMerge, new Condition() { - @Override - public boolean value(DfaMemoryStateImpl state) { - return !mergedStates.contains(state); - } - })); - return result; + private static DfaMemoryStateImpl withUnknownVariables(DfaMemoryStateImpl original, Set toFlush) { + DfaMemoryStateImpl copy = original.createCopy(); + for (DfaVariableValue value : toFlush) { + copy.doFlush(value, true); + } + return copy; } @Nullable @@ -159,6 +146,7 @@ class StateMerger { byHash.putValue(state.getPartialHashCode(false, true), state); } + Replacements replacements = new Replacements(states); for (Integer key : byHash.keySet()) { Collection similarStates = byHash.get(key); if (similarStates.size() < 2) continue; @@ -171,16 +159,11 @@ class StateMerger { return state1.equalsByRelations(state2) && state1.equalsByVariableStates(state2); } }); - if (complementary.size() > 1) { - DfaMemoryStateImpl copy = state1.createCopy(); - mergeUnknowns(copy, complementary); - return getMergeResult(states, ContainerUtil.newIdentityTroveSet(complementary), copy); - } + if (mergeUnknowns(replacements, complementary)) break; } - } - return null; + return replacements.getMergeResult(); } @Nullable @@ -191,10 +174,12 @@ class StateMerger { byHash.putValue(state.getPartialHashCode(false, false), state); } + Replacements replacements = new Replacements(states); for (Integer key : byHash.keySet()) { Collection similarStates = byHash.get(key); if (similarStates.size() < 2) continue; + groupLoop: for (final DfaMemoryStateImpl state1 : similarStates) { ProgressManager.checkCanceled(); for (final DfaVariableValue var : state1.getChangedVariables()) { @@ -205,25 +190,33 @@ class StateMerger { List complementary = ContainerUtil.filter(similarStates, new Condition() { @Override public boolean value(DfaMemoryStateImpl state2) { - return state1.equalsByRelations(state2) && + return state1.equalsByRelations(state2) && areEquivalentModuloVar(state1, state2, var) && areVarStatesEqualModuloNullability(state1, state2, var); } }); - if (complementary.size() > 1) { - DfaMemoryStateImpl copy = state1.createCopy(); - mergeUnknowns(copy, complementary); - return getMergeResult(states, ContainerUtil.newIdentityTroveSet(complementary), copy); - } + if (mergeUnknowns(replacements, complementary)) break groupLoop; } - } - } - return null; + return replacements.getMergeResult(); } - + + private static boolean mergeUnknowns(Replacements replacements, List complementary) { + if (complementary.size() < 2) return false; + + final Set toFlush = getAllUnknownVariables(complementary); + if (toFlush.isEmpty()) return false; + + return replacements.stripAndMerge(complementary, new Function() { + @Override + public DfaMemoryStateImpl fun(DfaMemoryStateImpl original) { + return withUnknownVariables(original, toFlush); + } + }); + } + private boolean areEquivalentModuloVar(DfaMemoryStateImpl state1, DfaMemoryStateImpl state2, DfaVariableValue var) { DfaMemoryStateImpl copy1 = copyWithoutVar(state1, var); DfaMemoryStateImpl copy2 = copyWithoutVar(state2, var); @@ -380,4 +373,51 @@ class StateMerger { } } } + + private static class Replacements { + private final List myAllStates; + private final Set myRemovedStates = ContainerUtil.newIdentityTroveSet(); + private final List myMerged = ContainerUtil.newArrayList(); + + Replacements(List allStates) { + myAllStates = allStates; + } + + boolean hasMerges() { return !myMerged.isEmpty(); } + + @Nullable + List getMergeResult() { + if (hasMerges()) { + List result = ContainerUtil.newArrayList(myMerged); + for (DfaMemoryStateImpl state : myAllStates) { + if (!myRemovedStates.contains(state)) { + result.add(state); + } + } + return result; + } + return null; + } + + boolean stripAndMerge(Collection group, + Function stripper) { + if (group.size() <= 1) return false; + + boolean hasMerges = false; + MultiMap strippedToOriginals = MultiMap.create(); + for (DfaMemoryStateImpl original : group) { + strippedToOriginals.putValue(stripper.fun(original), original); + } + for (Map.Entry> entry : strippedToOriginals.entrySet()) { + Collection merged = entry.getValue(); + if (merged.size() > 1) { + myRemovedStates.addAll(merged); + myMerged.add(entry.getKey()); + hasMerges = true; + } + } + return hasMerges; + } + } + } diff --git a/java/java-tests/testData/codeInsight/completion/normal/DontCastPartiallyInstanceofedQualifier.java b/java/java-tests/testData/codeInsight/completion/normal/DontCastPartiallyInstanceofedQualifier.java new file mode 100644 index 000000000000..ce2b3df46e79 --- /dev/null +++ b/java/java-tests/testData/codeInsight/completion/normal/DontCastPartiallyInstanceofedQualifier.java @@ -0,0 +1,16 @@ +public abstract class Zzza { + + abstract Object getFoo(); + + void foo(Zzza other) { + int a; + if (other.getFoo() instanceof String) { + a = 1; + } else { + a = 2; + } + other.getFoo().subst + } + + +} \ No newline at end of file diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionDfaTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionDfaTest.groovy index 4c3cec03ce17..eaa0975f37d0 100644 --- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionDfaTest.groovy +++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionDfaTest.groovy @@ -34,6 +34,7 @@ class NormalCompletionDfaTest extends LightFixtureCompletionTestCase { void testCastTooComplexInstanceofedQualifier() { doAntiTest() } void testDontCastInstanceofedQualifier() { doTest(); } + void testDontCastPartiallyInstanceofedQualifier() { doAntiTest(); } void testQualifierCastingWithUnknownAssignments() { doTest(); } void testQualifierCastingBeforeLt() { doTest(); } void testCastQualifierForPrivateFieldReference() { doTest(); } From 5601387094812b053040b98e215f1af84b99021e Mon Sep 17 00:00:00 2001 From: Max Medvedev Date: Sat, 4 Oct 2014 14:00:12 +0400 Subject: [PATCH 10/12] Revert: PY-13740 Django 1.7 QuerySet.as_manager() code completion support: TODO: * Add tests * Check performance (679ef3e9760d7c4197387309ef6b9bcfdec0c419) --- .../python/codeInsight/PyCustomMember.java | 7 +- .../src/com/jetbrains/python/psi/PyClass.java | 14 +- .../com/jetbrains/python/psi/PyFunction.java | 46 ----- .../jetbrains/python/psi/types/PyType.java | 4 +- .../python/psi/types/PyTypeProviderBase.java | 1 - .../com/jetbrains/python/PyBundle.properties | 6 +- .../jetbrains/python/PyCustomMembersType.java | 189 ------------------ .../codeInsight/PyCustomMemberUtils.java | 34 ---- .../PyMethodNavigationOffsetProvider.java | 2 +- .../PySuperMethodCompletionContributor.java | 4 +- .../override/PyOverrideImplementUtil.java | 2 +- .../PyUserSkeletonsClassMembersProvider.java | 2 +- .../PyOldStyleClassesInspection.java | 2 +- .../quickfix/AddFieldQuickFix.java | 2 +- .../PyUnresolvedReferencesInspection.java | 26 +-- .../python/projectView/PyElementNode.java | 2 +- .../com/jetbrains/python/psi/PsiQuery.java | 23 +-- .../python/psi/impl/PyClassImpl.java | 44 +--- .../python/psi/impl/PyEvaluator.java | 9 - .../python/psi/impl/PyFunctionImpl.java | 36 ---- .../python/psi/types/PyClassTypeImpl.java | 19 +- .../membersManager/MethodsManager.java | 4 +- .../extractmethod/PyExtractMethodUtil.java | 2 +- .../PythonAtTestConfigurationProducer.java | 2 +- .../testing/doctest/PythonDocTestUtil.java | 2 +- .../python/testing/pytest/PyTestUtil.java | 2 +- .../python/PyControlFlowBuilderTest.java | 4 +- .../com/jetbrains/python/PyOverrideTest.java | 8 +- .../com/jetbrains/python/PyStubsTest.java | 10 +- .../classes/PyDependenciesComparatorTest.java | 3 +- 30 files changed, 63 insertions(+), 448 deletions(-) delete mode 100644 python/src/com/jetbrains/python/PyCustomMembersType.java delete mode 100644 python/src/com/jetbrains/python/codeInsight/PyCustomMemberUtils.java diff --git a/python/psi-api/src/com/jetbrains/python/codeInsight/PyCustomMember.java b/python/psi-api/src/com/jetbrains/python/codeInsight/PyCustomMember.java index ffc846796806..12b81805822d 100644 --- a/python/psi-api/src/com/jetbrains/python/codeInsight/PyCustomMember.java +++ b/python/psi-api/src/com/jetbrains/python/codeInsight/PyCustomMember.java @@ -75,16 +75,13 @@ public class PyCustomMember { myTypeCallback = typeCallback; } - public PyCustomMember(@NotNull final String name, @Nullable final PsiElement target, @Nullable String typeName) { + public PyCustomMember(@NotNull final String name, @Nullable final PsiElement target) { myName = name; myTarget = target; myResolveToInstance = false; - myTypeName = typeName; + myTypeName = null; myTypeCallback = null; } - public PyCustomMember(@NotNull final String name, @Nullable final PsiElement target) { - this(name, target, null); - } public PyCustomMember resolvesTo(String moduleQName) { myPsiPath = new PyPsiPath.ToFile(moduleQName); diff --git a/python/psi-api/src/com/jetbrains/python/psi/PyClass.java b/python/psi-api/src/com/jetbrains/python/psi/PyClass.java index b6a26fc35539..a988714c144a 100644 --- a/python/psi-api/src/com/jetbrains/python/psi/PyClass.java +++ b/python/psi-api/src/com/jetbrains/python/psi/PyClass.java @@ -110,12 +110,8 @@ public interface PyClass extends PsiNameIdentifierOwner, PyStatement, NameDefine @NotNull PyExpression[] getSuperClassExpressions(); - /** - * @param inherited return inherited (parent) methods as well - * @return class methods - */ @NotNull - PyFunction[] getMethods(boolean inherited); + PyFunction[] getMethods(); /** * Get class properties. @@ -247,12 +243,4 @@ 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); } diff --git a/python/psi-api/src/com/jetbrains/python/psi/PyFunction.java b/python/psi-api/src/com/jetbrains/python/psi/PyFunction.java index 0f7031b85dc2..e70a7ad12a51 100644 --- a/python/psi-api/src/com/jetbrains/python/psi/PyFunction.java +++ b/python/psi-api/src/com/jetbrains/python/psi/PyFunction.java @@ -26,8 +26,6 @@ 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 def and everything within). * @@ -103,48 +101,4 @@ extends @Nullable PyAnnotation getAnnotation(); - - // TODO: Doc - // - - /** - * Searches for function attributes. - * See PEP-0232 - * @return assignment statements for function attributes - */ - @NotNull - List 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; - } - } } diff --git a/python/psi-api/src/com/jetbrains/python/psi/types/PyType.java b/python/psi-api/src/com/jetbrains/python/psi/types/PyType.java index 4640fceb324d..67ba765bbf81 100644 --- a/python/psi-api/src/com/jetbrains/python/psi/types/PyType.java +++ b/python/psi-api/src/com/jetbrains/python/psi/types/PyType.java @@ -47,8 +47,8 @@ public interface PyType { * or a list of elements that define the name, a la multiResolve(). */ @Nullable - List resolveMember(@NotNull String name, @Nullable final PyExpression location, - @NotNull final AccessDirection direction, @NotNull final PyResolveContext resolveContext); + List resolveMember(@NotNull final String name, @Nullable PyExpression location, + @NotNull AccessDirection direction, @NotNull PyResolveContext resolveContext); /** * Proposes completion variants from type's attributes. diff --git a/python/psi-api/src/com/jetbrains/python/psi/types/PyTypeProviderBase.java b/python/psi-api/src/com/jetbrains/python/psi/types/PyTypeProviderBase.java index 320397c4c12a..0c60e6555b59 100644 --- a/python/psi-api/src/com/jetbrains/python/psi/types/PyTypeProviderBase.java +++ b/python/psi-api/src/com/jetbrains/python/psi/types/PyTypeProviderBase.java @@ -80,7 +80,6 @@ public class PyTypeProviderBase implements PyTypeProvider { } }; - @Nullable @Override public PyType getReferenceExpressionType(@NotNull PyReferenceExpression referenceExpression, @NotNull TypeEvalContext context) { return null; diff --git a/python/src/com/jetbrains/python/PyBundle.properties b/python/src/com/jetbrains/python/PyBundle.properties index 9e9c68f64a69..d82e9a6fde62 100644 --- a/python/src/com/jetbrains/python/PyBundle.properties +++ b/python/src/com/jetbrains/python/PyBundle.properties @@ -846,8 +846,4 @@ 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: - -# 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} \ No newline at end of file +remote.interpreter.configure.temp.files.path.label=PyCharm helpers path: \ No newline at end of file diff --git a/python/src/com/jetbrains/python/PyCustomMembersType.java b/python/src/com/jetbrains/python/PyCustomMembersType.java deleted file mode 100644 index 7e6b3b07f727..000000000000 --- a/python/src/com/jetbrains/python/PyCustomMembersType.java +++ /dev/null @@ -1,189 +0,0 @@ -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 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(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 getSuperClassTypes(@NotNull TypeEvalContext context) { - return Collections.emptyList(); - } - - @Nullable - @Override - public List 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 getParameters(@NotNull TypeEvalContext context) { - return null; - } - - @Nullable - @Override - public List 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 lookupElements = new ArrayList(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); - } -} diff --git a/python/src/com/jetbrains/python/codeInsight/PyCustomMemberUtils.java b/python/src/com/jetbrains/python/codeInsight/PyCustomMemberUtils.java deleted file mode 100644 index 86da6a9326f5..000000000000 --- a/python/src/com/jetbrains/python/codeInsight/PyCustomMemberUtils.java +++ /dev/null @@ -1,34 +0,0 @@ -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; - } -} diff --git a/python/src/com/jetbrains/python/codeInsight/PyMethodNavigationOffsetProvider.java b/python/src/com/jetbrains/python/codeInsight/PyMethodNavigationOffsetProvider.java index a00366ab5d7d..045bdc1307b3 100644 --- a/python/src/com/jetbrains/python/codeInsight/PyMethodNavigationOffsetProvider.java +++ b/python/src/com/jetbrains/python/codeInsight/PyMethodNavigationOffsetProvider.java @@ -54,7 +54,7 @@ public class PyMethodNavigationOffsetProvider implements MethodNavigationOffsetP array.add(psiElement); } else if (psiElement instanceof PyClass) { - Collections.addAll(array, ((PyClass)psiElement).getMethods(false)); + Collections.addAll(array, ((PyClass)psiElement).getMethods()); } } } diff --git a/python/src/com/jetbrains/python/codeInsight/completion/PySuperMethodCompletionContributor.java b/python/src/com/jetbrains/python/codeInsight/completion/PySuperMethodCompletionContributor.java index 4778c6db1ccc..04ad5ae8e958 100644 --- a/python/src/com/jetbrains/python/codeInsight/completion/PySuperMethodCompletionContributor.java +++ b/python/src/com/jetbrains/python/codeInsight/completion/PySuperMethodCompletionContributor.java @@ -57,13 +57,13 @@ public class PySuperMethodCompletionContributor extends CompletionContributor { return; } Set seenNames = new HashSet(); - for (PyFunction function : containingClass.getMethods(false)) { + for (PyFunction function : containingClass.getMethods()) { 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(false)) { + for (PyFunction superMethod : ancestor.getMethods()) { if (!seenNames.contains(superMethod.getName())) { String text = superMethod.getName() + superMethod.getParameterList().getText(); LookupElementBuilder element = LookupElementBuilder.create(text); diff --git a/python/src/com/jetbrains/python/codeInsight/override/PyOverrideImplementUtil.java b/python/src/com/jetbrains/python/codeInsight/override/PyOverrideImplementUtil.java index 634eaf9a59c9..5a6caf0a8941 100644 --- a/python/src/com/jetbrains/python/codeInsight/override/PyOverrideImplementUtil.java +++ b/python/src/com/jetbrains/python/codeInsight/override/PyOverrideImplementUtil.java @@ -281,7 +281,7 @@ public class PyOverrideImplementUtil { public static Collection getAllSuperFunctions(@NotNull final PyClass pyClass) { final Map superFunctions = new HashMap(); for (PyClass aClass : pyClass.getAncestorClasses()) { - for (PyFunction function : aClass.getMethods(false)) { + for (PyFunction function : aClass.getMethods()) { if (!superFunctions.containsKey(function.getName())) { superFunctions.put(function.getName(), function); } diff --git a/python/src/com/jetbrains/python/codeInsight/userSkeletons/PyUserSkeletonsClassMembersProvider.java b/python/src/com/jetbrains/python/codeInsight/userSkeletons/PyUserSkeletonsClassMembersProvider.java index bcc39aab9010..104aceb861c0 100644 --- a/python/src/com/jetbrains/python/codeInsight/userSkeletons/PyUserSkeletonsClassMembersProvider.java +++ b/python/src/com/jetbrains/python/codeInsight/userSkeletons/PyUserSkeletonsClassMembersProvider.java @@ -75,7 +75,7 @@ public class PyUserSkeletonsClassMembersProvider extends PyClassMembersProviderB private static Collection getClassMembers(@NotNull PyClass cls) { final List result = new ArrayList(); - for (PyFunction function : cls.getMethods(false)) { + for (PyFunction function : cls.getMethods()) { final String name = function.getName(); if (name != null) { result.add(new PyCustomMember(name, function)); diff --git a/python/src/com/jetbrains/python/inspections/PyOldStyleClassesInspection.java b/python/src/com/jetbrains/python/inspections/PyOldStyleClassesInspection.java index 0ea757dbebc1..a253be86344f 100644 --- a/python/src/com/jetbrains/python/inspections/PyOldStyleClassesInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyOldStyleClassesInspection.java @@ -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(false)) { + for (PyFunction attr : node.getMethods()) { if ("__getattribute__".equals(attr.getName())) { final ASTNode nameNode = attr.getNameNode(); assert nameNode != null; diff --git a/python/src/com/jetbrains/python/inspections/quickfix/AddFieldQuickFix.java b/python/src/com/jetbrains/python/inspections/quickfix/AddFieldQuickFix.java index 367f22b0540c..8ecd8a5d9b03 100644 --- a/python/src/com/jetbrains/python/inspections/quickfix/AddFieldQuickFix.java +++ b/python/src/com/jetbrains/python/inspections/quickfix/AddFieldQuickFix.java @@ -166,7 +166,7 @@ public class AddFieldQuickFix implements LocalQuickFix { appendToMethod(newInit, callback); PsiElement addAnchor = null; - PyFunction[] meths = cls.getMethods(false); + PyFunction[] meths = cls.getMethods(); if (meths.length > 0) addAnchor = meths[0].getPrevSibling(); PyStatementList clsContent = cls.getStatementList(); newInit = (PyFunction) clsContent.addAfter(newInit, addAnchor); diff --git a/python/src/com/jetbrains/python/inspections/unresolvedReference/PyUnresolvedReferencesInspection.java b/python/src/com/jetbrains/python/inspections/unresolvedReference/PyUnresolvedReferencesInspection.java index 10b4c6f8705a..0e2491134d5c 100644 --- a/python/src/com/jetbrains/python/inspections/unresolvedReference/PyUnresolvedReferencesInspection.java +++ b/python/src/com/jetbrains/python/inspections/unresolvedReference/PyUnresolvedReferencesInspection.java @@ -33,7 +33,6 @@ 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.PyCustomMember; @@ -463,7 +462,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; } } @@ -543,10 +542,6 @@ 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; @@ -610,16 +605,6 @@ 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). */ @@ -702,13 +687,6 @@ 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)) { @@ -832,7 +810,7 @@ public class PyUnresolvedReferencesInspection extends PyInspection { } } } - for (PyFunction method : containedClass.getMethods(false)) { + for (PyFunction method : containedClass.getMethods()) { if (expr.getText().equals(method.getName())) { actions.add(new UnresolvedReferenceAddSelfQuickFix(expr, qualifier)); } diff --git a/python/src/com/jetbrains/python/projectView/PyElementNode.java b/python/src/com/jetbrains/python/projectView/PyElementNode.java index 3ef8ddd71a6b..6ec347236773 100644 --- a/python/src/com/jetbrains/python/projectView/PyElementNode.java +++ b/python/src/com/jetbrains/python/projectView/PyElementNode.java @@ -50,7 +50,7 @@ public class PyElementNode extends BasePsiNode { for (PyClass aClass : pyClass.getNestedClasses()) { result.add(new PyElementNode(myProject, aClass, getSettings())); } - for (PyFunction function : pyClass.getMethods(false)) { + for (PyFunction function : pyClass.getMethods()) { result.add(new PyElementNode(myProject, function, getSettings())); } return result; diff --git a/python/src/com/jetbrains/python/psi/PsiQuery.java b/python/src/com/jetbrains/python/psi/PsiQuery.java index 3e1e26de12c3..d41f6ba68a2c 100644 --- a/python/src/com/jetbrains/python/psi/PsiQuery.java +++ b/python/src/com/jetbrains/python/psi/PsiQuery.java @@ -172,7 +172,9 @@ public class PsiQuery { } } } - return new PsiTypedQuery(clazz, result); + @SuppressWarnings("unchecked") // Type is preserved + final T[] array = (T[])result.toArray(new PsiElement[result.size()]); + return new PsiTypedQuery(clazz, array); } @@ -307,17 +309,14 @@ public class PsiQuery { * Filter elements by class */ @NotNull - public PsiTypedQuery filter(@NotNull final Class clazz) { + public PsiQuery filter(@NotNull final Class clazz) { final Set result = new HashSet(Arrays.asList(myPsiElements)); for (final PsiElement element : myPsiElements) { - if (!(clazz.isInstance(element))) { + if (PyUtil.as(element, clazz) == null) { result.remove(element); } } - // We checked it in runtime - @SuppressWarnings("unchecked") - final List toAdd = (List)new ArrayList(result); - return new PsiTypedQuery(clazz, toAdd); + return new PsiQuery(result.toArray(new PsiElement[result.size()])); } @@ -352,16 +351,16 @@ public class PsiQuery { @NotNull private final Class myClass; @NotNull - private final List myElements; + private final T[] myElements; /** * @param clazz type * @param elements elements */ - private PsiTypedQuery(@NotNull final Class clazz, @NotNull final List elements) { + private PsiTypedQuery(@NotNull final Class clazz, @NotNull final T... elements) { super(elements); myClass = clazz; - myElements = elements; + myElements = elements.clone(); } /** @@ -384,8 +383,8 @@ public class PsiQuery { * @return All elements of certain type */ @NotNull - public List getElements() { - return Collections.unmodifiableList(myElements); + public T[] getElements() { + return myElements.clone(); } } } diff --git a/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java b/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java index c7f2173973c0..611cbc84ad2e 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java @@ -389,34 +389,9 @@ public class PyClassImpl extends PyBaseElementImpl implements PyCla return result; } - @Override @NotNull - 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 result = new HashMap(); - // 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 functionsToReturn = result.values(); - return functionsToReturn.toArray(new PyFunction[functionsToReturn.size()]); + public PyFunction[] getMethods() { + return getClassChildren(PythonDialectsTokenSetProvider.INSTANCE.getFunctionDeclarationTokens(), PyFunction.ARRAY_FACTORY); } @Override @@ -539,7 +514,7 @@ public class PyClassImpl extends PyBaseElementImpl implements PyCla // look at @property decorators Map> grouped = new HashMap>(); // group suitable same-named methods, each group defines a property - for (PyFunction method : getMethods(false)) { + for (PyFunction method : getMethods()) { final String methodName = method.getName(); if (name == null || name.equals(methodName)) { List bucket = grouped.get(methodName); @@ -851,7 +826,7 @@ public class PyClassImpl extends PyBaseElementImpl implements PyCla public boolean visitMethods(Processor processor, boolean inherited, boolean skipClassObj) { - PyFunction[] methods = getMethods(false); + PyFunction[] methods = getMethods(); if (!ContainerUtil.process(methods, processor)) return false; if (inherited) { for (PyClass ancestor : getAncestorClasses()) { @@ -957,7 +932,7 @@ public class PyClassImpl extends PyBaseElementImpl implements PyCla collectInstanceAttributes(initMethod, result); } Set namesInInit = new HashSet(result.keySet()); - final PyFunction[] methods = getMethods(false); + final PyFunction[] methods = getMethods(); for (PyFunction method : methods) { if (!PyNames.INIT.equals(method.getName())) { collectInstanceAttributes(method, result, namesInInit); @@ -1006,8 +981,7 @@ public class PyClassImpl extends PyBaseElementImpl implements PyCla final List result = new ArrayList(); 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()) { @@ -1364,10 +1338,4 @@ public class PyClassImpl extends PyBaseElementImpl implements PyCla } return null; } - - @Nullable - @Override - public PyClassLikeType getType(@NotNull TypeEvalContext context) { - return PyUtil.as(context.getType(this), PyClassLikeType.class); - } } diff --git a/python/src/com/jetbrains/python/psi/impl/PyEvaluator.java b/python/src/com/jetbrains/python/psi/impl/PyEvaluator.java index 3f948c496592..dea9296f12c6 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyEvaluator.java +++ b/python/src/com/jetbrains/python/psi/impl/PyEvaluator.java @@ -65,15 +65,6 @@ 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); } diff --git a/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java index 9f6afb5e43f7..2c1842f3337f 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java @@ -23,7 +23,6 @@ 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; @@ -700,39 +699,4 @@ public class PyFunctionImpl extends PyBaseElementImpl implements public String getQualifiedName() { return QualifiedNameFinder.getQualifiedName(this); } - - @NotNull - @Override - public List findAttributes() { - final List result = new ArrayList(); - 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; - } } diff --git a/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java b/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java index d9b69121aa50..9a7f2f107ee8 100644 --- a/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java +++ b/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java @@ -16,6 +16,7 @@ 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 +34,6 @@ import com.intellij.util.ProcessingContext; import com.intellij.util.containers.ContainerUtil; import com.jetbrains.python.PyNames; 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,8 +151,7 @@ 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); } @@ -220,8 +219,7 @@ 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) { @@ -416,11 +414,16 @@ public class PyClassTypeImpl extends UserDataHolderBase implements PyClassType { addInheritedMembers(prefix, location, namesAlready, context, ret, typeEvalContext); // from providers - for (final PyClassMembersProvider provider : Extensions.getExtensions(PyClassMembersProvider.EP_NAME)) { - for (final PyCustomMember member : provider.getMembers(this, location)) { + for (PyClassMembersProvider provider : Extensions.getExtensions(PyClassMembersProvider.EP_NAME)) { + for (PyCustomMember member : provider.getMembers(this, location)) { final String name = member.getName(); if (!namesAlready.contains(name)) { - ret.add(PyCustomMemberUtils.toLookUpElement(member, getName())); + LookupElementBuilder lookupElementBuilder = LookupElementBuilder.create(name).withIcon(member.getIcon()).withTypeText(getName()); + if (member.isFunction()) { + lookupElementBuilder = lookupElementBuilder.withInsertHandler(ParenthesesInsertHandler.NO_PARAMETERS); + lookupElementBuilder.withTailText("()"); + } + ret.add(lookupElementBuilder); } } } diff --git a/python/src/com/jetbrains/python/refactoring/classes/membersManager/MethodsManager.java b/python/src/com/jetbrains/python/refactoring/classes/membersManager/MethodsManager.java index 56bd80ca3077..52c32d95d38d 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/membersManager/MethodsManager.java +++ b/python/src/com/jetbrains/python/refactoring/classes/membersManager/MethodsManager.java @@ -44,7 +44,7 @@ class MethodsManager extends MembersManager { @Override public boolean hasConflict(@NotNull final PyFunction member, @NotNull final PyClass aClass) { - return NamePredicate.hasElementWithSameName(member, Arrays.asList(aClass.getMethods(false))); + return NamePredicate.hasElementWithSameName(member, Arrays.asList(aClass.getMethods())); } @NotNull @@ -64,7 +64,7 @@ class MethodsManager extends MembersManager { @NotNull @Override protected List getMembersCouldBeMoved(@NotNull final PyClass pyClass) { - return FluentIterable.from(Arrays.asList(pyClass.getMethods(false))).filter(new NamelessFilter()).filter(NO_PROPERTIES).toList(); + return FluentIterable.from(Arrays.asList(pyClass.getMethods())).filter(new NamelessFilter()).filter(NO_PROPERTIES).toList(); } @Override diff --git a/python/src/com/jetbrains/python/refactoring/extractmethod/PyExtractMethodUtil.java b/python/src/com/jetbrains/python/refactoring/extractmethod/PyExtractMethodUtil.java index a396a354a381..d16712dea6c7 100644 --- a/python/src/com/jetbrains/python/refactoring/extractmethod/PyExtractMethodUtil.java +++ b/python/src/com/jetbrains/python/refactoring/extractmethod/PyExtractMethodUtil.java @@ -181,7 +181,7 @@ public class PyExtractMethodUtil { scope.add(owner); final PyClass containingClass = ((PyFunction)owner).getContainingClass(); if (containingClass != null) { - for (PyFunction function : containingClass.getMethods(false)) { + for (PyFunction function : containingClass.getMethods()) { if (!function.equals(owner) && !function.equals(generatedMethod)) scope.add(function); } diff --git a/python/src/com/jetbrains/python/testing/attest/PythonAtTestConfigurationProducer.java b/python/src/com/jetbrains/python/testing/attest/PythonAtTestConfigurationProducer.java index 006749a25e96..d0a6d19e19e2 100644 --- a/python/src/com/jetbrains/python/testing/attest/PythonAtTestConfigurationProducer.java +++ b/python/src/com/jetbrains/python/testing/attest/PythonAtTestConfigurationProducer.java @@ -60,7 +60,7 @@ public class PythonAtTestConfigurationProducer extends } private static boolean hasTestFunction(@NotNull final PyClass pyClass) { - PyFunction[] methods = pyClass.getMethods(false); + PyFunction[] methods = pyClass.getMethods(); for (PyFunction function : methods) { PyDecoratorList decorators = function.getDecoratorList(); if (decorators == null) continue; diff --git a/python/src/com/jetbrains/python/testing/doctest/PythonDocTestUtil.java b/python/src/com/jetbrains/python/testing/doctest/PythonDocTestUtil.java index b0889b72c46d..fd6e9ef357af 100644 --- a/python/src/com/jetbrains/python/testing/doctest/PythonDocTestUtil.java +++ b/python/src/com/jetbrains/python/testing/doctest/PythonDocTestUtil.java @@ -58,7 +58,7 @@ public class PythonDocTestUtil { } public static boolean isDocTestClass(PyClass pyClass) { - for (PyFunction cls : pyClass.getMethods(false)) { + for (PyFunction cls : pyClass.getMethods()) { if (isDocTestFunction(cls)) { return true; } diff --git a/python/src/com/jetbrains/python/testing/pytest/PyTestUtil.java b/python/src/com/jetbrains/python/testing/pytest/PyTestUtil.java index 357227532727..b6f463b15706 100644 --- a/python/src/com/jetbrains/python/testing/pytest/PyTestUtil.java +++ b/python/src/com/jetbrains/python/testing/pytest/PyTestUtil.java @@ -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(false)) { + for (PyFunction cls : pyClass.getMethods()) { if (isPyTestFunction(cls)) { return true; } diff --git a/python/testSrc/com/jetbrains/python/PyControlFlowBuilderTest.java b/python/testSrc/com/jetbrains/python/PyControlFlowBuilderTest.java index c5e489c06485..203b462c5a44 100644 --- a/python/testSrc/com/jetbrains/python/PyControlFlowBuilderTest.java +++ b/python/testSrc/com/jetbrains/python/PyControlFlowBuilderTest.java @@ -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(false)[0]); + final ControlFlow flow = ControlFlowCache.getControlFlow(pyClass.getMethods()[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(false)[0]); + final ControlFlow flow = ControlFlowCache.getControlFlow(pyClass.getMethods()[0]); check(fullPath, flow); } diff --git a/python/testSrc/com/jetbrains/python/PyOverrideTest.java b/python/testSrc/com/jetbrains/python/PyOverrideTest.java index fddb9e26c905..d80dc06182e7 100644 --- a/python/testSrc/com/jetbrains/python/PyOverrideTest.java +++ b/python/testSrc/com/jetbrains/python/PyOverrideTest.java @@ -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(false) [0]; + PyFunction toOverride = getTopLevelClass(0).getMethods() [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(false)[0]; + PyFunction toOverride = getTopLevelClass(0).getMethods()[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(false)[0]; + PyFunction toOverride = getTopLevelClass(0).getMethods()[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(false)[1]; + PyFunction toImplement = getTopLevelClass(0).getMethods()[1]; PyOverrideImplementUtil.overrideMethods(myFixture.getEditor(), getTopLevelClass(1), Collections.singletonList(new PyMethodMember(toImplement)), true); myFixture.checkResultByFile("override/" + getTestName(true) + "_after.py", true); diff --git a/python/testSrc/com/jetbrains/python/PyStubsTest.java b/python/testSrc/com/jetbrains/python/PyStubsTest.java index 2a58613f1668..0904b4c3d7d0 100644 --- a/python/testSrc/com/jetbrains/python/PyStubsTest.java +++ b/python/testSrc/com/jetbrains/python/PyStubsTest.java @@ -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(false); + final PyFunction[] methods = pyClass.getMethods(); 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 maybe_function = prop.getGetter(); assertTrue(maybe_function.isDefined()); - assertEquals(pyClass.getMethods(false)[0], maybe_function.value()); + assertEquals(pyClass.getMethods()[0], maybe_function.value()); Property setvalueProp = pyClass.findProperty("setvalue", true); Maybe 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(false)[0], maybe_function.value()); + assertEquals(pyClass.getMethods()[0], maybe_function.value()); maybe_function = prop.getSetter(); assertTrue(maybe_function.isDefined()); - assertEquals(pyClass.getMethods(false)[1], maybe_function.value()); + assertEquals(pyClass.getMethods()[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(false); + final PyFunction[] methods = pyClass.getMethods(); assertEquals(1, methods.length); final PyFunction.Modifier modifier = methods[0].getModifier(); assertEquals(PyFunction.Modifier.STATICMETHOD, modifier); diff --git a/python/testSrc/com/jetbrains/python/refactoring/classes/PyDependenciesComparatorTest.java b/python/testSrc/com/jetbrains/python/refactoring/classes/PyDependenciesComparatorTest.java index b3be3825f970..9ebe01b127dc 100644 --- a/python/testSrc/com/jetbrains/python/refactoring/classes/PyDependenciesComparatorTest.java +++ b/python/testSrc/com/jetbrains/python/refactoring/classes/PyDependenciesComparatorTest.java @@ -1,6 +1,7 @@ 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; @@ -22,7 +23,7 @@ public class PyDependenciesComparatorTest extends PyTestCase { @SuppressWarnings("ConstantConditions") // Can't be null (class has docstring) PsiElement docStringExpression = clazz.getDocStringExpression().getParent(); - PyFunction method = clazz.getMethods(false)[0]; + PyFunction method = clazz.getMethods()[0]; PsiElement classField = clazz.getClassAttributes().get(0).getParent(); final List elementList = new ArrayList(); From 0e3edfafbac49e3c9dcfba2c6065a6657ab360bd Mon Sep 17 00:00:00 2001 From: Max Medvedev Date: Sat, 4 Oct 2014 14:01:13 +0400 Subject: [PATCH 11/12] Revert: PY-13740 Django 1.7 QuerySet.as_manager() code completion support: PyDynamicMember renamed (6185917f904a995733c00e52c8392ebc6582fddd) --- ...CustomMember.java => PyDynamicMember.java} | 34 +++++++++---------- .../psi/types/PyClassMembersProvider.java | 4 +-- .../psi/types/PyClassMembersProviderBase.java | 10 +++--- .../psi/types/PyModuleMembersProvider.java | 8 ++--- .../NumpyModuleMembersProvider.java | 8 ++--- .../stdlib/PyStdlibClassMembersProvider.java | 16 ++++----- .../stdlib/PyStdlibModuleMembersProvider.java | 8 ++--- .../PyUserSkeletonsClassMembersProvider.java | 14 ++++---- .../PyUserSkeletonsModuleMembersProvider.java | 8 ++--- .../PyUnresolvedReferencesInspection.java | 6 ++-- .../python/psi/types/PyClassTypeImpl.java | 4 +-- .../python/psi/types/PyModuleType.java | 4 +-- 12 files changed, 62 insertions(+), 62 deletions(-) rename python/psi-api/src/com/jetbrains/python/codeInsight/{PyCustomMember.java => PyDynamicMember.java} (82%) diff --git a/python/psi-api/src/com/jetbrains/python/codeInsight/PyCustomMember.java b/python/psi-api/src/com/jetbrains/python/codeInsight/PyDynamicMember.java similarity index 82% rename from python/psi-api/src/com/jetbrains/python/codeInsight/PyCustomMember.java rename to python/psi-api/src/com/jetbrains/python/codeInsight/PyDynamicMember.java index 12b81805822d..a344e892588c 100644 --- a/python/psi-api/src/com/jetbrains/python/codeInsight/PyCustomMember.java +++ b/python/psi-api/src/com/jetbrains/python/codeInsight/PyDynamicMember.java @@ -33,7 +33,7 @@ import javax.swing.*; /** * @author Dennis.Ushakov */ -public class PyCustomMember { +public class PyDynamicMember { private String myName; private final boolean myResolveToInstance; private final Function myTypeCallback; @@ -45,7 +45,7 @@ public class PyCustomMember { boolean myFunction = false; - public PyCustomMember(@NotNull final String name, @Nullable final String type, final boolean resolveToInstance) { + public PyDynamicMember(@NotNull final String name, @Nullable final String type, final boolean resolveToInstance) { myName = name; myResolveToInstance = resolveToInstance; myTypeName = type; @@ -54,7 +54,7 @@ public class PyCustomMember { myTypeCallback = null; } - public PyCustomMember(@NotNull final String name) { + public PyDynamicMember(@NotNull final String name) { myName = name; myResolveToInstance = false; myTypeName = null; @@ -63,9 +63,9 @@ public class PyCustomMember { myTypeCallback = null; } - public PyCustomMember(@NotNull final String name, - @Nullable final String type, - final Function typeCallback) { + public PyDynamicMember(@NotNull final String name, + @Nullable final String type, + final Function typeCallback) { myName = name; myResolveToInstance = false; @@ -75,7 +75,7 @@ public class PyCustomMember { myTypeCallback = typeCallback; } - public PyCustomMember(@NotNull final String name, @Nullable final PsiElement target) { + public PyDynamicMember(@NotNull final String name, @Nullable final PsiElement target) { myName = name; myTarget = target; myResolveToInstance = false; @@ -83,47 +83,47 @@ public class PyCustomMember { myTypeCallback = null; } - public PyCustomMember resolvesTo(String moduleQName) { + public PyDynamicMember resolvesTo(String moduleQName) { myPsiPath = new PyPsiPath.ToFile(moduleQName); return this; } - public PyCustomMember resolvesToClass(String classQName) { + public PyDynamicMember resolvesToClass(String classQName) { myPsiPath = new PyPsiPath.ToClassQName(classQName); return this; } - public PyCustomMember toClass(String name) { + public PyDynamicMember toClass(String name) { myPsiPath = new PyPsiPath.ToClass(myPsiPath, name); return this; } - public PyCustomMember toFunction(String name) { + public PyDynamicMember toFunction(String name) { myPsiPath = new PyPsiPath.ToFunction(myPsiPath, name); return this; } - public PyCustomMember toFunctionRecursive(String name) { + public PyDynamicMember toFunctionRecursive(String name) { myPsiPath = new PyPsiPath.ToFunctionRecursive(myPsiPath, name); return this; } - public PyCustomMember toClassAttribute(String name) { + public PyDynamicMember toClassAttribute(String name) { myPsiPath = new PyPsiPath.ToClassAttribute(myPsiPath, name); return this; } - public PyCustomMember toCall(String name, String... args) { + public PyDynamicMember toCall(String name, String... args) { myPsiPath = new PyPsiPath.ToCall(myPsiPath, name, args); return this; } - public PyCustomMember toAssignment(String assignee) { + public PyDynamicMember toAssignment(String assignee) { myPsiPath = new PyPsiPath.ToAssignment(myPsiPath, assignee); return this; } - public PyCustomMember toPsiElement(final PsiElement psiElement) { + public PyDynamicMember toPsiElement(final PsiElement psiElement) { myPsiPath = new PyPsiPath() { @Override @@ -179,7 +179,7 @@ public class PyCustomMember { return myTypeName.substring(pos + 1); } - public PyCustomMember asFunction() { + public PyDynamicMember asFunction() { myFunction = true; return this; } diff --git a/python/psi-api/src/com/jetbrains/python/psi/types/PyClassMembersProvider.java b/python/psi-api/src/com/jetbrains/python/psi/types/PyClassMembersProvider.java index 6a61de999abc..e051b48fbfaa 100644 --- a/python/psi-api/src/com/jetbrains/python/psi/types/PyClassMembersProvider.java +++ b/python/psi-api/src/com/jetbrains/python/psi/types/PyClassMembersProvider.java @@ -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.PyCustomMember; +import com.jetbrains.python.codeInsight.PyDynamicMember; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -30,7 +30,7 @@ public interface PyClassMembersProvider { ExtensionPointName EP_NAME = ExtensionPointName.create("Pythonid.pyClassMembersProvider"); @NotNull - Collection getMembers(PyClassType clazz, @Nullable PsiElement location); + Collection getMembers(PyClassType clazz, @Nullable PsiElement location); @Nullable PsiElement resolveMember(PyClassType clazz, String name, @Nullable PsiElement location); diff --git a/python/psi-api/src/com/jetbrains/python/psi/types/PyClassMembersProviderBase.java b/python/psi-api/src/com/jetbrains/python/psi/types/PyClassMembersProviderBase.java index 6ec96559911a..a7d66499cf52 100644 --- a/python/psi-api/src/com/jetbrains/python/psi/types/PyClassMembersProviderBase.java +++ b/python/psi-api/src/com/jetbrains/python/psi/types/PyClassMembersProviderBase.java @@ -16,7 +16,7 @@ package com.jetbrains.python.psi.types; import com.intellij.psi.PsiElement; -import com.jetbrains.python.codeInsight.PyCustomMember; +import com.jetbrains.python.codeInsight.PyDynamicMember; 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 getMembers(PyClassType clazz, PsiElement location) { + public Collection getMembers(PyClassType clazz, PsiElement location) { return Collections.emptyList(); } @Override public PsiElement resolveMember(PyClassType clazz, String name, PsiElement location) { - final Collection members = getMembers(clazz, location); + final Collection members = getMembers(clazz, location); return resolveMemberByName(members, clazz, name); } @Nullable - public static PsiElement resolveMemberByName(Collection members, + public static PsiElement resolveMemberByName(Collection members, PyClassType clazz, String name) { final PyClass pyClass = clazz.getPyClass(); - for (PyCustomMember member : members) { + for (PyDynamicMember member : members) { if (member.getName().equals(name)) { return member.resolve(pyClass); } diff --git a/python/psi-api/src/com/jetbrains/python/psi/types/PyModuleMembersProvider.java b/python/psi-api/src/com/jetbrains/python/psi/types/PyModuleMembersProvider.java index 60d13fde976e..696dcaee6623 100644 --- a/python/psi-api/src/com/jetbrains/python/psi/types/PyModuleMembersProvider.java +++ b/python/psi-api/src/com/jetbrains/python/psi/types/PyModuleMembersProvider.java @@ -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.PyCustomMember; +import com.jetbrains.python.codeInsight.PyDynamicMember; 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 EP_NAME = ExtensionPointName.create("Pythonid.pyModuleMembersProvider"); - public Collection getMembers(PyFile module, PointInImport point) { + public Collection 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 (PyCustomMember o : getMembers(module, PointInImport.NONE)) { + for (PyDynamicMember 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 getMembersByQName(PyFile module, String qName); + protected abstract Collection getMembersByQName(PyFile module, String qName); } diff --git a/python/src/com/jetbrains/numpy/codeInsight/NumpyModuleMembersProvider.java b/python/src/com/jetbrains/numpy/codeInsight/NumpyModuleMembersProvider.java index fadf38916d0b..1fd2e3afd58f 100644 --- a/python/src/com/jetbrains/numpy/codeInsight/NumpyModuleMembersProvider.java +++ b/python/src/com/jetbrains/numpy/codeInsight/NumpyModuleMembersProvider.java @@ -15,7 +15,7 @@ */ package com.jetbrains.numpy.codeInsight; -import com.jetbrains.python.codeInsight.PyCustomMember; +import com.jetbrains.python.codeInsight.PyDynamicMember; 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 getMembersByQName(PyFile module, String qName) { + protected Collection getMembersByQName(PyFile module, String qName) { if ("numpy".equals(qName)) { - final List members = new ArrayList(); + final List members = new ArrayList(); for (String type : NUMERIC_TYPES) { - members.add(new PyCustomMember(type, "numpy.core.multiarray.dtype", false)); + members.add(new PyDynamicMember(type, "numpy.core.multiarray.dtype", false)); } return members; } diff --git a/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibClassMembersProvider.java b/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibClassMembersProvider.java index 334552aaf8c0..b0b8c06c92de 100644 --- a/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibClassMembersProvider.java +++ b/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibClassMembersProvider.java @@ -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.PyCustomMember; +import com.jetbrains.python.codeInsight.PyDynamicMember; 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> mySocketMembersKey = Key.create("socket.members"); + private Key> mySocketMembersKey = Key.create("socket.members"); @NotNull @Override - public Collection getMembers(PyClassType classType, PsiElement location) { + public Collection 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 socketMembers = socketFile.getUserData(mySocketMembersKey); + List 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 calcSocketMembers(PyFile socketFile) { - List result = new ArrayList(); + private static List calcSocketMembers(PyFile socketFile) { + List result = new ArrayList(); addMethodsFromAttr(socketFile, result, "_socketmethods"); addMethodsFromAttr(socketFile, result, "_delegate_methods"); return result; } - private static void addMethodsFromAttr(PyFile socketFile, List result, final String attrName) { + private static void addMethodsFromAttr(PyFile socketFile, List result, final String attrName) { final PyTargetExpression socketMethods = socketFile.findTopLevelAttribute(attrName); if (socketMethods != null) { final List methods = PyUtil.getStringListFromTargetExpression(socketMethods); if (methods != null) { for (String name : methods) { - result.add(new PyCustomMember(name).resolvesTo("_socket").toClass("SocketType").toFunction(name)); + result.add(new PyDynamicMember(name).resolvesTo("_socket").toClass("SocketType").toFunction(name)); } } } diff --git a/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibModuleMembersProvider.java b/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibModuleMembersProvider.java index a724b7808a75..80d3627ac083 100644 --- a/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibModuleMembersProvider.java +++ b/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibModuleMembersProvider.java @@ -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.PyCustomMember; +import com.jetbrains.python.codeInsight.PyDynamicMember; 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 getMembersByQName(PyFile module, String qName) { + protected Collection getMembersByQName(PyFile module, String qName) { if (qName.equals("os")) { - final List results = new ArrayList(); + final List results = new ArrayList(); PsiElement path = null; if (module != null) { final String pathModuleName = SystemInfo.isWindows ? "ntpath" : "posixpath"; path = ResolveImportUtil.resolveModuleInRoots(QualifiedName.fromDottedString(pathModuleName), module); } - results.add(new PyCustomMember("path", path)); + results.add(new PyDynamicMember("path", path)); return results; } return Collections.emptyList(); diff --git a/python/src/com/jetbrains/python/codeInsight/userSkeletons/PyUserSkeletonsClassMembersProvider.java b/python/src/com/jetbrains/python/codeInsight/userSkeletons/PyUserSkeletonsClassMembersProvider.java index 104aceb861c0..5ac7fc10751c 100644 --- a/python/src/com/jetbrains/python/codeInsight/userSkeletons/PyUserSkeletonsClassMembersProvider.java +++ b/python/src/com/jetbrains/python/codeInsight/userSkeletons/PyUserSkeletonsClassMembersProvider.java @@ -16,7 +16,7 @@ package com.jetbrains.python.codeInsight.userSkeletons; import com.intellij.psi.PsiElement; -import com.jetbrains.python.codeInsight.PyCustomMember; +import com.jetbrains.python.codeInsight.PyDynamicMember; 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 getMembers(@NotNull PyClassType classType, PsiElement location) { + public Collection 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 getClassMembers(@NotNull PyClass cls) { - final List result = new ArrayList(); + private static Collection getClassMembers(@NotNull PyClass cls) { + final List result = new ArrayList(); for (PyFunction function : cls.getMethods()) { final String name = function.getName(); if (name != null) { - result.add(new PyCustomMember(name, function)); + result.add(new PyDynamicMember(name, function)); } } for (PyTargetExpression attribute : cls.getInstanceAttributes()) { final String name = attribute.getName(); if (name != null) { - result.add(new PyCustomMember(name, attribute)); + result.add(new PyDynamicMember(name, attribute)); } } for (PyTargetExpression attribute : cls.getClassAttributes()) { final String name = attribute.getName(); if (name != null) { - result.add(new PyCustomMember(name, attribute)); + result.add(new PyDynamicMember(name, attribute)); } } return result; diff --git a/python/src/com/jetbrains/python/codeInsight/userSkeletons/PyUserSkeletonsModuleMembersProvider.java b/python/src/com/jetbrains/python/codeInsight/userSkeletons/PyUserSkeletonsModuleMembersProvider.java index c42d15c6f463..ad876ee4ec91 100644 --- a/python/src/com/jetbrains/python/codeInsight/userSkeletons/PyUserSkeletonsModuleMembersProvider.java +++ b/python/src/com/jetbrains/python/codeInsight/userSkeletons/PyUserSkeletonsModuleMembersProvider.java @@ -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.PyCustomMember; +import com.jetbrains.python.codeInsight.PyDynamicMember; 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 getMembersByQName(PyFile module, String qName) { + protected Collection getMembersByQName(PyFile module, String qName) { final PyFile moduleSkeleton = PyUserSkeletonsUtil.getUserSkeletonForModuleQName(qName, module); if (moduleSkeleton != null) { - final List results = new ArrayList(); + final List results = new ArrayList(); for (PyElement element : moduleSkeleton.iterateNames()) { if (element instanceof PsiFileSystemItem) { continue; } final String name = element.getName(); if (name != null) { - results.add(new PyCustomMember(name, element)); + results.add(new PyDynamicMember(name, element)); } } return results; diff --git a/python/src/com/jetbrains/python/inspections/unresolvedReference/PyUnresolvedReferencesInspection.java b/python/src/com/jetbrains/python/inspections/unresolvedReference/PyUnresolvedReferencesInspection.java index 0e2491134d5c..8049546a6e92 100644 --- a/python/src/com/jetbrains/python/inspections/unresolvedReference/PyUnresolvedReferencesInspection.java +++ b/python/src/com/jetbrains/python/inspections/unresolvedReference/PyUnresolvedReferencesInspection.java @@ -35,7 +35,7 @@ import com.intellij.util.PlatformUtils; import com.jetbrains.python.PyBundle; import com.jetbrains.python.PyNames; import com.jetbrains.python.codeInsight.PyCodeInsightSettings; -import com.jetbrains.python.codeInsight.PyCustomMember; +import com.jetbrains.python.codeInsight.PyDynamicMember; import com.jetbrains.python.codeInsight.controlflow.ScopeOwner; import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil; import com.jetbrains.python.codeInsight.imports.AutoImportHintAction; @@ -721,8 +721,8 @@ public class PyUnresolvedReferencesInspection extends PyInspection { PsiReference reference, @NotNull final String name) { for (PyClassMembersProvider provider : Extensions.getExtensions(PyClassMembersProvider.EP_NAME)) { - final Collection resolveResult = provider.getMembers(type, reference.getElement()); - for (PyCustomMember member : resolveResult) { + final Collection resolveResult = provider.getMembers(type, reference.getElement()); + for (PyDynamicMember member : resolveResult) { if (member.getName().equals(name)) return true; } } diff --git a/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java b/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java index 9a7f2f107ee8..34a92e16bf01 100644 --- a/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java +++ b/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java @@ -33,7 +33,7 @@ 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.PyCustomMember; +import com.jetbrains.python.codeInsight.PyDynamicMember; import com.jetbrains.python.psi.*; import com.jetbrains.python.psi.impl.PyBuiltinCache; import com.jetbrains.python.psi.impl.ResolveResultList; @@ -415,7 +415,7 @@ public class PyClassTypeImpl extends UserDataHolderBase implements PyClassType { // from providers for (PyClassMembersProvider provider : Extensions.getExtensions(PyClassMembersProvider.EP_NAME)) { - for (PyCustomMember member : provider.getMembers(this, location)) { + for (PyDynamicMember member : provider.getMembers(this, location)) { final String name = member.getName(); if (!namesAlready.contains(name)) { LookupElementBuilder lookupElementBuilder = LookupElementBuilder.create(name).withIcon(member.getIcon()).withTypeText(getName()); diff --git a/python/src/com/jetbrains/python/psi/types/PyModuleType.java b/python/src/com/jetbrains/python/psi/types/PyModuleType.java index 0aec8612c989..db5a9ba3f1ae 100644 --- a/python/src/com/jetbrains/python/psi/types/PyModuleType.java +++ b/python/src/com/jetbrains/python/psi/types/PyModuleType.java @@ -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.PyCustomMember; +import com.jetbrains.python.codeInsight.PyDynamicMember; 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 namesAlready = context.get(CTX_NAMES); PointInImport point = ResolveImportUtil.getPointInImport(location); for (PyModuleMembersProvider provider : Extensions.getExtensions(PyModuleMembersProvider.EP_NAME)) { - for (PyCustomMember member : provider.getMembers(myModule, point)) { + for (PyDynamicMember member : provider.getMembers(myModule, point)) { final String name = member.getName(); if (namesAlready != null) { namesAlready.add(name); From c21b529928a84a23d5b359b38dbd03ec5c5cfa02 Mon Sep 17 00:00:00 2001 From: Max Medvedev Date: Sat, 4 Oct 2014 14:26:35 +0400 Subject: [PATCH 12/12] IDEA-130022 Reset head dialog: select the text box by default --- plugins/git4idea/src/git4idea/ui/GitResetDialog.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/plugins/git4idea/src/git4idea/ui/GitResetDialog.java b/plugins/git4idea/src/git4idea/ui/GitResetDialog.java index 6600ee256acd..6f98e4c0d224 100644 --- a/plugins/git4idea/src/git4idea/ui/GitResetDialog.java +++ b/plugins/git4idea/src/git4idea/ui/GitResetDialog.java @@ -22,6 +22,7 @@ import git4idea.commands.GitCommand; import git4idea.commands.GitLineHandler; import git4idea.i18n.GitBundle; import git4idea.util.GitUIUtil; +import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.util.List; @@ -101,6 +102,12 @@ public class GitResetDialog extends DialogWrapper { init(); } + @Nullable + @Override + public JComponent getPreferredFocusedComponent() { + return myCommitTextField; + } + /** * Validate */