use of org.apache.groovy.parser.antlr4.GroovyLexer.IF 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.GroovyLexer.IF in project groovy by apache.
the class AstBuilder method visitSwitchBlockStatementGroup.
@Override
@SuppressWarnings("unchecked")
public List<Statement> visitSwitchBlockStatementGroup(final SwitchBlockStatementGroupContext ctx) {
int labelCnt = ctx.switchLabel().size();
List<Token> firstLabelHolder = new ArrayList<>(1);
return (List<Statement>) ctx.switchLabel().stream().map(e -> (Object) this.visitSwitchLabel(e)).reduce(new ArrayList<Statement>(4), (r, e) -> {
List<Statement> statementList = (List<Statement>) r;
Tuple2<Token, Expression> tuple = (Tuple2<Token, Expression>) e;
boolean isLast = labelCnt - 1 == statementList.size();
switch(tuple.getV1().getType()) {
case CASE:
{
if (!asBoolean(statementList)) {
firstLabelHolder.add(tuple.getV1());
}
statementList.add(configureAST(new CaseStatement(tuple.getV2(), // check whether processing the last label. if yes, block statement should be attached.
isLast ? this.visitBlockStatements(ctx.blockStatements()) : EmptyStatement.INSTANCE), firstLabelHolder.get(0)));
break;
}
case DEFAULT:
{
BlockStatement blockStatement = this.visitBlockStatements(ctx.blockStatements());
blockStatement.putNodeMetaData(IS_SWITCH_DEFAULT, true);
statementList.add(// this.configureAST(blockStatement, tuple.getKey())
blockStatement);
break;
}
}
return statementList;
});
}
use of org.apache.groovy.parser.antlr4.GroovyLexer.IF in project groovy by apache.
the class AstBuilder method visitUnaryAddExprAlt.
@Override
public Expression visitUnaryAddExprAlt(final UnaryAddExprAltContext ctx) {
ExpressionContext expressionCtx = ctx.expression();
Expression expression = (Expression) this.visit(expressionCtx);
switch(ctx.op.getType()) {
case ADD:
{
if (isNonStringConstantOutsideParentheses(expression)) {
return configureAST(expression, ctx);
}
return configureAST(new UnaryPlusExpression(expression), ctx);
}
case SUB:
{
if (isNonStringConstantOutsideParentheses(expression)) {
ConstantExpression constantExpression = (ConstantExpression) expression;
try {
String integerLiteralText = constantExpression.getNodeMetaData(INTEGER_LITERAL_TEXT);
if (null != integerLiteralText) {
ConstantExpression result = new ConstantExpression(Numbers.parseInteger(SUB_STR + integerLiteralText));
// reset the numberFormatError
this.numberFormatError = null;
return configureAST(result, ctx);
}
String floatingPointLiteralText = constantExpression.getNodeMetaData(FLOATING_POINT_LITERAL_TEXT);
if (null != floatingPointLiteralText) {
ConstantExpression result = new ConstantExpression(Numbers.parseDecimal(SUB_STR + floatingPointLiteralText));
// reset the numberFormatError
this.numberFormatError = null;
return configureAST(result, ctx);
}
} catch (Exception e) {
throw createParsingFailedException(e.getMessage(), ctx);
}
throw new GroovyBugError("Failed to find the original number literal text: " + constantExpression.getText());
}
return configureAST(new UnaryMinusExpression(expression), ctx);
}
case INC:
case DEC:
return configureAST(new PrefixExpression(this.createGroovyToken(ctx.op), expression), ctx);
default:
throw createParsingFailedException("Unsupported unary operation: " + ctx.getText(), ctx);
}
}
use of org.apache.groovy.parser.antlr4.GroovyLexer.IF 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.GroovyLexer.IF in project groovy by apache.
the class SmartDocumentFilter method findTokensToRender.
private List<Token> findTokensToRender(List<Token> tokenList) {
final Tuple2<Integer, Integer> renderRange = getRenderRange();
if (null != renderRange) {
long startLine = lineNumber(renderRange.getV1());
long stopLine = lineNumber(renderRange.getV2());
// should never happen
if (startLine < 0 || stopLine < 0)
return tokenList;
return tokenList.stream().filter(e -> e.getLine() >= startLine && PositionConfigureUtils.endPosition(e).getV1() <= stopLine).collect(Collectors.toList());
}
List<Token> tmpLatestTokenList = filterNewlines(this.latestTokenList);
int latestTokenListSize = tmpLatestTokenList.size();
if (0 == latestTokenListSize) {
return tokenList;
}
List<Token> tmpTokenList = filterNewlines(tokenList);
int tmpTokenListSize = tmpTokenList.size();
if (0 == tmpTokenListSize) {
return tokenList;
}
int startTokenIndex = 0;
int minSize = Math.min(tmpTokenListSize, latestTokenListSize);
for (int i = 0; i < minSize; i++) {
Token token = tmpTokenList.get(i);
Token latestToken = tmpLatestTokenList.get(i);
if (token.getType() == latestToken.getType() && token.getStartIndex() == latestToken.getStartIndex() && token.getStopIndex() == latestToken.getStopIndex()) {
continue;
}
startTokenIndex = i;
break;
}
List<Token> newTokenList = new ReversedList<>(tmpTokenList);
List<Token> newLatestTokenList = new ReversedList<>(tmpLatestTokenList);
int stopTokenIndex = tmpTokenListSize;
Token lastToken = newTokenList.get(0);
Token lastLatestToken = newLatestTokenList.get(0);
for (int i = 0; i < minSize; i++) {
Token token = newTokenList.get(i);
Token latestToken = newLatestTokenList.get(i);
if ((token.getType() == latestToken.getType()) && (token.getStartIndex() - lastToken.getStartIndex()) == (latestToken.getStartIndex() - lastLatestToken.getStartIndex()) && ((token.getStopIndex() - lastToken.getStopIndex()) == (latestToken.getStopIndex() - lastLatestToken.getStopIndex()))) {
continue;
}
stopTokenIndex = tmpTokenListSize - i;
break;
}
if (startTokenIndex == stopTokenIndex) {
return tmpTokenListSize != latestTokenListSize ? tokenList : Collections.emptyList();
} else if (startTokenIndex < stopTokenIndex) {
return tmpTokenList.subList(startTokenIndex, stopTokenIndex);
}
// should never reach here. If unexpected error occurred, it's better to render all tokens
return tokenList;
}
Aggregations