Skip to content

Commit 45c4a22

Browse files
committed
feat: implement add emit declaration
1 parent eefffa6 commit 45c4a22

File tree

3 files changed

+130
-0
lines changed

3 files changed

+130
-0
lines changed
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import { defineInlineTest } from 'jscodeshift/src/testUtils'
2+
const transform = require('../add-emit-declaration')
3+
4+
defineInlineTest(
5+
transform,
6+
{},
7+
`export default {
8+
props: ['text'],
9+
methods: {
10+
input: function() {
11+
this.$emit('increment')
12+
this.$emit('decrement')
13+
}
14+
}
15+
}`,
16+
`export default {
17+
emits: ["increment", "decrement"],
18+
props: ['text'],
19+
20+
methods: {
21+
input: function() {
22+
this.$emit('increment')
23+
this.$emit('decrement')
24+
}
25+
}
26+
};`,
27+
'add emit declaration'
28+
)
29+
30+
defineInlineTest(
31+
transform,
32+
{},
33+
`export default {
34+
emits: [],
35+
props: ['text'],
36+
methods: {
37+
input: function() {
38+
this.$emit('increment')
39+
this.$emit('decrement')
40+
}
41+
}
42+
}`,
43+
`export default {
44+
emits: ["increment", "decrement"],
45+
props: ['text'],
46+
methods: {
47+
input: function() {
48+
this.$emit('increment')
49+
this.$emit('decrement')
50+
}
51+
}
52+
}`,
53+
'add emit declaration(has emits property but empty)'
54+
)
55+
56+
defineInlineTest(
57+
transform,
58+
{},
59+
`export default {
60+
emits: ['increment'],
61+
props: ['text'],
62+
methods: {
63+
input: function() {
64+
this.$emit('increment')
65+
this.$emit('decrement')
66+
}
67+
}
68+
}
69+
`,
70+
`export default {
71+
emits: ['increment', "decrement"],
72+
props: ['text'],
73+
methods: {
74+
input: function() {
75+
this.$emit('increment')
76+
this.$emit('decrement')
77+
}
78+
}
79+
}`,
80+
'add emit declaration(has emits property and not empty)'
81+
)
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import wrap from '../src/wrapAstTransformation'
2+
import type { ASTTransformation } from '../src/wrapAstTransformation'
3+
4+
export const transformAST: ASTTransformation = ({ root, j }) => {
5+
// find the export default
6+
const defaultExportBody = root.find(j.ExportDefaultDeclaration)
7+
8+
// find the CallExpression
9+
const emitCalls = defaultExportBody.find(j.CallExpression, node => {
10+
return node.callee.object?.type === 'ThisExpression'
11+
&& node.callee.property?.name === '$emit'
12+
})
13+
14+
if (emitCalls.length) {
15+
// find the $emit argument
16+
const eventNames: string[] = []
17+
emitCalls.forEach(({ node }) => {
18+
if (node.arguments[0]?.type === 'StringLiteral') {
19+
eventNames.push(node.arguments[0].value)
20+
}
21+
})
22+
23+
// find the emit property
24+
const emitsProperty = defaultExportBody.find(j.ObjectProperty, node => {
25+
return node.key.name === 'emits'
26+
&& node.value.type === 'ArrayExpression'
27+
})
28+
29+
const elements = emitsProperty.length ? emitsProperty.get(0).node.value.elements : []
30+
const emits = elements.map((r: { value: string }) => r.value)
31+
const hasEmitsProperty = emitsProperty.length
32+
33+
// push not declare event name into emits
34+
eventNames.forEach(r => {
35+
if (!emits.includes(r)) {
36+
elements.push(j.stringLiteral(r))
37+
}
38+
})
39+
40+
if(!hasEmitsProperty){
41+
// no emits property then create emits:[...] AST
42+
defaultExportBody.get(0).node.declaration.properties.unshift(j.objectProperty(j.identifier('emits'),j.arrayExpression(elements)));
43+
}
44+
}
45+
}
46+
47+
export default wrap(transformAST)
48+
export const parser = 'babylon'

transformations/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ const transformationMap: {
1818
'new-directive-api': require('./new-directive-api'),
1919
'remove-vue-set-and-delete': require('./remove-vue-set-and-delete'),
2020
'rename-lifecycle': require('./rename-lifecycle'),
21+
'add-emit-declaration': require('./add-emit-declaration'),
2122

2223
// atomic ones
2324
'remove-contextual-h-from-render': require('./remove-contextual-h-from-render'),

0 commit comments

Comments
 (0)