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 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | 5785x 5785x 5785x 5785x 5785x 5785x 5785x 5785x 5785x 5785x 5785x 5785x 1x 5785x 6011x 4x 68x 61x 18x 3x 213x 2x 103x 1x 71x 22x 13x 12x 3x 249x 249x 249x 249x 249x 1x 249x | import { TypedValue } from './typed-value.js';
import type { EvaluationContext } from './evaluation-context/evaluation-context.js';
import type { PropertyAccessor } from './evaluation-context/property-accessor.js';
import type { MethodResolver } from './evaluation-context/method-resolver.js';
import type { TypeLocator } from './type/type-locator.js';
import type { BeanResolver } from './bean/bean-resolver.js';
import { SpelTypeConverter } from './bridge/type-coercion.js';
import { MapAccessor } from './evaluation-context/map-accessor.js';
import { ArrayAccessor } from './evaluation-context/array-accessor.js';
import { ReflectivePropertyAccessor } from './evaluation-context/reflective-property-accessor.js';
import { TypeDescriptorAccessor } from './evaluation-context/type-descriptor-accessor.js';
import { ReflectiveMethodResolver } from './evaluation-context/reflective-method-resolver.js';
import { StandardTypeLocator } from './type/standard-type-locator.js';
export class StandardEvaluationContext implements EvaluationContext {
private rootObject: TypedValue;
private readonly variables = new Map<string, TypedValue>();
private readonly functions = new Map<string, (...args: unknown[]) => unknown>();
private readonly propertyAccessors: PropertyAccessor[] = [];
private readonly methodResolvers: MethodResolver[] = [];
private typeLocator: TypeLocator;
private beanResolver: BeanResolver;
private typeConverter: SpelTypeConverter;
constructor(rootObject?: unknown) {
this.rootObject = new TypedValue(rootObject);
this.propertyAccessors.push(new MapAccessor());
this.propertyAccessors.push(new ArrayAccessor());
this.propertyAccessors.push(new TypeDescriptorAccessor());
this.propertyAccessors.push(new ReflectivePropertyAccessor());
this.methodResolvers.push(new ReflectiveMethodResolver());
// A working type locator is installed by default, matching Spring's
// StandardEvaluationContext, so `T(String)` and `instanceof` work out of the
// box. This previously held a stub that always threw, which meant the
// `T(...)` and `instanceof` syntax documented in the README could not be used.
this.typeLocator = new StandardTypeLocator();
// Left unset on purpose: Spring's StandardEvaluationContext also has no bean
// resolver, so `@bean` fails until one is installed via setBeanResolver().
this.beanResolver = {
resolve: (name: string) => {
throw new Error(`Bean "${name}" not found. BeanResolver not configured.`);
},
// Stub: no-op until a real BeanResolver is installed via setBeanResolver()
// eslint-disable-next-line @typescript-eslint/no-empty-function
register: () => {},
has: () => false,
};
this.typeConverter = new SpelTypeConverter();
}
public getRootObject(): TypedValue {
return this.rootObject;
}
public setRootObject(obj: unknown): void {
this.rootObject = new TypedValue(obj);
}
public lookupVariable(name: string): TypedValue | null {
return this.variables.get(name) ?? null;
}
public setVariable(name: string, value: unknown): void {
this.variables.set(name, new TypedValue(value));
}
public lookupFunction(name: string): ((...args: unknown[]) => unknown) | null {
return this.functions.get(name) ?? null;
}
public registerFunction(name: string, fn: (...args: unknown[]) => unknown): void {
this.functions.set(name, fn);
}
public getPropertyAccessors(): PropertyAccessor[] {
return this.propertyAccessors;
}
public addPropertyAccessor(accessor: PropertyAccessor): void {
this.propertyAccessors.push(accessor);
}
public getMethodResolvers(): MethodResolver[] {
return this.methodResolvers;
}
public addMethodResolver(resolver: MethodResolver): void {
this.methodResolvers.push(resolver);
}
public getTypeLocator(): TypeLocator {
return this.typeLocator;
}
public setTypeLocator(typeLocator: TypeLocator): void {
this.typeLocator = typeLocator;
}
public getBeanResolver(): BeanResolver {
return this.beanResolver;
}
public setBeanResolver(beanResolver: BeanResolver): void {
this.beanResolver = beanResolver;
}
public getTypeConverter(): SpelTypeConverter {
return this.typeConverter;
}
public createChildContext(rootObject: unknown): EvaluationContext {
const child = new StandardEvaluationContext(rootObject);
child.typeLocator = this.typeLocator;
child.beanResolver = this.beanResolver;
child.typeConverter = this.typeConverter;
for (const [name, fn] of this.functions) {
child.functions.set(name, fn);
}
return child;
}
}
|