mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Reused available TypeEvalContext instead of codeInsightFallback()
This commit is contained in:
@@ -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<PyType> cached = cache.getStdlibType(key);
|
||||
final Ref<PyType> 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<PyType> cached = cache.getStdlibType(key);
|
||||
final Ref<PyType> cached = cache.getStdlibType(key, context);
|
||||
if (cached != null) {
|
||||
return cached.get();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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<PyExpression> unmatched_args = new LinkedList<PyExpression>();
|
||||
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;
|
||||
|
||||
@@ -314,11 +314,11 @@ public class PyBuiltinCache {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Ref<PyType> getStdlibType(@NotNull String key) {
|
||||
public Ref<PyType> getStdlibType(@NotNull String key, @NotNull TypeEvalContext context) {
|
||||
synchronized (myStdlibTypeCache) {
|
||||
final Ref<PyType> 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -179,7 +179,7 @@ public class PyNamedParameterImpl extends PyPresentableElementImpl<PyNamedParame
|
||||
else {
|
||||
final PyStdlibTypeProvider stdlib = PyStdlibTypeProvider.getInstance();
|
||||
if (stdlib != null) {
|
||||
initType = stdlib.getConstructorType(containingClass);
|
||||
initType = stdlib.getConstructorType(containingClass, context);
|
||||
}
|
||||
}
|
||||
if (initType != null && !(initType instanceof PyNoneType || initType instanceof PyReturnTypeReference)) {
|
||||
|
||||
@@ -138,12 +138,13 @@ public class PyReferenceExpressionImpl extends PyElementImpl implements PyRefere
|
||||
if (elt instanceof PyTargetExpression) {
|
||||
PsiElement assigned_from = null;
|
||||
final PyTargetExpression expr = (PyTargetExpression)elt;
|
||||
if (resolveContext.getTypeEvalContext().maySwitchToAST(expr) || expr.getStub() == null) {
|
||||
final TypeEvalContext context = resolveContext.getTypeEvalContext();
|
||||
if (context.maySwitchToAST(expr) || expr.getStub() == null) {
|
||||
assigned_from = expr.findAssignedValue();
|
||||
}
|
||||
// TODO: Maybe findAssignedValueByStub() should become a part of the PyTargetExpression interface
|
||||
else if (elt instanceof PyTargetExpressionImpl) {
|
||||
assigned_from = ((PyTargetExpressionImpl)elt).findAssignedValueByStub();
|
||||
assigned_from = ((PyTargetExpressionImpl)elt).findAssignedValueByStub(context);
|
||||
}
|
||||
if (assigned_from instanceof PyReferenceExpression) {
|
||||
if (visited.contains(assigned_from)) {
|
||||
|
||||
@@ -118,7 +118,7 @@ public class PyTargetExpressionImpl extends PyPresentableElementImpl<PyTargetExp
|
||||
return pyType;
|
||||
}
|
||||
if (!context.maySwitchToAST(this)) {
|
||||
final PsiElement value = getStub() != null ? findAssignedValueByStub() : findAssignedValue();
|
||||
final PsiElement value = getStub() != null ? findAssignedValueByStub(context) : findAssignedValue();
|
||||
if (value instanceof PyTypedElement) {
|
||||
return context.getType((PyTypedElement)value);
|
||||
}
|
||||
@@ -438,7 +438,7 @@ public class PyTargetExpressionImpl extends PyPresentableElementImpl<PyTargetExp
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiElement findAssignedValueByStub() {
|
||||
public PsiElement findAssignedValueByStub(@NotNull TypeEvalContext context) {
|
||||
final PyTargetExpressionStub stub = getStub();
|
||||
if (stub != null && stub.getInitializerType() == PyTargetExpressionStub.InitializerType.ReferenceExpression) {
|
||||
final PyQualifiedName initializer = stub.getInitializer();
|
||||
@@ -451,7 +451,7 @@ public class PyTargetExpressionImpl extends PyPresentableElementImpl<PyTargetExp
|
||||
return ((PyFile)parent).getElementNamed(name);
|
||||
}
|
||||
else if (parent instanceof PyClass) {
|
||||
final PyType type = TypeEvalContext.codeInsightFallback().getType((PyClass)parent);
|
||||
final PyType type = context.getType((PyClass)parent);
|
||||
if (type != null) {
|
||||
final List<? extends RatedResolveResult> results = type.resolveMember(name, null, AccessDirection.READ,
|
||||
PyResolveContext.noImplicits());
|
||||
|
||||
@@ -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<? extends RatedResolveResult> result = refType.resolveMember(referencedName, null, AccessDirection.READ,
|
||||
PyResolveContext.defaultContext());
|
||||
final List<? extends RatedResolveResult> result = refType.resolveMember(referencedName, null, AccessDirection.READ, resolveContext);
|
||||
if (result != null && !result.isEmpty()) {
|
||||
return result.get(0).getElement();
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user