diff --git a/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibTypeProvider.java b/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibTypeProvider.java index c6eaaa5762ba..6d3d232d4e1c 100644 --- a/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibTypeProvider.java +++ b/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibTypeProvider.java @@ -87,30 +87,30 @@ public class PyStdlibTypeProvider extends PyTypeProviderBase { } } } - return getReturnTypeByQName(qname, function); + return getReturnTypeByQName(qname, function, context); } return null; } @Nullable - public PyType getConstructorType(@NotNull PyClass cls) { + public PyType getConstructorType(@NotNull PyClass cls, @NotNull TypeEvalContext context) { final String classQName = cls.getQualifiedName(); if (classQName != null) { final PyQualifiedName canonicalQName = PyStdlibCanonicalPathProvider.restoreStdlibCanonicalPath(PyQualifiedName.fromDottedString(classQName)); if (canonicalQName != null) { final PyQualifiedName qname = canonicalQName.append(PyNames.INIT); - return getReturnTypeByQName(qname.toString(), cls); + return getReturnTypeByQName(qname.toString(), cls, context); } } return null; } @Nullable - private PyType getReturnTypeByQName(@NotNull String qname, @NotNull PsiElement anchor) { + private PyType getReturnTypeByQName(@NotNull String qname, @NotNull PsiElement anchor, @NotNull TypeEvalContext context) { final LanguageLevel level = LanguageLevel.forElement(anchor); final String key = String.format("Python%d/%s.return", level.getVersion(), qname); final PyBuiltinCache cache = PyBuiltinCache.getInstance(anchor); - final Ref cached = cache.getStdlibType(key); + final Ref cached = cache.getStdlibType(key, context); if (cached != null) { return cached.get(); } @@ -133,7 +133,7 @@ public class PyStdlibTypeProvider extends PyTypeProviderBase { final String name = param.getName(); final String qname = getQualifiedName(func, param); if (qname != null && name != null) { - return getParameterTypeByQName(qname, name, func); + return getParameterTypeByQName(qname, name, func, context); } return null; } @@ -175,7 +175,7 @@ public class PyStdlibTypeProvider extends PyTypeProviderBase { PyType rtype; do { final String overloadedQName = String.format("%s.%d", qname, i); - rtype = getReturnTypeByQName(overloadedQName, anchor); + rtype = getReturnTypeByQName(overloadedQName, anchor, context); if (rtype != null) { boolean matched = true; boolean notNullParameterMatch = false; @@ -192,7 +192,7 @@ public class PyStdlibTypeProvider extends PyTypeProviderBase { continue; } final PyType argType = context.getType(entry.getKey()); - final PyType paramType = getParameterTypeByQName(overloadedQName, name, anchor); + final PyType paramType = getParameterTypeByQName(overloadedQName, name, anchor, context); if (PyTypeChecker.match(paramType, argType, context)) { if (paramType != null && !PyTypeChecker.isUnknown(argType)) { notNullParameterMatch = true; @@ -230,7 +230,7 @@ public class PyStdlibTypeProvider extends PyTypeProviderBase { } final PyBuiltinCache cache = PyBuiltinCache.getInstance(anchor); final LanguageLevel level = LanguageLevel.forElement(anchor); - final PyType paramType = getParameterTypeByQName(overloadedQName, "mode", anchor); + final PyType paramType = getParameterTypeByQName(overloadedQName, "mode", anchor, context); final PyType argType; // Binary mode if (mode.contains("b")) { @@ -249,11 +249,14 @@ public class PyStdlibTypeProvider extends PyTypeProviderBase { } @Nullable - private PyType getParameterTypeByQName(@NotNull String functionQName, @NotNull String name, @NotNull PsiElement anchor) { + private PyType getParameterTypeByQName(@NotNull String functionQName, + @NotNull String name, + @NotNull PsiElement anchor, + @NotNull TypeEvalContext context) { final LanguageLevel level = LanguageLevel.forElement(anchor); final String key = String.format("Python%d/%s.%s", level.getVersion(), functionQName, name); final PyBuiltinCache cache = PyBuiltinCache.getInstance(anchor); - final Ref cached = cache.getStdlibType(key); + final Ref cached = cache.getStdlibType(key, context); if (cached != null) { return cached.get(); } diff --git a/python/src/com/jetbrains/python/findUsages/PyUsageTypeProvider.java b/python/src/com/jetbrains/python/findUsages/PyUsageTypeProvider.java index b4a9de818885..97480fed2e40 100644 --- a/python/src/com/jetbrains/python/findUsages/PyUsageTypeProvider.java +++ b/python/src/com/jetbrains/python/findUsages/PyUsageTypeProvider.java @@ -39,11 +39,12 @@ public class PyUsageTypeProvider implements UsageTypeProviderEx { if (element instanceof PyQualifiedExpression) { final PyExpression qualifier = ((PyQualifiedExpression)element).getQualifier(); if (qualifier != null) { - final PyType type = TypeEvalContext.userInitiated().getType(qualifier); + final TypeEvalContext context = TypeEvalContext.userInitiated(); + final PyType type = context.getType(qualifier); if (type == null || type instanceof PyTypeReference) { final PyCallExpression call = PsiTreeUtil.getParentOfType(element, PyCallExpression.class); if (call != null && element == call.getCallee()) { - return checkMatchingSignatureGroup(call, targets); + return checkMatchingSignatureGroup(call, targets, context); } return UNTYPED; } @@ -74,7 +75,7 @@ public class PyUsageTypeProvider implements UsageTypeProviderEx { } @Nullable - private static UsageType checkMatchingSignatureGroup(PyCallExpression call, UsageTarget[] targets) { + private static UsageType checkMatchingSignatureGroup(PyCallExpression call, UsageTarget[] targets, TypeEvalContext context) { if (targets.length == 1 && targets[0] instanceof PsiElementUsageTarget) { final PsiElement element = ((PsiElementUsageTarget)targets[0]).getElement(); if (element instanceof PyFunction) { @@ -82,7 +83,7 @@ public class PyUsageTypeProvider implements UsageTypeProviderEx { final PyFunction.Modifier modifier = function.getModifier(); PyCallExpression.PyMarkedCallee callee = new PyCallExpression.PyMarkedCallee(function, modifier, 1, true); CallArgumentsMappingImpl mapping = new CallArgumentsMappingImpl(call.getArgumentList()); - mapping.mapArguments(callee, null); + mapping.mapArguments(callee, context); if (mapping.hasProblems()) { return SIGNATURE_MISMATCH; } diff --git a/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java b/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java index 4a519c2c4a6a..dc75c6f20e30 100644 --- a/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java @@ -646,7 +646,7 @@ public class PyUnresolvedReferencesInspection extends PyInspection { if (cls.findProperty(refText) != null) { return true; } - if (PyUtil.hasUnresolvedAncestors(cls)) { + if (PyUtil.hasUnresolvedAncestors(cls, myTypeEvalContext)) { return true; } if (isDecoratedAsDynamic(cls, true)) { diff --git a/python/src/com/jetbrains/python/psi/PyUtil.java b/python/src/com/jetbrains/python/psi/PyUtil.java index 4abf744b131f..cc614bed1850 100644 --- a/python/src/com/jetbrains/python/psi/PyUtil.java +++ b/python/src/com/jetbrains/python/psi/PyUtil.java @@ -617,8 +617,8 @@ public class PyUtil { : psiNamedElement.getName(); } - public static boolean hasUnresolvedAncestors(@NotNull PyClass cls) { - for (PyClassLikeType type : cls.getAncestorTypes(TypeEvalContext.codeInsightFallback())) { + public static boolean hasUnresolvedAncestors(@NotNull PyClass cls, @NotNull TypeEvalContext context) { + for (PyClassLikeType type : cls.getAncestorTypes(context)) { if (type == null) { return true; } diff --git a/python/src/com/jetbrains/python/psi/impl/CallArgumentsMappingImpl.java b/python/src/com/jetbrains/python/psi/impl/CallArgumentsMappingImpl.java index c3b958b6e558..e8cddd605855 100644 --- a/python/src/com/jetbrains/python/psi/impl/CallArgumentsMappingImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/CallArgumentsMappingImpl.java @@ -47,14 +47,10 @@ public class CallArgumentsMappingImpl implements CallArgumentsMapping { * positional paramaters, but at least one item long. * @param arguments what to map, get if from call site * @param resolved_callee what to map parameters of - * @param type_context optional shared type evaluator / cache. + * @param context optional shared type evaluator / cache. */ - public void mapArguments( - PyCallExpression.PyMarkedCallee resolved_callee, - @Nullable TypeEvalContext type_context - ) { + public void mapArguments(PyCallExpression.PyMarkedCallee resolved_callee, @Nullable TypeEvalContext context) { PyExpression[] arguments = myArgumentList.getArguments(); - if (type_context == null) type_context = TypeEvalContext.codeInsightFallback(); myMarkedCallee = resolved_callee; List unmatched_args = new LinkedList(); Collections.addAll(unmatched_args, arguments); @@ -144,8 +140,8 @@ public class CallArgumentsMappingImpl implements CallArgumentsMapping { mapped_args.add(arg); // tuple itself is always mapped; its insides can fail } else { - PyType arg_type = type_context.getType(arg); - if (arg_type != null && arg_type.isBuiltin(type_context) && "list".equals(arg_type.getName())) { + PyType arg_type = context.getType(arg); + if (arg_type != null && arg_type.isBuiltin(context) && "list".equals(arg_type.getName())) { mapped_args.add(arg); // we can't really analyze arbitrary lists statically yet // but ListLiteralExpressions are handled by visitor } @@ -210,10 +206,10 @@ public class CallArgumentsMappingImpl implements CallArgumentsMapping { if (cnt < parameters.length && cnt < positional_index && myTupleArg != null) { // check length of myTupleArg PyType tuple_arg_type = null; - if (type_context != null) { + if (context != null) { final PyExpression expression = PsiTreeUtil.getChildOfType(myTupleArg, PyExpression.class); if (expression != null) { - tuple_arg_type = type_context.getType(expression); + tuple_arg_type = context.getType(expression); } } int tuple_length; diff --git a/python/src/com/jetbrains/python/psi/impl/PyBuiltinCache.java b/python/src/com/jetbrains/python/psi/impl/PyBuiltinCache.java index 75e7040cdf32..0f450fd9fee7 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyBuiltinCache.java +++ b/python/src/com/jetbrains/python/psi/impl/PyBuiltinCache.java @@ -314,11 +314,11 @@ public class PyBuiltinCache { } @Nullable - public Ref getStdlibType(@NotNull String key) { + public Ref getStdlibType(@NotNull String key, @NotNull TypeEvalContext context) { synchronized (myStdlibTypeCache) { final Ref ref = myStdlibTypeCache.get(key); if (ref != null) { - if (!isValid(ref.get())) { + if (!isValid(ref.get(), context)) { myStdlibTypeCache.clear(); return null; } @@ -327,10 +327,10 @@ public class PyBuiltinCache { } } - private static boolean isValid(@Nullable PyType type) { + private static boolean isValid(@Nullable PyType type, @NotNull TypeEvalContext context) { if (type instanceof PyCollectionType) { - final PyType elementType = ((PyCollectionType)type).getElementType(TypeEvalContext.codeInsightFallback()); - if (!isValid(elementType)) { + final PyType elementType = ((PyCollectionType)type).getElementType(context); + if (!isValid(elementType, context)) { return false; } } @@ -340,7 +340,7 @@ public class PyBuiltinCache { } else if (type instanceof PyUnionType) { for (PyType member : ((PyUnionType)type).getMembers()) { - if (!isValid(member)) { + if (!isValid(member, context)) { return false; } } diff --git a/python/src/com/jetbrains/python/psi/impl/PyNamedParameterImpl.java b/python/src/com/jetbrains/python/psi/impl/PyNamedParameterImpl.java index ad9be49db02f..6812fc8bd4aa 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyNamedParameterImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyNamedParameterImpl.java @@ -179,7 +179,7 @@ public class PyNamedParameterImpl extends PyPresentableElementImpl results = type.resolveMember(name, null, AccessDirection.READ, PyResolveContext.noImplicits()); diff --git a/python/src/com/jetbrains/python/psi/resolve/ResolveImportUtil.java b/python/src/com/jetbrains/python/psi/resolve/ResolveImportUtil.java index 47385ee210eb..9527d30f82ea 100644 --- a/python/src/com/jetbrains/python/psi/resolve/ResolveImportUtil.java +++ b/python/src/com/jetbrains/python/psi/resolve/ResolveImportUtil.java @@ -6,14 +6,16 @@ import com.intellij.openapi.projectRoots.Sdk; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.*; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiInvalidElementAccessException; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.containers.HashSet; import com.jetbrains.python.PyNames; import com.jetbrains.python.psi.*; import com.jetbrains.python.psi.impl.*; import com.jetbrains.python.psi.types.PyType; -import com.jetbrains.python.psi.types.TypeEvalContext; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -271,10 +273,10 @@ public class ResolveImportUtil { dir = (PsiDirectory)parent; } else if (parent != null) { - PyType refType = PyReferenceExpressionImpl.getReferenceTypeFromProviders(parent, TypeEvalContext.codeInsightFallback(), null); + final PyResolveContext resolveContext = PyResolveContext.defaultContext(); + PyType refType = PyReferenceExpressionImpl.getReferenceTypeFromProviders(parent, resolveContext.getTypeEvalContext(), null); if (refType != null) { - final List result = refType.resolveMember(referencedName, null, AccessDirection.READ, - PyResolveContext.defaultContext()); + final List result = refType.resolveMember(referencedName, null, AccessDirection.READ, resolveContext); if (result != null && !result.isEmpty()) { return result.get(0).getElement(); } diff --git a/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java b/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java index eefb1636612f..57641c8cec3b 100644 --- a/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java +++ b/python/src/com/jetbrains/python/psi/types/PyTypeChecker.java @@ -104,7 +104,7 @@ public class PyTypeChecker { final PyClass superClass = ((PyClassType)expected).getPyClass(); final PyClass subClass = ((PyClassType)actual).getPyClass(); if (expected instanceof PyCollectionType && actual instanceof PyCollectionType) { - if (!matchClasses(superClass, subClass)) { + if (!matchClasses(superClass, subClass, context)) { return false; } final PyType superElementType = ((PyCollectionType)expected).getElementType(context); @@ -126,7 +126,7 @@ public class PyTypeChecker { return true; } } - else if (matchClasses(superClass, subClass)) { + else if (matchClasses(superClass, subClass, context)) { return true; } else if (((PyClassType)actual).isDefinition() && PyNames.CALLABLE.equals(expected.getName())) { @@ -287,7 +287,7 @@ public class PyTypeChecker { // Unify generics in stdlib pseudo-constructor final PyStdlibTypeProvider stdlib = PyStdlibTypeProvider.getInstance(); if (stdlib != null) { - final PyType initType = stdlib.getConstructorType(cls); + final PyType initType = stdlib.getConstructorType(cls, context); if (initType != null) { match(initType, qualifierType, context, substitutions); } @@ -297,11 +297,11 @@ public class PyTypeChecker { return substitutions; } - private static boolean matchClasses(@Nullable PyClass superClass, @Nullable PyClass subClass) { + private static boolean matchClasses(@Nullable PyClass superClass, @Nullable PyClass subClass, @NotNull TypeEvalContext context) { if (superClass == null || subClass == null || subClass.isSubclass(superClass) || PyABCUtil.isSubclass(subClass, superClass)) { return true; } - else if (PyUtil.hasUnresolvedAncestors(subClass)) { + else if (PyUtil.hasUnresolvedAncestors(subClass, context)) { return true; } else {