From 31f907f89336a63fdb773e68ad566ccf189bde3b Mon Sep 17 00:00:00 2001 From: daiwei Date: Wed, 30 Nov 2022 09:11:27 +0800 Subject: [PATCH 1/4] fix(compiler-core): proper rewrite identifier of for --- packages/compiler-core/src/babelUtils.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/packages/compiler-core/src/babelUtils.ts b/packages/compiler-core/src/babelUtils.ts index e773015f90f..4842860bfe4 100644 --- a/packages/compiler-core/src/babelUtils.ts +++ b/packages/compiler-core/src/babelUtils.ts @@ -167,6 +167,17 @@ export function walkBlockDeclarations( ) { if (stmt.declare || !stmt.id) continue onIdent(stmt.id) + } else if ( + stmt.type === 'ForOfStatement' || + stmt.type === 'ForInStatement' + ) { + if (stmt.left.type === 'VariableDeclaration') { + for (const decl of stmt.left.declarations) { + for (const id of extractIdentifiers(decl.id)) { + onIdent(id) + } + } + } } } } From 11e74b1a469e1dab88756a4288360b7fb4351da1 Mon Sep 17 00:00:00 2001 From: daiwei Date: Wed, 30 Nov 2022 09:34:20 +0800 Subject: [PATCH 2/4] test: add test case --- .../transformExpressions.spec.ts.snap | 28 +++++++++++++++++++ .../transforms/transformExpressions.spec.ts | 24 ++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/packages/compiler-core/__tests__/transforms/__snapshots__/transformExpressions.spec.ts.snap b/packages/compiler-core/__tests__/transforms/__snapshots__/transformExpressions.spec.ts.snap index aa8a6e2e20e..05e76d9c3b2 100644 --- a/packages/compiler-core/__tests__/transforms/__snapshots__/transformExpressions.spec.ts.snap +++ b/packages/compiler-core/__tests__/transforms/__snapshots__/transformExpressions.spec.ts.snap @@ -13,3 +13,31 @@ return function render(_ctx, _cache, $props, $setup, $data, $options) { return (_openBlock(), _createElementBlock("div", null, _toDisplayString($props.props) + " " + _toDisplayString($setup.setup) + " " + _toDisplayString($data.data) + " " + _toDisplayString($options.options), 1 /* TEXT */)) }" `; + +exports[`compiler: expression transform bindingMetadata should not prefix temp variable of for...in 1`] = ` +"const { openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue + +return function render(_ctx, _cache, $props, $setup, $data, $options) { + return (_openBlock(), _createElementBlock("div", { + onClick: () => { + for (const x in _ctx.list) { + _ctx.log(x) + } + } + }, null, 8 /* PROPS */, ["onClick"])) +}" +`; + +exports[`compiler: expression transform bindingMetadata should not prefix temp variable of for...of 1`] = ` +"const { openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue + +return function render(_ctx, _cache, $props, $setup, $data, $options) { + return (_openBlock(), _createElementBlock("div", { + onClick: () => { + for (const x of _ctx.list) { + _ctx.log(x) + } + } + }, null, 8 /* PROPS */, ["onClick"])) +}" +`; diff --git a/packages/compiler-core/__tests__/transforms/transformExpressions.spec.ts b/packages/compiler-core/__tests__/transforms/transformExpressions.spec.ts index 4db7aa61903..17f7f619af1 100644 --- a/packages/compiler-core/__tests__/transforms/transformExpressions.spec.ts +++ b/packages/compiler-core/__tests__/transforms/transformExpressions.spec.ts @@ -531,5 +531,29 @@ describe('compiler: expression transform', () => { expect(code).toMatch(`_ctx.options`) expect(code).toMatchSnapshot() }) + + test('should not prefix temp variable of for...in', () => { + const { code } = compileWithBindingMetadata( + `
` + ) + expect(code).not.toMatch(`_ctx.x`) + expect(code).toMatchSnapshot() + }) + + test('should not prefix temp variable of for...of', () => { + const { code } = compileWithBindingMetadata( + `
` + ) + expect(code).not.toMatch(`_ctx.x`) + expect(code).toMatchSnapshot() + }) }) }) From 1846e4436ec7dcc6c7bdc15910a8ad4757bb6e0f Mon Sep 17 00:00:00 2001 From: daiwei Date: Thu, 23 Feb 2023 09:34:22 +0800 Subject: [PATCH 3/4] test: update test case --- .../__snapshots__/transformExpressions.spec.ts.snap | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/compiler-core/__tests__/transforms/__snapshots__/transformExpressions.spec.ts.snap b/packages/compiler-core/__tests__/transforms/__snapshots__/transformExpressions.spec.ts.snap index 937cca4ff6f..4c4356cea74 100644 --- a/packages/compiler-core/__tests__/transforms/__snapshots__/transformExpressions.spec.ts.snap +++ b/packages/compiler-core/__tests__/transforms/__snapshots__/transformExpressions.spec.ts.snap @@ -14,30 +14,30 @@ return function render(_ctx, _cache, $props, $setup, $data, $options) { }" `; -exports[`compiler: expression transform bindingMetadata should not prefix temp variable of for...in 1`] = ` +exports[`compiler: expression transform > bindingMetadata > should not prefix temp variable of for...in 1`] = ` "const { openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue return function render(_ctx, _cache, $props, $setup, $data, $options) { - return (_openBlock(), _createElementBlock("div", { + return (_openBlock(), _createElementBlock(\\"div\\", { onClick: () => { for (const x in _ctx.list) { _ctx.log(x) } } - }, null, 8 /* PROPS */, ["onClick"])) + }, null, 8 /* PROPS */, [\\"onClick\\"])) }" `; -exports[`compiler: expression transform bindingMetadata should not prefix temp variable of for...of 1`] = ` +exports[`compiler: expression transform > bindingMetadata > should not prefix temp variable of for...of 1`] = ` "const { openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue return function render(_ctx, _cache, $props, $setup, $data, $options) { - return (_openBlock(), _createElementBlock("div", { + return (_openBlock(), _createElementBlock(\\"div\\", { onClick: () => { for (const x of _ctx.list) { _ctx.log(x) } } - }, null, 8 /* PROPS */, ["onClick"])) + }, null, 8 /* PROPS */, [\\"onClick\\"])) }" `; From 97c377adab61e5555b3da864d09128a7df8fffe1 Mon Sep 17 00:00:00 2001 From: daiwei Date: Thu, 17 Aug 2023 13:56:04 +0800 Subject: [PATCH 4/4] chore: add more case --- .../transformExpressions.spec.ts.snap | 14 ++++++++++++++ .../transforms/transformExpressions.spec.ts | 16 ++++++++++++++-- packages/compiler-core/src/babelUtils.ts | 8 +++++--- 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/packages/compiler-core/__tests__/transforms/__snapshots__/transformExpressions.spec.ts.snap b/packages/compiler-core/__tests__/transforms/__snapshots__/transformExpressions.spec.ts.snap index 440249cc8c8..a99b88a16bc 100644 --- a/packages/compiler-core/__tests__/transforms/__snapshots__/transformExpressions.spec.ts.snap +++ b/packages/compiler-core/__tests__/transforms/__snapshots__/transformExpressions.spec.ts.snap @@ -14,6 +14,20 @@ return function render(_ctx, _cache, $props, $setup, $data, $options) { }" `; +exports[`compiler: expression transform > bindingMetadata > should not prefix temp variable of for loop 1`] = ` +"const { openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue + +return function render(_ctx, _cache, $props, $setup, $data, $options) { + return (_openBlock(), _createElementBlock(\\"div\\", { + onClick: () => { + for (let i = 0; i < _ctx.list.length; i++) { + _ctx.log(i) + } + } + }, null, 8 /* PROPS */, [\\"onClick\\"])) +}" +`; + exports[`compiler: expression transform > bindingMetadata > should not prefix temp variable of for...in 1`] = ` "const { openBlock: _openBlock, createElementBlock: _createElementBlock } = Vue diff --git a/packages/compiler-core/__tests__/transforms/transformExpressions.spec.ts b/packages/compiler-core/__tests__/transforms/transformExpressions.spec.ts index c39424f0b80..16dd4bb98ec 100644 --- a/packages/compiler-core/__tests__/transforms/transformExpressions.spec.ts +++ b/packages/compiler-core/__tests__/transforms/transformExpressions.spec.ts @@ -531,7 +531,7 @@ describe('compiler: expression transform', () => { expect(code).toMatch(`_ctx, _cache, $props, $setup, $data, $options`) expect(code).toMatchSnapshot() }) - + test('should not prefix temp variable of for...in', () => { const { code } = compileWithBindingMetadata( `
{ + for (let i = 0; i < list.length; i++) { + log(i) + } + }"/>` + ) + expect(code).not.toMatch(`_ctx.i`) + expect(code).toMatchSnapshot() + }) + test('inline mode', () => { const { code } = compileWithBindingMetadata( `
{{ props }} {{ setup }} {{ setupConst }} {{ data }} {{ options }}
`, diff --git a/packages/compiler-core/src/babelUtils.ts b/packages/compiler-core/src/babelUtils.ts index 02a2bfee796..1f1e3896a1e 100644 --- a/packages/compiler-core/src/babelUtils.ts +++ b/packages/compiler-core/src/babelUtils.ts @@ -167,10 +167,12 @@ export function walkBlockDeclarations( onIdent(stmt.id) } else if ( stmt.type === 'ForOfStatement' || - stmt.type === 'ForInStatement' + stmt.type === 'ForInStatement' || + stmt.type === 'ForStatement' ) { - if (stmt.left.type === 'VariableDeclaration') { - for (const decl of stmt.left.declarations) { + const variable = stmt.type === 'ForStatement' ? stmt.init : stmt.left + if (variable && variable.type === 'VariableDeclaration') { + for (const decl of variable.declarations) { for (const id of extractIdentifiers(decl.id)) { onIdent(id) }