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:
+ *
+ * - Instantiate {@link com.jetbrains.python.psi.types.TypeEvalContext} you want to use
+ * - Pass its instance here as argument
+ * - Use result
+ *
+ *
+ * @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) {