forked from vuejs/jsx-vue2
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.js
82 lines (75 loc) · 1.81 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import syntaxJsx from '@babel/plugin-syntax-jsx'
/**
* Check if first parameter is `h`
* @param t
* @param path ObjectMethod | ClassMethod
* @returns boolean
*/
const firstParamIsH = (t, path) => {
const params = path.get('params')
return params.length && t.isIdentifier(params[0]) && params[0].node.name === 'h'
}
/**
* Check if body contains JSX
* @param t
* @param path ObjectMethod | ClassMethod
* @returns boolean
*/
const hasJSX = (t, path) => {
const JSXChecker = {
hasJSX: false,
}
path.traverse(
{
JSXElement() {
this.hasJSX = true
},
},
JSXChecker,
)
return JSXChecker.hasJSX
}
/**
* Check if is inside a JSX expression
* @param t
* @param path ObjectMethod | ClassMethod
* @returns boolean
*/
const isInsideJSXExpression = (t, path) => {
if (!path.parentPath) {
return false
}
if (t.isJSXExpressionContainer(path.parentPath)) {
return true
}
return isInsideJSXExpression(t, path.parentPath)
}
export default babel => {
const t = babel.types
return {
inherits: syntaxJsx,
visitor: {
'ObjectMethod|ClassMethod': {
exit(path) {
if (firstParamIsH(t, path) || !hasJSX(t, path) || isInsideJSXExpression(t, path)) {
return
}
const isRender = path.node.key.name === 'render'
path
.get('body')
.unshiftContainer(
'body',
t.variableDeclaration('const', [
t.variableDeclarator(
t.identifier('h'),
isRender
? t.memberExpression(t.identifier('arguments'), t.numericLiteral(0), true)
: t.memberExpression(t.thisExpression(), t.identifier('$createElement')),
),
]),
)
},
},
},
}
}