@@ -804,10 +804,39 @@ export function parse(source: string): ASTNode {
804804 return new Parser ( source ) . parse ( ) ;
805805}
806806
807+ /**
808+ * 代码生成上下文
809+ * 用于在嵌套 lambda 中分配唯一参数名
810+ */
811+ interface GenerateContext {
812+ /** lambda 参数计数器,用于生成唯一参数名 */
813+ lambdaParamCounter : number ;
814+ /** 占位符到实际参数名的映射 */
815+ paramMapping : Map < string , string > ;
816+ }
817+
818+ /**
819+ * 创建新的生成上下文
820+ */
821+ function createGenerateContext ( ) : GenerateContext {
822+ return {
823+ lambdaParamCounter : 0 ,
824+ paramMapping : new Map ( ) ,
825+ } ;
826+ }
827+
807828/**
808829 * 从 AST 生成规范化的代码
809830 */
810831export function generate ( node : ASTNode ) : string {
832+ const ctx = createGenerateContext ( ) ;
833+ return generateWithContext ( node , ctx ) ;
834+ }
835+
836+ /**
837+ * 带上下文的代码生成
838+ */
839+ function generateWithContext ( node : ASTNode , ctx : GenerateContext ) : string {
811840 switch ( node . type ) {
812841 case "NumberLiteral" :
813842 return node . raw ;
@@ -822,12 +851,15 @@ export function generate(node: ASTNode): string {
822851 case "NullLiteral" :
823852 return "null" ;
824853
825- case "Identifier" :
826- return node . name ;
854+ case "Identifier" : {
855+ // 检查是否是 lambda 参数占位符
856+ const mappedName = ctx . paramMapping . get ( node . name ) ;
857+ return mappedName ?? node . name ;
858+ }
827859
828860 case "BinaryExpr" : {
829- const left = wrapIfNeeded ( node . left , node , "left" ) ;
830- const right = wrapIfNeeded ( node . right , node , "right" ) ;
861+ const left = wrapIfNeededWithContext ( node . left , node , "left" , ctx ) ;
862+ const right = wrapIfNeededWithContext ( node . right , node , "right" , ctx ) ;
831863 // 关键字运算符需要空格
832864 if ( node . operator === "in" || node . operator === "instanceof" ) {
833865 return `${ left } ${ node . operator } ${ right } ` ;
@@ -837,55 +869,74 @@ export function generate(node: ASTNode): string {
837869
838870 case "UnaryExpr" :
839871 if ( node . prefix ) {
840- const arg = wrapIfNeeded ( node . argument , node , "argument" ) ;
872+ const arg = wrapIfNeededWithContext ( node . argument , node , "argument" , ctx ) ;
841873 // 对于关键字运算符(typeof, void)需要空格
842874 if ( node . operator === "typeof" || node . operator === "void" ) {
843875 return `${ node . operator } ${ arg } ` ;
844876 }
845877 return `${ node . operator } ${ arg } ` ;
846878 }
847- return generate ( node . argument ) + node . operator ;
879+ return generateWithContext ( node . argument , ctx ) + node . operator ;
848880
849881 case "ConditionalExpr" : {
850- const test = wrapIfNeeded ( node . test , node , "test" ) ;
851- const consequent = wrapIfNeeded ( node . consequent , node , "consequent" ) ;
852- const alternate = wrapIfNeeded ( node . alternate , node , "alternate" ) ;
882+ const test = wrapIfNeededWithContext ( node . test , node , "test" , ctx ) ;
883+ const consequent = wrapIfNeededWithContext ( node . consequent , node , "consequent" , ctx ) ;
884+ const alternate = wrapIfNeededWithContext ( node . alternate , node , "alternate" , ctx ) ;
853885 return `${ test } ?${ consequent } :${ alternate } ` ;
854886 }
855887
856888 case "MemberExpr" : {
857- const object = wrapIfNeeded ( node . object , node , "object" ) ;
858- const property = generate ( node . property ) ;
889+ const object = wrapIfNeededWithContext ( node . object , node , "object" , ctx ) ;
890+ const property = generateWithContext ( node . property , ctx ) ;
859891 return node . computed
860892 ? `${ object } ${ node . optional ? "?." : "" } [${ property } ]`
861893 : `${ object } ${ node . optional ? "?." : "." } ${ property } ` ;
862894 }
863895
864896 case "CallExpr" : {
865- const callee = wrapIfNeeded ( node . callee , node , "callee" ) ;
866- const args = node . arguments . map ( generate ) . join ( "," ) ;
897+ const callee = wrapIfNeededWithContext ( node . callee , node , "callee" , ctx ) ;
898+ const args = node . arguments . map ( ( arg ) => generateWithContext ( arg , ctx ) ) . join ( "," ) ;
867899 const isNew = node . callee . type === "Identifier" && BUILTIN_CONSTRUCTORS . has ( node . callee . name ) ;
868900 return `${ isNew ? "new " : "" } ${ callee } ${ node . optional ? "?." : "" } (${ args } )` ;
869901 }
870902
871903 case "ArrayExpr" :
872- return `[${ node . elements . map ( generate ) . join ( "," ) } ]` ;
904+ return `[${ node . elements . map ( ( el ) => generateWithContext ( el , ctx ) ) . join ( "," ) } ]` ;
873905
874906 case "ObjectExpr" : {
875907 const props = node . properties . map ( ( prop ) => {
876908 if ( prop . shorthand ) {
877- return generate ( prop . key ) ;
909+ return generateWithContext ( prop . key , ctx ) ;
878910 }
879- const key = prop . computed ? `[${ generate ( prop . key ) } ]` : generate ( prop . key ) ;
880- return `${ key } :${ generate ( prop . value ) } ` ;
911+ const key = prop . computed ? `[${ generateWithContext ( prop . key , ctx ) } ]` : generateWithContext ( prop . key , ctx ) ;
912+ return `${ key } :${ generateWithContext ( prop . value , ctx ) } ` ;
881913 } ) ;
882914 return `{${ props . join ( "," ) } }` ;
883915 }
884916
885917 case "ArrowFunctionExpr" : {
886- const params = node . params . map ( ( p ) => p . name ) . join ( "," ) ;
887- const body = node . body . type === "ObjectExpr" ? `(${ generate ( node . body ) } )` : generate ( node . body ) ;
888- const paramsStr = node . params . length === 1 ? params : `(${ params } )` ;
918+ // 为每个参数分配唯一的参数名
919+ const paramNames : string [ ] = [ ] ;
920+ for ( const param of node . params ) {
921+ const uniqueName = `_${ ctx . lambdaParamCounter ++ } ` ;
922+ paramNames . push ( uniqueName ) ;
923+ // 建立占位符到实际参数名的映射
924+ ctx . paramMapping . set ( param . name , uniqueName ) ;
925+ }
926+
927+ const paramsStr = paramNames . length === 1 ? paramNames [ 0 ] ! : `(${ paramNames . join ( "," ) } )` ;
928+ const body =
929+ node . body . type === "ObjectExpr"
930+ ? `(${ generateWithContext ( node . body , ctx ) } )`
931+ : generateWithContext ( node . body , ctx ) ;
932+
933+ // 清理参数映射(可选,防止污染外层作用域)
934+ // 注意:由于我们使用唯一的参数名,不清理也不会冲突
935+ // 但为了语义清晰,在函数体生成完成后移除映射
936+ for ( const param of node . params ) {
937+ ctx . paramMapping . delete ( param . name ) ;
938+ }
939+
889940 return `${ paramsStr } =>${ body } ` ;
890941 }
891942
@@ -898,14 +949,15 @@ export function generate(node: ASTNode): string {
898949}
899950
900951/**
901- * 判断是否需要括号包裹,并生成代码
952+ * 判断是否需要括号包裹,并生成代码(带上下文版本)
902953 */
903- function wrapIfNeeded (
954+ function wrapIfNeededWithContext (
904955 child : ASTNode ,
905956 parent : ASTNode ,
906- position : "left" | "right" | "argument" | "object" | "callee" | "test" | "consequent" | "alternate"
957+ position : "left" | "right" | "argument" | "object" | "callee" | "test" | "consequent" | "alternate" ,
958+ ctx : GenerateContext
907959) : string {
908- const code = generate ( child ) ;
960+ const code = generateWithContext ( child , ctx ) ;
909961
910962 if ( needsParens ( child , parent , position ) ) {
911963 return `(${ code } )` ;
0 commit comments