PY-18816 Acknowledge TypeEvalContext#maySwitchToAST in reference expressions resolve

Don't use getReference().multiResolve() blindly, because now there can
be reference expressions coming from expression fragments and their
presence doesn't mean that surrounding AST has been unstubbed already.
This commit is contained in:
Mikhail Golubev
2017-07-19 19:28:31 +03:00
parent ca6c7ce90f
commit c0885880aa
2 changed files with 13 additions and 9 deletions
@@ -30,6 +30,7 @@ import com.jetbrains.python.codeInsight.PyInjectionUtil;
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;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -89,7 +90,8 @@ public class PythonRegexpInjector implements MultiHostInjector {
if (callee instanceof PyReferenceExpression && canBeRegexpCall(callee)) {
final PyReferenceExpression referenceExpression = (PyReferenceExpression)callee;
return referenceExpression.getReference(PyResolveContext.noImplicits()).resolve();
final TypeEvalContext context = TypeEvalContext.codeAnalysis(call.getProject(), call.getContainingFile());
return referenceExpression.getReference(PyResolveContext.noImplicits().withTypeEvalContext(context)).resolve();
}
return null;
@@ -285,16 +285,18 @@ public class PyReferenceExpressionImpl extends PyElementImpl implements PyRefere
final PyResolveContext resolveContext = PyResolveContext.noImplicits().withTypeEvalContext(context);
final List<PyType> members = new ArrayList<>();
for (PsiElement target : PyUtil.multiResolveTopPriority(getReference(resolveContext))) {
if (target == this || target == null) {
continue;
}
if (context.maySwitchToAST(this)) {
for (PsiElement target : PyUtil.multiResolveTopPriority(getReference(resolveContext))) {
if (target == this || target == null) {
continue;
}
if (!target.isValid()) {
throw new PsiInvalidElementAccessException(this);
}
if (!target.isValid()) {
throw new PsiInvalidElementAccessException(this);
}
members.add(getTypeFromTarget(target, context, this));
members.add(getTypeFromTarget(target, context, this));
}
}
return PyUnionType.union(members);