PY-18816 Explicitly set appropriate TypeEvalContext in a number of places in code insight

instead of relying on PyResolveContext#defaultContext().

Now we can't assume that whenever we have a reference expression the
underlying file is already unstubbed and we don't need to take take into
account AST policy of the context.
This commit is contained in:
Mikhail Golubev
2017-07-19 19:28:31 +03:00
parent c0885880aa
commit 0aa8039a3a
6 changed files with 26 additions and 6 deletions
@@ -66,8 +66,9 @@ public class PyStaticCallHierarchyUtil {
public void visitPyCallExpression(PyCallExpression node) {
super.visitPyCallExpression(node);
final TypeEvalContext typeEvalContext = TypeEvalContext.userInitiated(element.getProject(), null);
StreamEx
.of(node.multiResolveCalleeFunction(PyResolveContext.defaultContext()))
.of(node.multiResolveCalleeFunction(PyResolveContext.defaultContext().withTypeEvalContext(typeEvalContext)))
.select(PyFunction.class)
.forEach(callees::add);
}
@@ -25,6 +25,7 @@ import com.jetbrains.python.codeInsight.controlflow.ScopeOwner
import com.jetbrains.python.codeInsight.dataflow.scope.ScopeUtil
import com.jetbrains.python.psi.*
import com.jetbrains.python.psi.resolve.PyResolveContext
import com.jetbrains.python.psi.types.TypeEvalContext
class PyRainbowVisitor : RainbowVisitor() {
@@ -89,7 +90,9 @@ class PyRainbowVisitor : RainbowVisitor() {
val parent = targetExpression.parent
if (parent is PyGlobalStatement) return targetExpression.containingFile
if (parent is PyNonlocalStatement) {
val outerResolved = targetExpression.reference.resolve()
val typeEvalContext = TypeEvalContext.codeAnalysis(targetExpression.project, targetExpression.containingFile)
val resolveContext = PyResolveContext.defaultContext().withTypeEvalContext(typeEvalContext)
val outerResolved = targetExpression.getReference(resolveContext).resolve()
return if (outerResolved is PyTargetExpression) getTargetContext(outerResolved) else null
}
@@ -21,6 +21,7 @@ import com.intellij.psi.PsiElementVisitor;
import com.jetbrains.python.PyBundle;
import com.jetbrains.python.psi.PyGlobalStatement;
import com.jetbrains.python.psi.PyTargetExpression;
import com.jetbrains.python.psi.resolve.PyResolveContext;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -57,7 +58,8 @@ public class PyGlobalUndefinedInspection extends PyInspection {
final PyTargetExpression[] globals = node.getGlobals();
for (PyTargetExpression global : globals) {
if (global.getReference().resolve() == global) {
final PyResolveContext resolveContext = PyResolveContext.defaultContext().withTypeEvalContext(myTypeEvalContext);
if (global.getReference(resolveContext).resolve() == global) {
registerProblem(global, PyBundle.message("INSP.NAME.global.$0.undefined", global.getName()));
}
}
@@ -398,7 +398,8 @@ public class PyNamedParameterImpl extends PyBaseElementImpl<PyNamedParameterStub
public void visitPyTargetExpression(PyTargetExpression node) {
if (parameterWasReassigned.get()) return;
if (node.getReference().isReferenceTo(PyNamedParameterImpl.this)) {
final PyResolveContext resolveContext = PyResolveContext.defaultContext().withTypeEvalContext(context);
if (node.getReference(resolveContext).isReferenceTo(PyNamedParameterImpl.this)) {
parameterWasReassigned.set(true);
}
else {
@@ -21,6 +21,8 @@ import com.jetbrains.NotNullPredicate;
import com.jetbrains.python.PyNames;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.impl.PyFunctionBuilder;
import com.jetbrains.python.psi.resolve.PyResolveContext;
import com.jetbrains.python.psi.types.TypeEvalContext;
import com.jetbrains.python.refactoring.classes.PyClassRefactoringUtil;
import org.jetbrains.annotations.NotNull;
@@ -133,7 +135,9 @@ class InstanceFieldsManager extends FieldsManager {
private static class FieldsOnly extends NotNullPredicate<PyTargetExpression> {
@Override
protected boolean applyNotNull(@NotNull final PyTargetExpression input) {
return input.getReference().resolve() instanceof PyTargetExpression;
final TypeEvalContext typeEvalContext = TypeEvalContext.userInitiated(input.getProject(), null);
final PyResolveContext context = PyResolveContext.defaultContext().withTypeEvalContext(typeEvalContext);
return input.getReference(context).resolve() instanceof PyTargetExpression;
}
}
}
@@ -20,6 +20,8 @@ import com.intellij.psi.PsiReference;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.containers.MultiMap;
import com.jetbrains.python.psi.*;
import com.jetbrains.python.psi.resolve.PyResolveContext;
import com.jetbrains.python.psi.types.TypeEvalContext;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
@@ -185,7 +187,14 @@ class PropertiesManager extends MembersManager<PyElement> {
@Override
public void visitPyExpression(final PyExpression node) {
final PsiReference reference = node.getReference();
final PsiReference reference;
if (node instanceof PyReferenceOwner) {
final TypeEvalContext context = TypeEvalContext.userInitiated(node.getProject(), null);
reference = ((PyReferenceOwner)node).getReference(PyResolveContext.defaultContext().withTypeEvalContext(context));
}
else {
reference = node.getReference();
}
if (reference == null) {
return;
}