mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
dedicated interface for type callbacks of instructions
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
package com.jetbrains.python.codeInsight.controlflow;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.jetbrains.python.psi.types.PyType;
|
||||
import com.jetbrains.python.psi.types.TypeEvalContext;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* @author yole
|
||||
*/
|
||||
public interface InstructionTypeCallback {
|
||||
PyType getType(TypeEvalContext context, @Nullable PsiElement anchor);
|
||||
}
|
||||
+17
-15
@@ -1,11 +1,12 @@
|
||||
package com.jetbrains.python.codeInsight.controlflow;
|
||||
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.util.containers.CollectionFactory;
|
||||
import com.jetbrains.python.PyNames;
|
||||
import com.jetbrains.python.PyTokenTypes;
|
||||
import com.jetbrains.python.psi.*;
|
||||
import com.jetbrains.python.psi.types.*;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -43,9 +44,9 @@ public class PyTypeAssertionEvaluator extends PyRecursiveElementVisitor {
|
||||
final PyExpression typeElement = args[1];
|
||||
final boolean positive = myPositive;
|
||||
if (!processTuple(target, typeElement)) {
|
||||
pushAssertion(target, new Function<TypeEvalContext, PyType>() {
|
||||
pushAssertion(target, new InstructionTypeCallback() {
|
||||
@Override
|
||||
public PyType fun(TypeEvalContext context) {
|
||||
public PyType getType(TypeEvalContext context, PsiElement anchor) {
|
||||
final List<PyType> types = new ArrayList<PyType>();
|
||||
types.add(context.getType(typeElement));
|
||||
return createAssertionType(context.getType(target), types, positive, context);
|
||||
@@ -59,9 +60,9 @@ public class PyTypeAssertionEvaluator extends PyRecursiveElementVisitor {
|
||||
if (args.length == 1 && args[0] instanceof PyReferenceExpression) {
|
||||
final PyReferenceExpression target = (PyReferenceExpression)args[0];
|
||||
final boolean positive = myPositive;
|
||||
pushAssertion(target, new Function<TypeEvalContext, PyType>() {
|
||||
pushAssertion(target, new InstructionTypeCallback() {
|
||||
@Override
|
||||
public PyType fun(TypeEvalContext context) {
|
||||
public PyType getType(TypeEvalContext context, PsiElement anchor) {
|
||||
final List<PyType> types = new ArrayList<PyType>();
|
||||
types.add(PyTypeParser.getTypeByName(target, PyNames.CALLABLE));
|
||||
return createAssertionType(context.getType(target), types, positive, context);
|
||||
@@ -74,9 +75,9 @@ public class PyTypeAssertionEvaluator extends PyRecursiveElementVisitor {
|
||||
@Override
|
||||
public void visitPyReferenceExpression(final PyReferenceExpression node) {
|
||||
if (node.getParent() instanceof PyIfPart) {
|
||||
pushAssertion(node, new Function<TypeEvalContext, PyType>() {
|
||||
pushAssertion(node, new InstructionTypeCallback() {
|
||||
@Override
|
||||
public PyType fun(TypeEvalContext context) {
|
||||
public PyType getType(TypeEvalContext context, PsiElement anchor) {
|
||||
final List<PyType> types = new ArrayList<PyType>();
|
||||
types.add(PyNoneType.INSTANCE);
|
||||
return createAssertionType(context.getType(node), types, false, context);
|
||||
@@ -95,9 +96,9 @@ public class PyTypeAssertionEvaluator extends PyRecursiveElementVisitor {
|
||||
if (lhs instanceof PyReferenceExpression && rhs instanceof PyReferenceExpression) {
|
||||
final PyReferenceExpression target = (PyReferenceExpression)lhs;
|
||||
if (PyNames.NONE.equals(rhs.getName())) {
|
||||
pushAssertion(target, new Function<TypeEvalContext, PyType>() {
|
||||
pushAssertion(target, new InstructionTypeCallback() {
|
||||
@Override
|
||||
public PyType fun(TypeEvalContext context) {
|
||||
public PyType getType(TypeEvalContext context, @Nullable PsiElement anchor) {
|
||||
final List<PyType> types = new ArrayList<PyType>();
|
||||
types.add(PyNoneType.INSTANCE);
|
||||
return createAssertionType(context.getType(target), types, false, context);
|
||||
@@ -117,9 +118,9 @@ public class PyTypeAssertionEvaluator extends PyRecursiveElementVisitor {
|
||||
if (contained instanceof PyTupleExpression) {
|
||||
final PyTupleExpression tuple = (PyTupleExpression)contained;
|
||||
final boolean positive = myPositive;
|
||||
pushAssertion(target, new Function<TypeEvalContext, PyType>() {
|
||||
pushAssertion(target, new InstructionTypeCallback() {
|
||||
@Override
|
||||
public PyType fun(TypeEvalContext context) {
|
||||
public PyType getType(TypeEvalContext context, @Nullable PsiElement anchor) {
|
||||
final List<PyType> types = new ArrayList<PyType>();
|
||||
for (PyExpression e : tuple.getElements()) {
|
||||
types.add(context.getType(e));
|
||||
@@ -133,6 +134,7 @@ public class PyTypeAssertionEvaluator extends PyRecursiveElementVisitor {
|
||||
return pushed;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PyType createAssertionType(PyType initial, List<PyType> types, boolean positive, TypeEvalContext context) {
|
||||
final List<PyType> members = new ArrayList<PyType>();
|
||||
for (PyType t : types) {
|
||||
@@ -151,15 +153,15 @@ public class PyTypeAssertionEvaluator extends PyRecursiveElementVisitor {
|
||||
return initial;
|
||||
}
|
||||
|
||||
private void pushAssertion(PyReferenceExpression element, Function<TypeEvalContext, PyType> getType) {
|
||||
private void pushAssertion(PyReferenceExpression element, InstructionTypeCallback getType) {
|
||||
myStack.push(new Assertion(element, getType));
|
||||
}
|
||||
|
||||
static class Assertion {
|
||||
private final PyReferenceExpression element;
|
||||
private Function<TypeEvalContext, PyType> myFunction;
|
||||
private InstructionTypeCallback myFunction;
|
||||
|
||||
Assertion(PyReferenceExpression element, Function<TypeEvalContext, PyType> getType) {
|
||||
Assertion(PyReferenceExpression element, InstructionTypeCallback getType) {
|
||||
this.element = element;
|
||||
this.myFunction = getType;
|
||||
}
|
||||
@@ -168,7 +170,7 @@ public class PyTypeAssertionEvaluator extends PyRecursiveElementVisitor {
|
||||
return element;
|
||||
}
|
||||
|
||||
public Function<TypeEvalContext, PyType> getTypeEvalFunction() {
|
||||
public InstructionTypeCallback getTypeEvalFunction() {
|
||||
return myFunction;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package com.jetbrains.python.codeInsight.controlflow;
|
||||
import com.intellij.codeInsight.controlflow.ControlFlowBuilder;
|
||||
import com.intellij.codeInsight.controlflow.impl.InstructionImpl;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.util.Function;
|
||||
import com.jetbrains.python.psi.PyElement;
|
||||
import com.jetbrains.python.psi.PyExpression;
|
||||
import com.jetbrains.python.psi.types.PyType;
|
||||
@@ -12,9 +11,9 @@ import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class ReadWriteInstruction extends InstructionImpl {
|
||||
final Function<TypeEvalContext, PyType> EXPR_TYPE = new Function<TypeEvalContext, PyType>() {
|
||||
final InstructionTypeCallback EXPR_TYPE = new InstructionTypeCallback() {
|
||||
@Override
|
||||
public PyType fun(TypeEvalContext context) {
|
||||
public PyType getType(TypeEvalContext context, @Nullable PsiElement anchor) {
|
||||
return myElement instanceof PyExpression ? context.getType((PyExpression)myElement) : null;
|
||||
}
|
||||
};
|
||||
@@ -50,7 +49,7 @@ public class ReadWriteInstruction extends InstructionImpl {
|
||||
|
||||
private final String myName;
|
||||
private final ACCESS myAccess;
|
||||
private final Function<TypeEvalContext, PyType> myGetType;
|
||||
private final InstructionTypeCallback myGetType;
|
||||
|
||||
private ReadWriteInstruction(final ControlFlowBuilder builder,
|
||||
final PsiElement element,
|
||||
@@ -63,7 +62,7 @@ public class ReadWriteInstruction extends InstructionImpl {
|
||||
final PsiElement element,
|
||||
final String name,
|
||||
final ACCESS access,
|
||||
@Nullable final Function<TypeEvalContext, PyType> getType) {
|
||||
@Nullable final InstructionTypeCallback getType) {
|
||||
super(builder, element);
|
||||
myName = name;
|
||||
myAccess = access;
|
||||
@@ -100,13 +99,13 @@ public class ReadWriteInstruction extends InstructionImpl {
|
||||
public static ReadWriteInstruction assertType(final ControlFlowBuilder builder,
|
||||
final PsiElement element,
|
||||
final String name,
|
||||
final Function<TypeEvalContext, PyType> getType) {
|
||||
final InstructionTypeCallback getType) {
|
||||
return new ReadWriteInstruction(builder, element, name, ACCESS.ASSERTTYPE, getType);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PyType getType(TypeEvalContext context) {
|
||||
return myGetType.fun(context);
|
||||
public PyType getType(TypeEvalContext context, @Nullable PsiElement anchor) {
|
||||
return myGetType.getType(context, anchor);
|
||||
}
|
||||
|
||||
@NonNls
|
||||
|
||||
@@ -310,9 +310,9 @@ public class PyReferenceExpressionImpl extends PyElementImpl implements PyRefere
|
||||
augAssignment != null ? augAssignment : anchor,
|
||||
true);
|
||||
if (!defs.isEmpty()) {
|
||||
PyType type = defs.get(0).getType(context);
|
||||
PyType type = defs.get(0).getType(context, anchor);
|
||||
for (int i = 1; i < defs.size(); i++) {
|
||||
type = PyUnionType.union(type, defs.get(i).getType(context));
|
||||
type = PyUnionType.union(type, defs.get(i).getType(context, anchor));
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user