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 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | 1x 1x 1x 1x 1x 1x 1x 24x 24x 1x 6x 6x 1x 6x 6x 1x 13x 13x 13x 9x 9x 6x 6x 6x 6x 6x 6x 3x 3x 12x 1x 1x 13x 1x 1x 2x 2x 2x 2x 2x 13x 1x 1x 5x 5x 5x 2x 2x 2x 2x 2x 3x 2x 2x 2x 5x 1x 1x 1x 5x 1x 6x 6x 1x | import type { ExpressionState } from '../../expression-state.js';
import { TypedValue } from '../../typed-value.js';
import { SpelEvaluationException } from '../../error/spel-evaluation-exception.js';
import { SpelMessage } from '../../error/spel-message.js';
import { SpelNodeImpl } from '../spel-node.js';
import { NodeType } from '../../language/node-type.js';
export class Indexer extends SpelNodeImpl {
constructor(startPos: number, endPos: number, target: SpelNodeImpl, index: SpelNodeImpl) {
super(NodeType.INDEXER, startPos, endPos, target, index);
}
/** Get the target node being indexed */
public getTarget(): SpelNodeImpl {
return this.children[0]!;
}
/** Get the index/key node */
public getIndex(): SpelNodeImpl {
return this.children[1]!;
}
public getValueInternal(state: ExpressionState): TypedValue {
const target = this.children[0]!.getValue(state).getValue();
const index = this.children[1]!.getValue(state).getValue();
if (Array.isArray(target)) {
const idx = Number(index);
if (isNaN(idx) || idx < 0 || idx >= target.length) {
throw new SpelEvaluationException(
this.startPos,
SpelMessage.INDEX_OUT_OF_BOUNDS,
String(idx),
);
}
return new TypedValue(target[idx]);
}
if (target instanceof Map) {
return new TypedValue(target.get(index));
}
if (typeof target === 'object' && target !== null) {
return new TypedValue((target as Record<string, unknown>)[String(index)]);
}
throw new SpelEvaluationException(
this.startPos,
SpelMessage.INDEXING_NOT_SUPPORTED_FOR_TYPE,
typeof target,
);
}
public override isWritable(_state: ExpressionState): boolean {
return true;
}
public override setValue(state: ExpressionState, newValue: unknown): void {
const target = this.children[0]!.getValue(state).getValue();
const index = this.children[1]!.getValue(state).getValue();
if (Array.isArray(target)) {
const idx = Number(index);
if (idx >= 0 && idx < target.length) {
(target as unknown[])[idx] = newValue;
return;
}
throw new SpelEvaluationException(
this.startPos,
SpelMessage.INDEX_OUT_OF_BOUNDS,
String(idx),
);
}
if (target instanceof Map) {
target.set(index, newValue);
return;
}
if (typeof target === 'object' && target !== null) {
(target as Record<string, unknown>)[String(index)] = newValue;
return;
}
throw new SpelEvaluationException(
this.startPos,
SpelMessage.INDEXING_NOT_SUPPORTED_FOR_TYPE,
typeof target,
);
}
public toStringAST(): string {
return this.getTarget().toStringAST() + '[' + this.getIndex().toStringAST() + ']';
}
}
|