1 | "use strict";
|
2 |
|
3 | Object.defineProperty(exports, "__esModule", {
|
4 | value: true
|
5 | });
|
6 | exports.default = void 0;
|
7 |
|
8 | var _path = require("path");
|
9 |
|
10 | var _helperModuleImports = require("@babel/helper-module-imports");
|
11 |
|
12 | function transCamel(_str, symbol) {
|
13 | const str = _str[0].toLowerCase() + _str.substr(1);
|
14 |
|
15 | return str.replace(/([A-Z])/g, $1 => `${symbol}${$1.toLowerCase()}`);
|
16 | }
|
17 |
|
18 | function winPath(path) {
|
19 | return path.replace(/\\/g, '/');
|
20 | }
|
21 |
|
22 | function normalizeCustomName(originCustomName) {
|
23 |
|
24 | if (typeof originCustomName === 'string') {
|
25 | const customNameExports = require(originCustomName);
|
26 |
|
27 | return typeof customNameExports === 'function' ? customNameExports : customNameExports.default;
|
28 | }
|
29 |
|
30 | return originCustomName;
|
31 | }
|
32 |
|
33 | class Plugin {
|
34 | constructor(libraryName, libraryDirectory, style, styleLibraryDirectory, customStyleName, camel2DashComponentName, camel2UnderlineComponentName, fileName, customName, transformToDefaultImport, types, index = 0) {
|
35 | this.libraryName = libraryName;
|
36 | this.libraryDirectory = typeof libraryDirectory === 'undefined' ? 'lib' : libraryDirectory;
|
37 | this.camel2DashComponentName = typeof camel2DashComponentName === 'undefined' ? true : camel2DashComponentName;
|
38 | this.camel2UnderlineComponentName = camel2UnderlineComponentName;
|
39 | this.style = style || false;
|
40 | this.styleLibraryDirectory = styleLibraryDirectory;
|
41 | this.customStyleName = normalizeCustomName(customStyleName);
|
42 | this.fileName = fileName || '';
|
43 | this.customName = normalizeCustomName(customName);
|
44 | this.transformToDefaultImport = typeof transformToDefaultImport === 'undefined' ? true : transformToDefaultImport;
|
45 | this.types = types;
|
46 | this.pluginStateKey = `importPluginState${index}`;
|
47 | }
|
48 |
|
49 | getPluginState(state) {
|
50 | if (!state[this.pluginStateKey]) {
|
51 | state[this.pluginStateKey] = {};
|
52 | }
|
53 |
|
54 | return state[this.pluginStateKey];
|
55 | }
|
56 |
|
57 | importMethod(methodName, file, pluginState) {
|
58 | if (!pluginState.selectedMethods[methodName]) {
|
59 | const libraryDirectory = this.libraryDirectory;
|
60 | const style = this.style;
|
61 | const transformedMethodName = this.camel2UnderlineComponentName
|
62 | ? transCamel(methodName, '_') : this.camel2DashComponentName ? transCamel(methodName, '-') : methodName;
|
63 | const path = winPath(this.customName ? this.customName(transformedMethodName) : (0, _path.join)(this.libraryName, libraryDirectory, transformedMethodName, this.fileName)
|
64 | );
|
65 | pluginState.selectedMethods[methodName] = this.transformToDefaultImport
|
66 | ? (0, _helperModuleImports.addDefault)(file.path, path, {
|
67 | nameHint: methodName
|
68 | }) : (0, _helperModuleImports.addNamed)(file.path, methodName, path);
|
69 |
|
70 | if (this.customStyleName) {
|
71 | const stylePath = winPath(this.customStyleName(transformedMethodName));
|
72 | (0, _helperModuleImports.addSideEffect)(file.path, `${stylePath}`);
|
73 | } else if (this.styleLibraryDirectory) {
|
74 | const stylePath = winPath((0, _path.join)(this.libraryName, this.styleLibraryDirectory, transformedMethodName, this.fileName));
|
75 | (0, _helperModuleImports.addSideEffect)(file.path, `${stylePath}`);
|
76 | } else if (style === true) {
|
77 | (0, _helperModuleImports.addSideEffect)(file.path, `${path}/style`);
|
78 | } else if (style === 'css') {
|
79 | (0, _helperModuleImports.addSideEffect)(file.path, `${path}/style/css`);
|
80 | } else if (typeof style === 'function') {
|
81 | const stylePath = style(path, file);
|
82 |
|
83 | if (stylePath) {
|
84 | (0, _helperModuleImports.addSideEffect)(file.path, stylePath);
|
85 | }
|
86 | }
|
87 | }
|
88 |
|
89 | return Object.assign({}, pluginState.selectedMethods[methodName]);
|
90 | }
|
91 |
|
92 | buildExpressionHandler(node, props, path, state) {
|
93 | const file = path && path.hub && path.hub.file || state && state.file;
|
94 | const types = this.types;
|
95 | const pluginState = this.getPluginState(state);
|
96 | props.forEach(prop => {
|
97 | if (!types.isIdentifier(node[prop])) return;
|
98 |
|
99 | if (pluginState.specified[node[prop].name] && types.isImportSpecifier(path.scope.getBinding(node[prop].name).path)) {
|
100 | node[prop] = this.importMethod(pluginState.specified[node[prop].name], file, pluginState);
|
101 | }
|
102 | });
|
103 | }
|
104 |
|
105 | buildDeclaratorHandler(node, prop, path, state) {
|
106 | const file = path && path.hub && path.hub.file || state && state.file;
|
107 | const types = this.types;
|
108 | const pluginState = this.getPluginState(state);
|
109 | if (!types.isIdentifier(node[prop])) return;
|
110 |
|
111 | if (pluginState.specified[node[prop].name] && path.scope.hasBinding(node[prop].name) && path.scope.getBinding(node[prop].name).path.type === 'ImportSpecifier') {
|
112 | node[prop] = this.importMethod(pluginState.specified[node[prop].name], file, pluginState);
|
113 | }
|
114 | }
|
115 |
|
116 | ProgramEnter(path, state) {
|
117 | const pluginState = this.getPluginState(state);
|
118 | pluginState.specified = Object.create(null);
|
119 | pluginState.libraryObjs = Object.create(null);
|
120 | pluginState.selectedMethods = Object.create(null);
|
121 | pluginState.pathsToRemove = [];
|
122 | }
|
123 |
|
124 | ProgramExit(path, state) {
|
125 | this.getPluginState(state).pathsToRemove.forEach(p => !p.removed && p.remove());
|
126 | }
|
127 |
|
128 | ImportDeclaration(path, state) {
|
129 | const node = path.node;
|
130 |
|
131 | if (!node) return;
|
132 | const value = node.source.value;
|
133 | const libraryName = this.libraryName;
|
134 | const types = this.types;
|
135 | const pluginState = this.getPluginState(state);
|
136 |
|
137 | if (value === libraryName) {
|
138 | node.specifiers.forEach(spec => {
|
139 | if (types.isImportSpecifier(spec)) {
|
140 | pluginState.specified[spec.local.name] = spec.imported.name;
|
141 | } else {
|
142 | pluginState.libraryObjs[spec.local.name] = true;
|
143 | }
|
144 | });
|
145 | pluginState.pathsToRemove.push(path);
|
146 | }
|
147 | }
|
148 |
|
149 | CallExpression(path, state) {
|
150 | const node = path.node;
|
151 | const file = path && path.hub && path.hub.file || state && state.file;
|
152 | const name = node.callee.name;
|
153 | const types = this.types;
|
154 | const pluginState = this.getPluginState(state);
|
155 |
|
156 | if (types.isIdentifier(node.callee)) {
|
157 | if (pluginState.specified[name]) {
|
158 | node.callee = this.importMethod(pluginState.specified[name], file, pluginState);
|
159 | }
|
160 | }
|
161 |
|
162 | node.arguments = node.arguments.map(arg => {
|
163 | const argName = arg.name;
|
164 |
|
165 | if (pluginState.specified[argName] && path.scope.hasBinding(argName) && path.scope.getBinding(argName).path.type === 'ImportSpecifier') {
|
166 | return this.importMethod(pluginState.specified[argName], file, pluginState);
|
167 | }
|
168 |
|
169 | return arg;
|
170 | });
|
171 | }
|
172 |
|
173 | MemberExpression(path, state) {
|
174 | const node = path.node;
|
175 | const file = path && path.hub && path.hub.file || state && state.file;
|
176 | const pluginState = this.getPluginState(state);
|
177 |
|
178 | if (!node.object || !node.object.name) return;
|
179 |
|
180 | if (pluginState.libraryObjs[node.object.name]) {
|
181 |
|
182 | path.replaceWith(this.importMethod(node.property.name, file, pluginState));
|
183 | } else if (pluginState.specified[node.object.name] && path.scope.hasBinding(node.object.name)) {
|
184 | const scope = path.scope.getBinding(node.object.name).scope;
|
185 |
|
186 | if (scope.path.parent.type === 'File') {
|
187 | node.object = this.importMethod(pluginState.specified[node.object.name], file, pluginState);
|
188 | }
|
189 | }
|
190 | }
|
191 |
|
192 | Property(path, state) {
|
193 | const node = path.node;
|
194 | this.buildDeclaratorHandler(node, 'value', path, state);
|
195 | }
|
196 |
|
197 | VariableDeclarator(path, state) {
|
198 | const node = path.node;
|
199 | this.buildDeclaratorHandler(node, 'init', path, state);
|
200 | }
|
201 |
|
202 | ArrayExpression(path, state) {
|
203 | const node = path.node;
|
204 | const props = node.elements.map((_, index) => index);
|
205 | this.buildExpressionHandler(node.elements, props, path, state);
|
206 | }
|
207 |
|
208 | LogicalExpression(path, state) {
|
209 | const node = path.node;
|
210 | this.buildExpressionHandler(node, ['left', 'right'], path, state);
|
211 | }
|
212 |
|
213 | ConditionalExpression(path, state) {
|
214 | const node = path.node;
|
215 | this.buildExpressionHandler(node, ['test', 'consequent', 'alternate'], path, state);
|
216 | }
|
217 |
|
218 | IfStatement(path, state) {
|
219 | const node = path.node;
|
220 | this.buildExpressionHandler(node, ['test'], path, state);
|
221 | this.buildExpressionHandler(node.test, ['left', 'right'], path, state);
|
222 | }
|
223 |
|
224 | ExpressionStatement(path, state) {
|
225 | const node = path.node;
|
226 | const types = this.types;
|
227 |
|
228 | if (types.isAssignmentExpression(node.expression)) {
|
229 | this.buildExpressionHandler(node.expression, ['right'], path, state);
|
230 | }
|
231 | }
|
232 |
|
233 | ReturnStatement(path, state) {
|
234 | const node = path.node;
|
235 | this.buildExpressionHandler(node, ['argument'], path, state);
|
236 | }
|
237 |
|
238 | ExportDefaultDeclaration(path, state) {
|
239 | const node = path.node;
|
240 | this.buildExpressionHandler(node, ['declaration'], path, state);
|
241 | }
|
242 |
|
243 | BinaryExpression(path, state) {
|
244 | const node = path.node;
|
245 | this.buildExpressionHandler(node, ['left', 'right'], path, state);
|
246 | }
|
247 |
|
248 | NewExpression(path, state) {
|
249 | const node = path.node;
|
250 | this.buildExpressionHandler(node, ['callee', 'arguments'], path, state);
|
251 | }
|
252 |
|
253 | ClassDeclaration(path, state) {
|
254 | const node = path.node;
|
255 | this.buildExpressionHandler(node, ['superClass'], path, state);
|
256 | }
|
257 |
|
258 | }
|
259 |
|
260 | exports.default = Plugin; |
\ | No newline at end of file |