conditional expression with method call in condition

This commit is contained in:
Maxim Medvedev
2011-04-08 12:18:46 +04:00
parent d06265ae66
commit 7eaffc2742
9 changed files with 178 additions and 33 deletions
@@ -27,6 +27,7 @@ import org.jetbrains.plugins.groovy.lang.parser.parsing.auxiliary.parameters.Par
import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.TupleParse;
import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.blocks.OpenOrClosableBlock;
import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions.AssignmentExpression;
import org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions.ConditionalExpression;
import org.jetbrains.plugins.groovy.lang.parser.parsing.util.ParserUtils;
/**
@@ -80,12 +80,16 @@ public class AssignmentExpression implements GroovyElementTypes {
if (comExprAllowed) {
Marker marker = builder.mark();
if (ExpressionStatement.parse(builder, parser)) {
marker.drop();
return true;
}
else {
marker.rollbackTo();
final ExpressionStatement.Result result = ExpressionStatement.parse(builder, parser);
switch (result) {
case EXPR_STATEMENT:
marker.drop();
return true;
case EXPRESSION:
ConditionalExpression.parseAfterCondition(builder, parser, marker);
return true;
case WRONG_WAY:
marker.rollbackTo();
}
}
return ConditionalExpression.parse(builder, parser);
@@ -31,32 +31,36 @@ public class ConditionalExpression implements GroovyElementTypes {
PsiBuilder.Marker marker = builder.mark();
if (BinaryExpression.parseLogicalExpression(builder, parser)) {
if (ParserUtils.getToken(builder, mQUESTION)) {
ParserUtils.getToken(builder, mNLS);
if (!AssignmentExpression.parse(builder, parser)) {
builder.error(GroovyBundle.message("expression.expected"));
}
if (ParserUtils.getToken(builder, mCOLON, GroovyBundle.message("colon.expected"))) {
ParserUtils.getToken(builder, mNLS);
parse(builder, parser);
}
marker.done(CONDITIONAL_EXPRESSION);
} else if (ParserUtils.getToken(builder, mELVIS)) {
ParserUtils.getToken(builder, mNLS);
if (!parse(builder, parser)) {
builder.error(GroovyBundle.message("expression.expected"));
}
marker.done(ELVIS_EXPRESSION);
} else {
marker.drop();
}
parseAfterCondition(builder, parser, marker);
return true;
} else {
}
else {
marker.drop();
return false;
}
}
public static void parseAfterCondition(PsiBuilder builder, GroovyParser parser, PsiBuilder.Marker marker) {
if (ParserUtils.getToken(builder, mQUESTION)) {
ParserUtils.getToken(builder, mNLS);
if (!AssignmentExpression.parse(builder, parser)) {
builder.error(GroovyBundle.message("expression.expected"));
}
if (ParserUtils.getToken(builder, mCOLON, GroovyBundle.message("colon.expected"))) {
ParserUtils.getToken(builder, mNLS);
parse(builder, parser);
}
marker.done(CONDITIONAL_EXPRESSION);
}
else if (ParserUtils.getToken(builder, mELVIS)) {
ParserUtils.getToken(builder, mNLS);
if (!parse(builder, parser)) {
builder.error(GroovyBundle.message("expression.expected"));
}
marker.done(ELVIS_EXPRESSION);
}
else {
marker.drop();
}
}
}
@@ -18,7 +18,6 @@ package org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expressions;
import com.intellij.lang.PsiBuilder;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.plugins.groovy.lang.lexer.GroovyElementType;
import org.jetbrains.plugins.groovy.lang.parser.GroovyElementTypes;
import org.jetbrains.plugins.groovy.lang.parser.GroovyParser;
@@ -42,7 +41,6 @@ import static org.jetbrains.plugins.groovy.lang.parser.parsing.statements.expres
*/
public class ExpressionStatement implements GroovyElementTypes {
@Nullable
private static IElementType parseExpressionStatement(PsiBuilder builder, GroovyParser parser) {
if (checkForTypeCast(builder, parser)) return CAST_EXPRESSION;
PsiBuilder.Marker marker = builder.mark();
@@ -78,15 +76,21 @@ public class ExpressionStatement implements GroovyElementTypes {
return AssignmentExpression.parse(builder, parser);
}
public static boolean parse(PsiBuilder builder, GroovyParser parser) {
enum Result {
WRONG_WAY, EXPR_STATEMENT, EXPRESSION
}
public static Result parse(PsiBuilder builder, GroovyParser parser) {
PsiBuilder.Marker marker = builder.mark();
final IElementType result = parseExpressionStatement(builder, parser);
if (result != CALL_EXPRESSION && result != PATH_METHOD_CALL) {
marker.drop();
return result != WRONGWAY;
return result == WRONGWAY ? Result.WRONG_WAY : Result.EXPRESSION;
}
boolean isExprStatement = result == CALL_EXPRESSION;
while (true) {
boolean nameParsed = namePartParse(builder, parser) == REFERENCE_EXPRESSION;
@@ -123,6 +127,7 @@ public class ExpressionStatement implements GroovyElementTypes {
exprStatement.done(PATH_METHOD_CALL);
}
else if (nameParsed && CommandArguments.parseCommandArguments(builder, parser)) {
isExprStatement = true;
exprStatement.done(CALL_EXPRESSION);
}
else {
@@ -133,7 +138,7 @@ public class ExpressionStatement implements GroovyElementTypes {
marker = exprStatement.precede();
}
return true;
return isExprStatement ? Result.EXPR_STATEMENT : Result.EXPRESSION;
}
private static GroovyElementType namePartParse(PsiBuilder builder, GroovyParser parser) {
@@ -45,6 +45,10 @@ public class StatementsParsingTest extends GroovyParsingTestCase {
public void testDeclaration$decl9() throws Throwable { doTest(); }
public void testDeclaration$decl12() throws Throwable { doTest(); }
public void testDeclaration$decl13() throws Throwable { doTest(); }
public void testDeclaration$exprStatement() throws Throwable { doTest(); }
public void testDeclaration$conditional1() throws Throwable { doTest(); }
public void testDeclaration$conditional2() throws Throwable { doTest(); }
public void testDeclaration$conditional3() throws Throwable { doTest(); }
public void testDeclaration$dollar() throws Throwable {doTest();}
public void testDeclaration$groovyMain() throws Throwable { doTest(); }
@@ -0,0 +1,28 @@
def a = foo() ? bar: test
-----
Groovy script
Variable definitions
Modifiers
PsiElement(def)('def')
PsiWhiteSpace(' ')
Variable
PsiElement(identifier)('a')
PsiWhiteSpace(' ')
PsiElement(=)('=')
PsiWhiteSpace(' ')
Conditional expression
Method call
Reference expression
PsiElement(identifier)('foo')
Arguments
PsiElement(()('(')
PsiElement())(')')
PsiWhiteSpace(' ')
PsiElement(?)('?')
PsiWhiteSpace(' ')
Reference expression
PsiElement(identifier)('bar')
PsiElement(:)(':')
PsiWhiteSpace(' ')
Reference expression
PsiElement(identifier)('test')
@@ -0,0 +1,20 @@
def a = foo ?: test
-----
Groovy script
Variable definitions
Modifiers
PsiElement(def)('def')
PsiWhiteSpace(' ')
Variable
PsiElement(identifier)('a')
PsiWhiteSpace(' ')
PsiElement(=)('=')
PsiWhiteSpace(' ')
Elvis expression
Reference expression
PsiElement(identifier)('foo')
PsiWhiteSpace(' ')
PsiElement(?:)('?:')
PsiWhiteSpace(' ')
Reference expression
PsiElement(identifier)('test')
@@ -0,0 +1,45 @@
def a = foo(1, 2).bar().test ? ab : c
-----
Groovy script
Variable definitions
Modifiers
PsiElement(def)('def')
PsiWhiteSpace(' ')
Variable
PsiElement(identifier)('a')
PsiWhiteSpace(' ')
PsiElement(=)('=')
PsiWhiteSpace(' ')
Conditional expression
Reference expression
Method call
Reference expression
Method call
Reference expression
PsiElement(identifier)('foo')
Arguments
PsiElement(()('(')
Literal
PsiElement(Integer)('1')
PsiElement(,)(',')
PsiWhiteSpace(' ')
Literal
PsiElement(Integer)('2')
PsiElement())(')')
PsiElement(.)('.')
PsiElement(identifier)('bar')
Arguments
PsiElement(()('(')
PsiElement())(')')
PsiElement(.)('.')
PsiElement(identifier)('test')
PsiWhiteSpace(' ')
PsiElement(?)('?')
PsiWhiteSpace(' ')
Reference expression
PsiElement(identifier)('ab')
PsiWhiteSpace(' ')
PsiElement(:)(':')
PsiWhiteSpace(' ')
Reference expression
PsiElement(identifier)('c')
@@ -0,0 +1,34 @@
def a = foo 1, 2 bar 4 foo
-----
Groovy script
Variable definitions
Modifiers
PsiElement(def)('def')
PsiWhiteSpace(' ')
Variable
PsiElement(identifier)('a')
PsiWhiteSpace(' ')
PsiElement(=)('=')
PsiWhiteSpace(' ')
Reference expression
Call expression
Reference expression
Call expression
Reference expression
PsiElement(identifier)('foo')
PsiWhiteSpace(' ')
Command arguments
Literal
PsiElement(Integer)('1')
PsiElement(,)(',')
PsiWhiteSpace(' ')
Literal
PsiElement(Integer)('2')
PsiWhiteSpace(' ')
PsiElement(identifier)('bar')
PsiWhiteSpace(' ')
Command arguments
Literal
PsiElement(Integer)('4')
PsiWhiteSpace(' ')
PsiElement(identifier)('foo')