private boolean maybeEatNullReference() { if (peekToken(TokenKind.IDENTIFIER)) { Token nullToken = peekToken(); Assert.state(nullToken != null, "Expected token"); if (!"null".equalsIgnoreCase(nullToken.stringValue())) { return false; } nextToken(); this.constructedNodes.push(new NullLiteral(nullToken.startPos, nullToken.endPos)); return true; } return false; }
private Token eatToken(TokenKind expectedKind) { Token t = nextToken(); if (t == null) { int pos = this.expressionString.length(); throw internalException(pos, SpelMessage.OOD); } if (t.kind != expectedKind) { throw internalException(t.startPos, SpelMessage.NOT_EXPECTED_TOKEN, expectedKind.toString().toLowerCase(), t.getKind().toString().toLowerCase()); } return t; }
private boolean maybeEatParenExpression() { if (peekToken(TokenKind.LPAREN)) { nextToken(); SpelNodeImpl expr = eatExpression(); Assert.state(expr != null, "No node"); eatToken(TokenKind.RPAREN); push(expr); return true; } else { return false; } }
@Override protected SpelExpression doParseExpression(String expressionString, @Nullable ParserContext context) throws ParseException { try { this.expressionString = expressionString; Tokenizer tokenizer = new Tokenizer(expressionString); this.tokenStream = tokenizer.process(); this.tokenStreamLength = this.tokenStream.size(); this.tokenStreamPointer = 0; this.constructedNodes.clear(); SpelNodeImpl ast = eatExpression(); Assert.state(ast != null, "No node"); Token t = peekToken(); if (t != null) { throw new SpelParseException(t.startPos, SpelMessage.MORE_INPUT, toString(nextToken())); } Assert.isTrue(this.constructedNodes.isEmpty(), "At least one node expected"); return new SpelExpression(expressionString, ast, this.configuration); } catch (InternalParseException ex) { throw ex.getCause(); } }
private boolean maybeEatSelection(boolean nullSafeNavigation) { Token t = peekToken(); if (!peekSelectToken()) { return false; } Assert.state(t != null, "No token"); nextToken(); SpelNodeImpl expr = eatExpression(); if (expr == null) { throw internalException(t.startPos, SpelMessage.MISSING_SELECTION_EXPRESSION); } eatToken(TokenKind.RSQUARE); if (t.kind == TokenKind.SELECT_FIRST) { this.constructedNodes.push(new Selection(nullSafeNavigation, Selection.FIRST, t.startPos, t.endPos, expr)); } else if (t.kind == TokenKind.SELECT_LAST) { this.constructedNodes.push(new Selection(nullSafeNavigation, Selection.LAST, t.startPos, t.endPos, expr)); } else { this.constructedNodes.push(new Selection(nullSafeNavigation, Selection.ALL, t.startPos, t.endPos, expr)); } return true; }
/** * Used for consuming arguments for either a method or a constructor call. */ private void consumeArguments(List<SpelNodeImpl> accumulatedArguments) { Token t = peekToken(); Assert.state(t != null, "Expected token"); int pos = t.startPos; Token next; do { nextToken(); // consume (first time through) or comma (subsequent times) t = peekToken(); if (t == null) { throw internalException(pos, SpelMessage.RUN_OUT_OF_ARGUMENTS); } if (t.kind != TokenKind.RPAREN) { accumulatedArguments.add(eatExpression()); } next = peekToken(); } while (next != null && next.kind == TokenKind.COMMA); if (next == null) { throw internalException(pos, SpelMessage.RUN_OUT_OF_ARGUMENTS); } }
/** * Eat an identifier, possibly qualified (meaning that it is dotted). * TODO AndyC Could create complete identifiers (a.b.c) here rather than a sequence of them? (a, b, c) */ private SpelNodeImpl eatPossiblyQualifiedId() { Deque<SpelNodeImpl> qualifiedIdPieces = new ArrayDeque<>(); Token node = peekToken(); while (isValidQualifiedId(node)) { nextToken(); if (node.kind != TokenKind.DOT) { qualifiedIdPieces.add(new Identifier(node.stringValue(), node.startPos, node.endPos)); } node = peekToken(); } if (qualifiedIdPieces.isEmpty()) { if (node == null) { throw internalException( this.expressionString.length(), SpelMessage.OOD); } throw internalException(node.startPos, SpelMessage.NOT_EXPECTED_TOKEN, "qualified ID", node.getKind().toString().toLowerCase()); } return new QualifiedIdentifier(qualifiedIdPieces.getFirst().getStartPosition(), qualifiedIdPieces.getLast().getEndPosition(), qualifiedIdPieces.toArray(new SpelNodeImpl[0])); }
private Token eatToken(TokenKind expectedKind) { Token t = nextToken(); if (t == null) { int pos = this.expressionString.length(); throw internalException(pos, SpelMessage.OOD); } if (t.kind != expectedKind) { throw internalException(t.startPos, SpelMessage.NOT_EXPECTED_TOKEN, expectedKind.toString().toLowerCase(), t.getKind().toString().toLowerCase()); } return t; }
private boolean maybeEatNullReference() { if (peekToken(TokenKind.IDENTIFIER)) { Token nullToken = peekToken(); Assert.state(nullToken != null, "Expected token"); if (!"null".equalsIgnoreCase(nullToken.stringValue())) { return false; } nextToken(); this.constructedNodes.push(new NullLiteral(toPos(nullToken))); return true; } return false; }
private boolean maybeEatParenExpression() { if (peekToken(TokenKind.LPAREN)) { nextToken(); SpelNodeImpl expr = eatExpression(); Assert.state(expr != null, "No node"); eatToken(TokenKind.RPAREN); push(expr); return true; } else { return false; } }
@Override protected SpelExpression doParseExpression(String expressionString, @Nullable ParserContext context) throws ParseException { try { this.expressionString = expressionString; Tokenizer tokenizer = new Tokenizer(expressionString); this.tokenStream = tokenizer.process(); this.tokenStreamLength = this.tokenStream.size(); this.tokenStreamPointer = 0; this.constructedNodes.clear(); SpelNodeImpl ast = eatExpression(); Assert.state(ast != null, "No node"); Token t = peekToken(); if (t != null) { throw new SpelParseException(t.startPos, SpelMessage.MORE_INPUT, toString(nextToken())); } Assert.isTrue(this.constructedNodes.isEmpty(), "At least one node expected"); return new SpelExpression(expressionString, ast, this.configuration); } catch (InternalParseException ex) { throw ex.getCause(); } }
expr = new NullLiteral(t.startPos - 1, t.endPos - 1); nextToken(); SpelNodeImpl assignedValue = eatLogicalOrExpression(); return new Assign(t.startPos, t.endPos, expr, assignedValue); expr = new NullLiteral(t.startPos - 1, t.endPos - 2); nextToken(); // elvis has left the building SpelNodeImpl valueIfNull = eatExpression(); if (valueIfNull == null) { expr = new NullLiteral(t.startPos - 1, t.endPos - 1); nextToken(); SpelNodeImpl ifTrueExprValue = eatExpression(); eatToken(TokenKind.COLON);
/** * Used for consuming arguments for either a method or a constructor call. */ private void consumeArguments(List<SpelNodeImpl> accumulatedArguments) { Token t = peekToken(); Assert.state(t != null, "Expected token"); int pos = t.startPos; Token next; do { nextToken(); // consume (first time through) or comma (subsequent times) t = peekToken(); if (t == null) { throw internalException(pos, SpelMessage.RUN_OUT_OF_ARGUMENTS); } if (t.kind != TokenKind.RPAREN) { accumulatedArguments.add(eatExpression()); } next = peekToken(); } while (next != null && next.kind == TokenKind.COMMA); if (next == null) { throw internalException(pos, SpelMessage.RUN_OUT_OF_ARGUMENTS); } }
/** * Eat an identifier, possibly qualified (meaning that it is dotted). * TODO AndyC Could create complete identifiers (a.b.c) here rather than a sequence of them? (a, b, c) */ private SpelNodeImpl eatPossiblyQualifiedId() { Deque<SpelNodeImpl> qualifiedIdPieces = new ArrayDeque<>(); Token node = peekToken(); while (isValidQualifiedId(node)) { nextToken(); if (node.kind != TokenKind.DOT) { qualifiedIdPieces.add(new Identifier(node.stringValue(), toPos(node))); } node = peekToken(); } if (qualifiedIdPieces.isEmpty()) { if (node == null) { throw internalException( this.expressionString.length(), SpelMessage.OOD); } throw internalException(node.startPos, SpelMessage.NOT_EXPECTED_TOKEN, "qualified ID", node.getKind().toString().toLowerCase()); } int pos = toPos(qualifiedIdPieces.getFirst().getStartPosition(), qualifiedIdPieces.getLast().getEndPosition()); return new QualifiedIdentifier(pos, qualifiedIdPieces.toArray(new SpelNodeImpl[0])); }
private boolean maybeEatSelection(boolean nullSafeNavigation) { Token t = peekToken(); if (!peekSelectToken()) { return false; } Assert.state(t != null, "No token"); nextToken(); SpelNodeImpl expr = eatExpression(); if (expr == null) { throw internalException(toPos(t), SpelMessage.MISSING_SELECTION_EXPRESSION); } eatToken(TokenKind.RSQUARE); if (t.kind == TokenKind.SELECT_FIRST) { this.constructedNodes.push(new Selection(nullSafeNavigation, Selection.FIRST, toPos(t), expr)); } else if (t.kind == TokenKind.SELECT_LAST) { this.constructedNodes.push(new Selection(nullSafeNavigation, Selection.LAST, toPos(t), expr)); } else { this.constructedNodes.push(new Selection(nullSafeNavigation, Selection.ALL, toPos(t), expr)); } return true; }
expr = new NullLiteral(toPos(t.startPos - 1, t.endPos - 1)); nextToken(); SpelNodeImpl assignedValue = eatLogicalOrExpression(); return new Assign(toPos(t), expr, assignedValue); expr = new NullLiteral(toPos(t.startPos - 1, t.endPos - 2)); nextToken(); // elvis has left the building SpelNodeImpl valueIfNull = eatExpression(); if (valueIfNull == null) { expr = new NullLiteral(toPos(t.startPos - 1, t.endPos - 1)); nextToken(); SpelNodeImpl ifTrueExprValue = eatExpression(); eatToken(TokenKind.COLON);
return false; nextToken(); return true;
return false; nextToken(); return true;
private Token eatToken(TokenKind expectedKind) { Token t = nextToken(); if (t == null) { int pos = this.expressionString.length(); throw internalException(pos, SpelMessage.OOD); } if (t.kind != expectedKind) { throw internalException(t.startPos, SpelMessage.NOT_EXPECTED_TOKEN, expectedKind.toString().toLowerCase(), t.getKind().toString().toLowerCase()); } return t; }
private boolean maybeEatParenExpression() { if (peekToken(TokenKind.LPAREN)) { nextToken(); SpelNodeImpl expr = eatExpression(); Assert.state(expr != null, "No node"); eatToken(TokenKind.RPAREN); push(expr); return true; } else { return false; } }