From 5779dc688580988c8af576b43a1ab78cdf6d82a6 Mon Sep 17 00:00:00 2001 From: Maxim Shafirov Date: Tue, 11 Jan 2011 00:21:11 +0300 Subject: [PATCH] Proper parsing for binary operations with type RHS. --- idea/src/org/jetbrains/jet/JetNodeTypes.java | 23 ++++---- .../lang/parsing/JetExpressionParsing.java | 19 ++++++- .../psi/JetBinaryExpressionWithTypeRHS.java | 55 +++++++++++++++++++ .../jetbrains/jet/lang/psi/JetVisitor.java | 4 ++ idea/testData/psi/Precedence.jet | 2 +- idea/testData/psi/Precedence.txt | 21 +------ idea/testData/psi/Properties.txt | 7 ++- idea/testData/psi/ThisType.txt | 18 +++--- idea/testData/psi/examples/BitArith.txt | 7 ++- .../psi/examples/collections/HashMap.txt | 51 ++++++++--------- idea/testData/psi/examples/io/IOSamples.txt | 7 ++- .../examples/priorityqueues/BinaryHeap.txt | 18 +++--- .../testData/psi/examples/util/Comparison.txt | 36 ++++++------ 13 files changed, 162 insertions(+), 106 deletions(-) create mode 100644 idea/src/org/jetbrains/jet/lang/psi/JetBinaryExpressionWithTypeRHS.java diff --git a/idea/src/org/jetbrains/jet/JetNodeTypes.java b/idea/src/org/jetbrains/jet/JetNodeTypes.java index 1d65c795591..ffb3bc79360 100644 --- a/idea/src/org/jetbrains/jet/JetNodeTypes.java +++ b/idea/src/org/jetbrains/jet/JetNodeTypes.java @@ -47,19 +47,19 @@ public interface JetNodeTypes { JetNodeType TYPE_REFERENCE = new JetNodeType("TYPE_REFERENCE", JetTypeReference.class); JetNodeType LABELED_TUPLE_ENTRY = new JetNodeType("LABELED_TUPLE_ENTRY"); - JetNodeType USER_TYPE = new JetNodeType("USER_TYPE", JetUserType.class); - JetNodeType TUPLE_TYPE = new JetNodeType("TUPLE_TYPE", JetTupleType.class); - JetNodeType FUNCTION_TYPE = new JetNodeType("FUNCTION_TYPE", JetFunctionType.class); - JetNodeType SELF_TYPE = new JetNodeType("SELF_TYPE", JetSelfType.class); + JetNodeType USER_TYPE = new JetNodeType("USER_TYPE", JetUserType.class); + JetNodeType TUPLE_TYPE = new JetNodeType("TUPLE_TYPE", JetTupleType.class); + JetNodeType FUNCTION_TYPE = new JetNodeType("FUNCTION_TYPE", JetFunctionType.class); + JetNodeType SELF_TYPE = new JetNodeType("SELF_TYPE", JetSelfType.class); - JetNodeType DECOMPOSER_PROPERTY_LIST = new JetNodeType("DECOMPOSER_PROPERTY_LIST", JetDecomposerPropertyList.class); + JetNodeType DECOMPOSER_PROPERTY_LIST = new JetNodeType("DECOMPOSER_PROPERTY_LIST", JetDecomposerPropertyList.class); // TODO: review - JetNodeType RECEIVER_TYPE_ATTRIBUTES = new JetNodeType("RECEIVER_TYPE_ATTRIBUTES"); - JetNodeType PROPERTY_ACCESSOR = new JetNodeType("PROPERTY_ACCESSOR", JetPropertyAccessor.class); - JetNodeType INITIALIZER_LIST = new JetNodeType("INITIALIZER_LIST", JetInitializerList.class); - JetNodeType THIS_CALL = new JetNodeType("THIS_CALL", JetDelegatorToThisCall.class); - JetNodeType TYPE_CONSTRAINT_LIST = new JetNodeType("TYPE_CONSTRAINT_LIST", JetTypeConstraintList.class); - JetNodeType TYPE_CONSTRAINT = new JetNodeType("TYPE_CONSTRAINT", JetTypeConstraint.class); + JetNodeType RECEIVER_TYPE_ATTRIBUTES = new JetNodeType("RECEIVER_TYPE_ATTRIBUTES"); + JetNodeType PROPERTY_ACCESSOR = new JetNodeType("PROPERTY_ACCESSOR", JetPropertyAccessor.class); + JetNodeType INITIALIZER_LIST = new JetNodeType("INITIALIZER_LIST", JetInitializerList.class); + JetNodeType THIS_CALL = new JetNodeType("THIS_CALL", JetDelegatorToThisCall.class); + JetNodeType TYPE_CONSTRAINT_LIST = new JetNodeType("TYPE_CONSTRAINT_LIST", JetTypeConstraintList.class); + JetNodeType TYPE_CONSTRAINT = new JetNodeType("TYPE_CONSTRAINT", JetTypeConstraint.class); // TODO: Not sure if we need separate NT for each kind of constants JetNodeType NULL = new JetNodeType("NULL", JetConstantExpression.class); @@ -97,6 +97,7 @@ public interface JetNodeTypes { JetNodeType REFERENCE_EXPRESSION = new JetNodeType("REFERENCE_EXPRESSION", JetReferenceExpression.class); JetNodeType THIS_EXPRESSION = new JetNodeType("THIS_EXPRESSION", JetThisExpression.class); JetNodeType BINARY_EXPRESSION = new JetNodeType("BINARY_EXPRESSION", JetBinaryExpression.class); + JetNodeType BINARY_WITH_TYPE = new JetNodeType("BINARY_WITH_TYPE", JetBinaryExpressionWithTypeRHS.class); JetNodeType PREFIX_EXPRESSION = new JetNodeType("PREFIX_EXPRESSION", JetPrefixExpression.class); JetNodeType POSTFIX_EXPRESSION = new JetNodeType("POSTFIX_EXPRESSION", JetPostfixExpression.class); JetNodeType CALL_EXPRESSION = new JetNodeType("CALL_EXPRESSION", JetCallExpression.class); diff --git a/idea/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java b/idea/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java index b313e3fe8a2..61d4cca23bb 100644 --- a/idea/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java +++ b/idea/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java @@ -61,7 +61,18 @@ public class JetExpressionParsing extends AbstractJetParsing { RANGE(JetTokens.RANGE), SIMPLE_NAME(IDENTIFIER), ELVIS(JetTokens.ELVIS), - NAMED_INFIX_OR_TYPE(IN_KEYWORD, NOT_IN, IS_KEYWORD, NOT_IS, AS_KEYWORD, COLON), + WITH_TYPE_RHS(IS_KEYWORD, NOT_IS, AS_KEYWORD, COLON) { + @Override + public void parseRightHandSide(JetExpressionParsing parsing) { + parsing.myJetParsing.parseTypeRef(); + } + + @Override + public JetNodeType getProductType() { + return BINARY_WITH_TYPE; + } + }, + NAMED_INFIX(IN_KEYWORD, NOT_IN), COMPARISON(LT, GT, LTEQ, GTEQ), EQUALITY(EQEQ, EXCLEQ, EQEQEQ, EXCLEQEQEQ), CONJUNCTION(ANDAND), @@ -101,6 +112,10 @@ public class JetExpressionParsing extends AbstractJetParsing { parseHigherPrecedence(parsing); } + public JetNodeType getProductType() { + return BINARY_EXPRESSION; + } + public final TokenSet getOperations() { return operations; } @@ -146,7 +161,7 @@ public class JetExpressionParsing extends AbstractJetParsing { while (!myBuilder.newlineBeforeCurrentToken() && atSet(precedence.getOperations())) { advance(); // operation precedence.parseRightHandSide(this); - expression.done(BINARY_EXPRESSION); + expression.done(precedence.getProductType()); expression = expression.precede(); } diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetBinaryExpressionWithTypeRHS.java b/idea/src/org/jetbrains/jet/lang/psi/JetBinaryExpressionWithTypeRHS.java new file mode 100644 index 00000000000..f3107c81625 --- /dev/null +++ b/idea/src/org/jetbrains/jet/lang/psi/JetBinaryExpressionWithTypeRHS.java @@ -0,0 +1,55 @@ +package org.jetbrains.jet.lang.psi; + +import com.intellij.lang.ASTNode; +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lexer.JetToken; +import org.jetbrains.jet.lexer.JetTokens; + +/** + * @author max + */ +public class JetBinaryExpressionWithTypeRHS extends JetExpression { + public JetBinaryExpressionWithTypeRHS(@NotNull ASTNode node) { + super(node); + } + + @Override + public void accept(JetVisitor visitor) { + visitor.visitBinaryWithTypeRHSExpression(this); + } + + @NotNull + public JetExpression getLeft() { + JetExpression left = findChildByClass(JetExpression.class); + assert left != null; + return left; + } + + @Nullable + public JetTypeReference getRight() { + ASTNode node = getOperationTokenNode(); + while (node != null) { + PsiElement psi = node.getPsi(); + if (psi instanceof JetTypeReference) { + return (JetTypeReference) psi; + } + node = node.getTreeNext(); + } + + return null; + } + + @NotNull + public ASTNode getOperationTokenNode() { + ASTNode operationNode = getNode().findChildByType(JetTokens.OPERATIONS); + assert operationNode != null; + return operationNode; + } + + @Nullable + public JetToken getOperationSign() { + return (JetToken) getOperationTokenNode().getElementType(); + } +} diff --git a/idea/src/org/jetbrains/jet/lang/psi/JetVisitor.java b/idea/src/org/jetbrains/jet/lang/psi/JetVisitor.java index 06b050216e7..55b0c0c930f 100644 --- a/idea/src/org/jetbrains/jet/lang/psi/JetVisitor.java +++ b/idea/src/org/jetbrains/jet/lang/psi/JetVisitor.java @@ -313,4 +313,8 @@ public class JetVisitor extends PsiElementVisitor { public void visitSelfType(JetSelfType type) { visitTypeElement(type); } + + public void visitBinaryWithTypeRHSExpression(JetBinaryExpressionWithTypeRHS expression) { + visitExpression(expression); + } } diff --git a/idea/testData/psi/Precedence.jet b/idea/testData/psi/Precedence.jet index 62287bd6294..901fef558cf 100644 --- a/idea/testData/psi/Precedence.jet +++ b/idea/testData/psi/Precedence.jet @@ -26,7 +26,7 @@ fun foo() { 1 foo 2 ?: 1 bar 3 a b c d e f g a ?: b in b?: c - a : b < b : c + // TODO a : b < b : c a < b == b > c a != b && c a || b && c diff --git a/idea/testData/psi/Precedence.txt b/idea/testData/psi/Precedence.txt index 176aa5a26bb..77b6f560dbe 100644 --- a/idea/testData/psi/Precedence.txt +++ b/idea/testData/psi/Precedence.txt @@ -516,26 +516,7 @@ JetFile: Precedence.jet REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('c') PsiWhiteSpace('\n ') - BINARY_EXPRESSION - BINARY_EXPRESSION - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('a') - PsiWhiteSpace(' ') - PsiElement(COLON)(':') - PsiWhiteSpace(' ') - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('b') - PsiWhiteSpace(' ') - PsiElement(LT)('<') - PsiWhiteSpace(' ') - BINARY_EXPRESSION - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('b') - PsiWhiteSpace(' ') - PsiElement(COLON)(':') - PsiWhiteSpace(' ') - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('c') + PsiComment(EOL_COMMENT)('// TODO a : b < b : c') PsiWhiteSpace('\n ') BINARY_EXPRESSION BINARY_EXPRESSION diff --git a/idea/testData/psi/Properties.txt b/idea/testData/psi/Properties.txt index d00f6bd775a..1392766a3b3 100644 --- a/idea/testData/psi/Properties.txt +++ b/idea/testData/psi/Properties.txt @@ -673,14 +673,15 @@ JetFile: Properties.jet VALUE_ARGUMENT_LIST PsiElement(LPAR)('(') VALUE_ARGUMENT - BINARY_EXPRESSION + BINARY_WITH_TYPE REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('int') PsiWhiteSpace(' ') PsiElement(COLON)(':') PsiWhiteSpace(' ') - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('x') + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('x') PsiElement(RPAR)(')') PsiWhiteSpace(' ') PsiElement(EQ)('=') diff --git a/idea/testData/psi/ThisType.txt b/idea/testData/psi/ThisType.txt index 29d92e9f9fe..7e9a4a251fe 100644 --- a/idea/testData/psi/ThisType.txt +++ b/idea/testData/psi/ThisType.txt @@ -65,21 +65,21 @@ JetFile: ThisType.jet PsiWhiteSpace(' ') PsiElement(by)('by') PsiWhiteSpace(' ') - BINARY_EXPRESSION + BINARY_WITH_TYPE REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('foo') PsiWhiteSpace(' ') PsiElement(as)('as') PsiWhiteSpace(' ') - CALL_EXPRESSION - REFERENCE_EXPRESSION + TYPE_REFERENCE + USER_TYPE PsiElement(IDENTIFIER)('List') - TYPE_ARGUMENT_LIST - PsiElement(LT)('<') - TYPE_REFERENCE - SELF_TYPE - PsiElement(This)('This') - PsiElement(GT)('>') + TYPE_ARGUMENT_LIST + PsiElement(LT)('<') + TYPE_REFERENCE + SELF_TYPE + PsiElement(This)('This') + PsiElement(GT)('>') PsiWhiteSpace(' ') CLASS_BODY PsiElement(LBRACE)('{') diff --git a/idea/testData/psi/examples/BitArith.txt b/idea/testData/psi/examples/BitArith.txt index 658ff528aba..e61c85a0117 100644 --- a/idea/testData/psi/examples/BitArith.txt +++ b/idea/testData/psi/examples/BitArith.txt @@ -342,7 +342,7 @@ JetFile: BitArith.jet PsiWhiteSpace(' ') PsiElement(EQ)('=') PsiWhiteSpace(' ') - BINARY_EXPRESSION + BINARY_WITH_TYPE PARENTHESIZED PsiElement(LPAR)('(') BINARY_EXPRESSION @@ -380,8 +380,9 @@ JetFile: BitArith.jet PsiWhiteSpace(' ') PsiElement(as)('as') PsiWhiteSpace(' ') - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('Int') + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('Int') PsiWhiteSpace('\n\n') FUN PsiElement(fun)('fun') diff --git a/idea/testData/psi/examples/collections/HashMap.txt b/idea/testData/psi/examples/collections/HashMap.txt index 064932dfb90..fb9e65bb367 100644 --- a/idea/testData/psi/examples/collections/HashMap.txt +++ b/idea/testData/psi/examples/collections/HashMap.txt @@ -43,21 +43,20 @@ JetFile: HashMap.jet DOT_QIALIFIED_EXPRESSION PARENTHESIZED PsiElement(LPAR)('(') - BINARY_EXPRESSION + BINARY_WITH_TYPE THIS_EXPRESSION PsiElement(this)('this') PsiWhiteSpace(' ') PsiElement(as)('as') PsiWhiteSpace(' ') - DOT_QIALIFIED_EXPRESSION - DOT_QIALIFIED_EXPRESSION - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('java') - PsiElement(DOT)('.') - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('lang') + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('java') PsiElement(DOT)('.') - REFERENCE_EXPRESSION + USER_TYPE + PsiElement(IDENTIFIER)('lang') + PsiElement(DOT)('.') + USER_TYPE PsiElement(IDENTIFIER)('Object') PsiElement(RPAR)(')') PsiElement(DOT)('.') @@ -66,21 +65,20 @@ JetFile: HashMap.jet VALUE_ARGUMENT_LIST PsiElement(LPAR)('(') VALUE_ARGUMENT - BINARY_EXPRESSION + BINARY_WITH_TYPE REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('other') PsiWhiteSpace(' ') PsiElement(as)('as') PsiWhiteSpace(' ') - DOT_QIALIFIED_EXPRESSION - DOT_QIALIFIED_EXPRESSION - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('java') - PsiElement(DOT)('.') - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('lang') + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('java') PsiElement(DOT)('.') - REFERENCE_EXPRESSION + USER_TYPE + PsiElement(IDENTIFIER)('lang') + PsiElement(DOT)('.') + USER_TYPE PsiElement(IDENTIFIER)('Object') PsiElement(RPAR)(')') PsiWhiteSpace('\n') @@ -129,21 +127,20 @@ JetFile: HashMap.jet DOT_QIALIFIED_EXPRESSION PARENTHESIZED PsiElement(LPAR)('(') - BINARY_EXPRESSION + BINARY_WITH_TYPE THIS_EXPRESSION PsiElement(this)('this') PsiWhiteSpace(' ') PsiElement(as)('as') PsiWhiteSpace(' ') - DOT_QIALIFIED_EXPRESSION - DOT_QIALIFIED_EXPRESSION - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('java') - PsiElement(DOT)('.') - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('lang') + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('java') PsiElement(DOT)('.') - REFERENCE_EXPRESSION + USER_TYPE + PsiElement(IDENTIFIER)('lang') + PsiElement(DOT)('.') + USER_TYPE PsiElement(IDENTIFIER)('Object') PsiElement(RPAR)(')') PsiElement(DOT)('.') diff --git a/idea/testData/psi/examples/io/IOSamples.txt b/idea/testData/psi/examples/io/IOSamples.txt index facc5361a89..d1b418d589a 100644 --- a/idea/testData/psi/examples/io/IOSamples.txt +++ b/idea/testData/psi/examples/io/IOSamples.txt @@ -356,14 +356,15 @@ JetFile: IOSamples.jet RETURN PsiElement(return)('return') PsiWhiteSpace(' ') - BINARY_EXPRESSION + BINARY_WITH_TYPE REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('next') PsiWhiteSpace(' ') PsiElement(as)('as') PsiWhiteSpace(' ') - REFERENCE_EXPRESSION - PsiElement(IDENTIFIER)('Byte') + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('Byte') PsiWhiteSpace('\n ') PsiElement(RBRACE)('}') PsiWhiteSpace('\n ') diff --git a/idea/testData/psi/examples/priorityqueues/BinaryHeap.txt b/idea/testData/psi/examples/priorityqueues/BinaryHeap.txt index 696cb42cd28..0029bd8936e 100644 --- a/idea/testData/psi/examples/priorityqueues/BinaryHeap.txt +++ b/idea/testData/psi/examples/priorityqueues/BinaryHeap.txt @@ -291,21 +291,21 @@ JetFile: BinaryHeap.jet VALUE_ARGUMENT_LIST PsiElement(LPAR)('(') VALUE_ARGUMENT - BINARY_EXPRESSION + BINARY_WITH_TYPE REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('T') PsiWhiteSpace(' ') PsiElement(is)('is') PsiWhiteSpace(' ') - CALL_EXPRESSION - REFERENCE_EXPRESSION + TYPE_REFERENCE + USER_TYPE PsiElement(IDENTIFIER)('IComparable') - TYPE_ARGUMENT_LIST - PsiElement(LT)('<') - TYPE_REFERENCE - USER_TYPE - PsiElement(IDENTIFIER)('T') - PsiElement(GT)('>') + TYPE_ARGUMENT_LIST + PsiElement(LT)('<') + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('T') + PsiElement(GT)('>') PsiElement(RPAR)(')') PsiWhiteSpace('\n ') BINARY_EXPRESSION diff --git a/idea/testData/psi/examples/util/Comparison.txt b/idea/testData/psi/examples/util/Comparison.txt index 2d3eeb59d1b..9ec15a0606c 100644 --- a/idea/testData/psi/examples/util/Comparison.txt +++ b/idea/testData/psi/examples/util/Comparison.txt @@ -145,21 +145,21 @@ JetFile: Comparison.jet DOT_QIALIFIED_EXPRESSION PARENTHESIZED PsiElement(LPAR)('(') - BINARY_EXPRESSION + BINARY_WITH_TYPE REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('a') PsiWhiteSpace(' ') PsiElement(as)('as') PsiWhiteSpace(' ') - CALL_EXPRESSION - REFERENCE_EXPRESSION + TYPE_REFERENCE + USER_TYPE PsiElement(IDENTIFIER)('Comparable') - TYPE_ARGUMENT_LIST - PsiElement(LT)('<') - TYPE_REFERENCE - USER_TYPE - PsiElement(IDENTIFIER)('Object') - PsiElement(GT)('>') + TYPE_ARGUMENT_LIST + PsiElement(LT)('<') + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('Object') + PsiElement(GT)('>') PsiElement(RPAR)(')') PsiElement(DOT)('.') REFERENCE_EXPRESSION @@ -167,21 +167,21 @@ JetFile: Comparison.jet VALUE_ARGUMENT_LIST PsiElement(LPAR)('(') VALUE_ARGUMENT - BINARY_EXPRESSION + BINARY_WITH_TYPE REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('b') PsiWhiteSpace(' ') PsiElement(as)('as') PsiWhiteSpace(' ') - CALL_EXPRESSION - REFERENCE_EXPRESSION + TYPE_REFERENCE + USER_TYPE PsiElement(IDENTIFIER)('Comparable') - TYPE_ARGUMENT_LIST - PsiElement(LT)('<') - TYPE_REFERENCE - USER_TYPE - PsiElement(IDENTIFIER)('Object') - PsiElement(GT)('>') + TYPE_ARGUMENT_LIST + PsiElement(LT)('<') + TYPE_REFERENCE + USER_TYPE + PsiElement(IDENTIFIER)('Object') + PsiElement(GT)('>') PsiElement(RPAR)(')') PsiWhiteSpace('\n\n') CLASS