diff --git a/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaSuperMethodsSearchExecutor.java b/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaSuperMethodsSearchExecutor.java index d718332f3b8d..9b6e3713a697 100644 --- a/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaSuperMethodsSearchExecutor.java +++ b/python/pluginSrc/com/jetbrains/python/psi/impl/PyJavaSuperMethodsSearchExecutor.java @@ -36,7 +36,7 @@ public class PyJavaSuperMethodsSearchExecutor implements QueryExecutor + * This class created to support hash/equals for context. + * + * @author Ilya.Kazakevich + */ +@SuppressWarnings("PackageVisibleField") + // This is an utility class to be used only in package. Fields are open to type less code +class TypeEvalConstraints { + final boolean myAllowDataFlow; + final boolean myAllowStubToAST; + @Nullable final PsiFile myOrigin; + + /** + * @see com.jetbrains.python.psi.types.TypeEvalContext + */ + TypeEvalConstraints(final boolean allowDataFlow, final boolean allowStubToAST, @Nullable final PsiFile origin) { + myAllowDataFlow = allowDataFlow; + myAllowStubToAST = allowStubToAST; + myOrigin = origin; + } + + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof TypeEvalConstraints)) return false; + + TypeEvalConstraints that = (TypeEvalConstraints)o; + + if (myAllowDataFlow != that.myAllowDataFlow) return false; + if (myAllowStubToAST != that.myAllowStubToAST) return false; + if (myOrigin != null ? !myOrigin.equals(that.myOrigin) : that.myOrigin != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = (myAllowDataFlow ? 1 : 0); + result = 31 * result + (myAllowStubToAST ? 1 : 0); + result = 31 * result + (myOrigin != null ? myOrigin.hashCode() : 0); + return result; + } +} diff --git a/python/psi-api/src/com/jetbrains/python/psi/types/TypeEvalContext.java b/python/psi-api/src/com/jetbrains/python/psi/types/TypeEvalContext.java index f3c688bc88ae..6cd720be6dc2 100644 --- a/python/psi-api/src/com/jetbrains/python/psi/types/TypeEvalContext.java +++ b/python/psi-api/src/com/jetbrains/python/psi/types/TypeEvalContext.java @@ -15,6 +15,7 @@ */ package com.jetbrains.python.psi.types; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; @@ -29,17 +30,25 @@ import java.util.*; * @author yole */ public class TypeEvalContext { + /** + * Contexts are cached here to prevent useless recreations (and cache loss) + */ + @NotNull + private static final TypeEvalContextCache CACHE = new TypeEvalContextCache(); + public static class Key { private static final Key INSTANCE = new Key(); - private Key() {} + private Key() { + } } - private final boolean myAllowDataFlow; - private final boolean myAllowStubToAST; + @NotNull + private final TypeEvalConstraints myConstraints; + + private List myTrace; private String myTraceIndent = ""; - @Nullable private final PsiFile myOrigin; private final Map myEvaluated = new HashMap(); private final Map myEvaluatedReturn = new HashMap(); @@ -57,63 +66,70 @@ public class TypeEvalContext { }; private TypeEvalContext(boolean allowDataFlow, boolean allowStubToAST, @Nullable PsiFile origin) { - myAllowDataFlow = allowDataFlow; - myAllowStubToAST = allowStubToAST; - myOrigin = origin; + myConstraints = new TypeEvalConstraints(allowDataFlow, allowStubToAST, origin); } @Override public String toString() { - return String.format("TypeEvalContext(%b, %b, %s)", myAllowDataFlow, myAllowStubToAST, myOrigin); + return String + .format("TypeEvalContext(%b, %b, %s)", myConstraints.myAllowDataFlow, myConstraints.myAllowStubToAST, myConstraints.myOrigin); } public boolean allowDataFlow(PsiElement element) { - return myAllowDataFlow || element.getContainingFile() == myOrigin; + return myConstraints.myAllowDataFlow || element.getContainingFile() == myConstraints.myOrigin; } public boolean allowReturnTypes(PsiElement element) { - return myAllowDataFlow || element.getContainingFile() == myOrigin; + return myConstraints.myAllowDataFlow || element.getContainingFile() == myConstraints.myOrigin; } public boolean allowLocalUsages(@NotNull PsiElement element) { - return myAllowStubToAST && myAllowDataFlow && element.getContainingFile() == myOrigin; + return myConstraints.myAllowStubToAST && myConstraints.myAllowDataFlow && element.getContainingFile() == myConstraints.myOrigin; } /** * Create the most detailed type evaluation context for user-initiated actions. - * + *

* Should be used for code completion, go to definition, find usages, refactorings, documentation. */ - public static TypeEvalContext userInitiated(@Nullable PsiFile origin) { - return new TypeEvalContext(true, true, origin); + public static TypeEvalContext userInitiated(@NotNull final Project project, @Nullable final PsiFile origin) { + return CACHE.getContext(project, new TypeEvalContext(true, true, origin)); } /** * Create a type evaluation context for performing analysis operations on the specified file which is currently open in the editor, * without accessing stubs. For such a file, additional slow operations are allowed. - * + *

* Inspections should not create a new type evaluation context. They should re-use the context of the inspection session. */ - public static TypeEvalContext codeAnalysis(@Nullable PsiFile origin) { - return new TypeEvalContext(false, false, origin); + public static TypeEvalContext codeAnalysis(@NotNull final Project project, @Nullable final PsiFile origin) { + return CACHE.getContext(project, new TypeEvalContext(false, false, origin)); } /** * Create the most shallow type evaluation context for code insight purposes when other more detailed contexts are not available. - * * It's use should be minimized. + *

+ *

+ * + * @param project pass project here to enable cache. Pass null if you do not have any project. + * Always do your best to pass project here: it increases performance! */ - public static TypeEvalContext codeInsightFallback() { - return new TypeEvalContext(false, false, null); + public static TypeEvalContext codeInsightFallback(@Nullable final Project project) { + final TypeEvalContext anchor = new TypeEvalContext(false, false, null); + if (project != null) { + return CACHE.getContext(project, anchor); + } + return anchor; } /** * Create a type evaluation context for deeper and slower code insight. - * + *

* Should be used only when normal code insight context is not enough for getting good results. */ - public static TypeEvalContext deepCodeInsight() { - return new TypeEvalContext(false, true, null); + public static TypeEvalContext deepCodeInsight(@NotNull final Project project) { + return CACHE.getContext(project, new TypeEvalContext(false, true, null)); } public TypeEvalContext withTracing() { @@ -137,7 +153,7 @@ public class TypeEvalContext { public void traceUnindent() { if (myTrace != null && myTraceIndent.length() >= 2) { - myTraceIndent = myTraceIndent.substring(0, myTraceIndent.length()-2); + myTraceIndent = myTraceIndent.substring(0, myTraceIndent.length() - 2); } } @@ -210,11 +226,19 @@ public class TypeEvalContext { } public boolean maySwitchToAST(@NotNull PsiElement element) { - return myAllowStubToAST || myOrigin == element.getContainingFile(); + return myConstraints.myAllowStubToAST || myConstraints.myOrigin == element.getContainingFile(); } @Nullable public PsiFile getOrigin() { - return myOrigin; + return myConstraints.myOrigin; + } + + /** + * @return context constraints (see {@link com.jetbrains.python.psi.types.TypeEvalConstraints} + */ + @NotNull + TypeEvalConstraints getConstraints() { + return myConstraints; } } diff --git a/python/psi-api/src/com/jetbrains/python/psi/types/TypeEvalContextCache.java b/python/psi-api/src/com/jetbrains/python/psi/types/TypeEvalContextCache.java new file mode 100644 index 000000000000..217bb26c1bd1 --- /dev/null +++ b/python/psi-api/src/com/jetbrains/python/psi/types/TypeEvalContextCache.java @@ -0,0 +1,71 @@ +package com.jetbrains.python.psi.types; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.util.PsiModificationTracker; +import com.intellij.psi.util.PsiModificationTracker.SERVICE; +import org.jetbrains.annotations.NotNull; + +import java.util.HashMap; +import java.util.Map; + +/** + * Caches context by their constraints (to prevent context cache loss). Flushes cache every PSI change. + * Class is thread safe. + * See {@link #getContext(com.intellij.openapi.project.Project, TypeEvalContext)} + * + * @author Ilya.Kazakevich + */ +class TypeEvalContextCache { + /** + * Cache itself. + */ + @NotNull + private final Map myCache = new HashMap(); + /** + * Current PSI modification count + */ + private long myModificationCount = -1; + /** + * Lock to sync + */ + @NotNull + private final Object myLock = new Object(); + + + /** + * Returns context from cache (if exist) or returns the one you provided (and puts it into cache). + * To use this method, do the following: + *

    + *
  1. Instantiate {@link com.jetbrains.python.psi.types.TypeEvalContext} you want to use
  2. + *
  3. Pass its instance here as argument
  4. + *
  5. Use result
  6. + *
+ * + * @param project project is required for caching engine + * @param standard context you want to use. Just instantiate it and pass here. + * @return context from cache (the one equals by constraints to yours or the one you provided) + */ + @NotNull + TypeEvalContext getContext(@NotNull final Project project, @NotNull final TypeEvalContext standard) { + final PsiModificationTracker tracker = SERVICE.getInstance(project); + synchronized (myLock) { + final long currentCount = tracker.getOutOfCodeBlockModificationCount(); + if (currentCount == myModificationCount) { + // Cache is valid, use it + final TypeEvalContext valueFromCache = myCache.get(standard.getConstraints()); + if (valueFromCache != null) { + // We have element in cache, return it + return valueFromCache; + } + } + else { + // Cache is invalid, flush it and store current count + myCache.clear(); + myModificationCount = currentCount; + } + // We do not have value in cache (or cache is invalid), put it + myCache.put(standard.getConstraints(), standard); + return standard; + } + } +} diff --git a/python/src/com/jetbrains/python/PyParameterInfoHandler.java b/python/src/com/jetbrains/python/PyParameterInfoHandler.java index 5aec4444193b..7252014da211 100644 --- a/python/src/com/jetbrains/python/PyParameterInfoHandler.java +++ b/python/src/com/jetbrains/python/PyParameterInfoHandler.java @@ -54,7 +54,7 @@ public class PyParameterInfoHandler implements ParameterInfoHandler parameters = new ArrayList(); Pair quotes = Pair.create("\"", "\""); boolean quotesDetected = false; - final TypeEvalContext context = TypeEvalContext.userInitiated(file); + final TypeEvalContext context = TypeEvalContext.userInitiated(file.getProject(), file); int paramCount = 0; boolean isUnicode = false; final PyClassTypeImpl unicodeType = PyBuiltinCache.getInstance(element).getObjectType("unicode"); diff --git a/python/src/com/jetbrains/python/codeInsight/intentions/TypeAssertionIntention.java b/python/src/com/jetbrains/python/codeInsight/intentions/TypeAssertionIntention.java index 6165e8144c58..0858632e2234 100644 --- a/python/src/com/jetbrains/python/codeInsight/intentions/TypeAssertionIntention.java +++ b/python/src/com/jetbrains/python/codeInsight/intentions/TypeAssertionIntention.java @@ -75,7 +75,7 @@ public class TypeAssertionIntention implements IntentionAction { (reference != null && reference.resolve() == null)) { return false; } - final PyType type = TypeEvalContext.codeAnalysis(file).getType(problemElement); + final PyType type = TypeEvalContext.codeAnalysis(file.getProject(), file).getType(problemElement); return type == null; } diff --git a/python/src/com/jetbrains/python/codeInsight/intentions/TypeIntention.java b/python/src/com/jetbrains/python/codeInsight/intentions/TypeIntention.java index b39af5873d0a..0486c6be86cd 100644 --- a/python/src/com/jetbrains/python/codeInsight/intentions/TypeIntention.java +++ b/python/src/com/jetbrains/python/codeInsight/intentions/TypeIntention.java @@ -180,7 +180,7 @@ public abstract class TypeIntention implements IntentionAction { } protected PyResolveContext getResolveContext(@NotNull PsiElement origin) { - return PyResolveContext.defaultContext().withTypeEvalContext(TypeEvalContext.codeAnalysis(origin.getContainingFile())); + return PyResolveContext.defaultContext().withTypeEvalContext(TypeEvalContext.codeAnalysis(origin.getProject(), origin.getContainingFile())); } public boolean startInWriteAction() { diff --git a/python/src/com/jetbrains/python/codeInsight/liveTemplates/PyIterableVariableMacro.java b/python/src/com/jetbrains/python/codeInsight/liveTemplates/PyIterableVariableMacro.java index 68eec70b4477..d3039e1eab22 100644 --- a/python/src/com/jetbrains/python/codeInsight/liveTemplates/PyIterableVariableMacro.java +++ b/python/src/com/jetbrains/python/codeInsight/liveTemplates/PyIterableVariableMacro.java @@ -84,7 +84,7 @@ public class PyIterableVariableMacro extends Macro { @NotNull protected List getIterableElements(@NotNull PsiElement element) { - final TypeEvalContext typeEvalContext = TypeEvalContext.userInitiated(element.getContainingFile()); + final TypeEvalContext typeEvalContext = TypeEvalContext.userInitiated(element.getProject(), element.getContainingFile()); final List components = new ArrayList(); for (PsiNamedElement namedElement : getVisibleNamedElements(element)) { if (namedElement instanceof PyTypedElement) { diff --git a/python/src/com/jetbrains/python/codeInsight/override/PyMethodMember.java b/python/src/com/jetbrains/python/codeInsight/override/PyMethodMember.java index 9630b8b25f91..b203010f7faf 100644 --- a/python/src/com/jetbrains/python/codeInsight/override/PyMethodMember.java +++ b/python/src/com/jetbrains/python/codeInsight/override/PyMethodMember.java @@ -36,7 +36,7 @@ public class PyMethodMember extends PsiElementMemberChooserObject implements Cla private final String myFullName; private static String buildNameFor(final PyElement element) { if (element instanceof PyFunction) { - final TypeEvalContext context = TypeEvalContext.userInitiated(element.getContainingFile()); + final TypeEvalContext context = TypeEvalContext.userInitiated(element.getProject(), element.getContainingFile()); final List parameters = PyUtil.getParameters((PyFunction)element, context); return element.getName() + "(" + StringUtil.join(parameters, new Function() { @Override diff --git a/python/src/com/jetbrains/python/codeInsight/override/PyOverrideImplementUtil.java b/python/src/com/jetbrains/python/codeInsight/override/PyOverrideImplementUtil.java index 634eaf9a59c9..439945b75726 100644 --- a/python/src/com/jetbrains/python/codeInsight/override/PyOverrideImplementUtil.java +++ b/python/src/com/jetbrains/python/codeInsight/override/PyOverrideImplementUtil.java @@ -193,7 +193,7 @@ public class PyOverrideImplementUtil { if (anno != null) { pyFunctionBuilder.annotation(anno.getText()); } - final TypeEvalContext context = TypeEvalContext.userInitiated(baseFunction.getContainingFile()); + final TypeEvalContext context = TypeEvalContext.userInitiated(baseFunction.getProject(), baseFunction.getContainingFile()); final List baseParams = PyUtil.getParameters(baseFunction, context); for (PyParameter parameter : baseParams) { pyFunctionBuilder.parameter(parameter.getText()); diff --git a/python/src/com/jetbrains/python/codeInsight/userSkeletons/PyUserSkeletonsUtil.java b/python/src/com/jetbrains/python/codeInsight/userSkeletons/PyUserSkeletonsUtil.java index ef13600bfa43..73b1077336c0 100644 --- a/python/src/com/jetbrains/python/codeInsight/userSkeletons/PyUserSkeletonsUtil.java +++ b/python/src/com/jetbrains/python/codeInsight/userSkeletons/PyUserSkeletonsUtil.java @@ -159,7 +159,8 @@ public class PyUserSkeletonsUtil { assert owner != element; final PsiElement originalOwner = getUserSkeleton(owner, skeletonFile); if (originalOwner instanceof PyClass) { - final PyType type = TypeEvalContext.codeInsightFallback().getType((PyClass)originalOwner); + final PyClass classOwner = (PyClass)originalOwner; + final PyType type = TypeEvalContext.codeInsightFallback(classOwner.getProject()).getType(classOwner); if (type instanceof PyClassLikeType) { final PyClassLikeType classType = (PyClassLikeType)type; final PyClassLikeType instanceType = classType.toInstance(); diff --git a/python/src/com/jetbrains/python/documentation/DocStringTypeReference.java b/python/src/com/jetbrains/python/documentation/DocStringTypeReference.java index 92771e70cf5c..65ecc8d9bca3 100644 --- a/python/src/com/jetbrains/python/documentation/DocStringTypeReference.java +++ b/python/src/com/jetbrains/python/documentation/DocStringTypeReference.java @@ -132,7 +132,7 @@ public class DocStringTypeReference extends PsiPolyVariantReferenceBase cat = new ChainIterable(); final String name = fun.getName(); cat.addItem("def ").addWith(func_name_wrapper, $(name)); - final TypeEvalContext context = TypeEvalContext.userInitiated(fun.getContainingFile()); + final TypeEvalContext context = TypeEvalContext.userInitiated(fun.getProject(), fun.getContainingFile()); final List parameters = PyUtil.getParameters(fun, context); final String paramStr = "(" + StringUtil.join(parameters, @@ -195,12 +195,12 @@ public class PythonDocumentationProvider extends AbstractDocumentationProvider i } static String describeType(@NotNull PyTypedElement element) { - final TypeEvalContext context = TypeEvalContext.userInitiated(element.getContainingFile()); + final TypeEvalContext context = TypeEvalContext.userInitiated(element.getProject(), element.getContainingFile()); return String.format("Inferred type: %s", getTypeName(context.getType(element), context)); } public static void getTypeDescription(@NotNull PyFunction fun, ChainIterable body) { - final TypeEvalContext context = TypeEvalContext.userInitiated(fun.getContainingFile()); + final TypeEvalContext context = TypeEvalContext.userInitiated(fun.getProject(), fun.getContainingFile()); PyTypeModelBuilder builder = new PyTypeModelBuilder(context); builder.build(context.getType(fun), true).toBodyWithLinks(body, fun); } @@ -524,7 +524,7 @@ public class PythonDocumentationProvider extends AbstractDocumentationProvider i @Nullable private static PyClass inferClassOfParameter(PsiElement context) { if (context instanceof PyNamedParameter) { - final PyType type = TypeEvalContext.userInitiated(context.getContainingFile()).getType((PyNamedParameter)context); + final PyType type = TypeEvalContext.userInitiated(context.getProject(), context.getContainingFile()).getType((PyNamedParameter)context); if (type instanceof PyClassType) { return ((PyClassType)type).getPyClass(); } @@ -594,7 +594,7 @@ public class PythonDocumentationProvider extends AbstractDocumentationProvider i //TODO: this code duplicates PyDocstringGenerator in some parts final StringBuilder builder = new StringBuilder(offset); - final TypeEvalContext context = TypeEvalContext.userInitiated(function.getContainingFile()); + final TypeEvalContext context = TypeEvalContext.userInitiated(function.getProject(), function.getContainingFile()); PySignature signature = PySignatureCacheManager.getInstance(function.getProject()).findSignature(function); final PyDecoratorList decoratorList = function.getDecoratorList(); final PyDecorator classMethod = decoratorList == null ? null : decoratorList.findDecorator(PyNames.CLASSMETHOD); diff --git a/python/src/com/jetbrains/python/findUsages/PyUsageTypeProvider.java b/python/src/com/jetbrains/python/findUsages/PyUsageTypeProvider.java index 6e4204bce627..1578ba85ae20 100644 --- a/python/src/com/jetbrains/python/findUsages/PyUsageTypeProvider.java +++ b/python/src/com/jetbrains/python/findUsages/PyUsageTypeProvider.java @@ -53,7 +53,7 @@ public class PyUsageTypeProvider implements UsageTypeProviderEx { if (element instanceof PyQualifiedExpression) { final PyExpression qualifier = ((PyQualifiedExpression)element).getQualifier(); if (qualifier != null) { - final TypeEvalContext context = TypeEvalContext.userInitiated(element.getContainingFile()); + final TypeEvalContext context = TypeEvalContext.userInitiated(element.getProject(), element.getContainingFile()); final PyType type = context.getType(qualifier); if (type == null) { final PyCallExpression call = PsiTreeUtil.getParentOfType(element, PyCallExpression.class); diff --git a/python/src/com/jetbrains/python/inspections/PyCompatibilityInspection.java b/python/src/com/jetbrains/python/inspections/PyCompatibilityInspection.java index 0f69f4f72a56..c2f2dfa2b61b 100644 --- a/python/src/com/jetbrains/python/inspections/PyCompatibilityInspection.java +++ b/python/src/com/jetbrains/python/inspections/PyCompatibilityInspection.java @@ -302,7 +302,7 @@ public class PyCompatibilityInspection extends PyInspection { public void visitPyReferenceExpression(PyReferenceExpression node) { super.visitPyElement(node); if (shouldBeCompatibleWithPy3()) { - final TypeEvalContext context = TypeEvalContext.codeAnalysis(node.getContainingFile()); + final TypeEvalContext context = TypeEvalContext.codeAnalysis(node.getProject(), node.getContainingFile()); final String nodeText = node.getText(); if (nodeText.endsWith("iteritems") || nodeText.endsWith("iterkeys") || nodeText.endsWith("itervalues")) { final PyExpression qualifier = node.getQualifier(); diff --git a/python/src/com/jetbrains/python/inspections/PyInspectionVisitor.java b/python/src/com/jetbrains/python/inspections/PyInspectionVisitor.java index 6c86e72b1bcd..775bc8b69fab 100644 --- a/python/src/com/jetbrains/python/inspections/PyInspectionVisitor.java +++ b/python/src/com/jetbrains/python/inspections/PyInspectionVisitor.java @@ -21,6 +21,7 @@ import com.intellij.openapi.util.Key; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiErrorElement; +import com.intellij.psi.PsiFile; import com.jetbrains.python.psi.PyElementVisitor; import com.jetbrains.python.psi.resolve.PyResolveContext; import com.jetbrains.python.psi.types.TypeEvalContext; @@ -45,7 +46,8 @@ public abstract class PyInspectionVisitor extends PyElementVisitor { synchronized (INSPECTION_TYPE_EVAL_CONTEXT) { context = session.getUserData(INSPECTION_TYPE_EVAL_CONTEXT); if (context == null) { - context = TypeEvalContext.codeAnalysis(session.getFile()); + PsiFile file = session.getFile(); + context = TypeEvalContext.codeAnalysis(file.getProject(), file); session.putUserData(INSPECTION_TYPE_EVAL_CONTEXT, context); } } diff --git a/python/src/com/jetbrains/python/inspections/quickfix/AddFieldQuickFix.java b/python/src/com/jetbrains/python/inspections/quickfix/AddFieldQuickFix.java index 367f22b0540c..49f84e85ec7a 100644 --- a/python/src/com/jetbrains/python/inspections/quickfix/AddFieldQuickFix.java +++ b/python/src/com/jetbrains/python/inspections/quickfix/AddFieldQuickFix.java @@ -118,7 +118,7 @@ public class AddFieldQuickFix implements LocalQuickFix { if (element instanceof PyQualifiedExpression) { final PyExpression qualifier = ((PyQualifiedExpression)element).getQualifier(); if (qualifier == null) return null; - final PyType type = TypeEvalContext.userInitiated(element.getContainingFile()).getType(qualifier); + final PyType type = TypeEvalContext.userInitiated(element.getProject(), element.getContainingFile()).getType(qualifier); return type instanceof PyClassType ? (PyClassType)type : null; } final PyClass aClass = PsiTreeUtil.getParentOfType(element, PyClass.class); diff --git a/python/src/com/jetbrains/python/inspections/quickfix/AddFunctionQuickFix.java b/python/src/com/jetbrains/python/inspections/quickfix/AddFunctionQuickFix.java index 69106cc057d3..bd5db4c02361 100644 --- a/python/src/com/jetbrains/python/inspections/quickfix/AddFunctionQuickFix.java +++ b/python/src/com/jetbrains/python/inspections/quickfix/AddFunctionQuickFix.java @@ -78,7 +78,7 @@ public class AddFunctionQuickFix implements LocalQuickFix { if (!(problemElement instanceof PyQualifiedExpression)) return; final PyExpression qualifier = ((PyQualifiedExpression)problemElement).getQualifier(); if (qualifier == null) return; - final PyType type = TypeEvalContext.userInitiated(problemElement.getContainingFile()).getType(qualifier); + final PyType type = TypeEvalContext.userInitiated(problemElement.getProject(), problemElement.getContainingFile()).getType(qualifier); if (!(type instanceof PyModuleType)) return; final PyFile file = ((PyModuleType)type).getModule(); sure(file); diff --git a/python/src/com/jetbrains/python/inspections/quickfix/AddMethodQuickFix.java b/python/src/com/jetbrains/python/inspections/quickfix/AddMethodQuickFix.java index 9924292ad906..beac24e00501 100644 --- a/python/src/com/jetbrains/python/inspections/quickfix/AddMethodQuickFix.java +++ b/python/src/com/jetbrains/python/inspections/quickfix/AddMethodQuickFix.java @@ -96,7 +96,7 @@ public class AddMethodQuickFix implements LocalQuickFix { boolean madeInstance = false; if (callByClass) { if (args.length > 0) { - PyType firstArgType = TypeEvalContext.userInitiated(cls.getContainingFile()).getType(args[0]); + PyType firstArgType = TypeEvalContext.userInitiated(cls.getProject(), cls.getContainingFile()).getType(args[0]); if (firstArgType instanceof PyClassType && ((PyClassType)firstArgType).getPyClass().isSubclass(cls)) { // class, first arg ok: instance method builder.parameter("self"); // NOTE: might use a name other than 'self', according to code style. @@ -151,7 +151,7 @@ public class AddMethodQuickFix implements LocalQuickFix { if ((problemElement instanceof PyQualifiedExpression)) { final PyExpression qualifier = ((PyQualifiedExpression)problemElement).getQualifier(); if (qualifier == null) return null; - final PyType type = TypeEvalContext.userInitiated(problemElement.getContainingFile()).getType(qualifier); + final PyType type = TypeEvalContext.userInitiated(problemElement.getProject(), problemElement.getContainingFile()).getType(qualifier); return type instanceof PyClassType ? (PyClassType)type : null; } final PyClass pyClass = PsiTreeUtil.getParentOfType(problemElement, PyClass.class); diff --git a/python/src/com/jetbrains/python/inspections/quickfix/PyAddSpecifierToFormatQuickFix.java b/python/src/com/jetbrains/python/inspections/quickfix/PyAddSpecifierToFormatQuickFix.java index 6d40f31bfb77..8590c2d51190 100644 --- a/python/src/com/jetbrains/python/inspections/quickfix/PyAddSpecifierToFormatQuickFix.java +++ b/python/src/com/jetbrains/python/inspections/quickfix/PyAddSpecifierToFormatQuickFix.java @@ -65,7 +65,7 @@ public class PyAddSpecifierToFormatQuickFix implements LocalQuickFix { final Document document = FileDocumentManager.getInstance().getDocument(file.getVirtualFile()); if (document == null) return; final int offset = element.getTextOffset(); - final TypeEvalContext context = TypeEvalContext.userInitiated(file); + final TypeEvalContext context = TypeEvalContext.userInitiated(file.getProject(), file); final PyClassType strType = PyBuiltinCache.getInstance(element).getStrType(); final PyClassType floatType = PyBuiltinCache.getInstance(element).getFloatType(); diff --git a/python/src/com/jetbrains/python/inspections/quickfix/PyCreatePropertyQuickFix.java b/python/src/com/jetbrains/python/inspections/quickfix/PyCreatePropertyQuickFix.java index f88652aa1a12..89b4fd531fa5 100644 --- a/python/src/com/jetbrains/python/inspections/quickfix/PyCreatePropertyQuickFix.java +++ b/python/src/com/jetbrains/python/inspections/quickfix/PyCreatePropertyQuickFix.java @@ -50,7 +50,7 @@ public class PyCreatePropertyQuickFix implements LocalQuickFix { if (element instanceof PyQualifiedExpression) { final PyExpression qualifier = ((PyQualifiedExpression)element).getQualifier(); if (qualifier != null) { - final PyType type = TypeEvalContext.codeAnalysis(element.getContainingFile()).getType(qualifier); + final PyType type = TypeEvalContext.codeAnalysis(element.getProject(), element.getContainingFile()).getType(qualifier); if (type instanceof PyClassType) { final PyClass cls = ((PyClassType)type).getPyClass(); final String propertyName = ((PyQualifiedExpression)element).getName(); diff --git a/python/src/com/jetbrains/python/patterns/PythonPatterns.java b/python/src/com/jetbrains/python/patterns/PythonPatterns.java index 1ce1d7585220..213bf6380e4f 100644 --- a/python/src/com/jetbrains/python/patterns/PythonPatterns.java +++ b/python/src/com/jetbrains/python/patterns/PythonPatterns.java @@ -108,7 +108,7 @@ public class PythonPatterns extends PlatformPatterns { // TODO is it better or worse to allow implicits here? PyResolveContext context = PyResolveContext.noImplicits() - .withTypeEvalContext(TypeEvalContext.codeAnalysis(expression.getContainingFile())); + .withTypeEvalContext(TypeEvalContext.codeAnalysis(expression.getProject(), expression.getContainingFile())); PyCallExpression.PyMarkedCallee callee = call.resolveCallee(context); return callee != null ? callee.getCallable() : null; diff --git a/python/src/com/jetbrains/python/psi/PyUtil.java b/python/src/com/jetbrains/python/psi/PyUtil.java index dc8787328554..1518b3410f11 100644 --- a/python/src/com/jetbrains/python/psi/PyUtil.java +++ b/python/src/com/jetbrains/python/psi/PyUtil.java @@ -1209,7 +1209,7 @@ public class PyUtil { if (isBaseException(pyClass.getQualifiedName())) { return true; } - for (PyClassLikeType type : pyClass.getAncestorTypes(TypeEvalContext.codeInsightFallback())) { + for (PyClassLikeType type : pyClass.getAncestorTypes(TypeEvalContext.codeInsightFallback(pyClass.getProject()))) { if (type != null && isBaseException(type.getClassQName())) { return true; } diff --git a/python/src/com/jetbrains/python/psi/impl/PyBaseElementImpl.java b/python/src/com/jetbrains/python/psi/impl/PyBaseElementImpl.java index bd3170321650..fd533068b8d0 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyBaseElementImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyBaseElementImpl.java @@ -148,7 +148,7 @@ public class PyBaseElementImpl extends StubBasedPsiElemen List referencesList = new ArrayList(); final PsiFile file = element.getContainingFile(); final PyResolveContext resolveContext = file != null ? - PyResolveContext.defaultContext().withTypeEvalContext(TypeEvalContext.codeAnalysis(file)) : + PyResolveContext.defaultContext().withTypeEvalContext(TypeEvalContext.codeAnalysis(file.getProject(), file)) : PyResolveContext.defaultContext(); while (element != null) { addReferences(offset, element, referencesList, resolveContext); diff --git a/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java b/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java index c7f2173973c0..ad815a9fcb3e 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java @@ -201,7 +201,7 @@ public class PyClassImpl extends PyBaseElementImpl implements PyCla @NotNull @Override public List getAncestorClasses() { - return getAncestorClasses(TypeEvalContext.codeInsightFallback()); + return getAncestorClasses(TypeEvalContext.codeInsightFallback(getProject())); } @NotNull @@ -231,7 +231,7 @@ public class PyClassImpl extends PyBaseElementImpl implements PyCla if (superClassQName.equals(getQualifiedName())) { return true; } - for (PyClassLikeType type : getAncestorTypes(TypeEvalContext.codeInsightFallback())) { + for (PyClassLikeType type : getAncestorTypes(TypeEvalContext.codeInsightFallback(getProject()))) { if (type != null && superClassQName.equals(type.getClassQName())) { return true; } @@ -279,7 +279,7 @@ public class PyClassImpl extends PyBaseElementImpl implements PyCla @NotNull public PyClass[] getSuperClasses() { - final List superTypes = getSuperClassTypes(TypeEvalContext.codeInsightFallback()); + final List superTypes = getSuperClassTypes(TypeEvalContext.codeInsightFallback(getProject())); if (superTypes.isEmpty()) { return EMPTY_ARRAY; } @@ -1033,7 +1033,7 @@ public class PyClassImpl extends PyBaseElementImpl implements PyCla final PyClass objClass = PyBuiltinCache.getInstance(this).getClass("object"); if (this == objClass) return true; // a rare but possible case if (hasNewStyleMetaClass(this)) return true; - for (PyClassLikeType type : getOldStyleAncestorTypes(TypeEvalContext.codeInsightFallback())) { + for (PyClassLikeType type : getOldStyleAncestorTypes(TypeEvalContext.codeInsightFallback(getProject()))) { if (type == null) { // unknown, assume new-style class return true; diff --git a/python/src/com/jetbrains/python/psi/impl/references/KeywordArgumentCompletionUtil.java b/python/src/com/jetbrains/python/psi/impl/references/KeywordArgumentCompletionUtil.java index 3e60926c6cff..66bddd1b83a1 100644 --- a/python/src/com/jetbrains/python/psi/impl/references/KeywordArgumentCompletionUtil.java +++ b/python/src/com/jetbrains/python/psi/impl/references/KeywordArgumentCompletionUtil.java @@ -66,7 +66,7 @@ public class KeywordArgumentCompletionUtil { visited.add(def); boolean needSelf = def.getContainingClass() != null && def.getModifier() != PyFunction.Modifier.STATICMETHOD; final KwArgParameterCollector collector = new KwArgParameterCollector(needSelf, ret); - final TypeEvalContext context = TypeEvalContext.userInitiated(def.getContainingFile()); + final TypeEvalContext context = TypeEvalContext.userInitiated(def.getProject(), def.getContainingFile()); final List parameters = PyUtil.getParameters(def, context); for (PyParameter parameter : parameters) { parameter.accept(collector); diff --git a/python/src/com/jetbrains/python/psi/impl/references/PyImportReference.java b/python/src/com/jetbrains/python/psi/impl/references/PyImportReference.java index a3dad0b8eba8..77f5829673bb 100644 --- a/python/src/com/jetbrains/python/psi/impl/references/PyImportReference.java +++ b/python/src/com/jetbrains/python/psi/impl/references/PyImportReference.java @@ -97,7 +97,7 @@ public class PyImportReference extends PyReferenceImpl { } PyExpression qualifier = myElement.getQualifier(); - final TypeEvalContext context = TypeEvalContext.userInitiated(CompletionUtil.getOriginalOrSelf(myElement).getContainingFile()); + final TypeEvalContext context = TypeEvalContext.userInitiated(myElement.getProject(), CompletionUtil.getOriginalOrSelf(myElement).getContainingFile()); if (qualifier != null) { // qualifier's type must be module, it should know how to complete PyType type = context.getType(qualifier); diff --git a/python/src/com/jetbrains/python/psi/impl/references/PyQualifiedReference.java b/python/src/com/jetbrains/python/psi/impl/references/PyQualifiedReference.java index a537dae722c1..60d2905312b3 100644 --- a/python/src/com/jetbrains/python/psi/impl/references/PyQualifiedReference.java +++ b/python/src/com/jetbrains/python/psi/impl/references/PyQualifiedReference.java @@ -260,7 +260,7 @@ public class PyQualifiedReference extends PyReferenceImpl { } final PyQualifiedExpression element = CompletionUtil.getOriginalOrSelf(myElement); - PyType qualifierType = TypeEvalContext.userInitiated(element.getContainingFile()).getType(qualifier); + PyType qualifierType = TypeEvalContext.userInitiated(element.getProject(), element.getContainingFile()).getType(qualifier); ProcessingContext ctx = new ProcessingContext(); final Set namesAlready = new HashSet(); ctx.put(PyType.CTX_NAMES, namesAlready); @@ -415,7 +415,7 @@ public class PyQualifiedReference extends PyReferenceImpl { if (containingFile instanceof StubBasedPsiElement) { assert ((StubBasedPsiElement)containingFile).getStub() == null : "Stub origin for type eval context in isReferenceTo()"; } - final TypeEvalContext context = TypeEvalContext.codeAnalysis(containingFile); + final TypeEvalContext context = TypeEvalContext.codeAnalysis(containingFile.getProject(), containingFile); resolveContext = resolveContext.withTypeEvalContext(context); } if (element instanceof PyFunction && Comparing.equal(referencedName, ((PyFunction)element).getName()) && diff --git a/python/src/com/jetbrains/python/psi/resolve/CompletionVariantsProcessor.java b/python/src/com/jetbrains/python/psi/resolve/CompletionVariantsProcessor.java index bfa402449853..cbc791fbfc60 100644 --- a/python/src/com/jetbrains/python/psi/resolve/CompletionVariantsProcessor.java +++ b/python/src/com/jetbrains/python/psi/resolve/CompletionVariantsProcessor.java @@ -17,6 +17,7 @@ package com.jetbrains.python.psi.resolve; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementBuilder; +import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; @@ -65,8 +66,9 @@ public class CompletionVariantsProcessor extends VariantsProcessor { object instanceof PyFunction && ((PyFunction)object).getProperty() == null && !PyUtil.hasCustomDecorators((PyFunction)object) && !isSingleArgDecoratorCall(myContext, (PyFunction)object)) { + final Project project = ((PyFunction)object).getProject(); item = item.withInsertHandler(PyFunctionInsertHandler.INSTANCE); - final TypeEvalContext context = TypeEvalContext.userInitiated(myContext != null ? myContext.getContainingFile() : null); + final TypeEvalContext context = TypeEvalContext.userInitiated(project, myContext != null ? myContext.getContainingFile() : null); final List parameters = PyUtil.getParameters((PyFunction)object, context); final String params = StringUtil.join(parameters, new Function() { @Override diff --git a/python/src/com/jetbrains/python/psi/types/PyCallableTypeImpl.java b/python/src/com/jetbrains/python/psi/types/PyCallableTypeImpl.java index 520c9b558881..08d0ffd6e84e 100644 --- a/python/src/com/jetbrains/python/psi/types/PyCallableTypeImpl.java +++ b/python/src/com/jetbrains/python/psi/types/PyCallableTypeImpl.java @@ -82,7 +82,7 @@ public class PyCallableTypeImpl implements PyCallableType { @Nullable @Override public String getName() { - final TypeEvalContext context = TypeEvalContext.codeInsightFallback(); + final TypeEvalContext context = TypeEvalContext.codeInsightFallback(null); return String.format("(%s) -> %s", myParameters != null ? StringUtil.join(myParameters, diff --git a/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java b/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java index d9b69121aa50..25b524272b7b 100644 --- a/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java +++ b/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java @@ -25,6 +25,7 @@ import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.UserDataHolderBase; import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; import com.intellij.psi.PsiInvalidElementAccessException; import com.intellij.psi.PsiReference; import com.intellij.psi.util.PsiTreeUtil; @@ -410,9 +411,11 @@ public class PyClassTypeImpl extends UserDataHolderBase implements PyClassType { boolean suppressParentheses = context.get(CTX_SUPPRESS_PARENTHESES) != null; addOwnClassMembers(location, namesAlready, suppressParentheses, ret); - final TypeEvalContext typeEvalContext = TypeEvalContext.userInitiated(location != null ? - CompletionUtil.getOriginalOrSelf(location).getContainingFile() : - null); + PsiFile origin = (location != null) ? + CompletionUtil.getOriginalOrSelf(location) + .getContainingFile() : + null; + final TypeEvalContext typeEvalContext = TypeEvalContext.userInitiated(myClass.getProject(), origin); addInheritedMembers(prefix, location, namesAlready, context, ret, typeEvalContext); // from providers diff --git a/python/src/com/jetbrains/python/psi/types/PyCollectionTypeImpl.java b/python/src/com/jetbrains/python/psi/types/PyCollectionTypeImpl.java index 81efda9e040d..24072ddb74e9 100644 --- a/python/src/com/jetbrains/python/psi/types/PyCollectionTypeImpl.java +++ b/python/src/com/jetbrains/python/psi/types/PyCollectionTypeImpl.java @@ -55,7 +55,7 @@ public class PyCollectionTypeImpl extends PyClassTypeImpl implements PyCollectio PyCollectionType type = (PyCollectionType)o; - final TypeEvalContext context = TypeEvalContext.codeInsightFallback(); + final TypeEvalContext context = TypeEvalContext.codeInsightFallback(myClass.getProject()); if (myElementType != null ? !myElementType.equals(type.getElementType(context)) : type.getElementType(context) != null) return false; return true; diff --git a/python/src/com/jetbrains/python/psi/types/PyDynamicallyEvaluatedType.java b/python/src/com/jetbrains/python/psi/types/PyDynamicallyEvaluatedType.java index 85624b1d0f10..0260b2f84656 100644 --- a/python/src/com/jetbrains/python/psi/types/PyDynamicallyEvaluatedType.java +++ b/python/src/com/jetbrains/python/psi/types/PyDynamicallyEvaluatedType.java @@ -15,6 +15,7 @@ */ package com.jetbrains.python.psi.types; +import com.intellij.openapi.project.Project; import com.jetbrains.python.PyNames; import org.jetbrains.annotations.NotNull; @@ -49,7 +50,7 @@ public class PyDynamicallyEvaluatedType extends PyUnionType { @Override public String getName() { - PyType res = excludeNull(TypeEvalContext.codeInsightFallback()); + PyType res = excludeNull(TypeEvalContext.codeInsightFallback(null)); return res != null ? res.getName() : PyNames.UNKNOWN_TYPE; } } diff --git a/python/src/com/jetbrains/python/psi/types/PyFunctionType.java b/python/src/com/jetbrains/python/psi/types/PyFunctionType.java index fe3633449b74..35ccb2138322 100644 --- a/python/src/com/jetbrains/python/psi/types/PyFunctionType.java +++ b/python/src/com/jetbrains/python/psi/types/PyFunctionType.java @@ -88,7 +88,7 @@ public class PyFunctionType implements PyCallableType { @Override public Object[] getCompletionVariants(String completionPrefix, PsiElement location, ProcessingContext context) { - final TypeEvalContext typeEvalContext = TypeEvalContext.userInitiated(location.getContainingFile()); + final TypeEvalContext typeEvalContext = TypeEvalContext.userInitiated(location.getProject(), location.getContainingFile()); final PyClassType delegate; if (location instanceof PyReferenceExpression) { delegate = selectFakeType(((PyReferenceExpression)location).getQualifier(), typeEvalContext); diff --git a/python/src/com/jetbrains/python/psi/types/PyTypeParser.java b/python/src/com/jetbrains/python/psi/types/PyTypeParser.java index 9e1923218494..114c6469d4c9 100644 --- a/python/src/com/jetbrains/python/psi/types/PyTypeParser.java +++ b/python/src/com/jetbrains/python/psi/types/PyTypeParser.java @@ -343,7 +343,7 @@ public class PyTypeParser { if (file instanceof PyFile) { final PyFile pyFile = (PyFile)file; - final TypeEvalContext context = TypeEvalContext.codeInsightFallback(); + final TypeEvalContext context = TypeEvalContext.codeInsightFallback(file.getProject()); final Map types = new HashMap(); final Map fullRanges = new HashMap(); final Map imports = new HashMap(); diff --git a/python/src/com/jetbrains/python/refactoring/PyReplaceExpressionUtil.java b/python/src/com/jetbrains/python/refactoring/PyReplaceExpressionUtil.java index 6186eafc0905..9a2cb502431b 100644 --- a/python/src/com/jetbrains/python/refactoring/PyReplaceExpressionUtil.java +++ b/python/src/com/jetbrains/python/refactoring/PyReplaceExpressionUtil.java @@ -152,7 +152,7 @@ public class PyReplaceExpressionUtil implements PyElementTypes { return replaceSubstringWithDictFormatting(oldExpression, quotes, prefix, suffix, formatValue, newText); } else { - final TypeEvalContext context = TypeEvalContext.userInitiated(oldExpression.getContainingFile()); + final TypeEvalContext context = TypeEvalContext.userInitiated(oldExpression.getProject(), oldExpression.getContainingFile()); final PyType valueType = context.getType(formatValue); final PyBuiltinCache builtinCache = PyBuiltinCache.getInstance(oldExpression); final PyType tupleType = builtinCache.getTupleType(); diff --git a/python/src/com/jetbrains/python/refactoring/classes/membersManager/MethodsManager.java b/python/src/com/jetbrains/python/refactoring/classes/membersManager/MethodsManager.java index 56bd80ca3077..d3501ec1ea25 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/membersManager/MethodsManager.java +++ b/python/src/com/jetbrains/python/refactoring/classes/membersManager/MethodsManager.java @@ -122,7 +122,7 @@ class MethodsManager extends MembersManager { // TODO: Copy/Paste with PyClass.getMeta.. private static boolean addMetaAbcIfNeeded(@NotNull final PyClass aClass) { final PsiFile file = aClass.getContainingFile(); - final PyType type = aClass.getMetaClassType(TypeEvalContext.userInitiated(file)); + final PyType type = aClass.getMetaClassType(TypeEvalContext.userInitiated(aClass.getProject(), file)); if (type != null) { return false; //User already has metaclass. He probably knows about metaclasses, so we should not add ABCMeta } diff --git a/python/src/com/jetbrains/python/refactoring/classes/pullUp/PyAncestorsUtils.java b/python/src/com/jetbrains/python/refactoring/classes/pullUp/PyAncestorsUtils.java index 05c41c47894a..bc2af5e6f8ef 100644 --- a/python/src/com/jetbrains/python/refactoring/classes/pullUp/PyAncestorsUtils.java +++ b/python/src/com/jetbrains/python/refactoring/classes/pullUp/PyAncestorsUtils.java @@ -45,7 +45,7 @@ class PyAncestorsUtils extends NotNullPredicate { */ @NotNull static Collection getAncestorsUnderUserControl(@NotNull final PyClass pyClass) { - final List allAncestors = pyClass.getAncestorClasses(TypeEvalContext.userInitiated(pyClass.getContainingFile())); + final List allAncestors = pyClass.getAncestorClasses(TypeEvalContext.userInitiated(pyClass.getProject(), pyClass.getContainingFile())); return Collections2.filter(allAncestors, new PyAncestorsUtils(PyUtil.getSourceRoots(pyClass))); } diff --git a/python/src/com/jetbrains/python/refactoring/introduce/IntroduceHandler.java b/python/src/com/jetbrains/python/refactoring/introduce/IntroduceHandler.java index 069f0e596197..27c755b7bcd9 100644 --- a/python/src/com/jetbrains/python/refactoring/introduce/IntroduceHandler.java +++ b/python/src/com/jetbrains/python/refactoring/introduce/IntroduceHandler.java @@ -205,7 +205,7 @@ abstract public class IntroduceHandler implements RefactoringActionHandler { if (text != null) { candidates.addAll(NameSuggesterUtil.generateNames(text)); } - final TypeEvalContext context = TypeEvalContext.userInitiated(expression.getContainingFile()); + final TypeEvalContext context = TypeEvalContext.userInitiated(expression.getProject(), expression.getContainingFile()); PyType type = context.getType(expression); if (type != null && type != PyNoneType.INSTANCE) { String typeName = type.getName(); diff --git a/python/src/com/jetbrains/python/testing/PythonUnitTestUtil.java b/python/src/com/jetbrains/python/testing/PythonUnitTestUtil.java index ef4af733e096..7b7b4a89965d 100644 --- a/python/src/com/jetbrains/python/testing/PythonUnitTestUtil.java +++ b/python/src/com/jetbrains/python/testing/PythonUnitTestUtil.java @@ -82,7 +82,7 @@ public class PythonUnitTestUtil { if (expression.getText().equals("TestCase")) return true; } } - for (PyClassLikeType type : cls.getAncestorTypes(TypeEvalContext.codeInsightFallback())) { + for (PyClassLikeType type : cls.getAncestorTypes(TypeEvalContext.codeInsightFallback(cls.getProject()))) { if (type != null && testQualifiedNames.contains(type.getClassQName())) { return true; } @@ -153,7 +153,7 @@ public class PythonUnitTestUtil { } public static boolean isTestCaseClass(@NotNull PyClass cls, Set testQualifiedNames) { - for (PyClassLikeType type : cls.getAncestorTypes(TypeEvalContext.codeInsightFallback())) { + for (PyClassLikeType type : cls.getAncestorTypes(TypeEvalContext.codeInsightFallback(cls.getProject()))) { if (type != null) { if (testQualifiedNames.contains(type.getClassQName())) { return true; diff --git a/python/src/com/jetbrains/python/testing/attest/PythonAtTestConfigurationProducer.java b/python/src/com/jetbrains/python/testing/attest/PythonAtTestConfigurationProducer.java index 006749a25e96..6035d5b266e1 100644 --- a/python/src/com/jetbrains/python/testing/attest/PythonAtTestConfigurationProducer.java +++ b/python/src/com/jetbrains/python/testing/attest/PythonAtTestConfigurationProducer.java @@ -51,7 +51,7 @@ public class PythonAtTestConfigurationProducer extends @Override protected boolean isTestClass(@NotNull final PyClass pyClass, @Nullable final AbstractPythonTestRunConfiguration configuration) { - for (PyClassLikeType type : pyClass.getAncestorTypes(TypeEvalContext.codeInsightFallback())) { + for (PyClassLikeType type : pyClass.getAncestorTypes(TypeEvalContext.codeInsightFallback(pyClass.getProject()))) { if (type != null && "TestBase".equals(type.getName()) && hasTestFunction(pyClass)) { return true; } diff --git a/python/src/com/jetbrains/python/testing/pytest/PyTestUtil.java b/python/src/com/jetbrains/python/testing/pytest/PyTestUtil.java index 357227532727..11dfb4fb0e5c 100644 --- a/python/src/com/jetbrains/python/testing/pytest/PyTestUtil.java +++ b/python/src/com/jetbrains/python/testing/pytest/PyTestUtil.java @@ -71,7 +71,7 @@ public class PyTestUtil { } public static boolean isPyTestClass(PyClass pyClass) { - for (PyClassLikeType type : pyClass.getAncestorTypes(TypeEvalContext.codeInsightFallback())) { + for (PyClassLikeType type : pyClass.getAncestorTypes(TypeEvalContext.codeInsightFallback(pyClass.getProject()))) { if (type != null && PYTHON_TEST_QUALIFIED_CLASSES.contains(type.getClassQName())) { return true; } diff --git a/python/testSrc/com/jetbrains/env/python/PythonSkeletonsTest.java b/python/testSrc/com/jetbrains/env/python/PythonSkeletonsTest.java index c6b150f31359..325482d23911 100644 --- a/python/testSrc/com/jetbrains/env/python/PythonSkeletonsTest.java +++ b/python/testSrc/com/jetbrains/env/python/PythonSkeletonsTest.java @@ -126,7 +126,8 @@ public class PythonSkeletonsTest extends PyEnvTestCase { myFixture.configureByText(PythonFileType.INSTANCE, "expr = slice(1, 2).start\n"); final PyExpression expr = myFixture.findElementByText("expr", PyExpression.class); - final TypeEvalContext context = TypeEvalContext.codeAnalysis(myFixture.getFile()); + PsiFile file = myFixture.getFile(); + final TypeEvalContext context = TypeEvalContext.codeAnalysis(file.getProject(), file); ApplicationManager.getApplication().runReadAction(new Runnable() { @Override public void run() { diff --git a/python/testSrc/com/jetbrains/python/PyClassicPropertyTest.java b/python/testSrc/com/jetbrains/python/PyClassicPropertyTest.java index 2e55003cddd0..71d2498b39f8 100644 --- a/python/testSrc/com/jetbrains/python/PyClassicPropertyTest.java +++ b/python/testSrc/com/jetbrains/python/PyClassicPropertyTest.java @@ -95,7 +95,7 @@ public class PyClassicPropertyTest extends PyTestCase { accessor = p.getGetter(); assertFalse(accessor.isDefined()); - final PyType codeInsightType = p.getType(TypeEvalContext.codeInsightFallback()); + final PyType codeInsightType = p.getType(TypeEvalContext.codeInsightFallback(myClass.getProject())); assertNull(codeInsightType); accessor = p.getSetter(); diff --git a/python/testSrc/com/jetbrains/python/PyStubsTest.java b/python/testSrc/com/jetbrains/python/PyStubsTest.java index 2a58613f1668..633d110116c9 100644 --- a/python/testSrc/com/jetbrains/python/PyStubsTest.java +++ b/python/testSrc/com/jetbrains/python/PyStubsTest.java @@ -422,7 +422,7 @@ public class PyStubsTest extends PyTestCase { final PyClass d = file.findTopLevelClass("D"); assertNotNull(d); assertNull(d.getMetaClassExpression()); - assertNotNull(d.getMetaClassType(TypeEvalContext.codeInsightFallback())); + assertNotNull(d.getMetaClassType(TypeEvalContext.codeInsightFallback(c.getProject()))); assertNotParsed(file); } } diff --git a/python/testSrc/com/jetbrains/python/PyTypeParserTest.java b/python/testSrc/com/jetbrains/python/PyTypeParserTest.java index 7db230a1d7c1..adc7a931dc86 100644 --- a/python/testSrc/com/jetbrains/python/PyTypeParserTest.java +++ b/python/testSrc/com/jetbrains/python/PyTypeParserTest.java @@ -68,7 +68,7 @@ public class PyTypeParserTest extends PyTestCase { } private TypeEvalContext getTypeEvalContext() { - return TypeEvalContext.userInitiated(myFixture.getFile()); + return TypeEvalContext.userInitiated(myFixture.getProject(), myFixture.getFile()); } public void testUnionType() { @@ -188,7 +188,7 @@ public class PyTypeParserTest extends PyTestCase { final PyCollectionType collectionType = (PyCollectionType)type; assertNotNull(collectionType); assertEquals("list", collectionType.getName()); - final PyType elementType = collectionType.getElementType(TypeEvalContext.codeInsightFallback()); + final PyType elementType = collectionType.getElementType(TypeEvalContext.codeInsightFallback(null)); assertInstanceOf(elementType, PyUnionType.class); } @@ -209,7 +209,7 @@ public class PyTypeParserTest extends PyTestCase { final PyCollectionType collectionType = (PyCollectionType)type; assertNotNull(collectionType); assertEquals("list", collectionType.getName()); - final PyType elementType = collectionType.getElementType(TypeEvalContext.codeInsightFallback()); + final PyType elementType = collectionType.getElementType(TypeEvalContext.codeInsightFallback(null)); assertNotNull(elementType); assertEquals("int", elementType.getName()); } @@ -221,7 +221,7 @@ public class PyTypeParserTest extends PyTestCase { final PyCollectionType collectionType = (PyCollectionType)type; assertNotNull(collectionType); assertEquals("dict", collectionType.getName()); - final PyType elementType = collectionType.getElementType(TypeEvalContext.codeInsightFallback()); + final PyType elementType = collectionType.getElementType(TypeEvalContext.codeInsightFallback(null)); assertNotNull(elementType); assertInstanceOf(elementType, PyTupleType.class); final PyTupleType tupleType = (PyTupleType)elementType; @@ -291,7 +291,7 @@ public class PyTypeParserTest extends PyTestCase { myFixture.configureByFile("typeParser/typeParser.py"); final PsiFile file = myFixture.getFile(); final PyType type = PyTypeParser.getTypeByName(file, text); - TypeEvalContext context = TypeEvalContext.userInitiated(file).withTracing(); + TypeEvalContext context = TypeEvalContext.userInitiated(file.getProject(), file).withTracing(); final String actualType = PythonDocumentationProvider.getTypeName(type, context); assertEquals(expectedType, actualType); } diff --git a/python/testSrc/com/jetbrains/python/PyTypeTest.java b/python/testSrc/com/jetbrains/python/PyTypeTest.java index 7f33c1185eb4..1596596ad2de 100644 --- a/python/testSrc/com/jetbrains/python/PyTypeTest.java +++ b/python/testSrc/com/jetbrains/python/PyTypeTest.java @@ -874,7 +874,7 @@ public class PyTypeTest extends PyTestCase { } private static TypeEvalContext getTypeEvalContext(@NotNull PyExpression element) { - return TypeEvalContext.userInitiated(element.getContainingFile()).withTracing(); + return TypeEvalContext.userInitiated(element.getProject(), element.getContainingFile()).withTracing(); } private PyExpression parseExpr(String text) { diff --git a/python/testSrc/com/jetbrains/python/PyTypingTest.java b/python/testSrc/com/jetbrains/python/PyTypingTest.java index 9513795cb5b7..96ad88365d06 100644 --- a/python/testSrc/com/jetbrains/python/PyTypingTest.java +++ b/python/testSrc/com/jetbrains/python/PyTypingTest.java @@ -253,8 +253,8 @@ public class PyTypingTest extends PyTestCase { myFixture.copyDirectoryToProject("typing", ""); myFixture.configureByText(PythonFileType.INSTANCE, text); final PyExpression expr = myFixture.findElementByText("expr", PyExpression.class); - final TypeEvalContext codeAnalysis = TypeEvalContext.codeAnalysis(expr.getContainingFile()); - final TypeEvalContext userInitiated = TypeEvalContext.userInitiated(expr.getContainingFile()).withTracing(); + final TypeEvalContext codeAnalysis = TypeEvalContext.codeAnalysis(expr.getProject(),expr.getContainingFile()); + final TypeEvalContext userInitiated = TypeEvalContext.userInitiated(expr.getProject(), expr.getContainingFile()).withTracing(); assertType(expectedType, expr, codeAnalysis, "code analysis"); assertType(expectedType, expr, userInitiated, "user initiated"); } diff --git a/python/testSrc/com/jetbrains/python/codeInsight/PyClassMROTest.java b/python/testSrc/com/jetbrains/python/codeInsight/PyClassMROTest.java index 6d9fea6d4a97..eb828b7eed8c 100644 --- a/python/testSrc/com/jetbrains/python/codeInsight/PyClassMROTest.java +++ b/python/testSrc/com/jetbrains/python/codeInsight/PyClassMROTest.java @@ -72,7 +72,7 @@ public class PyClassMROTest extends PyTestCase { } public void assertMRO(@NotNull PyClass cls, @NotNull String... mro) { - final List types = cls.getAncestorTypes(TypeEvalContext.codeInsightFallback()); + final List types = cls.getAncestorTypes(TypeEvalContext.codeInsightFallback(cls.getProject())); final List classNames = new ArrayList(); for (PyClassLikeType type : types) { if (type != null) {