mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
PY-14081 Django: QuerySet.as_manager() code editing is really slow
Context cache added
This commit is contained in:
+1
-1
@@ -36,7 +36,7 @@ public class PyJavaSuperMethodsSearchExecutor implements QueryExecutor<PsiElemen
|
||||
PyFunction func = queryParameters.getDerivedMethod();
|
||||
PyClass containingClass = func.getContainingClass();
|
||||
if (containingClass != null) {
|
||||
for (PyClassLikeType type : containingClass.getSuperClassTypes(TypeEvalContext.codeInsightFallback())) {
|
||||
for (PyClassLikeType type : containingClass.getSuperClassTypes(TypeEvalContext.codeInsightFallback(containingClass.getProject()))) {
|
||||
if (type instanceof PyJavaClassType) {
|
||||
final PsiClass psiClass = ((PyJavaClassType)type).getPsiClass();
|
||||
PsiMethod[] methods = psiClass.findMethodsByName(func.getName(), true);
|
||||
|
||||
@@ -71,7 +71,7 @@ public class PyResolveContext {
|
||||
}
|
||||
|
||||
public TypeEvalContext getTypeEvalContext() {
|
||||
return myTypeEvalContext != null ? myTypeEvalContext : TypeEvalContext.codeInsightFallback();
|
||||
return myTypeEvalContext != null ? myTypeEvalContext : TypeEvalContext.codeInsightFallback(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package com.jetbrains.python.psi.types;
|
||||
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* A pack of constraints that limit behavior of {@link com.jetbrains.python.psi.types.TypeEvalContext}.
|
||||
* Any two {@link com.jetbrains.python.psi.types.TypeEvalContext}s may share their cache if their constraints are equal and no PSI changes
|
||||
* happened between their creation.
|
||||
* <p/>
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
@@ -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<String> myTrace;
|
||||
private String myTraceIndent = "";
|
||||
@Nullable private final PsiFile myOrigin;
|
||||
|
||||
private final Map<PyTypedElement, PyType> myEvaluated = new HashMap<PyTypedElement, PyType>();
|
||||
private final Map<Callable, PyType> myEvaluatedReturn = new HashMap<Callable, PyType>();
|
||||
@@ -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.
|
||||
*
|
||||
* <p/>
|
||||
* 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.
|
||||
*
|
||||
* <p/>
|
||||
* 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.
|
||||
* <p/>
|
||||
* <p/>
|
||||
*
|
||||
* @param project pass project here to enable cache. Pass null if you do not have any project.
|
||||
* <strong>Always</strong> 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.
|
||||
*
|
||||
* <p/>
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<TypeEvalConstraints, TypeEvalContext> myCache = new HashMap<TypeEvalConstraints, TypeEvalContext>();
|
||||
/**
|
||||
* 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:
|
||||
* <ol>
|
||||
* <li>Instantiate {@link com.jetbrains.python.psi.types.TypeEvalContext} you want to use</li>
|
||||
* <li>Pass its instance here as argument</li>
|
||||
* <li>Use result</li>
|
||||
* </ol>
|
||||
*
|
||||
* @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;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -54,7 +54,7 @@ public class PyParameterInfoHandler implements ParameterInfoHandler<PyArgumentLi
|
||||
public PyArgumentList findElementForParameterInfo(@NotNull final CreateParameterInfoContext context) {
|
||||
PyArgumentList arglist = findArgumentList(context);
|
||||
if (arglist != null) {
|
||||
final TypeEvalContext typeEvalContext = TypeEvalContext.userInitiated(arglist.getContainingFile());
|
||||
final TypeEvalContext typeEvalContext = TypeEvalContext.userInitiated(arglist.getProject(), arglist.getContainingFile());
|
||||
final PyResolveContext resolveContext = PyResolveContext.noImplicits().withTypeEvalContext(typeEvalContext);
|
||||
CallArgumentsMapping result = arglist.analyzeCall(resolveContext);
|
||||
if (result.getMarkedCallee() != null) {
|
||||
@@ -130,7 +130,7 @@ public class PyParameterInfoHandler implements ParameterInfoHandler<PyArgumentLi
|
||||
final PyArgumentList argList = prevResult.getArgumentList();
|
||||
if (!argList.isValid()) return;
|
||||
// really we need to redo analysis every UI update; findElementForParameterInfo isn't called while typing
|
||||
final TypeEvalContext typeEvalContext = TypeEvalContext.userInitiated(argList.getContainingFile());
|
||||
final TypeEvalContext typeEvalContext = TypeEvalContext.userInitiated(argList.getProject(), argList.getContainingFile());
|
||||
final PyResolveContext resolveContext = PyResolveContext.noImplicits().withTypeEvalContext(typeEvalContext);
|
||||
final CallArgumentsMapping argumentsMapping = argList.analyzeCall(resolveContext);
|
||||
final PyMarkedCallee marked = argumentsMapping.getMarkedCallee();
|
||||
|
||||
+1
-1
@@ -129,7 +129,7 @@ public class PyDictKeyNamesCompletionContributor extends CompletionContributor {
|
||||
if (callee == null) return;
|
||||
final String name = callee.getText();
|
||||
if ("dict".equals(name)) {
|
||||
final TypeEvalContext context = TypeEvalContext.userInitiated(callee.getContainingFile());
|
||||
final TypeEvalContext context = TypeEvalContext.userInitiated(callee.getProject(), callee.getContainingFile());
|
||||
final PyType type = context.getType(dictConstructor);
|
||||
if (type != null && type.isBuiltin()) {
|
||||
final PyArgumentList list = dictConstructor.getArgumentList();
|
||||
|
||||
+1
-1
@@ -255,7 +255,7 @@ public class ConvertFormatOperatorToMethodIntention extends BaseIntentionAction
|
||||
final PyExpression rhs = PyPsiUtils.flattenParens(rightExpression);
|
||||
if (rhs == null) return;
|
||||
final String paramText = sure(rhs).getText();
|
||||
final TypeEvalContext context = TypeEvalContext.userInitiated(file);
|
||||
final TypeEvalContext context = TypeEvalContext.userInitiated(file.getProject(), file);
|
||||
final PyType rhsType = context.getType(rhs);
|
||||
String prefix = "";
|
||||
if (PyTypeChecker.match(PyBuiltinCache.getInstance(rhs).getObjectType("unicode"), rhsType, context)) {
|
||||
|
||||
+1
-1
@@ -160,7 +160,7 @@ public class ImportFromToImportIntention implements IntentionAction {
|
||||
PyReferenceExpression ref = import_element.getImportReferenceExpression();
|
||||
if (ref != null && ref.isValid()) {
|
||||
PsiElement target = ref.getReference().resolve();
|
||||
final TypeEvalContext context = TypeEvalContext.codeAnalysis(file);
|
||||
final TypeEvalContext context = TypeEvalContext.codeAnalysis(file.getProject(), file);
|
||||
if (target instanceof PyExpression && context.getType((PyExpression)target) instanceof PyModuleType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
+1
-1
@@ -56,7 +56,7 @@ public class PyDictConstructorToLiteralFormIntention extends BaseIntentionAction
|
||||
PsiTreeUtil.getParentOfType(file.findElementAt(editor.getCaretModel().getOffset()), PyCallExpression.class);
|
||||
|
||||
if (expression != null && expression.isCalleeText("dict")) {
|
||||
final TypeEvalContext context = TypeEvalContext.codeAnalysis(file);
|
||||
final TypeEvalContext context = TypeEvalContext.codeAnalysis(file.getProject(), file);
|
||||
PyType type = context.getType(expression);
|
||||
if (type != null && type.isBuiltin()) {
|
||||
PyExpression[] argumentList = expression.getArguments();
|
||||
|
||||
+3
-3
@@ -82,9 +82,9 @@ public class PyStringConcatenationToFormatIntention extends BaseIntentionAction
|
||||
}
|
||||
if (expression instanceof PyStringLiteralExpression)
|
||||
continue;
|
||||
final PyType type = TypeEvalContext.codeAnalysis(file).getType(expression);
|
||||
final PyType type = TypeEvalContext.codeAnalysis(file.getProject(), file).getType(expression);
|
||||
final boolean isStringReference = PyTypeChecker.match(cache.getStringType(LanguageLevel.forElement(expression)),
|
||||
type, TypeEvalContext.codeAnalysis(file)) && type != null;
|
||||
type, TypeEvalContext.codeAnalysis(file.getProject(), file)) && type != null;
|
||||
if (!isStringReference) {
|
||||
return false;
|
||||
}
|
||||
@@ -136,7 +136,7 @@ public class PyStringConcatenationToFormatIntention extends BaseIntentionAction
|
||||
List<String> parameters = new ArrayList<String>();
|
||||
Pair<String, String> 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");
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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() {
|
||||
|
||||
+1
-1
@@ -84,7 +84,7 @@ public class PyIterableVariableMacro extends Macro {
|
||||
|
||||
@NotNull
|
||||
protected List<PsiNamedElement> getIterableElements(@NotNull PsiElement element) {
|
||||
final TypeEvalContext typeEvalContext = TypeEvalContext.userInitiated(element.getContainingFile());
|
||||
final TypeEvalContext typeEvalContext = TypeEvalContext.userInitiated(element.getProject(), element.getContainingFile());
|
||||
final List<PsiNamedElement> components = new ArrayList<PsiNamedElement>();
|
||||
for (PsiNamedElement namedElement : getVisibleNamedElements(element)) {
|
||||
if (namedElement instanceof PyTypedElement) {
|
||||
|
||||
@@ -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<PyParameter> parameters = PyUtil.getParameters((PyFunction)element, context);
|
||||
return element.getName() + "(" + StringUtil.join(parameters, new Function<PyParameter, String>() {
|
||||
@Override
|
||||
|
||||
@@ -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<PyParameter> baseParams = PyUtil.getParameters(baseFunction, context);
|
||||
for (PyParameter parameter : baseParams) {
|
||||
pyFunctionBuilder.parameter(parameter.getText());
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -132,7 +132,7 @@ public class DocStringTypeReference extends PsiPolyVariantReferenceBase<PsiEleme
|
||||
for (PyImportElement element : elements) {
|
||||
final PyReferenceExpression referenceExpression = element.getImportReferenceExpression();
|
||||
if (referenceExpression == null) continue;
|
||||
final PyType type = TypeEvalContext.userInitiated(CompletionUtil.getOriginalOrSelf(file)).getType(referenceExpression);
|
||||
final PyType type = TypeEvalContext.userInitiated(file.getProject(), CompletionUtil.getOriginalOrSelf(file)).getType(referenceExpression);
|
||||
if (type instanceof PyClassType) {
|
||||
variants.add(((PyClassType)type).getPyClass());
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ class PyDocumentationBuilder {
|
||||
PsiElement outer = null;
|
||||
boolean is_property = false;
|
||||
String accessor_kind = "None";
|
||||
final TypeEvalContext context = TypeEvalContext.userInitiated(myElement.getContainingFile());
|
||||
final TypeEvalContext context = TypeEvalContext.userInitiated(myElement.getProject(), myElement.getContainingFile());
|
||||
if (myOriginalElement != null) {
|
||||
String elementName = myOriginalElement.getText();
|
||||
if (PyUtil.isPythonIdentifier(elementName)) {
|
||||
|
||||
@@ -152,7 +152,7 @@ public class PythonDocumentationProvider extends AbstractDocumentationProvider i
|
||||
ChainIterable<String> cat = new ChainIterable<String>();
|
||||
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<PyParameter> 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<String> 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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
+1
-1
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -148,7 +148,7 @@ public class PyBaseElementImpl<T extends StubElement> extends StubBasedPsiElemen
|
||||
List<PsiReference> referencesList = new ArrayList<PsiReference>();
|
||||
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);
|
||||
|
||||
@@ -201,7 +201,7 @@ public class PyClassImpl extends PyBaseElementImpl<PyClassStub> implements PyCla
|
||||
@NotNull
|
||||
@Override
|
||||
public List<PyClass> getAncestorClasses() {
|
||||
return getAncestorClasses(TypeEvalContext.codeInsightFallback());
|
||||
return getAncestorClasses(TypeEvalContext.codeInsightFallback(getProject()));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -231,7 +231,7 @@ public class PyClassImpl extends PyBaseElementImpl<PyClassStub> 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<PyClassStub> implements PyCla
|
||||
|
||||
@NotNull
|
||||
public PyClass[] getSuperClasses() {
|
||||
final List<PyClassLikeType> superTypes = getSuperClassTypes(TypeEvalContext.codeInsightFallback());
|
||||
final List<PyClassLikeType> superTypes = getSuperClassTypes(TypeEvalContext.codeInsightFallback(getProject()));
|
||||
if (superTypes.isEmpty()) {
|
||||
return EMPTY_ARRAY;
|
||||
}
|
||||
@@ -1033,7 +1033,7 @@ public class PyClassImpl extends PyBaseElementImpl<PyClassStub> 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;
|
||||
|
||||
+1
-1
@@ -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<PyParameter> parameters = PyUtil.getParameters(def, context);
|
||||
for (PyParameter parameter : parameters) {
|
||||
parameter.accept(collector);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<String> namesAlready = new HashSet<String>();
|
||||
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()) &&
|
||||
|
||||
@@ -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<PyParameter> parameters = PyUtil.getParameters((PyFunction)object, context);
|
||||
final String params = StringUtil.join(parameters, new Function<PyParameter, String>() {
|
||||
@Override
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<TextRange, PyType> types = new HashMap<TextRange, PyType>();
|
||||
final Map<PyType, TextRange> fullRanges = new HashMap<PyType, TextRange>();
|
||||
final Map<PyType, PyImportElement> imports = new HashMap<PyType, PyImportElement>();
|
||||
|
||||
@@ -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();
|
||||
|
||||
+1
-1
@@ -122,7 +122,7 @@ class MethodsManager extends MembersManager<PyFunction> {
|
||||
// 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
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ class PyAncestorsUtils extends NotNullPredicate<PyClass> {
|
||||
*/
|
||||
@NotNull
|
||||
static Collection<PyClass> getAncestorsUnderUserControl(@NotNull final PyClass pyClass) {
|
||||
final List<PyClass> allAncestors = pyClass.getAncestorClasses(TypeEvalContext.userInitiated(pyClass.getContainingFile()));
|
||||
final List<PyClass> allAncestors = pyClass.getAncestorClasses(TypeEvalContext.userInitiated(pyClass.getProject(), pyClass.getContainingFile()));
|
||||
return Collections2.filter(allAncestors, new PyAncestorsUtils(PyUtil.getSourceRoots(pyClass)));
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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<String> 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;
|
||||
|
||||
+1
-1
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ public class PyClassMROTest extends PyTestCase {
|
||||
}
|
||||
|
||||
public void assertMRO(@NotNull PyClass cls, @NotNull String... mro) {
|
||||
final List<PyClassLikeType> types = cls.getAncestorTypes(TypeEvalContext.codeInsightFallback());
|
||||
final List<PyClassLikeType> types = cls.getAncestorTypes(TypeEvalContext.codeInsightFallback(cls.getProject()));
|
||||
final List<String> classNames = new ArrayList<String>();
|
||||
for (PyClassLikeType type : types) {
|
||||
if (type != null) {
|
||||
|
||||
Reference in New Issue
Block a user