Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | 1x 1x 1x 1x 1x 1x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 2x 2x 2x 2x 2x 2x 2x 6x 6x 5x 4x 8x 3x 3x 3x 3x 3x 3x 3x 3x 3x 3x 1x 2x 8x 8x 7x 7x 7x 7x 7x 7x 7x 3x 8x 8x 8x | import type { ExpressionState } from '../../expression-state.js';
import { TypedValue } from '../../typed-value.js';
import { SpelNodeImpl } from '../spel-node.js';
import { SpelEvaluationException } from '../../error/spel-evaluation-exception.js';
import { SpelMessage } from '../../error/spel-message.js';
import { NodeType } from '../../language/node-type.js';
export class Projection extends SpelNodeImpl {
private readonly nullSafe: boolean;
constructor(
startPos: number,
endPos: number,
nullSafe: boolean,
target: SpelNodeImpl,
projection: SpelNodeImpl,
) {
super(NodeType.PROJECTION, startPos, endPos, target, projection);
this.nullSafe = nullSafe;
}
public isNullSafe(): boolean {
return this.nullSafe;
}
public getValueInternal(state: ExpressionState): TypedValue {
const targetValue = this.children[0]!.getValue(state).getValue();
if (targetValue === null || targetValue === undefined) {
if (this.nullSafe) return TypedValue.NULL;
throw new SpelEvaluationException(
this.startPos,
SpelMessage.PROJECTION_NOT_SUPPORTED_ON_TYPE,
'null',
);
}
if (
!Array.isArray(targetValue) &&
!(targetValue instanceof Set) &&
!(targetValue instanceof Map)
) {
// Spring SpEL: non-collection is wrapped in single-element array for projection
state.pushHeadIndex(new TypedValue(targetValue));
try {
const projected = this.children[1]!.getValue(state).getValue();
return new TypedValue([projected]);
} finally {
state.popHeadIndex();
}
}
const collection =
targetValue instanceof Map
? [...targetValue.values()]
: [...(targetValue as Iterable<unknown>)];
const result: unknown[] = [];
for (const item of collection) {
state.pushHeadIndex(new TypedValue(item));
try {
result.push(this.children[1]!.getValue(state).getValue());
} finally {
state.popHeadIndex();
}
}
return new TypedValue(result);
}
public toStringAST(): string {
return `${this.children[0]!.toStringAST()}.![${this.children[1]!.toStringAST()}]`;
}
}
|