reworked int/hex/long handling - more consistent and reliable now
This commit is contained in:
parent
a06b5aaa8d
commit
2173a49855
|
|
@ -17,33 +17,18 @@ package org.springframework.expression.spel.ast;
|
|||
|
||||
import org.antlr.runtime.Token;
|
||||
|
||||
/**
|
||||
* Expression language AST node that represents an integer literal.
|
||||
*
|
||||
* @author Andy Clement
|
||||
*/
|
||||
public class IntLiteral extends Literal {
|
||||
|
||||
private static String[] suffixes = {"UL" , "LU" , "ul" , "lu" , "uL" , "lU" , "U" , "L" , "u" , "l" };
|
||||
|
||||
private Integer value;
|
||||
private final Integer value;
|
||||
|
||||
public IntLiteral(Token payload) {
|
||||
IntLiteral(Token payload, int value) {
|
||||
super(payload);
|
||||
// TODO properly support longs and unsigned numbers
|
||||
String toParse = payload.getText();
|
||||
try {
|
||||
value = Integer.parseInt(toParse);
|
||||
} catch (NumberFormatException nfe) {
|
||||
for (int i=0;i<suffixes.length;i++) {
|
||||
if (toParse.endsWith(suffixes[i])) {
|
||||
value = Integer.parseInt(toParse.substring(0,toParse.length()-suffixes[i].length()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
throw nfe;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public IntLiteral(Token payload, int radix) {
|
||||
super(payload);
|
||||
value = Integer.parseInt(payload.getText().substring(2), radix);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -16,8 +16,10 @@
|
|||
package org.springframework.expression.spel.ast;
|
||||
|
||||
import org.antlr.runtime.Token;
|
||||
import org.springframework.expression.spel.SpelException;
|
||||
import org.springframework.expression.spel.ExpressionState;
|
||||
import org.springframework.expression.spel.SpelException;
|
||||
import org.springframework.expression.spel.SpelMessages;
|
||||
import org.springframework.expression.spel.internal.InternalELException;
|
||||
|
||||
/**
|
||||
* Common superclass for nodes representing literals (boolean, string, number, etc).
|
||||
|
|
@ -53,4 +55,47 @@ public abstract class Literal extends SpelNode {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the string form of a number, using the specified base if supplied and return an appropriate literal to
|
||||
* hold it. Any suffix to indicate a long will be taken into account (either 'l' or 'L' is supported).
|
||||
*
|
||||
* @param numberToken the token holding the number as its payload (eg. 1234 or 0xCAFE)
|
||||
* @param radix the base of number
|
||||
* @return a subtype of Literal that can represent it
|
||||
*/
|
||||
public static Literal getIntLiteral(Token numberToken, int radix) {
|
||||
String numberString = numberToken.getText();
|
||||
|
||||
boolean isLong = false;
|
||||
boolean isHex = (radix == 16);
|
||||
|
||||
if (numberString.length() > 0) {
|
||||
isLong = numberString.endsWith("L") || numberString.endsWith("l");
|
||||
}
|
||||
|
||||
if (isLong || isHex) { // needs to be chopped up a little
|
||||
int len = numberString.length();
|
||||
// assert: if hex then startsWith 0x or 0X
|
||||
numberString = numberString.substring((isHex ? 2 : 0), isLong ? len - 1 : len);
|
||||
}
|
||||
|
||||
if (isLong) {
|
||||
try {
|
||||
long value = Long.parseLong(numberString, radix);
|
||||
return new LongLiteral(numberToken, value);
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new InternalELException(new SpelException(numberToken.getCharPositionInLine(), nfe,
|
||||
SpelMessages.NOT_A_LONG, numberToken.getText()));
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
int value = Integer.parseInt(numberString, radix);
|
||||
return new IntLiteral(numberToken, value);
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new InternalELException(new SpelException(numberToken.getCharPositionInLine(), nfe,
|
||||
SpelMessages.NOT_AN_INTEGER, numberToken.getText()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright 2004-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springframework.expression.spel.ast;
|
||||
|
||||
import org.antlr.runtime.Token;
|
||||
|
||||
/**
|
||||
* Expression language AST node that represents a long integer literal.
|
||||
*
|
||||
* @author Andy Clement
|
||||
*/
|
||||
public class LongLiteral extends Literal {
|
||||
|
||||
private final Long value;
|
||||
|
||||
LongLiteral(Token payload, long value) {
|
||||
super(payload);
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Long getLiteralValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -28,9 +28,9 @@ import org.springframework.expression.spel.ast.ExpressionListNode;
|
|||
import org.springframework.expression.spel.ast.FunctionReference;
|
||||
import org.springframework.expression.spel.ast.Identifier;
|
||||
import org.springframework.expression.spel.ast.Indexer;
|
||||
import org.springframework.expression.spel.ast.IntLiteral;
|
||||
import org.springframework.expression.spel.ast.Lambda;
|
||||
import org.springframework.expression.spel.ast.ListInitializer;
|
||||
import org.springframework.expression.spel.ast.Literal;
|
||||
import org.springframework.expression.spel.ast.LocalFunctionReference;
|
||||
import org.springframework.expression.spel.ast.LocalVariableReference;
|
||||
import org.springframework.expression.spel.ast.MapEntry;
|
||||
|
|
@ -94,9 +94,9 @@ public class SpelTreeAdaptor extends CommonTreeAdaptor {
|
|||
case SpringExpressionsLexer.REAL_LITERAL:
|
||||
return new RealLiteral(payload);
|
||||
case SpringExpressionsLexer.INTEGER_LITERAL:
|
||||
return new IntLiteral(payload);
|
||||
return Literal.getIntLiteral(payload, 10);
|
||||
case SpringExpressionsLexer.HEXADECIMAL_INTEGER_LITERAL:
|
||||
return new IntLiteral(payload, 16/* HEX */);
|
||||
return Literal.getIntLiteral(payload, 16);
|
||||
|
||||
case SpringExpressionsLexer.NOT_EQUAL:
|
||||
return new OperatorInequality(payload);
|
||||
|
|
|
|||
Loading…
Reference in New Issue