From dc6f943c6ccb26778906a49532966aaf69fdc5a5 Mon Sep 17 00:00:00 2001 From: Linghao Su Date: Fri, 26 Jul 2024 21:22:00 +0800 Subject: [PATCH] fix(language-core): support parse method to access ctx var in object (#4609) --- .../lib/codegen/template/interpolation.ts | 49 ++++++++++++------- test-workspace/tsc/vue3/#4604/main.vue | 14 ++++++ 2 files changed, 44 insertions(+), 19 deletions(-) create mode 100644 test-workspace/tsc/vue3/#4604/main.vue diff --git a/packages/language-core/lib/codegen/template/interpolation.ts b/packages/language-core/lib/codegen/template/interpolation.ts index 7367549734..3e2760f576 100644 --- a/packages/language-core/lib/codegen/template/interpolation.ts +++ b/packages/language-core/lib/codegen/template/interpolation.ts @@ -177,25 +177,7 @@ function walkIdentifiers( } } else if (ts.isArrowFunction(node) || ts.isFunctionExpression(node)) { - - const functionArgs: string[] = []; - - for (const param of node.parameters) { - collectVars(ts, param.name, ast, functionArgs); - if (param.type) { - walkIdentifiers(ts, param.type, ast, cb, ctx, blockVars, false); - } - } - - for (const varName of functionArgs) { - ctx.addLocalVariable(varName); - } - - walkIdentifiers(ts, node.body, ast, cb, ctx, blockVars, false); - - for (const varName of functionArgs) { - ctx.removeLocalVariable(varName); - } + processFunction(ts, node, ast, cb, ctx); } else if (ts.isObjectLiteralExpression(node)) { for (const prop of node.properties) { @@ -215,6 +197,10 @@ function walkIdentifiers( // TODO: cannot report "Spread types may only be created from object types.ts(2698)" walkIdentifiers(ts, prop.expression, ast, cb, ctx, blockVars, false); } + // fix https://github.com/vuejs/language-tools/issues/4604 + else if (ts.isFunctionLike(prop) && prop.body) { + processFunction(ts, prop, ast, cb, ctx); + } } } else if (ts.isTypeReferenceNode(node)) { @@ -242,6 +228,31 @@ function walkIdentifiers( } } +function processFunction( + ts: typeof import('typescript'), + node: ts.ArrowFunction | ts.FunctionExpression | ts.AccessorDeclaration | ts.MethodDeclaration, + ast: ts.SourceFile, + cb: (varNode: ts.Identifier, isShorthand: boolean) => void, + ctx: TemplateCodegenContext +) { + const functionArgs: string[] = []; + for (const param of node.parameters) { + collectVars(ts, param.name, ast, functionArgs); + if (param.type) { + walkIdentifiers(ts, param.type, ast, cb, ctx); + } + } + for (const varName of functionArgs) { + ctx.addLocalVariable(varName); + } + if (node.body) { + walkIdentifiers(ts, node.body, ast, cb, ctx); + } + for (const varName of functionArgs) { + ctx.removeLocalVariable(varName); + } +} + function walkIdentifiersInTypeReference( ts: typeof import('typescript'), node: ts.Node, diff --git a/test-workspace/tsc/vue3/#4604/main.vue b/test-workspace/tsc/vue3/#4604/main.vue new file mode 100644 index 0000000000..ca7cb40861 --- /dev/null +++ b/test-workspace/tsc/vue3/#4604/main.vue @@ -0,0 +1,14 @@ + + +