Skip to content

Commit 6a263bd

Browse files
committed
refactor(lambda): simplify lambda function implementation
Break down the large lambda function into smaller specialized functions to improve readability and maintainability - Decompose complex logic into helper functions: createLambdaParams, extractBodyAstAndDeps, transformParamPlaceholders, createArrowFunctionAst, and filterClosureDeps - Fix issue with collectDepsFromArgs call in extractBodyAstAndDeps function - Remove unnecessary type assertions - Maintain all functionality unchanged and pass all tests
1 parent 5a9dd20 commit 6a263bd

File tree

1 file changed

+79
-36
lines changed

1 file changed

+79
-36
lines changed

src/lambda.ts

Lines changed: 79 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ function createLambdaParam<T>(index: number): Proxify<T> {
4343
const proxy = createProxyVariable<T>(id);
4444

4545
// 记录参数索引
46-
lambdaParamIndices.set(proxy as object, index);
46+
lambdaParamIndices.set(proxy, index);
4747

4848
return proxy;
4949
}
@@ -67,8 +67,44 @@ function createLambdaParam<T>(index: number): Proxify<T> {
6767
* ```
6868
*/
6969
export function lambda<Args extends unknown[], R>(builder: LambdaBuilder<Args, R>): Lambda<Args, R> {
70-
// 1. 根据 builder 函数的参数数量创建参数代理
70+
// 1. 创建参数代理和符号映射
7171
const paramCount = builder.length;
72+
const { params, paramSymbols } = createLambdaParams(paramCount);
73+
74+
// 2. 调用 builder 获取函数体表达式
75+
const bodyExpr = builder(...(params as Parameters<LambdaBuilder<Args, R>>));
76+
77+
// 3. 从 bodyExpr 中提取 AST 和依赖
78+
const { bodyAst, bodyDeps } = extractBodyAstAndDeps(bodyExpr);
79+
80+
// 4. 将参数占位符标识符转换为实际参数名 (_0, _1, _2...)
81+
const transformedBodyAst = transformParamPlaceholders(bodyAst, paramSymbols);
82+
83+
// 5. 构造完整的箭头函数 AST
84+
const arrowFunctionAst = createArrowFunctionAst(transformedBodyAst, paramCount);
85+
86+
// 6. 过滤掉 lambda 参数依赖,只保留外部闭包变量
87+
const closureDeps = filterClosureDeps(bodyDeps, paramSymbols);
88+
89+
// 7. 返回包含 lambda AST 的 Proxy
90+
const lambdaProxy = createProxyExpressionWithAST<(...args: Args) => R>(arrowFunctionAst, closureDeps);
91+
92+
// 8. 设置额外的 lambda 元数据(标记为 lambda 类型)
93+
const existingMeta = getProxyMetadata(lambdaProxy);
94+
if (existingMeta) {
95+
setProxyMetadata(lambdaProxy, {
96+
...existingMeta,
97+
type: "expression", // 保持为 expression,但 AST 包含箭头函数
98+
});
99+
}
100+
101+
return lambdaProxy as Lambda<Args, R>;
102+
}
103+
104+
/**
105+
* 创建 lambda 参数和符号映射
106+
*/
107+
function createLambdaParams(paramCount: number) {
72108
const params: Proxify<unknown>[] = [];
73109
const paramSymbols: symbol[] = [];
74110

@@ -77,39 +113,47 @@ export function lambda<Args extends unknown[], R>(builder: LambdaBuilder<Args, R
77113
params.push(param);
78114

79115
// 获取参数的 Symbol ID
80-
const meta = getProxyMetadata(param as object);
116+
const meta = getProxyMetadata(param);
81117
if (meta?.rootVariable) {
82118
paramSymbols.push(meta.rootVariable);
83119
}
84120
}
85121

86-
// 2. 调用 builder 获取函数体表达式
87-
const bodyExpr = builder(...(params as Parameters<LambdaBuilder<Args, R>>));
88-
89-
// 3. 从 bodyExpr 中提取 AST 和依赖
90-
// 支持返回 Proxy 表达式、普通对象/数组、或原始值
91-
let bodyAst: ASTNode;
92-
let bodyDeps: Set<symbol>;
122+
return { params, paramSymbols };
123+
}
93124

125+
/**
126+
* 从表达式中提取 AST 和依赖
127+
*/
128+
function extractBodyAstAndDeps(bodyExpr: unknown): { bodyAst: ASTNode; bodyDeps: Set<symbol> } {
94129
const meta =
95130
(typeof bodyExpr === "object" || typeof bodyExpr === "function") && bodyExpr !== null
96-
? getProxyMetadata(bodyExpr as object)
131+
? getProxyMetadata(bodyExpr)
97132
: undefined;
98133

99134
if (meta?.ast) {
100135
// Proxy 表达式:使用其 AST 和依赖
101-
bodyAst = meta.ast;
102-
bodyDeps = meta.dependencies ?? new Set<symbol>();
136+
return {
137+
bodyAst: meta.ast,
138+
bodyDeps: meta.dependencies ?? new Set<symbol>(),
139+
};
103140
} else {
104141
// 普通对象、数组或原始值:使用 serializeArgumentToAST 转换
105142
// 并收集其中可能包含的 Proxy 变量依赖
106-
bodyAst = serializeArgumentToAST(bodyExpr);
107-
bodyDeps = new Set<symbol>();
143+
const bodyDeps = new Set<symbol>();
108144
collectDepsFromArgs([bodyExpr], bodyDeps);
145+
return {
146+
bodyAst: serializeArgumentToAST(bodyExpr),
147+
bodyDeps,
148+
};
109149
}
150+
}
110151

111-
// 4. 将参数占位符标识符转换为实际参数名 (_0, _1, _2...)
112-
const transformedBodyAst = transformIdentifiers(bodyAst, (name) => {
152+
/**
153+
* 将参数占位符标识符转换为实际参数名
154+
*/
155+
function transformParamPlaceholders(bodyAst: ASTNode, paramSymbols: symbol[]): ASTNode {
156+
return transformIdentifiers(bodyAst, (name) => {
113157
for (let i = 0; i < paramSymbols.length; i++) {
114158
const sym = paramSymbols[i];
115159
if (!sym) continue;
@@ -121,34 +165,33 @@ export function lambda<Args extends unknown[], R>(builder: LambdaBuilder<Args, R
121165
}
122166
return name;
123167
});
168+
}
124169

125-
// 5. 构造完整的箭头函数 AST
126-
const paramIdentifiers = params.map((_, i) => ({ type: "Identifier" as const, name: `_${i}` }));
127-
const arrowFunctionAst: ASTNode = {
170+
/**
171+
* 创建箭头函数 AST
172+
*/
173+
function createArrowFunctionAst(bodyAst: ASTNode, paramCount: number): ASTNode {
174+
const paramIdentifiers = Array.from({ length: paramCount }, (_, i) => ({
175+
type: "Identifier" as const,
176+
name: `_${i}`,
177+
}));
178+
179+
return {
128180
type: "ArrowFunctionExpr",
129181
params: paramIdentifiers,
130-
body: transformedBodyAst,
182+
body: bodyAst,
131183
};
184+
}
132185

133-
// 6. 过滤掉 lambda 参数依赖,只保留外部闭包变量
186+
/**
187+
* 过滤掉 lambda 参数依赖,只保留外部闭包变量
188+
*/
189+
function filterClosureDeps(bodyDeps: Set<symbol>, paramSymbols: symbol[]): Set<symbol> {
134190
const closureDeps = new Set<symbol>();
135191
for (const dep of bodyDeps) {
136192
if (!paramSymbols.includes(dep)) {
137193
closureDeps.add(dep);
138194
}
139195
}
140-
141-
// 7. 返回包含 lambda AST 的 Proxy
142-
const lambdaProxy = createProxyExpressionWithAST<(...args: Args) => R>(arrowFunctionAst, closureDeps);
143-
144-
// 8. 设置额外的 lambda 元数据(标记为 lambda 类型)
145-
const existingMeta = getProxyMetadata(lambdaProxy as object);
146-
if (existingMeta) {
147-
setProxyMetadata(lambdaProxy as object, {
148-
...existingMeta,
149-
type: "expression", // 保持为 expression,但 AST 包含箭头函数
150-
});
151-
}
152-
153-
return lambdaProxy as Lambda<Args, R>;
196+
return closureDeps;
154197
}

0 commit comments

Comments
 (0)