From 2f5c1b17db0ea5ee3a151fffb7eb0353478ca684 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Wed, 22 Aug 2012 15:35:18 +0200 Subject: [PATCH] dedicated interface for type callbacks of instructions --- .../controlflow/InstructionTypeCallback.java | 13 ++++++++ .../controlflow/PyTypeAssertionEvaluator.java | 32 ++++++++++--------- .../controlflow/ReadWriteInstruction.java | 15 ++++----- .../psi/impl/PyReferenceExpressionImpl.java | 4 +-- 4 files changed, 39 insertions(+), 25 deletions(-) create mode 100644 python/src/com/jetbrains/python/codeInsight/controlflow/InstructionTypeCallback.java diff --git a/python/src/com/jetbrains/python/codeInsight/controlflow/InstructionTypeCallback.java b/python/src/com/jetbrains/python/codeInsight/controlflow/InstructionTypeCallback.java new file mode 100644 index 000000000000..d65637dcb2d8 --- /dev/null +++ b/python/src/com/jetbrains/python/codeInsight/controlflow/InstructionTypeCallback.java @@ -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); +} diff --git a/python/src/com/jetbrains/python/codeInsight/controlflow/PyTypeAssertionEvaluator.java b/python/src/com/jetbrains/python/codeInsight/controlflow/PyTypeAssertionEvaluator.java index 4bcc297b6ec3..fd357d4335eb 100644 --- a/python/src/com/jetbrains/python/codeInsight/controlflow/PyTypeAssertionEvaluator.java +++ b/python/src/com/jetbrains/python/codeInsight/controlflow/PyTypeAssertionEvaluator.java @@ -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() { + pushAssertion(target, new InstructionTypeCallback() { @Override - public PyType fun(TypeEvalContext context) { + public PyType getType(TypeEvalContext context, PsiElement anchor) { final List types = new ArrayList(); 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() { + pushAssertion(target, new InstructionTypeCallback() { @Override - public PyType fun(TypeEvalContext context) { + public PyType getType(TypeEvalContext context, PsiElement anchor) { final List types = new ArrayList(); 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() { + pushAssertion(node, new InstructionTypeCallback() { @Override - public PyType fun(TypeEvalContext context) { + public PyType getType(TypeEvalContext context, PsiElement anchor) { final List types = new ArrayList(); 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() { + pushAssertion(target, new InstructionTypeCallback() { @Override - public PyType fun(TypeEvalContext context) { + public PyType getType(TypeEvalContext context, @Nullable PsiElement anchor) { final List types = new ArrayList(); 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() { + pushAssertion(target, new InstructionTypeCallback() { @Override - public PyType fun(TypeEvalContext context) { + public PyType getType(TypeEvalContext context, @Nullable PsiElement anchor) { final List types = new ArrayList(); 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 types, boolean positive, TypeEvalContext context) { final List members = new ArrayList(); for (PyType t : types) { @@ -151,15 +153,15 @@ public class PyTypeAssertionEvaluator extends PyRecursiveElementVisitor { return initial; } - private void pushAssertion(PyReferenceExpression element, Function getType) { + private void pushAssertion(PyReferenceExpression element, InstructionTypeCallback getType) { myStack.push(new Assertion(element, getType)); } static class Assertion { private final PyReferenceExpression element; - private Function myFunction; + private InstructionTypeCallback myFunction; - Assertion(PyReferenceExpression element, Function 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 getTypeEvalFunction() { + public InstructionTypeCallback getTypeEvalFunction() { return myFunction; } } diff --git a/python/src/com/jetbrains/python/codeInsight/controlflow/ReadWriteInstruction.java b/python/src/com/jetbrains/python/codeInsight/controlflow/ReadWriteInstruction.java index cbc25a83821a..a936acb73425 100644 --- a/python/src/com/jetbrains/python/codeInsight/controlflow/ReadWriteInstruction.java +++ b/python/src/com/jetbrains/python/codeInsight/controlflow/ReadWriteInstruction.java @@ -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 EXPR_TYPE = new Function() { + 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 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 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 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 diff --git a/python/src/com/jetbrains/python/psi/impl/PyReferenceExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyReferenceExpressionImpl.java index 6da658fb4a36..36a04c0471a9 100644 --- a/python/src/com/jetbrains/python/psi/impl/PyReferenceExpressionImpl.java +++ b/python/src/com/jetbrains/python/psi/impl/PyReferenceExpressionImpl.java @@ -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; }