提交 b2756f5b 编写于 作者: J Juergen Hoeller

Relaxed position assertion (for overflows in large inline maps)

Issue: SPR-17605
上级 31a24720
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2018 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.
......@@ -21,8 +21,8 @@ import org.springframework.expression.TypedValue;
import org.springframework.expression.spel.ExpressionState;
/**
* Represents assignment. An alternative to calling setValue() for an expression is to use
* an assign.
* Represents assignment. An alternative to calling {@code setValue}
* for an expression which indicates an assign statement.
*
* <p>Example: 'someNumberProperty=42'
*
......@@ -31,8 +31,8 @@ import org.springframework.expression.spel.ExpressionState;
*/
public class Assign extends SpelNodeImpl {
public Assign(int pos,SpelNodeImpl... operands) {
super(pos,operands);
public Assign(int pos, SpelNodeImpl... operands) {
super(pos, operands);
}
......
......@@ -47,7 +47,7 @@ public abstract class SpelNodeImpl implements SpelNode, Opcodes {
private static final SpelNodeImpl[] NO_CHILDREN = new SpelNodeImpl[0];
protected int pos; // start = top 16bits, end = bottom 16bits
protected final int pos; // start = top 16bits, end = bottom 16bits
protected SpelNodeImpl[] children = SpelNodeImpl.NO_CHILDREN;
......@@ -69,8 +69,6 @@ public abstract class SpelNodeImpl implements SpelNode, Opcodes {
public SpelNodeImpl(int pos, SpelNodeImpl... operands) {
this.pos = pos;
// pos combines start and end so can never be zero because tokens cannot be zero length
Assert.isTrue(pos != 0, "Pos must not be 0");
if (!ObjectUtils.isEmpty(operands)) {
this.children = operands;
for (SpelNodeImpl operand : operands) {
......@@ -84,7 +82,7 @@ public abstract class SpelNodeImpl implements SpelNode, Opcodes {
/**
* Return {@code true} if the next child is one of the specified classes.
*/
protected boolean nextChildIs(Class<?>... clazzes) {
protected boolean nextChildIs(Class<?>... classes) {
if (this.parent != null) {
SpelNodeImpl[] peers = this.parent.children;
for (int i = 0, max = peers.length; i < max; i++) {
......@@ -92,9 +90,9 @@ public abstract class SpelNodeImpl implements SpelNode, Opcodes {
if (i + 1 >= max) {
return false;
}
Class<?> clazz = peers[i + 1].getClass();
for (Class<?> desiredClazz : clazzes) {
if (clazz.equals(desiredClazz)) {
Class<?> peerClass = peers[i + 1].getClass();
for (Class<?> desiredClass : classes) {
if (peerClass == desiredClass) {
return true;
}
}
......@@ -146,11 +144,6 @@ public abstract class SpelNodeImpl implements SpelNode, Opcodes {
return (obj instanceof Class ? ((Class<?>) obj) : obj.getClass());
}
@Nullable
protected final <T> T getValue(ExpressionState state, Class<T> desiredReturnType) throws EvaluationException {
return ExpressionUtils.convertTypedValue(state.getEvaluationContext(), getValueInternal(state), desiredReturnType);
}
@Override
public int getStartPosition() {
return (this.pos >> 16);
......@@ -161,10 +154,6 @@ public abstract class SpelNodeImpl implements SpelNode, Opcodes {
return (this.pos & 0xffff);
}
protected ValueRef getValueRef(ExpressionState state) throws EvaluationException {
throw new SpelEvaluationException(this.pos, SpelMessage.NOT_ASSIGNABLE, toStringAST());
}
/**
* Check whether a node can be compiled to bytecode. The reasoning in each node may
* be different but will typically involve checking whether the exit type descriptor
......@@ -177,9 +166,8 @@ public abstract class SpelNodeImpl implements SpelNode, Opcodes {
/**
* Generate the bytecode for this node into the supplied visitor. Context info about
* the current expression being compiled is available in the codeflow object. For
* example it will include information about the type of the object currently
* on the stack.
* the current expression being compiled is available in the codeflow object, e.g.
* including information about the type of the object currently on the stack.
* @param mv the ASM MethodVisitor into which code should be generated
* @param cf a context object with info about what is on the stack
*/
......@@ -192,6 +180,15 @@ public abstract class SpelNodeImpl implements SpelNode, Opcodes {
return this.exitTypeDescriptor;
}
@Nullable
protected final <T> T getValue(ExpressionState state, Class<T> desiredReturnType) throws EvaluationException {
return ExpressionUtils.convertTypedValue(state.getEvaluationContext(), getValueInternal(state), desiredReturnType);
}
protected ValueRef getValueRef(ExpressionState state) throws EvaluationException {
throw new SpelEvaluationException(getStartPosition(), SpelMessage.NOT_ASSIGNABLE, toStringAST());
}
public abstract TypedValue getValueInternal(ExpressionState expressionState) throws EvaluationException;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册