This commit is contained in:
Andy Clement 2011-05-11 23:41:30 +00:00
parent 2f733bedc5
commit 580f35f6ee
4 changed files with 68 additions and 7 deletions

View File

@ -599,7 +599,7 @@ class InternalSpelExpressionParser extends TemplateAwareExpressionParser {
// This is complicated due to the support for dollars in identifiers. Dollars are normally separate tokens but
// there we want to combine a series of identifiers and dollars into a single identifier
private boolean maybeEatMethodOrProperty(boolean nullSafeNavigation) {
if (peekToken(TokenKind.IDENTIFIER)) {
if (peekToken(TokenKind.IDENTIFIER)) {
Token methodOrPropertyName = nextToken();
SpelNodeImpl[] args = maybeEatMethodArgs();
if (args==null) {
@ -761,6 +761,14 @@ class InternalSpelExpressionParser extends TemplateAwareExpressionParser {
}
return true;
} else {
if (desiredTokenKind == TokenKind.IDENTIFIER) {
// might be one of the textual forms of the operators (e.g. NE for != ) - in which case we can treat it as an identifier
// The list is represented here: Tokenizer.alternativeOperatorNames and those ones are in order in the TokenKind enum
if (t.kind.ordinal()>=TokenKind.DIV.ordinal() && t.kind.ordinal()<=TokenKind.NOT.ordinal() && t.data!=null) {
// if t.data were null, we'd know it wasn't the textual form, it was the symbol form
return true;
}
}
return false;
}
}

View File

@ -25,9 +25,10 @@ enum TokenKind {
LPAREN("("), RPAREN(")"), COMMA(","), IDENTIFIER,
COLON(":"),HASH("#"),RSQUARE("]"), LSQUARE("["),
LCURLY("{"),RCURLY("}"),
DOT("."), PLUS("+"), STAR("*"), DIV("/"), NOT("!"), MINUS("-"), SELECT_FIRST("^["), SELECT_LAST("$["), QMARK("?"), PROJECT("!["),
GE(">="),GT(">"),LE("<="),LT("<"),EQ("=="),NE("!="),ASSIGN("="), INSTANCEOF("instanceof"), MATCHES("matches"), BETWEEN("between"),
SELECT("?["), MOD("%"), POWER("^"),
DOT("."), PLUS("+"), STAR("*"), MINUS("-"), SELECT_FIRST("^["), SELECT_LAST("$["), QMARK("?"), PROJECT("!["),
DIV("/"), GE(">="), GT(">"), LE("<="), LT("<"), EQ("=="), NE("!="),
MOD("%"), NOT("!"), ASSIGN("="), INSTANCEOF("instanceof"), MATCHES("matches"), BETWEEN("between"),
SELECT("?["), POWER("^"),
ELVIS("?:"), SAFE_NAVI("?."), BEAN_REF("@")
;

View File

@ -360,7 +360,7 @@ class Tokenizer {
String asString = new String(subarray).toUpperCase();
int idx = Arrays.binarySearch(alternativeOperatorNames,asString);
if (idx>=0) {
pushOneCharOrTwoCharToken(TokenKind.valueOf(asString),start);
pushOneCharOrTwoCharToken(TokenKind.valueOf(asString),start,subarray);
return;
}
}
@ -429,8 +429,8 @@ class Tokenizer {
pos+=2;
}
private void pushOneCharOrTwoCharToken(TokenKind kind, int pos) {
tokens.add(new Token(kind,pos,pos+kind.getLength()));
private void pushOneCharOrTwoCharToken(TokenKind kind, int pos, char[] data) {
tokens.add(new Token(kind,data,pos,pos+kind.getLength()));
}
// ID: ('a'..'z'|'A'..'Z'|'_'|'$') ('a'..'z'|'A'..'Z'|'_'|'$'|'0'..'9'|DOT_ESCAPED)*;

View File

@ -1008,4 +1008,56 @@ public class SpringEL300Tests extends ExpressionTestCase {
}
}
@Test
public void testReservedWords_8228() throws Exception {
// "DIV","EQ","GE","GT","LE","LT","MOD","NE","NOT"
@SuppressWarnings("unused")
class Reserver {
public Reserver getReserver() {
return this;
}
public String NE = "abc";
public String ne = "def";
public int DIV = 1;
public int div = 3;
public Map m = new HashMap();
@SuppressWarnings("unchecked")
Reserver() {
m.put("NE","xyz");
}
}
StandardEvaluationContext ctx = new StandardEvaluationContext(new Reserver());
SpelExpressionParser parser = new SpelExpressionParser();
String ex = "getReserver().NE";
SpelExpression exp = null;
exp = parser.parseRaw(ex);
String value = (String)exp.getValue(ctx);
Assert.assertEquals("abc",value);
ex = "getReserver().ne";
exp = parser.parseRaw(ex);
value = (String)exp.getValue(ctx);
Assert.assertEquals("def",value);
ex = "getReserver().m[NE]";
exp = parser.parseRaw(ex);
value = (String)exp.getValue(ctx);
Assert.assertEquals("xyz",value);
ex = "getReserver().DIV";
exp = parser.parseRaw(ex);
Assert.assertEquals(1,exp.getValue(ctx));
ex = "getReserver().div";
exp = parser.parseRaw(ex);
Assert.assertEquals(3,exp.getValue(ctx));
exp = parser.parseRaw("NE");
Assert.assertEquals("abc",exp.getValue(ctx));
}
}