use of org.apache.groovy.parser.antlr4.GroovyParser.INSTANCEOF in project groovy by apache.
the class AstBuilder method visitSwitchBlockStatementExpressionGroup.
@Override
@SuppressWarnings("unchecked")
public Tuple3<List<Statement>, Boolean, Boolean> visitSwitchBlockStatementExpressionGroup(SwitchBlockStatementExpressionGroupContext ctx) {
int labelCnt = ctx.switchExpressionLabel().size();
List<Token> firstLabelHolder = new ArrayList<>(1);
final int[] arrowCntHolder = new int[1];
boolean[] isArrowHolder = new boolean[1];
boolean[] hasResultStmtHolder = new boolean[1];
List<Statement> result = (List<Statement>) ctx.switchExpressionLabel().stream().map(e -> (Object) this.visitSwitchExpressionLabel(e)).reduce(new ArrayList<Statement>(4), (r, e) -> {
List<Statement> statementList = (List<Statement>) r;
Tuple3<Token, List<Expression>, Integer> tuple = (Tuple3<Token, List<Expression>, Integer>) e;
boolean isArrow = ARROW == tuple.getV3();
isArrowHolder[0] = isArrow;
if (isArrow) {
if (++arrowCntHolder[0] > 1 && !firstLabelHolder.isEmpty()) {
throw createParsingFailedException("`case ... ->` does not support falling through cases", firstLabelHolder.get(0));
}
}
boolean isLast = labelCnt - 1 == statementList.size();
BlockStatement codeBlock = this.visitBlockStatements(ctx.blockStatements());
List<Statement> statements = codeBlock.getStatements();
int statementsCnt = statements.size();
if (0 == statementsCnt) {
throw createParsingFailedException("`yield` is expected", ctx.blockStatements());
}
if (isArrow && statementsCnt > 1) {
throw createParsingFailedException("Expect only 1 statement, but " + statementsCnt + " statements found", ctx.blockStatements());
}
if (!isArrow) {
boolean[] hasYieldHolder = new boolean[1];
boolean[] hasThrowHolder = new boolean[1];
codeBlock.visit(new CodeVisitorSupport() {
@Override
public void visitReturnStatement(ReturnStatement statement) {
if (isTrue(statement, IS_YIELD_STATEMENT)) {
hasYieldHolder[0] = true;
return;
}
super.visitReturnStatement(statement);
}
@Override
public void visitThrowStatement(ThrowStatement statement) {
hasThrowHolder[0] = true;
}
});
if (hasYieldHolder[0] || hasThrowHolder[0]) {
hasResultStmtHolder[0] = true;
}
}
Statement exprOrBlockStatement = statements.get(0);
if (exprOrBlockStatement instanceof BlockStatement) {
BlockStatement blockStatement = (BlockStatement) exprOrBlockStatement;
List<Statement> branchStatementList = blockStatement.getStatements();
if (1 == branchStatementList.size()) {
exprOrBlockStatement = branchStatementList.get(0);
}
}
if (!(exprOrBlockStatement instanceof ReturnStatement || exprOrBlockStatement instanceof ThrowStatement)) {
if (isArrow) {
MethodCallExpression callClosure = callX(configureAST(closureX(null, exprOrBlockStatement), exprOrBlockStatement), "call");
callClosure.setImplicitThis(false);
Expression resultExpr = exprOrBlockStatement instanceof ExpressionStatement ? ((ExpressionStatement) exprOrBlockStatement).getExpression() : callClosure;
codeBlock = configureAST(createBlockStatement(configureAST(returnS(resultExpr), exprOrBlockStatement)), exprOrBlockStatement);
}
}
switch(tuple.getV1().getType()) {
case CASE:
{
if (!asBoolean(statementList)) {
firstLabelHolder.add(tuple.getV1());
}
for (int i = 0, n = tuple.getV2().size(); i < n; i++) {
Expression expr = tuple.getV2().get(i);
statementList.add(configureAST(new CaseStatement(expr, // check whether processing the last label. if yes, block statement should be attached.
(isLast && i == n - 1) ? codeBlock : EmptyStatement.INSTANCE), firstLabelHolder.get(0)));
}
break;
}
case DEFAULT:
{
codeBlock.putNodeMetaData(IS_SWITCH_DEFAULT, true);
statementList.add(// this.configureAST(codeBlock, tuple.getKey())
codeBlock);
break;
}
}
return statementList;
});
return tuple(result, isArrowHolder[0], hasResultStmtHolder[0]);
}
use of org.apache.groovy.parser.antlr4.GroovyParser.INSTANCEOF in project groovy by apache.
the class SemanticPredicates method isFollowingArgumentsOrClosure.
/**
* Check whether following a method name of command expression.
* Method name should not end with "2: arguments" and "3: closure"
*
* @param context the preceding expression
*/
public static boolean isFollowingArgumentsOrClosure(ExpressionContext context) {
if (context instanceof PostfixExprAltContext) {
List<ParseTree> peacChildren = ((PostfixExprAltContext) context).children;
try {
ParseTree peacChild = peacChildren.get(0);
List<ParseTree> pecChildren = ((PostfixExpressionContext) peacChild).children;
ParseTree pecChild = pecChildren.get(0);
PathExpressionContext pec = (PathExpressionContext) pecChild;
int t = pec.t;
return (2 == t || 3 == t);
} catch (IndexOutOfBoundsException | ClassCastException e) {
throw new GroovyBugError("Unexpected structure of expression context: " + context, e);
}
}
return false;
}
use of org.apache.groovy.parser.antlr4.GroovyParser.INSTANCEOF in project groovy by apache.
the class AstBuilder method visitContinueStatement.
@Override
public ContinueStatement visitContinueStatement(final ContinueStatementContext ctx) {
if (visitingLoopStatementCount == 0) {
throw createParsingFailedException("continue statement is only allowed inside loops", ctx);
}
GroovyParserRuleContext gprc = switchExpressionRuleContextStack.peek();
if (gprc instanceof SwitchExpressionContext) {
throw createParsingFailedException("switch expression does not support `continue`", ctx);
}
String label = asBoolean(ctx.identifier()) ? this.visitIdentifier(ctx.identifier()) : null;
return configureAST(new ContinueStatement(label), ctx);
}
use of org.apache.groovy.parser.antlr4.GroovyParser.INSTANCEOF in project groovy by apache.
the class AstBuilder method visitCommandExpression.
@Override
public Expression visitCommandExpression(final CommandExpressionContext ctx) {
boolean hasArgumentList = asBoolean(ctx.enhancedArgumentListInPar());
boolean hasCommandArgument = asBoolean(ctx.commandArgument());
if ((hasArgumentList || hasCommandArgument) && visitingArrayInitializerCount > 0) {
// SEE http://groovy.329449.n5.nabble.com/parrot-Command-expressions-in-array-initializer-tt5752273.html
throw createParsingFailedException("Command chain expression can not be used in array initializer", ctx);
}
Expression baseExpr = (Expression) this.visit(ctx.expression());
if ((hasArgumentList || hasCommandArgument) && !isInsideParentheses(baseExpr) && baseExpr instanceof BinaryExpression && !"[".equals(((BinaryExpression) baseExpr).getOperation().getText())) {
throw createParsingFailedException("Unexpected input: '" + getOriginalText(ctx.expression()) + "'", ctx.expression());
}
MethodCallExpression methodCallExpression = null;
if (hasArgumentList) {
Expression arguments = this.visitEnhancedArgumentListInPar(ctx.enhancedArgumentListInPar());
if (baseExpr instanceof PropertyExpression) {
// e.g. obj.a 1, 2
methodCallExpression = configureAST(this.createMethodCallExpression((PropertyExpression) baseExpr, arguments), ctx.expression(), arguments);
} else if (baseExpr instanceof MethodCallExpression && !isInsideParentheses(baseExpr)) {
// e.g. m {} a, b OR m(...) a, b
if (asBoolean(arguments)) {
// The error should never be thrown.
throw new GroovyBugError("When baseExpr is a instance of MethodCallExpression, which should follow NO argumentList");
}
methodCallExpression = (MethodCallExpression) baseExpr;
} else if (!isInsideParentheses(baseExpr) && (// e.g. m 1, 2
baseExpr instanceof VariableExpression || // e.g. "$m" 1, 2
baseExpr instanceof GStringExpression || (baseExpr instanceof ConstantExpression && isTrue(baseExpr, IS_STRING)))) {
// e.g. "m" 1, 2
validateInvalidMethodDefinition(baseExpr, arguments);
methodCallExpression = configureAST(this.createMethodCallExpression(baseExpr, arguments), ctx.expression(), arguments);
} else {
// e.g. a[x] b, new A() b, etc.
methodCallExpression = configureAST(this.createCallMethodCallExpression(baseExpr, arguments), ctx.expression(), arguments);
}
methodCallExpression.putNodeMetaData(IS_COMMAND_EXPRESSION, Boolean.TRUE);
if (!hasCommandArgument) {
return methodCallExpression;
}
}
if (hasCommandArgument) {
baseExpr.putNodeMetaData(IS_COMMAND_EXPRESSION, Boolean.TRUE);
}
return configureAST((Expression) ctx.commandArgument().stream().map(e -> (Object) e).reduce(methodCallExpression != null ? methodCallExpression : baseExpr, (r, e) -> {
CommandArgumentContext commandArgumentContext = (CommandArgumentContext) e;
commandArgumentContext.putNodeMetaData(CMD_EXPRESSION_BASE_EXPR, r);
return this.visitCommandArgument(commandArgumentContext);
}), ctx);
}
use of org.apache.groovy.parser.antlr4.GroovyParser.INSTANCEOF in project groovy by apache.
the class AstBuilder method visitBreakStatement.
@Override
public BreakStatement visitBreakStatement(final BreakStatementContext ctx) {
if (0 == visitingLoopStatementCount && 0 == visitingSwitchStatementCount) {
throw createParsingFailedException("break statement is only allowed inside loops or switches", ctx);
}
GroovyParserRuleContext gprc = switchExpressionRuleContextStack.peek();
if (gprc instanceof SwitchExpressionContext) {
throw createParsingFailedException("switch expression does not support `break`", ctx);
}
String label = asBoolean(ctx.identifier()) ? this.visitIdentifier(ctx.identifier()) : null;
return configureAST(new BreakStatement(label), ctx);
}
Aggregations