Skip to content

Commit d6d8b10

Browse files
committed
feat: implement remove-vue-set-and-delete
1 parent efa3950 commit d6d8b10

File tree

2 files changed

+177
-0
lines changed

2 files changed

+177
-0
lines changed
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import { defineInlineTest } from 'jscodeshift/src/testUtils'
2+
const transform = require('../remove-vue-set-and-delete')
3+
4+
defineInlineTest(
5+
transform,
6+
{},
7+
`Vue.set(vm.someObject, 'b', 2);`,
8+
`vm.someObject['b'] = 2;`,
9+
'Remove Vue.set'
10+
)
11+
12+
defineInlineTest(
13+
transform,
14+
{},
15+
`export default {
16+
methods: {
17+
modify() {
18+
this.$set(this.someObject, 'b', 2);
19+
}
20+
}
21+
};`,
22+
`export default {
23+
methods: {
24+
modify() {
25+
this.someObject['b'] = 2;
26+
}
27+
}
28+
};`,
29+
'Remove this.$set'
30+
)
31+
32+
defineInlineTest(
33+
transform,
34+
{},
35+
`export default {
36+
created () {
37+
const vm = this;
38+
this.$on('some-event', function () {
39+
vm.$set(vm.someObject, 'b', 2);
40+
})
41+
}
42+
};`,
43+
`export default {
44+
created () {
45+
const vm = this;
46+
this.$on('some-event', function () {
47+
vm.someObject['b'] = 2;
48+
})
49+
}
50+
};`,
51+
'Remove vm.$set when vm is an alias to this'
52+
)
53+
54+
defineInlineTest(
55+
transform,
56+
{},
57+
`export default {
58+
created () {
59+
var vm = this;
60+
vm = { $set: () => {} }
61+
this.$on('some-event', function () {
62+
vm.$set(vm.someObject, 'b', 2);
63+
})
64+
}
65+
};`,
66+
`export default {
67+
created () {
68+
var vm = this;
69+
vm = { $set: () => {} }
70+
this.$on('some-event', function () {
71+
vm.$set(vm.someObject, 'b', 2);
72+
})
73+
}
74+
};`,
75+
`Don't remove vm.$set when we are not sure if vm is an alias to this`
76+
)
77+
78+
defineInlineTest(
79+
transform,
80+
{},
81+
`value.$set('a', 1)`,
82+
`value.$set('a', 1)`,
83+
`don't remove random .$set functions`
84+
)
85+
86+
// TODO: delete
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
// To remove:
2+
// Vue.set / Vue.delete
3+
// this.$set / this.$delete
4+
// vm = this; this.$set / this.$delete
5+
6+
import wrap from '../src/wrapAstTransformation'
7+
import type { ASTTransformation } from '../src/wrapAstTransformation'
8+
import type * as N from 'jscodeshift'
9+
10+
export const transformAST: ASTTransformation = (context) => {
11+
const { root, j } = context
12+
13+
const isVue = (node: N.ASTNode) => {
14+
return j.Identifier.check(node) && node.name === 'Vue'
15+
}
16+
17+
const setCalls = root
18+
.find(j.CallExpression, (n: N.CallExpression) => {
19+
if (
20+
!j.MemberExpression.check(n.callee) ||
21+
!j.Identifier.check(n.callee.property)
22+
) {
23+
return false
24+
}
25+
26+
if (n.callee.property.name === 'set' && isVue(n.callee.object)) {
27+
return true
28+
}
29+
30+
if (n.callee.property.name === '$set') {
31+
// we need the path & scope to check if the object is `this`
32+
// so leave it to the filter function
33+
return true
34+
}
35+
36+
return false
37+
})
38+
.filter((path) => {
39+
// @ts-ignore
40+
if (path.node.callee.property.name !== '$set') {
41+
return true
42+
}
43+
44+
const obj = (path.node.callee as N.MemberExpression).object
45+
46+
if (j.ThisExpression.check(obj)) {
47+
return true
48+
}
49+
50+
if (!j.Identifier.check(obj)) {
51+
return false
52+
}
53+
54+
const decls = j(path).getVariableDeclarators((p) => obj.name)
55+
if (decls && decls.length === 1) {
56+
const declPath = decls.paths()[0]
57+
const declNode = declPath.node
58+
const declStmt = declPath.parent.node
59+
60+
return (
61+
j.VariableDeclarator.check(declNode) &&
62+
(declStmt as N.VariableDeclaration).kind === 'const' &&
63+
j.Identifier.check(declNode.id) &&
64+
j.ThisExpression.check(declNode.init)
65+
)
66+
}
67+
68+
return false
69+
})
70+
71+
setCalls.replaceWith(({ node }) => {
72+
if (
73+
node.arguments.length !== 3 ||
74+
node.arguments.some((arg) => j.SpreadElement.check(arg))
75+
) {
76+
// TODO: add a comment to inform the user that this kind of usage can't be transformed
77+
return node
78+
}
79+
80+
return j.assignmentExpression(
81+
'=',
82+
// @ts-ignore
83+
j.memberExpression(node.arguments[0], node.arguments[1], true),
84+
// @ts-ignore
85+
node.arguments[2]
86+
)
87+
})
88+
}
89+
90+
export default wrap(transformAST)
91+
export const parser = 'babylon'

0 commit comments

Comments
 (0)