Skip to content

Commit da30e8c

Browse files
committed
add support for update expressions
1 parent 078ec73 commit da30e8c

File tree

5 files changed

+95
-1
lines changed

5 files changed

+95
-1
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
"fix": "npx prettier --write source/* test/*",
2626
"watch": "npm run build -- --watch source",
2727
"prepublishOnly": "npm run build",
28-
"release": "np --branch dev"
28+
"release": "npx np --branch dev"
2929
},
3030
"dependencies": {
3131
"@babel/types": "^7.16.0"

source/index.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ function transformToStateByScope(path: any, toMod: ToModifyVariableI[]) {
4848
},
4949
ExpressionStatement({node}: {node: t.ExpressionStatement}) {
5050
transformAssignmentExpression(node, toMod)
51+
transformUpdateExpression(node, toMod)
5152
},
5253
})
5354
}
@@ -154,6 +155,47 @@ function transformAssignmentExpression(
154155
node.expression = t.callExpression(t.identifier(setterName), callArgs)
155156
}
156157

158+
function transformUpdateExpression(
159+
node: t.ExpressionStatement,
160+
toMod: ToModifyVariableI[]
161+
) {
162+
if (!t.isUpdateExpression(node.expression)) {
163+
return
164+
}
165+
166+
const expression: t.UpdateExpression = node.expression
167+
168+
if (!t.isIdentifier(expression.argument)) {
169+
return
170+
}
171+
172+
if (!isReactiveIdentifier(expression.argument.name, toMod)) {
173+
return
174+
}
175+
176+
const normName = normalizeName(expression.argument.name)
177+
const setterName = getSetterName(normName)
178+
179+
let callArgs: t.Expression[]
180+
181+
switch (expression.operator) {
182+
case '++': {
183+
callArgs = [
184+
t.binaryExpression('+', t.identifier(normName), t.numericLiteral(1)),
185+
]
186+
break
187+
}
188+
case '--': {
189+
callArgs = [
190+
t.binaryExpression('-', t.identifier(normName), t.numericLiteral(1)),
191+
]
192+
break
193+
}
194+
}
195+
196+
node.expression = t.callExpression(t.identifier(setterName), callArgs)
197+
}
198+
157199
function isReactiveIdentifier(idName: string, modMap: ToModifyVariableI[]) {
158200
return (
159201
modMap.findIndex((x) => x.raw === idName || x.simplified === idName) > -1

test/snapshots/test.ts.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,3 +227,24 @@ Generated by [AVA](https://avajs.dev).
227227
onClick: updateUser␊
228228
}, "Click Me"));␊
229229
}`
230+
231+
## Update Expression Test
232+
233+
> Snapshot 1
234+
235+
`import * as React from "react";␊
236+
237+
function App() {␊
238+
const [count, setCount] = React.useState(1);␊
239+
240+
const updateUser = () => {␊
241+
setCount(count + 1);␊
242+
setCount(count - 1);␊
243+
};␊
244+
245+
return /*#__PURE__*/React.createElement(React.Fragment, null, users.map(user => {␊
246+
return /*#__PURE__*/React.createElement("p", null, user.name);␊
247+
}), /*#__PURE__*/React.createElement("p", null, updateCount), /*#__PURE__*/React.createElement("button", {␊
248+
onClick: updateUser␊
249+
}, "Click Me"));␊
250+
}`

test/snapshots/test.ts.snap

43 Bytes
Binary file not shown.

test/test.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,3 +287,34 @@ test('Mix and Match State', (t) => {
287287
}
288288
t.snapshot(result.code)
289289
})
290+
291+
test('Update Expression Test', (t) => {
292+
const code = `
293+
import * as React from "react";
294+
295+
function App() {
296+
let $count = 1;
297+
298+
const updateUser = () => {
299+
count++;
300+
count--;
301+
};
302+
303+
return (
304+
<>
305+
{$users.map(user=>{
306+
return <p>{user.name}</p>
307+
})}
308+
<p>{updateCount}</p>
309+
<button onClick={updateUser}>Click Me</button>
310+
</>
311+
);
312+
}
313+
`
314+
315+
const result = compile(code)
316+
if (!result) {
317+
return t.fail()
318+
}
319+
t.snapshot(result.code)
320+
})

0 commit comments

Comments
 (0)