UNPKG

10.3 kBJavaScriptView Raw
1'use strict';
2
3var _RewireState = require('./RewireState.js');
4
5var _RewireState2 = _interopRequireDefault(_RewireState);
6
7var _RewireHelpers = require('./RewireHelpers.js');
8
9function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
10
11/*Copyright (c) 2015, Robert Binna <r.binna@synedra.com>
12
13 Permission to use, copy, modify, and/or distribute this software for any
14 purpose with or without fee is hereby granted, provided that the above
15 copyright notice and this permission notice appear in all copies.
16
17 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
18 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
19 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
20 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
21 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
22 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
23 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.*/
24
25module.exports = function (_ref) {
26 var t = _ref.types;
27
28 function isRewireable(path, variableBinding) {
29 var node = path.node;
30 var parent = path.parent;
31
32
33 return variableBinding.referencePaths !== null && !(parent.type === 'VariableDeclarator' && parent.id == node) && !(parent.type === 'FunctionExpression' && parent.id === node) && !(parent.type === 'MemberExpression' && parent.property === node) && !(parent.type === 'ObjectProperty' && parent.key === node) && !(parent.type === 'ObjectMethod' && parent.key === node) && !(parent.type === 'ObjectProperty' && path.parentPath && path.parentPath.parent && path.parentPath.parent.type === 'ObjectPattern') && !(parent.type === 'ExportSpecifier') && !(parent.type === 'ImportSpecifier') && !(parent.type === 'ObjectTypeProperty') && !(parent.type === 'ClassMethod');
34 }
35
36 function doesIdentifierRepresentAValidReference(path, variableBinding, rewireInformation) {
37 var isIgnoredVariable = rewireInformation.ignoredIdentifiers.indexOf(path.node.name) !== -1;
38 return !isIgnoredVariable && variableBinding !== undefined && !(0, _RewireHelpers.wasProcessed)(path) && variableBinding.scope.block.type === 'Program';
39 }
40
41 function getVariableNameAndBinding(path) {
42 var node = path.node;
43 var parent = path.parent;
44 var scope = path.scope;
45
46 var variableName = node.name;
47 var variableBinding = !t.isFlow || !t.isFlow(node) && !t.isFlow(parent) ? scope.getBinding(variableName) : undefined;
48
49 return {
50 variableName: variableName,
51 variableBinding: variableBinding
52 };
53 }
54
55 var BodyVisitor = {
56 Identifier: function Identifier(path, rewireInformation) {
57 var node = path.node;
58 var parent = path.parent;
59 var scope = path.scope;
60
61 var _getVariableNameAndBi = getVariableNameAndBinding(path);
62
63 var variableName = _getVariableNameAndBi.variableName;
64 var variableBinding = _getVariableNameAndBi.variableBinding;
65
66 //Matches for body
67
68 if (doesIdentifierRepresentAValidReference(path, variableBinding, rewireInformation)) {
69 var isWildCardImport = variableBinding.path.type === 'ImportNamespaceSpecifier';
70 if (isRewireable(path, variableBinding) && (0, _RewireHelpers.contains)(variableBinding.referencePaths, path)) {
71 if (parent.type === 'UpdateExpression') {
72 rewireInformation.addUpdateableVariable(variableName);
73 path.parentPath.replaceWith(t.callExpression(rewireInformation.getUpdateOperationID(), [t.stringLiteral(parent.operator), t.stringLiteral(variableName), t.booleanLiteral(parent.prefix)]));
74 } else {
75 rewireInformation.ensureAccessor(variableName, isWildCardImport);
76 path.replaceWith(t.callExpression(rewireInformation.getUniversalGetterID(), [t.stringLiteral(variableName)]));
77 }
78 } else if (parent.type === 'AssignmentExpression' && parent.left == node) {
79 rewireInformation.addUpdateableVariable(variableName);
80
81 if (parent.operator === '=') {
82 path.parentPath.replaceWith((0, _RewireHelpers.noRewire)(t.callExpression(rewireInformation.getAssignmentOperationID(), [t.stringLiteral(variableName), parent.right])));
83 } else {
84 var baseOperator = parent.operator.substring(0, parent.operator.length - 1);
85 path.parentPath.replaceWith(t.assignmentExpression('=', parent.left, t.binaryExpression(baseOperator, t.callExpression(rewireInformation.getUniversalGetterID(), [t.stringLiteral(variableName)]), parent.right)));
86 }
87 //TODO variable bindings add accessor for each variable declaration even if its unused. The reason is that any other plugin could potentially change the code otherwise
88 }
89
90 if (variableBinding.identifier === node) {
91 rewireInformation.addTrackedIdentifier(variableName, isWildCardImport);
92 }
93 }
94 },
95
96 'ExportNamedDeclaration|ExportAllDeclaration': function ExportNamedDeclarationExportAllDeclaration(_ref2, rewireInformation) {
97 var _ref2$node$specifiers = _ref2.node.specifiers;
98 var specifiers = _ref2$node$specifiers === undefined ? [] : _ref2$node$specifiers;
99
100 var hasDefaultExport = specifiers.some(function (specifier) {
101 return specifier.local && specifier.local.name === 'default' || specifier.exported && specifier.exported.name === 'default';
102 });
103 rewireInformation.hasES6DefaultExport = rewireInformation.hasES6DefaultExport || hasDefaultExport;
104 rewireInformation.isES6Module = true;
105 },
106
107 AssignmentExpression: function AssignmentExpression(_ref3, rewireInformation) {
108 var assignmentExpression = _ref3.node;
109 var blockType = _ref3.scope.block.type;
110
111 rewireInformation.hasCommonJSExport = blockType === 'Program' && !!assignmentExpression.left.object && assignmentExpression.left.object.name === 'module' && !!assignmentExpression.left.property && assignmentExpression.left.property.name === 'exports';
112 },
113
114 ExportDefaultDeclaration: function ExportDefaultDeclaration(path, rewireInformation) {
115 if (!(0, _RewireHelpers.wasProcessed)(path)) {
116 (function () {
117 var exportIdentifier = null;
118 rewireInformation.hasES6DefaultExport = true;
119 rewireInformation.hasES6Export = true;
120 rewireInformation.isES6Module = true;
121
122 var declarationVisitors = {
123 ClassDeclaration: function ClassDeclaration(path, rewireInformation) {
124 var existingClassDeclaration = path.node;
125 var parent = path.parent;
126 var scope = path.scope;
127
128 if (existingClassDeclaration.id === null && parent.type === 'ExportDefaultDeclaration') {
129 exportIdentifier = scope.generateUidIdentifier("DefaultExportValue");
130 path.replaceWith(t.classDeclaration(exportIdentifier, existingClassDeclaration.superClass, existingClassDeclaration.body, existingClassDeclaration.decorators || []));
131 } else {
132 exportIdentifier = existingClassDeclaration.id;
133 }
134 },
135 FunctionDeclaration: function FunctionDeclaration(path, rewireInformation) {
136 var existingFunctionDeclaration = path.node;
137 var scope = path.scope;
138
139 if (existingFunctionDeclaration.id === null && path.parent.type === 'ExportDefaultDeclaration') {
140 exportIdentifier = scope.generateUidIdentifier("DefaultExportValue");
141 path.replaceWith(t.functionDeclaration(exportIdentifier, existingFunctionDeclaration.params, existingFunctionDeclaration.body, existingFunctionDeclaration.generator, existingFunctionDeclaration.async));
142 } else if (path.parent.type === 'ExportDefaultDeclaration') {
143 exportIdentifier = existingFunctionDeclaration.id;
144 }
145 },
146 Identifier: function Identifier(_ref4, rewireInformation) {
147 var parentType = _ref4.parent.type;
148 var identifier = _ref4.node;
149
150 if (parentType === 'ExportDefaultDeclaration') {
151 exportIdentifier = identifier;
152 }
153 }
154 };
155
156 path.traverse(declarationVisitors, rewireInformation);
157 if (exportIdentifier === null) {
158 exportIdentifier = (0, _RewireHelpers.noRewire)(path.scope.generateUidIdentifier("DefaultExportValue"));
159 path.replaceWithMultiple([t.variableDeclaration('let', [t.variableDeclarator(exportIdentifier, path.node.declaration)]), (0, _RewireHelpers.noRewire)(t.exportDefaultDeclaration(exportIdentifier))]);
160 }
161 rewireInformation.enrichExport(exportIdentifier);
162 })();
163 }
164 },
165
166 ImportDeclaration: function ImportDeclaration(path, rewireInformation) {
167 rewireInformation.isES6Module = true;
168 }
169 };
170
171 var BodySecondPassVisitor = {
172 Identifier: function Identifier(path, rewireInformation) {
173 var node = path.node;
174 var parent = path.parent;
175
176 var _getVariableNameAndBi2 = getVariableNameAndBinding(path);
177
178 var variableName = _getVariableNameAndBi2.variableName;
179 var variableBinding = _getVariableNameAndBi2.variableBinding;
180
181 //Matches for body
182
183 if (doesIdentifierRepresentAValidReference(path, variableBinding, rewireInformation) && isRewireable(path, variableBinding) && rewireInformation.hasTrackedIdentifier(variableName) && variableBinding.identifier !== node && parent.type !== 'UpdateExpression') {
184 var isWildCardImport = variableBinding.path.type === 'ImportNamespaceSpecifier';
185 rewireInformation.ensureAccessor(variableName, isWildCardImport);
186 path.replaceWith(t.callExpression(rewireInformation.getUniversalGetterID(), [t.stringLiteral(variableName)]));
187 }
188 }
189 };
190
191 var ProgramVisitor = {
192 Program: {
193 enter: function enter(path, state) {
194 if (!(0, _RewireHelpers.wasProcessed)(path)) {
195 var rewireState = new _RewireState2.default(path.scope);
196 rewireState.setIgnoredIdentifiers(state.opts.ignoredIdentifiers);
197
198 path.traverse(BodyVisitor, rewireState);
199
200 state.rewireState = rewireState;
201 }
202 },
203 exit: function exit(path, state) {
204 if (!(0, _RewireHelpers.wasProcessed)(path)) {
205 var scope = path.scope;
206 var program = path.node;
207
208 var rewireState = state.rewireState;
209 path.traverse(BodySecondPassVisitor, rewireState);
210 if (rewireState.containsDependenciesToRewire()) {
211 rewireState.prependUniversalAccessors(scope);
212 rewireState.appendExports();
213
214 path.replaceWith((0, _RewireHelpers.noRewire)(t.Program(program.body.concat(rewireState.nodesToAppendToProgramBody), program.directives)));
215 }
216 }
217 }
218 }
219 };
220
221 return {
222 visitor: ProgramVisitor
223 };
224};
\No newline at end of file