Skip to content

Commit 7007ffb

Browse files
committed
fix(reactivity-transform): should not rewrite for...in / for...of scope variables
1 parent dd70003 commit 7007ffb

File tree

2 files changed

+73
-35
lines changed

2 files changed

+73
-35
lines changed

packages/reactivity-transform/__tests__/reactivityTransform.spec.ts

+34-6
Original file line numberDiff line numberDiff line change
@@ -127,15 +127,43 @@ test('accessing ref binding', () => {
127127
assertCode(code)
128128
})
129129

130-
test('cases that should not append .value', () => {
131-
const { code } = transform(`
130+
describe('cases that should not append .value', () => {
131+
test('member expression', () => {
132+
const { code } = transform(`
133+
let a = $ref(1)
134+
console.log(b.a)
135+
`)
136+
expect(code).not.toMatch(`a.value`)
137+
})
138+
139+
test('function argument', () => {
140+
const { code } = transform(`
141+
let a = $ref(1)
142+
function get(a) {
143+
return a + 1
144+
}
145+
function get2({ a }) {
146+
return a + 1
147+
}
148+
function get3([a]) {
149+
return a + 1
150+
}
151+
`)
152+
expect(code).not.toMatch(`a.value`)
153+
})
154+
155+
test('for in/of loops', () => {
156+
const { code } = transform(`
132157
let a = $ref(1)
133-
console.log(b.a)
134-
function get(a) {
135-
return a + 1
158+
for (const [a, b] of arr) {
159+
console.log(a)
160+
}
161+
for (let a in arr) {
162+
console.log(a)
136163
}
137164
`)
138-
expect(code).not.toMatch(`a.value`)
165+
expect(code).not.toMatch(`a.value`)
166+
})
139167
})
140168

141169
test('mutating ref binding', () => {

packages/reactivity-transform/src/reactivityTransform.ts

+39-29
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ import {
77
ArrayPattern,
88
Program,
99
VariableDeclarator,
10-
Expression
10+
Expression,
11+
VariableDeclaration
1112
} from '@babel/types'
1213
import MagicString, { SourceMap } from 'magic-string'
1314
import { walk } from 'estree-walker'
@@ -216,40 +217,49 @@ export function transformAST(
216217
function walkScope(node: Program | BlockStatement, isRoot = false) {
217218
for (const stmt of node.body) {
218219
if (stmt.type === 'VariableDeclaration') {
219-
if (stmt.declare) continue
220-
for (const decl of stmt.declarations) {
221-
let refCall
222-
const isCall =
223-
decl.init &&
224-
decl.init.type === 'CallExpression' &&
225-
decl.init.callee.type === 'Identifier'
226-
if (
227-
isCall &&
228-
(refCall = isRefCreationCall((decl as any).init.callee.name))
229-
) {
230-
processRefDeclaration(refCall, decl.id, decl.init as CallExpression)
231-
} else {
232-
const isProps =
233-
isRoot &&
234-
isCall &&
235-
(decl as any).init.callee.name === 'defineProps'
236-
for (const id of extractIdentifiers(decl.id)) {
237-
if (isProps) {
238-
// for defineProps destructure, only exclude them since they
239-
// are already passed in as knownProps
240-
excludedIds.add(id)
241-
} else {
242-
registerBinding(id)
243-
}
244-
}
245-
}
246-
}
220+
walkVariableDeclaration(stmt, isRoot)
247221
} else if (
248222
stmt.type === 'FunctionDeclaration' ||
249223
stmt.type === 'ClassDeclaration'
250224
) {
251225
if (stmt.declare || !stmt.id) continue
252226
registerBinding(stmt.id)
227+
} else if (
228+
(stmt.type === 'ForOfStatement' || stmt.type === 'ForInStatement') &&
229+
stmt.left.type === 'VariableDeclaration'
230+
) {
231+
walkVariableDeclaration(stmt.left)
232+
}
233+
}
234+
}
235+
236+
function walkVariableDeclaration(stmt: VariableDeclaration, isRoot = false) {
237+
if (stmt.declare) {
238+
return
239+
}
240+
for (const decl of stmt.declarations) {
241+
let refCall
242+
const isCall =
243+
decl.init &&
244+
decl.init.type === 'CallExpression' &&
245+
decl.init.callee.type === 'Identifier'
246+
if (
247+
isCall &&
248+
(refCall = isRefCreationCall((decl as any).init.callee.name))
249+
) {
250+
processRefDeclaration(refCall, decl.id, decl.init as CallExpression)
251+
} else {
252+
const isProps =
253+
isRoot && isCall && (decl as any).init.callee.name === 'defineProps'
254+
for (const id of extractIdentifiers(decl.id)) {
255+
if (isProps) {
256+
// for defineProps destructure, only exclude them since they
257+
// are already passed in as knownProps
258+
excludedIds.add(id)
259+
} else {
260+
registerBinding(id)
261+
}
262+
}
253263
}
254264
}
255265
}

0 commit comments

Comments
 (0)