test fix: context passed to event more methods, PyClassImpl getSuperClasses fix
authorIlya.Kazakevich <Ilya.Kazakevich@jetbrains.com>
Mon, 2 Nov 2015 21:41:28 +0000 (00:41 +0300)
committerIlya.Kazakevich <Ilya.Kazakevich@jetbrains.com>
Mon, 9 Nov 2015 17:33:02 +0000 (20:33 +0300)
48 files changed:
python/psi-api/src/com/jetbrains/python/codeInsight/PyPsiPath.java
python/psi-api/src/com/jetbrains/python/psi/PyClass.java
python/src/com/jetbrains/python/actions/PyQualifiedNameProvider.java
python/src/com/jetbrains/python/codeInsight/PyGotoSuperHandler.java
python/src/com/jetbrains/python/codeInsight/PyLineMarkerProvider.java
python/src/com/jetbrains/python/codeInsight/override/PyOverrideImplementUtil.java
python/src/com/jetbrains/python/codeInsight/userSkeletons/PyUserSkeletonsClassMembersProvider.java
python/src/com/jetbrains/python/documentation/PyDocumentationBuilder.java
python/src/com/jetbrains/python/documentation/docstrings/DocStringParameterReference.java
python/src/com/jetbrains/python/findUsages/PyClassFindUsagesHandler.java
python/src/com/jetbrains/python/inspections/PyAbstractClassInspection.java
python/src/com/jetbrains/python/inspections/PyAttributeOutsideInitInspection.java
python/src/com/jetbrains/python/inspections/PyInitNewSignatureInspection.java
python/src/com/jetbrains/python/inspections/PyMissingConstructorInspection.java
python/src/com/jetbrains/python/inspections/PyPropertyAccessInspection.java
python/src/com/jetbrains/python/inspections/PyPropertyDefinitionInspection.java
python/src/com/jetbrains/python/inspections/PyStringFormatInspection.java
python/src/com/jetbrains/python/inspections/quickfix/AddCallSuperQuickFix.java
python/src/com/jetbrains/python/inspections/quickfix/AddFieldQuickFix.java
python/src/com/jetbrains/python/inspections/quickfix/PyChangeSignatureQuickFix.java
python/src/com/jetbrains/python/inspections/unresolvedReference/PyUnresolvedReferencesInspection.java
python/src/com/jetbrains/python/packaging/setupPy/SetupTaskIntrospector.java
python/src/com/jetbrains/python/psi/PyUtil.java
python/src/com/jetbrains/python/psi/impl/PyCallExpressionHelper.java
python/src/com/jetbrains/python/psi/impl/PyClassImpl.java
python/src/com/jetbrains/python/psi/impl/PySubscriptionExpressionImpl.java
python/src/com/jetbrains/python/psi/impl/PyTargetExpressionImpl.java
python/src/com/jetbrains/python/psi/impl/references/KeywordArgumentCompletionUtil.java
python/src/com/jetbrains/python/psi/impl/references/PyReferenceImpl.java
python/src/com/jetbrains/python/psi/impl/stubs/PyClassElementType.java
python/src/com/jetbrains/python/psi/search/PyOverridingMethodsSearchExecutor.java
python/src/com/jetbrains/python/psi/search/PySuperMethodsSearchExecutor.java
python/src/com/jetbrains/python/psi/types/PyABCUtil.java
python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java
python/src/com/jetbrains/python/refactoring/changeSignature/PyChangeSignatureUsageProcessor.java
python/src/com/jetbrains/python/refactoring/classes/PyClassRefactoringUtil.java
python/src/com/jetbrains/python/refactoring/classes/membersManager/ClassFieldsManager.java
python/src/com/jetbrains/python/refactoring/classes/membersManager/MethodsManager.java
python/src/com/jetbrains/python/refactoring/extractmethod/PyExtractMethodUtil.java
python/src/com/jetbrains/python/refactoring/introduce/field/PyIntroduceFieldHandler.java
python/src/com/jetbrains/python/refactoring/rename/RenamePyClassProcessor.java
python/src/com/jetbrains/python/refactoring/rename/RenamePyElementProcessor.java
python/src/com/jetbrains/python/testing/PythonUnitTestUtil.java
python/testSrc/com/jetbrains/python/PyClassicPropertyTest.java
python/testSrc/com/jetbrains/python/PyOverrideTest.java
python/testSrc/com/jetbrains/python/PyStubsTest.java
python/testSrc/com/jetbrains/python/codeInsight/PyClassMROTest.java
python/testSrc/com/jetbrains/python/refactoring/classes/PyClassRefactoringTest.java

index c2b7c5f9e581b43d2671cbf39a283bf46be11661..4369b4cc5d7337f246926df55f451db36c955393 100644 (file)
@@ -125,7 +125,7 @@ public abstract class PyPsiPath {
         return ((PyFile) parent).findTopLevelFunction(myFunctionName);
       }
       if (parent instanceof PyClass) {
-        return ((PyClass) parent).findMethodByName(myFunctionName, false);
+        return ((PyClass) parent).findMethodByName(myFunctionName, false, null);
       }
       for (PsiElement element : parent.getChildren()) {
         if (element instanceof PyFunction && myFunctionName.equals(((PyFunction)element).getName())) {
@@ -189,7 +189,7 @@ public abstract class PyPsiPath {
       if (!(parent instanceof PyClass)) {
         return null;
       }
-      return ((PyClass)parent).findClassAttribute(myAttributeName, true);
+      return ((PyClass)parent).findClassAttribute(myAttributeName, true, null);
     }
   }
 
index 0bf5ca3c00cab5a2b137eab61e586a05dc66926e..009466f41c893b228ce239028622643cfab12df7 100644 (file)
@@ -121,10 +121,11 @@ public interface PyClass extends PsiNameIdentifierOwner, PyStatement, NameDefine
    *
    * @param name      what to look for
    * @param inherited true: search in superclasses; false: only look for methods defined in this class.
+   * @param context
    * @return
    */
   @Nullable
-  PyFunction findMethodByName(@Nullable @NonNls final String name, boolean inherited);
+  PyFunction findMethodByName(@Nullable @NonNls final String name, boolean inherited, TypeEvalContext context);
 
   /**
    * Finds either __init__ or __new__, whichever is defined for given class.
@@ -193,7 +194,7 @@ public interface PyClass extends PsiNameIdentifierOwner, PyStatement, NameDefine
   List<PyTargetExpression> getClassAttributesInherited(@NotNull TypeEvalContext context);
 
   @Nullable
-  PyTargetExpression findClassAttribute(@NotNull String name, boolean inherited);
+  PyTargetExpression findClassAttribute(@NotNull String name, boolean inherited, TypeEvalContext context);
 
   /**
    * Effectively collects assignments to attributes of {@code self} in {@code __init__}, {@code __new__} and
index 6d7da2b25da8ce49ffb639e3a60e04d466ff79fb..024883766c03c1e889aca2632a15f4e9a1b7b395 100644 (file)
@@ -67,7 +67,7 @@ public class PyQualifiedNameProvider implements QualifiedNameProvider {
         final String memberName = StringUtil.getShortName(fqn, '#');
         final PyClass nestedClass = aClass.findNestedClass(memberName, false);
         if (nestedClass != null) return nestedClass;
-        final PyFunction methodByName = aClass.findMethodByName(memberName, false);
+        final PyFunction methodByName = aClass.findMethodByName(memberName, false, null);
         if (methodByName != null) return methodByName;
       }
     }
index f25ec4951979febab6c239fe5a8fe2823e7ff535..a71813402bcca05c8fba8c61572c6cc77be6b612 100644 (file)
@@ -86,7 +86,7 @@ public class PyGotoSuperHandler implements CodeInsightActionHandler {
     }
     final List<PyTargetExpression> result = new ArrayList<PyTargetExpression>();
     for (PyClass aClass: pyClass.getAncestorClasses(null)) {
-      final PyTargetExpression superAttr = aClass.findClassAttribute(name, false);
+      final PyTargetExpression superAttr = aClass.findClassAttribute(name, false, null);
       if (superAttr != null) {
         result.add(superAttr);
       }
@@ -101,7 +101,7 @@ public class PyGotoSuperHandler implements CodeInsightActionHandler {
     }
     final List<PyFunction> result = new ArrayList<PyFunction>();
     for (PyClass aClass: pyClass.getAncestorClasses(null)) {
-      final PyFunction byName = aClass.findMethodByName(name, false);
+      final PyFunction byName = aClass.findMethodByName(name, false, null);
       if (byName != null) {
         result.add(byName);
       }
index 8f48b7f10e8eec9a8715336cc587752c44ac8bdd..66050ee35f48b428208f4d565b9a160b19f64985 100644 (file)
@@ -92,7 +92,7 @@ public class PyLineMarkerProvider implements LineMarkerProvider, PyLineSeparator
             builder.append("Has overridden methods");
             return false;
           }
-          if (pyClass.findMethodByName(pyFunction.getName(), false) != null) {
+          if (pyClass.findMethodByName(pyFunction.getName(), false, null) != null) {
             builder.append("<br>&nbsp;&nbsp;").append(pyClass.getName());
           }
           return true;
@@ -126,7 +126,7 @@ public class PyLineMarkerProvider implements LineMarkerProvider, PyLineSeparator
       PyClass containingClass = PsiTreeUtil.getParentOfType(elt, PyClass.class);
       if (containingClass != null && elt instanceof PyTargetExpression) {
         for (PyClass ancestor : containingClass.getAncestorClasses(null)) {
-          final PyTargetExpression attribute = ancestor.findClassAttribute(((PyTargetExpression)elt).getReferencedName(), false);
+          final PyTargetExpression attribute = ancestor.findClassAttribute(((PyTargetExpression)elt).getReferencedName(), false, null);
           if (attribute != null) {
             result.add(attribute);
           }
@@ -180,7 +180,7 @@ public class PyLineMarkerProvider implements LineMarkerProvider, PyLineSeparator
     if (PyNames.INIT.equals(function.getName())) {
       return null;
     }
-    final TypeEvalContext context = TypeEvalContext.codeAnalysis(element.getProject(), null);
+    final TypeEvalContext context = TypeEvalContext.codeAnalysis(element.getProject(), (function != null ? function.getContainingFile() : null));
     final PsiElement superMethod = PySuperMethodsSearch.search(function, context).findFirst();
     if (superMethod != null) {
       PyClass superClass = null;
@@ -206,7 +206,7 @@ public class PyLineMarkerProvider implements LineMarkerProvider, PyLineSeparator
     if (containingClass == null) return null;
     for (PyClass ancestor : containingClass
       .getAncestorClasses(TypeEvalContext.codeAnalysis(element.getProject(), element.getContainingFile()))) {
-      final PyTargetExpression ancestorAttr = ancestor.findClassAttribute(name, false);
+      final PyTargetExpression ancestorAttr = ancestor.findClassAttribute(name, false, null);
       if (ancestorAttr != null) {
         return new LineMarkerInfo<PsiElement>(element, element.getTextRange().getStartOffset(),
                                               AllIcons.Gutter.OverridingMethod, Pass.UPDATE_ALL,
@@ -254,7 +254,7 @@ public class PyLineMarkerProvider implements LineMarkerProvider, PyLineSeparator
         public boolean process(final PyClass inheritor) {
           for (Iterator<PyFunction> it = candidates.get(pyClass).iterator(); it.hasNext(); ) {
             PyFunction func = it.next();
-            if (inheritor.findMethodByName(func.getName(), false) != null) {
+            if (inheritor.findMethodByName(func.getName(), false, null) != null) {
               overridden.add(func);
               it.remove();
             }
index 8b7e1d9a3599aced9b406d7dd139e05fbf2fde1c..ba97dd348b3e1a011e01100c2c92e08831fa09f3 100644 (file)
@@ -115,7 +115,7 @@ public class PyOverrideImplementUtil {
       if (name == null || PyUtil.isClassPrivateName(name)) {
         continue;
       }
-      if (pyClass.findMethodByName(name, false) == null) {
+      if (pyClass.findMethodByName(name, false, null) == null) {
         final PyMethodMember member = new PyMethodMember(function);
         elements.add(member);
       }
@@ -245,7 +245,7 @@ public class PyOverrideImplementUtil {
       if (!PyNames.INIT.equals(baseFunction.getName()) && context.getReturnType(baseFunction) != PyNoneType.INSTANCE || overridingNew) {
         statementBody.append("return ");
       }
-      if (baseClass.isNewStyleClass(null)) {
+      if (baseClass.isNewStyleClass(context)) {
         statementBody.append(PyNames.SUPER);
         statementBody.append("(");
         final LanguageLevel langLevel = ((PyFile)pyClass.getContainingFile()).getLanguageLevel();
index c0bcc8e3c7d3376d8a36820791d18f5c0fb103e0..8c06ef2a3af800db73ab0d700975dd8eac0f6d34 100644 (file)
@@ -60,7 +60,7 @@ public class PyUserSkeletonsClassMembersProvider extends PyClassMembersProviderB
   }
 
   public static PsiElement findClassMember(@NotNull PyClass cls, @NotNull String name, boolean isDefinition) {
-    final PyFunction function = cls.findMethodByName(name, false);
+    final PyFunction function = cls.findMethodByName(name, false, null);
     if (function != null) {
       final PyUtil.MethodFlags methodFlags = PyUtil.MethodFlags.of(function);
       final boolean instanceMethod = methodFlags == null || methodFlags.isInstanceMethod();
@@ -74,7 +74,7 @@ public class PyUserSkeletonsClassMembersProvider extends PyClassMembersProviderB
         return instanceAttribute;
       }
     }
-    final PyTargetExpression classAttribute = cls.findClassAttribute(name, false);
+    final PyTargetExpression classAttribute = cls.findClassAttribute(name, false, null);
     if (classAttribute != null) {
       return classAttribute;
     }
index 4cebb5b3e92cbc63fcdc21f17295a5ab6fa5d908..4caabd03b553096b6a999f5b5d1caaedd3c2944b 100644 (file)
@@ -359,7 +359,7 @@ public class PyDocumentationBuilder {
         isFromClass = true;
       }
       else {
-        inherited = ancestor.findMethodByName(methodName, false);
+        inherited = ancestor.findMethodByName(methodName, false, null);
       }
       if (inherited != null) {
         docstringElement = inherited.getDocStringExpression();
@@ -403,7 +403,7 @@ public class PyDocumentationBuilder {
     final PyClassType objectType = PyBuiltinCache.getInstance(fun).getObjectType(); // old- and new-style classes share the __xxx__ stuff
     if (objectType != null) {
       final PyClass objectClass = objectType.getPyClass();
-      final PyFunction predefinedMethod = objectClass.findMethodByName(mothodName, false);
+      final PyFunction predefinedMethod = objectClass.findMethodByName(mothodName, false, null);
       if (predefinedMethod != null) {
         final PyStringLiteralExpression predefinedDocstring = predefinedMethod.getDocStringExpression();
         final String predefinedDoc = predefinedDocstring != null ? predefinedDocstring.getStringValue() : null;
index 42395ef5e1115021199fcf9265b0851db85eb158..8a74aeffc9cbf7003b0e8cbf212ddbcce87a9b77 100644 (file)
@@ -58,7 +58,7 @@ public class DocStringParameterReference extends PsiReferenceBase<PyStringLitera
       return resolveParameter((PyFunction)owner);
     }
     if (owner instanceof PyClass) {
-      final PyFunction init = ((PyClass)owner).findMethodByName(PyNames.INIT, false);
+      final PyFunction init = ((PyClass)owner).findMethodByName(PyNames.INIT, false, null);
       if (init != null) {
         PsiElement element = resolveParameter(init);
         if (element == null && (myType.equals(ReferenceType.CLASS_VARIABLE) ||
index 10ddcea15fbe3c542dda0a8881bcafb81e553b45..5dcb8850c114cb552d2bca07c3d1e20f4971d422 100644 (file)
@@ -39,7 +39,7 @@ public class PyClassFindUsagesHandler extends FindUsagesHandler {
   @NotNull
   @Override
   public PsiElement[] getSecondaryElements() {
-    final PyFunction initMethod = myClass.findMethodByName(PyNames.INIT, false);
+    final PyFunction initMethod = myClass.findMethodByName(PyNames.INIT, false, null);
     if (initMethod != null) {
       return new PsiElement[] { initMethod };
     }
index 8873fe5228c08e681c1fcc6df9cb6d8381ae1a7b..e05a9eb762448faaa2aef1844f02d4e475acf624 100644 (file)
@@ -102,8 +102,8 @@ public class PyAbstractClassInspection extends PyInspection {
     private static boolean isAbstractMethodForClass(@NotNull PyFunction method, @NotNull PyClass cls) {
       final String methodName = method.getName();
       if (methodName == null ||
-          cls.findMethodByName(methodName, false) != null ||
-          cls.findClassAttribute(methodName, false) != null) {
+          cls.findMethodByName(methodName, false, null) != null ||
+          cls.findClassAttribute(methodName, false, null) != null) {
         return false;
       }
       return PyUtil.isDecoratedAsAbstract(method) || PyOverrideImplementUtil.raisesNotImplementedError(method);
index 00e3bc70a405b96abda5a7ef802c273f4b3c1fd9..31a0ed0e7d98b4a6d466e61ff94f8a608ab4449c 100644 (file)
@@ -82,12 +82,12 @@ public class PyAttributeOutsideInitInspection extends PyInspection {
         attributesInInit.put(classAttr.getName(), classAttr);
       }
 
-      final PyFunction initMethod = containingClass.findMethodByName(PyNames.INIT, false);
+      final PyFunction initMethod = containingClass.findMethodByName(PyNames.INIT, false, null);
       if (initMethod != null) {
         PyClassImpl.collectInstanceAttributes(initMethod, attributesInInit);
       }
       for (PyClass superClass : containingClass.getAncestorClasses(myTypeEvalContext)) {
-        final PyFunction superInit = superClass.findMethodByName(PyNames.INIT, false);
+        final PyFunction superInit = superClass.findMethodByName(PyNames.INIT, false, null);
         if (superInit != null)
           PyClassImpl.collectInstanceAttributes(superInit, attributesInInit);
 
index a083c57ac49ecb86bd42c4e256258bfd61698052..ed5a883e9e7c92bddd41b63a3002e2e756346d4a 100644 (file)
@@ -63,7 +63,7 @@ public class PyInitNewSignatureInspection extends PyInspection {
       if (cls == null) return;
       if (!cls.isNewStyleClass(null)) return;
       final String complementaryName = PyNames.NEW.equals(functionName) ? PyNames.INIT : PyNames.NEW;
-      final PyFunction complementaryMethod = cls.findMethodByName(complementaryName, true);
+      final PyFunction complementaryMethod = cls.findMethodByName(complementaryName, true, null);
       if (complementaryMethod == null || PyUtil.isObjectClass(assertNotNull(complementaryMethod.getContainingClass()))) return;
       if (!PyUtil.isSignatureCompatibleTo(complementaryMethod, node, myTypeEvalContext) &&
           !PyUtil.isSignatureCompatibleTo(node, complementaryMethod, myTypeEvalContext) &&
index 715d387dc63f5c8082982b52ebcc3642720eb5a7..6126168486e4757d3bdde3ed06ffed7863e1d72e 100644 (file)
@@ -64,7 +64,7 @@ public class PyMissingConstructorInspection extends PyInspection {
         return;
 
       if (!superHasConstructor(node)) return;
-      PyFunction initMethod = node.findMethodByName(INIT, false);
+      PyFunction initMethod = node.findMethodByName(INIT, false, null);
       if (initMethod != null) {
         if (isExceptionClass(node, myTypeEvalContext) || hasConstructorCall(node, initMethod)) {
           return;
@@ -81,7 +81,7 @@ public class PyMissingConstructorInspection extends PyInspection {
       final String className = cls.getName();
       for (PyClass c : cls.getAncestorClasses(myTypeEvalContext)) {
         final String name = c.getName();
-        if (!PyUtil.isObjectClass(c) && !Comparing.equal(className, name) && c.findMethodByName(INIT, false) != null) {
+        if (!PyUtil.isObjectClass(c) && !Comparing.equal(className, name) && c.findMethodByName(INIT, false, null) != null) {
           return true;
         }
       }
index b19e3ef8fe108297668d63af9af0bdf3b85d38af..45f39e1fc89565bc7661fd7d500a99cb274a0647 100644 (file)
@@ -87,7 +87,7 @@ public class PyPropertyAccessInspection extends PyInspection {
               property = myPropertyCache.get(key);
             }
             else {
-              property = cls.findProperty(name, true, null);
+              property = cls.findProperty(name, true, myTypeEvalContext);
             }
             myPropertyCache.put(key, property); // we store nulls, too, to know that a property does not exist
             if (property != null) {
index 2cd44f53b96ba723e2eaa9e783945d157d5cc65c..a6e04166e41c3dd25d4f07fc976e3e184858cb71 100644 (file)
@@ -92,9 +92,9 @@ public class PyPropertyDefinitionInspection extends PyInspection {
       // reference signatures
       PyClass objectClass = builtins.getClass("object");
       if (objectClass != null) {
-        final PyFunction methodRepr = objectClass.findMethodByName("__repr__", false);
+        final PyFunction methodRepr = objectClass.findMethodByName("__repr__", false, null);
         if (methodRepr != null) myOneParamFunction = methodRepr;
-        final PyFunction methodDelattr = objectClass.findMethodByName("__delattr__", false);
+        final PyFunction methodDelattr = objectClass.findMethodByName("__delattr__", false, null);
         if (methodDelattr != null) myTwoParamFunction = methodDelattr;
       }
     }
index fa9e6cfbe14f71adb5b3fced8ca011fc2f1941e4..cab8baab63ad21413c9cd9e7623b772198cf3241 100644 (file)
@@ -404,7 +404,7 @@ public class PyStringFormatInspection extends PyInspection {
         else {
           final PyClassType type = as(myTypeEvalContext.getType(rightExpression), PyClassType.class);
           if (type != null) {
-            if (myUsedMappingKeys.size() > 0 && !PyABCUtil.isSubclass(type.getPyClass(), PyNames.MAPPING)) {
+            if (myUsedMappingKeys.size() > 0 && !PyABCUtil.isSubclass(type.getPyClass(), PyNames.MAPPING, null)) {
               registerProblem(rightExpression, PyBundle.message("INSP.format.requires.mapping"));
               return;
             }
index 9fdb22b1a2d3d168b59ef64c2bff23c6ab79b988..ff2f8cebb201f49500209120c8ef026cdbd88f89 100644 (file)
@@ -66,7 +66,7 @@ public class AddCallSuperQuickFix implements LocalQuickFix {
     if (superClasses.length == 0) return;
 
     final PyClass superClass = superClasses[0];
-    final PyFunction superInit = superClass.findMethodByName(PyNames.INIT, true);
+    final PyFunction superInit = superClass.findMethodByName(PyNames.INIT, true, null);
     if (superInit == null) return;
 
     final ParametersInfo origInfo = new ParametersInfo(problemFunction.getParameterList());
index 5156205aa82ffa9338b1b7f4f8b830d4aee7dbfd..75a3ba574a91d5cc90be187919b570fe68e35fd3 100644 (file)
@@ -146,13 +146,13 @@ public class AddFieldQuickFix implements LocalQuickFix {
   @Nullable
   public static PsiElement addFieldToInit(Project project, PyClass cls, String itemName, Function<String, PyStatement> callback) {
     if (cls != null && itemName != null) {
-      PyFunction init = cls.findMethodByName(PyNames.INIT, false);
+      PyFunction init = cls.findMethodByName(PyNames.INIT, false, null);
       if (init != null) {
         return appendToMethod(init, callback);
       }
       else { // no init! boldly copy ancestor's.
         for (PyClass ancestor : cls.getAncestorClasses(null)) {
-          init = ancestor.findMethodByName(PyNames.INIT, false);
+          init = ancestor.findMethodByName(PyNames.INIT, false, null);
           if (init != null) break;
         }
         PyFunction newInit = createInitMethod(project, cls, init);
index 091bd88bc82d2dd19ea12b2bde7fd75f118c9647..3addc73996c448ac92ceadd2585006926027da87 100644 (file)
@@ -61,7 +61,7 @@ public class PyChangeSignatureQuickFix implements LocalQuickFix {
     final String complementaryName = PyNames.NEW.equals(functionName) ? PyNames.INIT : PyNames.NEW;
     final TypeEvalContext context = TypeEvalContext.userInitiated(project, descriptor.getEndElement().getContainingFile());
     final PyFunction complementaryMethod = myOverridenMethod ? (PyFunction)PySuperMethodsSearch.search(function, context).findFirst()
-                                                             : cls.findMethodByName(complementaryName, true);
+                                                             : cls.findMethodByName(complementaryName, true, null);
 
     assert complementaryMethod != null;
     final PyMethodDescriptor methodDescriptor = new PyMethodDescriptor(function) {
index d9d25f5e8d2301174473c7a28246d6e167e64ac3..797cc453b82f1c8dbf0341659a9ab7322686f482 100644 (file)
@@ -942,7 +942,7 @@ public class PyUnresolvedReferencesInspection extends PyInspection {
       // if we're in a class context and the class defines a variable with the same name, offer auto-import only as quickfix,
       // not as popup
       PyClass containingClass = PsiTreeUtil.getParentOfType(node, PyClass.class);
-      if (containingClass != null && (containingClass.findMethodByName(importFix.getNameToImport(), true) != null ||
+      if (containingClass != null && (containingClass.findMethodByName(importFix.getNameToImport(), true, null) != null ||
                                       containingClass.findInstanceAttribute(importFix.getNameToImport(), true) != null)) {
         return true;
       }
index b840d304114c411ca2963b9c0bff2e75c1e1b248..1b9a1ab3fbe4c187b5c432395d0fe7a149482cde 100644 (file)
@@ -116,7 +116,7 @@ public class SetupTaskIntrospector {
                               ? PyClassNameIndex.findClass("distutils.command.build_ext.build_ext", file.getProject())
                               : file.findTopLevelClass(name);
     if (taskClass != null) {
-      final PyTargetExpression description = taskClass.findClassAttribute("description", true);
+      final PyTargetExpression description = taskClass.findClassAttribute("description", true, null);
       if (description != null) {
         final String descriptionText = PyPsiUtils.strValue(PyPsiUtils.flattenParens(description.findAssignedValue()));
         if (descriptionText != null) {
@@ -133,7 +133,7 @@ public class SetupTaskIntrospector {
         }
       }
 
-      final PyTargetExpression negativeOpt = taskClass.findClassAttribute("negative_opt", true);
+      final PyTargetExpression negativeOpt = taskClass.findClassAttribute("negative_opt", true, null);
       final Map<String, String> negativeOptMap = negativeOpt == null
                                                  ? Collections.<String, String>emptyMap()
                                                  : parseNegativeOpt(negativeOpt.findAssignedValue());
@@ -152,7 +152,7 @@ public class SetupTaskIntrospector {
 
   private static List<PyExpression> resolveSequenceValue(PyClass aClass, String name) {
     List<PyExpression> result = new ArrayList<PyExpression>();
-    collectSequenceElements(aClass.findClassAttribute(name, true), result);
+    collectSequenceElements(aClass.findClassAttribute(name, true, null), result);
     return result;
   }
 
index bf32c66b7b6034daaec9a744cbfdd449357739a2..2a76d7129041848bc184b081257df9f91838bed4 100644 (file)
@@ -689,7 +689,7 @@ public class PyUtil {
    */
   @Nullable
   public static PyFunction getInitMethod(@NotNull final PyClass pyClass) {
-    return pyClass.findMethodByName(PyNames.INIT, false);
+    return pyClass.findMethodByName(PyNames.INIT, false,  null);
   }
 
   /**
index d86a93e53f7cb0114e383ffaf0a6d0307facd752..c4227fd6ee488d39f322223a1b58f99bea86c31a 100644 (file)
@@ -551,7 +551,7 @@ public class PyCallExpressionHelper {
         return Ref.create(t);
       }
       if (cls != null && t == null) {
-        final PyFunction newMethod = cls.findMethodByName(PyNames.NEW, true);
+        final PyFunction newMethod = cls.findMethodByName(PyNames.NEW, true, null);
         if (newMethod != null && !PyBuiltinCache.getInstance(call).isBuiltin(newMethod)) {
           return Ref.create(PyUnionType.createWeakType(new PyClassTypeImpl(cls, false)));
         }
index 0bea5262b0418796fedf68eca29d0deb1345e72f..19a5a8434a86833ca65849eef0f9b9252c51d540 100644 (file)
@@ -40,6 +40,7 @@ import com.jetbrains.python.codeInsight.controlflow.ScopeOwner;
 import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil;
 import com.jetbrains.python.documentation.docstrings.DocStringUtil;
 import com.jetbrains.python.psi.*;
+import com.jetbrains.python.psi.impl.stubs.PyClassElementType;
 import com.jetbrains.python.psi.resolve.PyResolveContext;
 import com.jetbrains.python.psi.resolve.PyResolveUtil;
 import com.jetbrains.python.psi.resolve.QualifiedNameFinder;
@@ -334,6 +335,7 @@ public class PyClassImpl extends PyBaseElementImpl<PyClassStub> implements PyCla
     }
     return PyFileImpl.getStringListFromTargetExpression(PyNames.SLOTS, getClassAttributes());
   }
+
   @NotNull
   public PyClass[] getSuperClasses(@Nullable TypeEvalContext context) {
     if (context == null) {
@@ -530,10 +532,11 @@ public class PyClassImpl extends PyBaseElementImpl<PyClassStub> implements PyCla
     }
   }
 
-  public PyFunction findMethodByName(@Nullable final String name, boolean inherited) {
+  @Override
+  public PyFunction findMethodByName(@Nullable final String name, boolean inherited, @Nullable TypeEvalContext context) {
     if (name == null) return null;
     NameFinder<PyFunction> proc = new NameFinder<PyFunction>(name);
-    visitMethods(proc, inherited, null);
+    visitMethods(proc, inherited, context);
     return proc.getResult();
   }
 
@@ -657,7 +660,7 @@ public class PyClassImpl extends PyBaseElementImpl<PyClassStub> implements PyCla
       if (value == null || PyNames.NONE.equals(value)) {
         return NONE;
       }
-      PyFunction method = findMethodByName(value, true);
+      PyFunction method = findMethodByName(value, true, null);
       if (method != null) return new Maybe<PyCallable>(method);
     }
     return UNKNOWN_CALL;
@@ -694,7 +697,7 @@ public class PyClassImpl extends PyBaseElementImpl<PyClassStub> implements PyCla
     if (property != null) {
       return property;
     }
-    if (findMethodByName(name, false) != null || findClassAttribute(name, false) != null) {
+    if (findMethodByName(name, false, null) != null || findClassAttribute(name, false, null) != null) {
       return null;
     }
     if (inherited) {
@@ -767,7 +770,7 @@ public class PyClassImpl extends PyBaseElementImpl<PyClassStub> implements PyCla
       return local;
     }
     if (inherited) {
-      if (name != null && (findMethodByName(name, false) != null || findClassAttribute(name, false) != null)) {
+      if (name != null && (findMethodByName(name, false, null) != null || findClassAttribute(name, false, null) != null)) {
         return null;
       }
       for (PyClass cls : getAncestorClasses(null)) {
@@ -980,9 +983,9 @@ public class PyClassImpl extends PyBaseElementImpl<PyClassStub> implements PyCla
   }
 
   @Override
-  public PyTargetExpression findClassAttribute(@NotNull String name, boolean inherited) {
+  public PyTargetExpression findClassAttribute(@NotNull String name, boolean inherited, TypeEvalContext context) {
     final NameFinder<PyTargetExpression> processor = new NameFinder<PyTargetExpression>(name);
-    visitClassAttributes(processor, inherited, null);
+    visitClassAttributes(processor, inherited, context);
     return processor.getResult();
   }
 
@@ -1017,7 +1020,7 @@ public class PyClassImpl extends PyBaseElementImpl<PyClassStub> implements PyCla
     Map<String, PyTargetExpression> result = new HashMap<String, PyTargetExpression>();
 
     collectAttributesInNew(result);
-    PyFunctionImpl initMethod = (PyFunctionImpl)findMethodByName(PyNames.INIT, false);
+    PyFunctionImpl initMethod = (PyFunctionImpl)findMethodByName(PyNames.INIT, false, null);
     if (initMethod != null) {
       collectInstanceAttributes(initMethod, result);
     }
@@ -1034,7 +1037,7 @@ public class PyClassImpl extends PyBaseElementImpl<PyClassStub> implements PyCla
   }
 
   private void collectAttributesInNew(@NotNull final Map<String, PyTargetExpression> result) {
-    final PyFunction newMethod = findMethodByName(PyNames.NEW, false);
+    final PyFunction newMethod = findMethodByName(PyNames.NEW, false, null);
     if (newMethod != null) {
       for (PyTargetExpression target : getTargetExpressions(newMethod)) {
         result.put(target.getName(), target);
@@ -1131,7 +1134,7 @@ public class PyClassImpl extends PyBaseElementImpl<PyClassStub> implements PyCla
         }
       }
     }
-    if (pyClass.findClassAttribute(PyNames.DUNDER_METACLASS, false) != null) {
+    if (pyClass.findClassAttribute(PyNames.DUNDER_METACLASS, false, null) != null) {
       return true;
     }
     return false;
@@ -1244,42 +1247,15 @@ public class PyClassImpl extends PyBaseElementImpl<PyClassStub> implements PyCla
     }
     final PyClassStub stub = getStub();
     final List<PyClassLikeType> result = new ArrayList<PyClassLikeType>();
+
     // In some cases stub may not provide all information, so we use stubs only if AST access id disabled
-    if (!context.maySwitchToAST(this) && stub != null) {
-      final PsiFile file = getContainingFile();
-      if (file instanceof PyFile) {
-        for (QualifiedName name : stub.getSuperClasses()) {
-          result.add(name != null ? classTypeFromQName(name, (PyFile)file, context) : null);
-        }
-      }
+    if (!context.maySwitchToAST(this)) {
+      fillSuperClassesNoSwitchToAst(context, stub, result);
     }
     else {
-      for (PyExpression expression : getSuperClassExpressions()) {
-        context.getType(expression);
-        expression = unfoldClass(expression);
-        if (expression instanceof PyKeywordArgument) {
-          continue;
-        }
-        final PyType type = context.getType(expression);
-        PyClassLikeType classLikeType = null;
-        if (type instanceof PyClassLikeType) {
-          classLikeType = (PyClassLikeType)type;
-        }
-        else {
-          final PsiReference ref = expression.getReference();
-          if (ref != null) {
-            final PsiElement resolved = ref.resolve();
-            if (resolved instanceof PyClass) {
-              final PyType resolvedType = context.getType((PyClass)resolved);
-              if (resolvedType instanceof PyClassLikeType) {
-                classLikeType = (PyClassLikeType)resolvedType;
-              }
-            }
-          }
-        }
-        result.add(classLikeType);
-      }
+      fillSuperClassesSwitchingToAst(context, result);
     }
+
     final PyBuiltinCache builtinCache = PyBuiltinCache.getInstance(this);
     if (result.isEmpty() && isValid() && !builtinCache.isBuiltin(this)) {
       final String implicitSuperName = LanguageLevel.forElement(this).isPy3K() ? PyNames.OBJECT : PyNames.FAKE_OLD_BASE;
@@ -1294,6 +1270,54 @@ public class PyClassImpl extends PyBaseElementImpl<PyClassStub> implements PyCla
     return result;
   }
 
+  private void fillSuperClassesSwitchingToAst(@NotNull TypeEvalContext context, List<PyClassLikeType> result) {
+    for (PyExpression expression : getSuperClassExpressions()) {
+      context.getType(expression);
+      expression = unfoldClass(expression);
+      if (expression instanceof PyKeywordArgument) {
+        continue;
+      }
+      final PyType type = context.getType(expression);
+      PyClassLikeType classLikeType = null;
+      if (type instanceof PyClassLikeType) {
+        classLikeType = (PyClassLikeType)type;
+      }
+      else {
+        final PsiReference ref = expression.getReference();
+        if (ref != null) {
+          final PsiElement resolved = ref.resolve();
+          if (resolved instanceof PyClass) {
+            final PyType resolvedType = context.getType((PyClass)resolved);
+            if (resolvedType instanceof PyClassLikeType) {
+              classLikeType = (PyClassLikeType)resolvedType;
+            }
+          }
+        }
+      }
+      result.add(classLikeType);
+    }
+  }
+
+  private void fillSuperClassesNoSwitchToAst(@NotNull final TypeEvalContext context,
+                                             @Nullable final PyClassStub stub,
+                                             @NotNull final List<PyClassLikeType> result) {
+    final List<QualifiedName> qualifiedNames;
+    if (stub != null) {
+      qualifiedNames = Arrays.asList(stub.getSuperClasses());
+    }
+    else {
+      qualifiedNames = PyClassElementType.getSuperClassQNames(this);
+    }
+
+
+    final PsiFile file = getContainingFile();
+    if (file instanceof PyFile) {
+      for (QualifiedName name : qualifiedNames) {
+        result.add(name != null ? classTypeFromQName(name, (PyFile)file, context) : null);
+      }
+    }
+  }
+
   @NotNull
   @Override
   public List<PyClassLikeType> getAncestorTypes(@NotNull TypeEvalContext context) {
@@ -1353,7 +1377,7 @@ public class PyClassImpl extends PyBaseElementImpl<PyClassStub> implements PyCla
       }
     }
     else {
-      final PyTargetExpression attribute = findClassAttribute(PyNames.DUNDER_METACLASS, false);
+      final PyTargetExpression attribute = findClassAttribute(PyNames.DUNDER_METACLASS, false, null);
       if (attribute != null) {
         return attribute.findAssignedValue();
       }
@@ -1397,7 +1421,7 @@ public class PyClassImpl extends PyBaseElementImpl<PyClassStub> implements PyCla
         if (cls == metaClass) {
           return false;
         }
-        final PyFunction mroMethod = metaClass.findMethodByName(PyNames.MRO, true);
+        final PyFunction mroMethod = metaClass.findMethodByName(PyNames.MRO, true, null);
         if (mroMethod != null) {
           final PyClass mroClass = mroMethod.getContainingClass();
           if (mroClass != null && mroClass != typeClass) {
index a50bdf3b2d5be7792367a0463459b0c7fbafa23d..85f711dc353f606530a962836a22e024069faa4a 100644 (file)
@@ -81,7 +81,7 @@ public class PySubscriptionExpressionImpl extends PyElementImpl implements PySub
         if (indexExpression != null) {
           final PyType type = context.getType(getOperand());
           final PyClass cls = (type instanceof PyClassType) ? ((PyClassType)type).getPyClass() : null;
-          if (cls != null && PyABCUtil.isSubclass(cls, PyNames.MAPPING)) {
+          if (cls != null && PyABCUtil.isSubclass(cls, PyNames.MAPPING, context)) {
             return res;
           }
           if (type instanceof PySubscriptableType) {
index 215118428c6cc175a8aff039b8f5e3eba65ada10..4446685fb38a7276eb4b2d6122e3bde98b11fb49 100644 (file)
@@ -247,7 +247,7 @@ public class PyTargetExpressionImpl extends PyBaseElementImpl<PyTargetExpression
       final PyType exprType = context.getType(expression);
       if (exprType instanceof PyClassType) {
         final PyClass cls = ((PyClassType)exprType).getPyClass();
-        final PyFunction enter = cls.findMethodByName(PyNames.ENTER, true);
+        final PyFunction enter = cls.findMethodByName(PyNames.ENTER, true, null);
         if (enter != null) {
           final PyType enterType = enter.getCallType(expression, Collections.<PyExpression, PyNamedParameter>emptyMap(), context);
           if (enterType != null) {
index 1723d0c523a3b220739a9d12cf67811251a5ed02..1c0d45ae6ece8143b689ccefe8d6d5de6e7a243c 100644 (file)
@@ -52,7 +52,7 @@ public class KeywordArgumentCompletionUtil {
           addKeywordArgumentVariants((PyCallable)def, callExpr, ret);
         }
         else if (def instanceof PyClass) {
-          PyFunction init = ((PyClass)def).findMethodByName(PyNames.INIT, true);  // search in superclasses
+          PyFunction init = ((PyClass)def).findMethodByName(PyNames.INIT, true, null);  // search in superclasses
           if (init != null) {
             addKeywordArgumentVariants(init, callExpr, ret);
           }
index 680fd503bffaee6ec7adf4e47d5e71749f8316b9..2375662fafc0aaa8aeaaa9098db4dc9cb30baf39 100644 (file)
@@ -136,14 +136,14 @@ public class PyReferenceImpl implements PsiReferenceEx, PsiPolyVariantReference
         final PsiElement elt = rrr.getElement();
         if (elt instanceof PyClass) {
           PyClass cls = (PyClass)elt;
-          PyFunction init = cls.findMethodByName(PyNames.INIT, false);
+          PyFunction init = cls.findMethodByName(PyNames.INIT, false, null);
           if (init != null) {
             // replace
             it.set(rrr.replace(init));
           }
           else { // init not found; maybe it's ancestor's
             for (PyClass ancestor : cls.getAncestorClasses(myContext.getTypeEvalContext())) {
-              init = ancestor.findMethodByName(PyNames.INIT, false);
+              init = ancestor.findMethodByName(PyNames.INIT, false, null);
               if (init != null) {
                 // add to results as low priority
                 it.add(new RatedResolveResult(RatedResolveResult.RATE_LOW, init));
index 54b2f8ecfce4238909e67dbc7bad6d89404c36b3..a62cae8583f436cd19f1606419e07aaefeb950f3 100644 (file)
@@ -53,7 +53,19 @@ public class PyClassElementType extends PyStubElementType<PyClassStub, PyClass>
   }
 
   public PyClassStub createStub(@NotNull final PyClass psi, final StubElement parentStub) {
-    final PyExpression[] exprs = psi.getSuperClassExpressions();
+    final List<QualifiedName> superClasses = getSuperClassQNames(psi);
+    final PyStringLiteralExpression docStringExpression = psi.getDocStringExpression();
+    return new PyClassStubImpl(psi.getName(), parentStub,
+                               superClasses.toArray(new QualifiedName[superClasses.size()]),
+                               PyPsiUtils.asQualifiedName(psi.getMetaClassExpression()),
+                               psi.getOwnSlots(),
+                               PyPsiUtils.strValue(docStringExpression),
+                               getStubElementType());
+  }
+
+  @NotNull
+  public static List<QualifiedName> getSuperClassQNames(@NotNull final PyClass pyClass) {
+    final PyExpression[] exprs = pyClass.getSuperClassExpressions();
     List<QualifiedName> superClasses = new ArrayList<QualifiedName>();
     for (PyExpression expression : exprs) {
       if (expression instanceof PyKeywordArgument) {
@@ -62,13 +74,7 @@ public class PyClassElementType extends PyStubElementType<PyClassStub, PyClass>
       expression = PyClassImpl.unfoldClass(expression);
       superClasses.add(PyPsiUtils.asQualifiedName(expression));
     }
-    final PyStringLiteralExpression docStringExpression = psi.getDocStringExpression();
-    return new PyClassStubImpl(psi.getName(), parentStub,
-                               superClasses.toArray(new QualifiedName[superClasses.size()]),
-                               PyPsiUtils.asQualifiedName(psi.getMetaClassExpression()),
-                               psi.getOwnSlots(),
-                               PyPsiUtils.strValue(docStringExpression),
-                               getStubElementType());
+    return superClasses;
   }
 
   public void serialize(@NotNull final PyClassStub pyClassStub, @NotNull final StubOutputStream dataStream) throws IOException {
@@ -106,7 +112,7 @@ public class PyClassElementType extends PyStubElementType<PyClassStub, PyClass>
       sink.occurrence(PyClassNameIndexInsensitive.KEY, name.toLowerCase());
     }
     final PyClass pyClass = createPsi(stub);
-    for (String attribute: PyClassAttributesIndex.getAllDeclaredAttributeNames(pyClass)) {
+    for (String attribute : PyClassAttributesIndex.getAllDeclaredAttributeNames(pyClass)) {
       sink.occurrence(PyClassAttributesIndex.KEY, attribute);
     }
     for (QualifiedName s : stub.getSuperClasses()) {
index 908cccd9211778885a07dbd39bde938101d801a6..84887c3efa6d43dbeced7e08aff91678b35c4263 100644 (file)
@@ -34,7 +34,7 @@ public class PyOverridingMethodsSearchExecutor implements QueryExecutor<PyFuncti
         final AccessToken accessToken = ApplicationManager.getApplication().acquireReadActionLock();
         PyFunction overridingMethod;
         try {
-          overridingMethod = pyClass.findMethodByName(baseMethod.getName(), false);
+          overridingMethod = pyClass.findMethodByName(baseMethod.getName(), false, null);
           if (overridingMethod != null) {
             final Property baseProperty = baseMethod.getProperty();
             final Property overridingProperty = overridingMethod.getProperty();
index 87b372b626232093869ea282fa60873cf4375444..251f7c501340d7114ede632faeda48713d880ee5 100644 (file)
@@ -52,7 +52,7 @@ public class PySuperMethodsSearchExecutor implements QueryExecutor<PsiElement, P
             continue;
           }
         }
-        PyFunction superMethod = superClass.findMethodByName(name, false);
+        PyFunction superMethod = superClass.findMethodByName(name, false, null);
         if (superMethod != null) {
           final Property property = func.getProperty();
           final Property superProperty = superMethod.getProperty();
index bfc90678a6058e0d4292a9d426cb528234145d90..ef14cd96e711291a3028b349a26e457ede8f67f0 100644 (file)
@@ -18,6 +18,7 @@ package com.jetbrains.python.psi.types;
 import com.jetbrains.python.PyNames;
 import com.jetbrains.python.psi.PyClass;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 /**
  * @author vlan
@@ -29,36 +30,36 @@ public class PyABCUtil {
   public static boolean isSubclass(@NotNull PyClass subClass, @NotNull PyClass superClass) {
     final String superName = superClass.getName();
     if (superName != null) {
-      return isSubclass(subClass, superName, true);
+      return isSubclass(subClass, superName, true, null);
     }
     return false;
   }
 
-  public static boolean isSubclass(@NotNull PyClass subClass, @NotNull String superClassName) {
-    return isSubclass(subClass, superClassName, true);
+  public static boolean isSubclass(@NotNull PyClass subClass, @NotNull String superClassName, @Nullable TypeEvalContext context) {
+    return isSubclass(subClass, superClassName, true, context);
   }
 
-  public static boolean isSubclass(@NotNull PyClass subClass, @NotNull String superClassName, boolean inherited) {
+  public static boolean isSubclass(@NotNull PyClass subClass, @NotNull String superClassName, boolean inherited, @Nullable TypeEvalContext context) {
     if (PyNames.CALLABLE.equals(superClassName)) {
-      return hasMethod(subClass, PyNames.CALL, inherited);
+      return hasMethod(subClass, PyNames.CALL, inherited, context);
     }
     if (PyNames.HASHABLE.equals(superClassName)) {
-      return hasMethod(subClass, PyNames.HASH, inherited);
+      return hasMethod(subClass, PyNames.HASH, inherited, context);
     }
-    final boolean hasIter = hasMethod(subClass, PyNames.ITER, inherited);
-    final boolean hasGetItem = hasMethod(subClass, PyNames.GETITEM, inherited);
+    final boolean hasIter = hasMethod(subClass, PyNames.ITER, inherited, context);
+    final boolean hasGetItem = hasMethod(subClass, PyNames.GETITEM, inherited, context);
     if (PyNames.ITERABLE.equals(superClassName)) {
       return hasIter || hasGetItem;
     }
     if (PyNames.ITERATOR.equals(superClassName)) {
-      return (hasIter && (hasMethod(subClass, PyNames.NEXT, inherited) || hasMethod(subClass,
-                                                                         PyNames.DUNDER_NEXT, inherited))) || hasGetItem;
+      return (hasIter && (hasMethod(subClass, PyNames.NEXT, inherited, context) || hasMethod(subClass,
+                                                                                          PyNames.DUNDER_NEXT, inherited, context))) || hasGetItem;
     }
-    final boolean isSized = hasMethod(subClass, PyNames.LEN, inherited);
+    final boolean isSized = hasMethod(subClass, PyNames.LEN, inherited, context);
     if (PyNames.SIZED.equals(superClassName)) {
       return isSized;
     }
-    final boolean isContainer = hasMethod(subClass, PyNames.CONTAINS, inherited);
+    final boolean isContainer = hasMethod(subClass, PyNames.CONTAINS, inherited, context);
     if (PyNames.CONTAINER.equals(superClassName)) {
       return isContainer;
     }
@@ -66,16 +67,16 @@ public class PyABCUtil {
       return isSized && hasIter && isContainer && hasGetItem;
     }
     if (PyNames.MAPPING.equals(superClassName)) {
-      return isSized && hasIter && isContainer && hasGetItem && hasMethod(subClass, PyNames.KEYS, inherited);
+      return isSized && hasIter && isContainer && hasGetItem && hasMethod(subClass, PyNames.KEYS, inherited, context);
     }
     if (PyNames.ABC_COMPLEX.equals(superClassName)) {
-      return hasMethod(subClass, "__complex__", inherited);
+      return hasMethod(subClass, "__complex__", inherited, context);
     }
     if (PyNames.ABC_REAL.equals(superClassName)) {
-      return hasMethod(subClass, "__float__", inherited);
+      return hasMethod(subClass, "__float__", inherited, context);
     }
     if (PyNames.ABC_INTEGRAL.equals(superClassName)) {
-      return hasMethod(subClass, "__int__", inherited);
+      return hasMethod(subClass, "__int__", inherited, context);
     }
     if (PyNames.ABC_NUMBER.equals(superClassName) && "Decimal".equals(subClass.getName())) {
       return true;
@@ -95,11 +96,11 @@ public class PyABCUtil {
         final PyClassLikeType metaClassType = classType.getMetaClassType(context, true);
         if (metaClassType instanceof PyClassType) {
           final PyClassType metaClass = (PyClassType)metaClassType;
-          return isSubclass(metaClass.getPyClass(), superClassName, true);
+          return isSubclass(metaClass.getPyClass(), superClassName, true, null);
         }
       }
       else {
-        return isSubclass(pyClass, superClassName, true);
+        return isSubclass(pyClass, superClassName, true, null);
       }
     }
     if (type instanceof PyUnionType) {
@@ -116,7 +117,7 @@ public class PyABCUtil {
     return false;
   }
 
-  private static boolean hasMethod(PyClass cls, String name, boolean inherited) {
-    return cls.findMethodByName(name, inherited) != null || cls.findClassAttribute(name, inherited) != null;
+  private static boolean hasMethod(PyClass cls, String name, boolean inherited, TypeEvalContext context) {
+    return cls.findMethodByName(name, inherited, context) != null || cls.findClassAttribute(name, inherited, context) != null;
   }
 }
index 3f0b032824ad73f338ec85f6d6f0f774e5fb468c..67c4a9c84b4ffea6826e42f01f3002b3429ffee5 100644 (file)
@@ -312,7 +312,7 @@ public class PyClassTypeImpl extends UserDataHolderBase implements PyClassType {
       return true;
     }
     final PyClass cls = getPyClass();
-    if (PyABCUtil.isSubclass(cls, PyNames.CALLABLE)) {
+    if (PyABCUtil.isSubclass(cls, PyNames.CALLABLE, null)) {
       return true;
     }
     return false;
index 6ab464b5a7b14339359c53bb19d9dd0cca44adfa..4a919113ea185546c84dbb7f109dd9dc812672fd 100644 (file)
@@ -77,7 +77,7 @@ public class PyChangeSignatureUsageProcessor implements ChangeSignatureUsageProc
     if (info instanceof PyChangeInfo && info.isNameChanged()) {
       final PyFunction function = ((PyChangeInfo)info).getMethod();
       final PyClass clazz = function.getContainingClass();
-      if (clazz != null && clazz.findMethodByName(info.getNewName(), true) != null) {
+      if (clazz != null && clazz.findMethodByName(info.getNewName(), true, null) != null) {
         conflicts.putValue(function, RefactoringBundle.message("method.0.is.already.defined.in.the.1",
                                                                info.getNewName(),
                                                                "class " + clazz.getQualifiedName()));
index ffcb809a10fb82a756858083f618c96fc95421f0..a0032f4f905d0f079bf36ed8da3468784e9e1e14 100644 (file)
@@ -157,7 +157,7 @@ public final class PyClassRefactoringUtil {
 
     for (final PyFunction method : methods) {
 
-      final PyFunction existingMethod = destination.findMethodByName(method.getName(), false);
+      final PyFunction existingMethod = destination.findMethodByName(method.getName(), false, null);
       if ((existingMethod != null) && skipIfExist) {
         result.add(existingMethod);
         continue; //We skip adding if class already has this method.
@@ -589,7 +589,7 @@ public final class PyClassRefactoringUtil {
     @NotNull final PyClass aClass,
     @NotNull final String attributeName,
     @NotNull final String value) {
-    if (aClass.findClassAttribute(attributeName, false) != null) {
+    if (aClass.findClassAttribute(attributeName, false, null) != null) {
       return null; //Do not add any if exist already
     }
     final PyElementGenerator generator = PyElementGenerator.getInstance(aClass.getProject());
index 38294c03efb0386d8b3ca114727c734dd367d226..927b4a10685439db1f565d81fd917933db51fe64 100644 (file)
@@ -70,7 +70,7 @@ class ClassFieldsManager extends FieldsManager {
 
   @Override
   protected boolean classHasField(@NotNull final PyClass pyClass, @NotNull final String fieldName) {
-    return pyClass.findClassAttribute(fieldName, true) != null;
+    return pyClass.findClassAttribute(fieldName, true, null) != null;
   }
 
   @NotNull
index 9f862729789e57fd338636fcec3d7592670d2b3a..2da065bb0374650c9b0b85e8b3213988c52b5360 100644 (file)
@@ -223,7 +223,7 @@ class MethodsManager extends MembersManager<PyFunction> {
     final PyClass clazz = PyUtil.getContainingClassOrSelf(pyFunction);
     assert clazz != null : "Refactoring called on function, not method: " + pyFunction;
     for (final PyClass parentClass : clazz.getSuperClasses(null)) {
-      final PyFunction parentMethod = parentClass.findMethodByName(pyFunction.getName(), true);
+      final PyFunction parentMethod = parentClass.findMethodByName(pyFunction.getName(), true, null);
       if (parentMethod != null) {
         return true;
       }
index 21c800a08ee49c7f85e9080a20bdc875ab625d00..2898211f315ec87f6edfbf414395e3fc1bbf79b8 100644 (file)
@@ -687,7 +687,7 @@ public class PyExtractMethodUtil {
           ScopeOwner owner = parent;
           while (owner != null) {
             if (owner instanceof PyClass) {
-              if (((PyClass)owner).findMethodByName(s, true) != null) {
+              if (((PyClass)owner).findMethodByName(s, true, null) != null) {
                 return false;
               }
             }
index a3e579d9e268be2cf6e8f93418073f9e20dee460..94474e59a59cdb3bdbc170d5346d9fb32beee866 100644 (file)
@@ -173,7 +173,7 @@ public class PyIntroduceFieldHandler extends IntroduceHandler {
     PyClass clazz = PyUtil.getContainingClassOrSelf(expr);
     PsiElement current = PyUtil.getConcealingParent(expression);
     if (clazz != null && current != null && current instanceof PyFunction) {
-      PyFunction init = clazz.findMethodByName(PyNames.INIT, false);
+      PyFunction init = clazz.findMethodByName(PyNames.INIT, false, null);
       if (current == init) {
         return true;
       }
@@ -183,7 +183,7 @@ public class PyIntroduceFieldHandler extends IntroduceHandler {
 
   @Nullable
   private static PsiElement addFieldToSetUp(PyClass clazz, final Function<String, PyStatement> callback) {
-    final PyFunction init = clazz.findMethodByName(PythonUnitTestUtil.TESTCASE_SETUP_NAME, false);
+    final PyFunction init = clazz.findMethodByName(PythonUnitTestUtil.TESTCASE_SETUP_NAME, false, null);
     if (init != null) {
       return AddFieldQuickFix.appendToMethod(init, callback);
     }
index 3f11c0505ee5f39fc8fb70fb0f8ff338634562eb..0e20885b57511b107cbf5579fb0275e98623ce99 100644 (file)
@@ -64,7 +64,7 @@ public class RenamePyClassProcessor extends RenamePyElementProcessor {
   @Override
   public Collection<PsiReference> findReferences(final PsiElement element) {
     if (element instanceof PyClass) {
-      final PyFunction initMethod = ((PyClass)element).findMethodByName(PyNames.INIT, true);
+      final PyFunction initMethod = ((PyClass)element).findMethodByName(PyNames.INIT, true, null);
       if (initMethod != null) {
         final List<PsiReference> allRefs = Collections.synchronizedList(new ArrayList<PsiReference>());
         allRefs.addAll(super.findReferences(element));
index 2db1b5ea6fd8ab46c3c43f79f66600dda46044ee..aeb062722008c9a5bbab8293399c3a586092bfeb 100644 (file)
@@ -50,11 +50,11 @@ public abstract class RenamePyElementProcessor extends RenamePsiElementProcessor
       if (conflictingClass != null) {
         conflicts.putValue(conflictingClass, "A class named '" + newName + "' is already defined in class '" + pyClass.getName() + "'");
       }
-      PyFunction conflictingFunction = pyClass.findMethodByName(newName, true);
+      PyFunction conflictingFunction = pyClass.findMethodByName(newName, true, null);
       if (conflictingFunction != null) {
         conflicts.putValue(conflictingFunction, "A function named '" + newName + "' is already defined in class '" + pyClass.getName() + "'");
       }
-      PyTargetExpression conflictingAttribute = pyClass.findClassAttribute(newName, true);
+      PyTargetExpression conflictingAttribute = pyClass.findClassAttribute(newName, true, null);
       if (conflictingAttribute != null) {
         conflicts.putValue(conflictingAttribute, "An attribute named '" + newName + "' is already defined in class '" + pyClass.getName() + "'");
       }
index 95e139a352dc534961746018d48fc988873c92a1..210200176a2f2d92fe22103eb5dc9e1463ecdc38 100644 (file)
@@ -204,7 +204,7 @@ public class PythonUnitTestUtil {
           locations.add(new PsiLocation<PyClass>(project, cls));
         }
         else {
-          final PyFunction method = cls.findMethodByName(methodName, true);
+          final PyFunction method = cls.findMethodByName(methodName, true, null);
           if (method == null) {
             continue;
           }
index 17a8adc6eb6c394e64e30d9f5ce05459681f8861..4733134eee6b6e4b27f29b098dbf00ce780ead41 100644 (file)
@@ -132,10 +132,10 @@ public class PyClassicPropertyTest extends PyTestCase {
   */
 
   public void testGetProperty() {
-    final PyFunction getter = myClass.findMethodByName("v5getter", false);
+    final PyFunction getter = myClass.findMethodByName("v5getter", false, null);
     assertNotNull(getter.getProperty());
 
-    final PyFunction setter = myClass.findMethodByName("v5setter", false);
+    final PyFunction setter = myClass.findMethodByName("v5setter", false, null);
     assertNotNull(setter.getProperty());
   }
 
index 53a5d7f55d12d6e7ac57859c4f931ba2ae7a8f12..f081558707350219b3690016d3072468e0d85680 100644 (file)
@@ -111,7 +111,7 @@ public class PyOverrideTest extends PyTestCase {
     myFixture.configureByFile("override/" + getTestName(true) + ".py");
     PyClass dateClass = PyClassNameIndex.findClass("datetime.date", myFixture.getProject());
     assertNotNull(dateClass);
-    PyFunction initMethod = dateClass.findMethodByName(PyNames.INIT, false);
+    PyFunction initMethod = dateClass.findMethodByName(PyNames.INIT, false, null);
     assertNotNull(initMethod);
     PyOverrideImplementUtil.overrideMethods(myFixture.getEditor(), getTopLevelClass(0),
                                             Collections.singletonList(new PyMethodMember(initMethod)), false);
@@ -183,7 +183,7 @@ public class PyOverrideTest extends PyTestCase {
   public void testInstanceCheck() {
     myFixture.configureByFile("override/" + getTestName(true) + ".py");
     final PyClass cls = getTopLevelClass(0);
-    final PyFunction method = cls.findMethodByName("__instancecheck__", true);
+    final PyFunction method = cls.findMethodByName("__instancecheck__", true, null);
     PyOverrideImplementUtil.overrideMethods(myFixture.getEditor(), cls, Collections.singletonList(new PyMethodMember(method)), false);
     myFixture.checkResultByFile("override/" + getTestName(true) + "_after.py", true);
   }
index 6b63660f8be5ccb796ac69173d2e5dd43422dd63..58735ff2541a495475dc5cadd4e4c415c126a829 100644 (file)
@@ -399,7 +399,7 @@ public class PyStubsTest extends PyTestCase {
     final PyFile file = getTestFile();
     final PyClass c = file.findTopLevelClass("C");
     assertNotNull(c);
-    final PyTargetExpression foo = c.findClassAttribute("foo", false);
+    final PyTargetExpression foo = c.findClassAttribute("foo", false, null);
     final String docString = foo.getDocStringValue();
     assertEquals("Foo docstring.", docString);
   }
index dca624adabca58e73a7d9588354de244f3f6a7b2..5d053da791b116f569d74096f2773bb8cd65edfc 100644 (file)
@@ -95,7 +95,7 @@ public class PyClassMROTest extends PyTestCase {
   }
 
   public void assertMRO(@NotNull PyClass cls, @NotNull String... mro) {
-    final List<PyClassLikeType> types = cls.getAncestorTypes(TypeEvalContext.codeInsightFallback(cls.getProject()));
+    final List<PyClassLikeType> types = cls.getAncestorTypes(TypeEvalContext.deepCodeInsight(cls.getProject()));
     final List<String> classNames = new ArrayList<String>();
     for (PyClassLikeType type : types) {
       if (type != null) {
index c47935da958887efc5bfae1e79cc0ec08e143167..dd24256021aa79635c5725ceda178330e6b7ab13 100644 (file)
@@ -87,7 +87,7 @@ public abstract class PyClassRefactoringTest extends PyTestCase {
 
   private PyElement findField(final String className, final String memberName) {
     final PyClass aClass = findClass(className);
-    final PyTargetExpression attribute = aClass.findClassAttribute(memberName, false);
+    final PyTargetExpression attribute = aClass.findClassAttribute(memberName, false, null);
     if (attribute != null) {
       return attribute;
     }
@@ -96,7 +96,7 @@ public abstract class PyClassRefactoringTest extends PyTestCase {
 
   private PyFunction findMethod(final String className, final String name) {
     final PyClass clazz = findClass(className);
-    return clazz.findMethodByName(name, false);
+    return clazz.findMethodByName(name, false, null);
   }
 
   protected PyClass findClass(final String name) {