From 1469a3d7d1cf07ade51abac1bcedef8c90babdfe Mon Sep 17 00:00:00 2001 From: Andrey Vlasovskikh Date: Mon, 4 Feb 2013 16:20:04 +0400 Subject: [PATCH] Moved isResolvedToSeveralMethods() to PyTypeChecker --- .../inspections/PyTypeCheckerInspection.java | 47 ++----------------- .../python/psi/types/PyTypeChecker.java | 43 ++++++++++++++++- 2 files changed, 47 insertions(+), 43 deletions(-) diff --git a/python/src/com/jetbrains/python/inspections/PyTypeCheckerInspection.java b/python/src/com/jetbrains/python/inspections/PyTypeCheckerInspection.java index c0c7614948e2..8be02c241f58 100644 --- a/python/src/com/jetbrains/python/inspections/PyTypeCheckerInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyTypeCheckerInspection.java @@ -10,13 +10,14 @@ import com.intellij.psi.PsiElementVisitor; import com.intellij.util.containers.hash.LinkedHashMap; import com.jetbrains.python.documentation.PythonDocumentationProvider; import com.jetbrains.python.psi.*; -import com.jetbrains.python.psi.resolve.RatedResolveResult; -import com.jetbrains.python.psi.types.*; +import com.jetbrains.python.psi.types.PyGenericType; +import com.jetbrains.python.psi.types.PyType; +import com.jetbrains.python.psi.types.PyTypeChecker; +import com.jetbrains.python.psi.types.TypeEvalContext; import org.jetbrains.annotations.Nls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.util.List; import java.util.Map; /** @@ -44,11 +45,7 @@ public class PyTypeCheckerInspection extends PyInspection { public void visitPyCallExpression(PyCallExpression node) { final PyExpression callee = node.getCallee(); if (callee instanceof PyQualifiedExpression) { - final PyQualifiedExpression qualified = (PyQualifiedExpression)callee; - if (isResolvedToSeveralMethods(qualified)) { - return; - } - checkCallSite(qualified); + checkCallSite((PyQualifiedExpression)callee); } } @@ -63,40 +60,6 @@ public class PyTypeCheckerInspection extends PyInspection { checkCallSite(node); } - /** - * Hack for skipping type checking for method calls of union members if there are several call alternatives. - * - * TODO: Multi-resolve callees when analysing calls. This requires multi-resolving in followAssignmentsChain. - */ - private boolean isResolvedToSeveralMethods(@NotNull PyQualifiedExpression callee) { - final PyExpression qualifier = callee.getQualifier(); - if (qualifier != null) { - final PyType qualifierType = qualifier.getType(myTypeEvalContext); - if (qualifierType instanceof PyUnionType) { - final PyUnionType unionType = (PyUnionType)qualifierType; - final String name = callee.getName(); - int sameNameCount = 0; - for (PyType member : unionType.getMembers()) { - if (member != null) { - final List results = member.resolveMember(name, callee, AccessDirection.READ, - resolveWithoutImplicits()); - if (results != null && !results.isEmpty()) { - sameNameCount++; - } - } - } - if (sameNameCount > 1) { - return true; - } - } - final PyExpression qualifierExpr = qualifier instanceof PyCallExpression ? ((PyCallExpression)qualifier).getCallee() : qualifier; - if (qualifierExpr instanceof PyQualifiedExpression) { - return isResolvedToSeveralMethods((PyQualifiedExpression)qualifierExpr); - } - } - return false; - } - private void checkCallSite(@Nullable PyQualifiedExpression callSite) { final Map substitutions = new LinkedHashMap(); final PyTypeChecker.AnalyzeCallResults results = PyTypeChecker.analyzeCallSite(callSite, myTypeEvalContext); diff --git a/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java b/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java index 8f074afbe9ec..8c3caf7f37b1 100644 --- a/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java +++ b/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java @@ -9,6 +9,7 @@ import com.jetbrains.python.codeInsight.stdlib.PyStdlibTypeProvider; import com.jetbrains.python.psi.*; import com.jetbrains.python.psi.impl.PyBuiltinCache; import com.jetbrains.python.psi.resolve.PyResolveContext; +import com.jetbrains.python.psi.resolve.RatedResolveResult; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -319,6 +320,13 @@ public class PyTypeChecker { @Nullable public static AnalyzeCallResults analyzeCall(@NotNull PyCallExpression call, @NotNull TypeEvalContext context) { + final PyExpression callee = call.getCallee(); + if (callee instanceof PyQualifiedExpression) { + final PyQualifiedExpression qualified = (PyQualifiedExpression)callee; + if (isResolvedToSeveralMethods(qualified, context)) { + return null; + } + } final PyArgumentList args = call.getArgumentList(); if (args != null) { final CallArgumentsMapping mapping = args.analyzeCall(PyResolveContext.noImplicits().withTypeEvalContext(context)); @@ -327,7 +335,6 @@ public class PyTypeChecker { if (markedCallee != null) { final Callable callable = markedCallee.getCallable(); if (callable instanceof PyFunction) { - final PyExpression callee = call.getCallee(); final PyExpression receiver = callee instanceof PyQualifiedExpression ? ((PyQualifiedExpression)callee).getQualifier() : null; return new AnalyzeCallResults(callable, receiver, arguments); } @@ -464,6 +471,40 @@ public class PyTypeChecker { return type.equals(builtinCache.getClassMethodType()) || type.equals(builtinCache.getStaticMethodType()); } + /** + * Hack for skipping type checking for method calls of union members if there are several call alternatives. + * + * TODO: Multi-resolve callees when analysing calls. This requires multi-resolving in followAssignmentsChain. + */ + public static boolean isResolvedToSeveralMethods(@NotNull PyQualifiedExpression callee, @NotNull TypeEvalContext context) { + final PyExpression qualifier = callee.getQualifier(); + if (qualifier != null) { + final PyType qualifierType = qualifier.getType(context); + if (qualifierType instanceof PyUnionType) { + final PyUnionType unionType = (PyUnionType)qualifierType; + final String name = callee.getName(); + int sameNameCount = 0; + for (PyType member : unionType.getMembers()) { + if (member != null) { + final PyResolveContext resolveContext = PyResolveContext.noImplicits().withTypeEvalContext(context); + final List results = member.resolveMember(name, callee, AccessDirection.READ, resolveContext); + if (results != null && !results.isEmpty()) { + sameNameCount++; + } + } + } + if (sameNameCount > 1) { + return true; + } + } + final PyExpression qualifierExpr = qualifier instanceof PyCallExpression ? ((PyCallExpression)qualifier).getCallee() : qualifier; + if (qualifierExpr instanceof PyQualifiedExpression) { + return isResolvedToSeveralMethods((PyQualifiedExpression)qualifierExpr, context); + } + } + return false; + } + public static class AnalyzeCallResults { @NotNull private final Callable myCallable; @Nullable private final PyExpression myReceiver;