-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
79 lines (67 loc) · 2.14 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
module.exports = function ({ types: t }) {
function buildImport(imported, source) {
return (
t.importDeclaration(
imported.map(
name => t.importSpecifier(t.identifier(name), t.identifier(name))
),
t.stringLiteral(source)
)
);
}
// has import * as
function hasImportAll(node) {
return node.specifiers.some(specifier =>
t.isImportNamespaceSpecifier(specifier)
);
}
function getNamespaceSpecifier(node) {
return node.specifiers.find(specifier =>
t.isImportNamespaceSpecifier(specifier)
);
}
return {
pre() {
// save reference to the "import * as" declaretion in order to replace it
this.importDeclaretion = null;
// In case of import * as R from 'ramda' importedIdentifier will be R
this.importedIdentifier = null;
// Set is used because we don't want to add some function several times
this.importedFunctions = new Set();
this.libraryName = null;
},
visitor: {
ImportDeclaration: {
exit(path, state) {
const { node } = path;
const { libraryName } = state.opts;
// We need to have access to library name in post method, so we save it
this.libraryName = libraryName;
if (hasImportAll(node) && node.source.value === libraryName) {
this.importDeclaretion = path;
this.importedIdentifier = getNamespaceSpecifier(node).local.name;
}
},
},
MemberExpression: {
enter(path) {
if (path.node.object.name === this.importedIdentifier) {
const propertyName = path.node.property.name;
this.importedFunctions.add(propertyName);
// R.foo() -> foo()
path.replaceWith(t.identifier(propertyName));
}
},
},
},
post(state) {
const { libraryName } = state.opts;
// Convert import * as R from 'ramda' to import { a, b, c } from 'ramda'
if (this.importDeclaretion) {
this.importDeclaretion.replaceWith(
buildImport(Array.from(this.importedFunctions), this.libraryName)
);
}
},
};
};