-
-
Notifications
You must be signed in to change notification settings - Fork 8
/
plugin.js
101 lines (84 loc) · 2.46 KB
/
plugin.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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
'use strict'
const transformImplicitParams = require('./dist/implicit-parameters').default
const transformPlaceholders = require('./dist/placeholders').default
const transformLift = require('./dist/lift').default
const { name } = require('./package.json')
const isPrimitive = val =>
val == null || ['s', 'b', 'n'].indexOf((typeof val)[0]) >= 0
const looksLike = (a, b) =>
a &&
b &&
Object.keys(b).every(bKey => {
const bVal = b[bKey]
const aVal = a[bKey]
if (typeof bVal === 'function') {
return bVal(aVal)
}
return isPrimitive(bVal)
? bVal === aVal
: looksLike(aVal, bVal)
})
const isImport = path => looksLike(path, {
node: {
source: {
value: name
}
}
})
const isRequire = path => looksLike(path, {
node: {
callee: {
type: 'Identifier',
name: 'require'
},
arguments: args =>
args.length === 1 && args[0] === name
},
parent: {
type: 'VariableDeclarator'
}
})
const applyPlugin = (babel, path, imports) => {
let hasReferences = false
const references = imports.reduce(
(byName, { importedName, localName }) => {
byName[importedName] = path.scope.getBinding(localName).referencePaths
hasReferences = hasReferences || Boolean(byName[importedName].length)
return byName
},
{}
)
if (!hasReferences) return
if (references.it) transformImplicitParams(babel.types, references.it)
if (references.default) transformImplicitParams(babel.types, references.default)
if (references._) transformPlaceholders(babel.types, references._)
if (references.lift) transformLift(babel.types, references.lift)
}
module.exports = babel => {
return {
name,
visitor: {
ImportDeclaration (path, state) {
if (!isImport(path)) return
const imports = path.node.specifiers.map(s => ({
localName: s.local.name,
importedName:
s.type === 'ImportDefaultSpecifier' ? 'default' : s.imported.name
}))
applyPlugin(babel, path, imports)
path.remove()
},
CallExpression (path, state) {
if (!isRequire(path)) return
const imports = path.parent.id.name
? [{ localName: path.parent.id.name, importedName: 'default' }]
: path.parent.id.properties.map(property => ({
localName: property.value.name,
importedName: property.key.name
}))
applyPlugin(babel, path, imports)
path.parentPath.remove()
}
}
}
}