import type Expression from './Expression' import ExpressionType from '../enums/ExpressionType' import ReturnWayException from '../exception/ReturnWayException' import JSONObject from '../instances/JSONObject' export default class Delegate { private exp: Expression private source: string private lambdaOutProps: string[] = [] private objectNames: JSONObject constructor(exp: Expression, source: string, objectNames?: JSONObject) { this.exp = exp this.source = source if (objectNames) { this.objectNames = objectNames } else { this.objectNames = new JSONObject() } } // 执行程序,执行前,参数必须实例化 invoke(params?: JSONObject): any { if (params == null) { params = new JSONObject() } // 把初始参数给参数表 this.objectNames = params // 沿根Expression节点遍历,把delegate传递下去 this.putDelegate(this.exp) // 调用exp的执行过程 try { return this.exp.invoke() } catch (returnWay) { if (returnWay instanceof ReturnWayException) { return returnWay.getReturnObject() } throw returnWay } } // 沿根节点递归,传递delegate的过程 private putDelegate(parent: Expression): void { for (const child of parent.children) { // 有些节点会放空的子节点 if (child == null) { continue } // try特殊处理 if (child.type === ExpressionType.Try) { const exps: Expression[] = child.value as Expression[] if (exps[0] != null) { exps[0].setDelegate(this) this.putDelegate(exps[0]) } if (exps[1] != null) { exps[1].setDelegate(this) this.putDelegate(exps[1]) } } child.setDelegate(this) this.putDelegate(child) } } // 获取表达式 getExp(): Expression { return this.exp } // 获取对象值存储 getObjectNames(): JSONObject { return this.objectNames } // 获取lambda外层参数名 getLambdaOutProps(): string[] { return this.lambdaOutProps } // 存储对象值 put(key: string, value: any): void { this.objectNames.put(key, value) } // 获取对象值 get(key: string): any { return this.objectNames.get(key) } // 检查是否包含某个键 containsKey(key: string): boolean { return this.objectNames.has(key) } // 获取源代码 getSource(): string { return this.source } // 使用参数调用 apply(params?: JSONObject): any { if (params === null) { params = new JSONObject() } const map = this.objectNames if (this.lambdaOutProps.length === 0) { this.lambdaOutProps.push(...map.keySet()) } const lambdaMap = new JSONObject(map) lambdaMap.put('data', params) return this.invoke(lambdaMap) } }