1 | "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
2 |
|
3 |
|
4 | var _keywords = require('../parser/tokenizer/keywords');
|
5 | var _types = require('../parser/tokenizer/types');
|
6 |
|
7 | var _getClassInfo = require('../util/getClassInfo'); var _getClassInfo2 = _interopRequireDefault(_getClassInfo);
|
8 | var _CJSImportTransformer = require('./CJSImportTransformer'); var _CJSImportTransformer2 = _interopRequireDefault(_CJSImportTransformer);
|
9 | var _ESMImportTransformer = require('./ESMImportTransformer'); var _ESMImportTransformer2 = _interopRequireDefault(_ESMImportTransformer);
|
10 | var _FlowTransformer = require('./FlowTransformer'); var _FlowTransformer2 = _interopRequireDefault(_FlowTransformer);
|
11 | var _JestHoistTransformer = require('./JestHoistTransformer'); var _JestHoistTransformer2 = _interopRequireDefault(_JestHoistTransformer);
|
12 | var _JSXTransformer = require('./JSXTransformer'); var _JSXTransformer2 = _interopRequireDefault(_JSXTransformer);
|
13 | var _NumericSeparatorTransformer = require('./NumericSeparatorTransformer'); var _NumericSeparatorTransformer2 = _interopRequireDefault(_NumericSeparatorTransformer);
|
14 | var _OptionalCatchBindingTransformer = require('./OptionalCatchBindingTransformer'); var _OptionalCatchBindingTransformer2 = _interopRequireDefault(_OptionalCatchBindingTransformer);
|
15 | var _OptionalChainingNullishTransformer = require('./OptionalChainingNullishTransformer'); var _OptionalChainingNullishTransformer2 = _interopRequireDefault(_OptionalChainingNullishTransformer);
|
16 | var _ReactDisplayNameTransformer = require('./ReactDisplayNameTransformer'); var _ReactDisplayNameTransformer2 = _interopRequireDefault(_ReactDisplayNameTransformer);
|
17 | var _ReactHotLoaderTransformer = require('./ReactHotLoaderTransformer'); var _ReactHotLoaderTransformer2 = _interopRequireDefault(_ReactHotLoaderTransformer);
|
18 |
|
19 | var _TypeScriptTransformer = require('./TypeScriptTransformer'); var _TypeScriptTransformer2 = _interopRequireDefault(_TypeScriptTransformer);
|
20 |
|
21 | class RootTransformer {
|
22 | __init() {this.transformers = []}
|
23 |
|
24 |
|
25 | __init2() {this.generatedVariables = []}
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 | constructor(
|
32 | sucraseContext,
|
33 | transforms,
|
34 | enableLegacyBabel5ModuleInterop,
|
35 | options,
|
36 | ) {;RootTransformer.prototype.__init.call(this);RootTransformer.prototype.__init2.call(this);
|
37 | this.nameManager = sucraseContext.nameManager;
|
38 | this.helperManager = sucraseContext.helperManager;
|
39 | const {tokenProcessor, importProcessor} = sucraseContext;
|
40 | this.tokens = tokenProcessor;
|
41 | this.isImportsTransformEnabled = transforms.includes("imports");
|
42 | this.isReactHotLoaderTransformEnabled = transforms.includes("react-hot-loader");
|
43 | this.disableESTransforms = Boolean(options.disableESTransforms);
|
44 |
|
45 | if (!options.disableESTransforms) {
|
46 | this.transformers.push(
|
47 | new (0, _OptionalChainingNullishTransformer2.default)(tokenProcessor, this.nameManager),
|
48 | );
|
49 | this.transformers.push(new (0, _NumericSeparatorTransformer2.default)(tokenProcessor));
|
50 | this.transformers.push(new (0, _OptionalCatchBindingTransformer2.default)(tokenProcessor, this.nameManager));
|
51 | }
|
52 |
|
53 | if (transforms.includes("jsx")) {
|
54 | this.transformers.push(
|
55 | new (0, _JSXTransformer2.default)(this, tokenProcessor, importProcessor, this.nameManager, options),
|
56 | );
|
57 | this.transformers.push(
|
58 | new (0, _ReactDisplayNameTransformer2.default)(this, tokenProcessor, importProcessor, options),
|
59 | );
|
60 | }
|
61 |
|
62 | let reactHotLoaderTransformer = null;
|
63 | if (transforms.includes("react-hot-loader")) {
|
64 | if (!options.filePath) {
|
65 | throw new Error("filePath is required when using the react-hot-loader transform.");
|
66 | }
|
67 | reactHotLoaderTransformer = new (0, _ReactHotLoaderTransformer2.default)(tokenProcessor, options.filePath);
|
68 | this.transformers.push(reactHotLoaderTransformer);
|
69 | }
|
70 |
|
71 |
|
72 |
|
73 |
|
74 | if (transforms.includes("imports")) {
|
75 | if (importProcessor === null) {
|
76 | throw new Error("Expected non-null importProcessor with imports transform enabled.");
|
77 | }
|
78 | this.transformers.push(
|
79 | new (0, _CJSImportTransformer2.default)(
|
80 | this,
|
81 | tokenProcessor,
|
82 | importProcessor,
|
83 | this.nameManager,
|
84 | reactHotLoaderTransformer,
|
85 | enableLegacyBabel5ModuleInterop,
|
86 | transforms.includes("typescript"),
|
87 | Boolean(options.preserveDynamicImport),
|
88 | ),
|
89 | );
|
90 | } else {
|
91 | this.transformers.push(
|
92 | new (0, _ESMImportTransformer2.default)(
|
93 | tokenProcessor,
|
94 | this.nameManager,
|
95 | this.helperManager,
|
96 | reactHotLoaderTransformer,
|
97 | transforms.includes("typescript"),
|
98 | options,
|
99 | ),
|
100 | );
|
101 | }
|
102 |
|
103 | if (transforms.includes("flow")) {
|
104 | this.transformers.push(
|
105 | new (0, _FlowTransformer2.default)(this, tokenProcessor, transforms.includes("imports")),
|
106 | );
|
107 | }
|
108 | if (transforms.includes("typescript")) {
|
109 | this.transformers.push(
|
110 | new (0, _TypeScriptTransformer2.default)(this, tokenProcessor, transforms.includes("imports")),
|
111 | );
|
112 | }
|
113 | if (transforms.includes("jest")) {
|
114 | this.transformers.push(
|
115 | new (0, _JestHoistTransformer2.default)(this, tokenProcessor, this.nameManager, importProcessor),
|
116 | );
|
117 | }
|
118 | }
|
119 |
|
120 | transform() {
|
121 | this.tokens.reset();
|
122 | this.processBalancedCode();
|
123 | const shouldAddUseStrict = this.isImportsTransformEnabled;
|
124 |
|
125 | let prefix = shouldAddUseStrict ? '"use strict";' : "";
|
126 | for (const transformer of this.transformers) {
|
127 | prefix += transformer.getPrefixCode();
|
128 | }
|
129 | prefix += this.helperManager.emitHelpers();
|
130 | prefix += this.generatedVariables.map((v) => ` var ${v};`).join("");
|
131 | for (const transformer of this.transformers) {
|
132 | prefix += transformer.getHoistedCode();
|
133 | }
|
134 | let suffix = "";
|
135 | for (const transformer of this.transformers) {
|
136 | suffix += transformer.getSuffixCode();
|
137 | }
|
138 | let code = this.tokens.finish();
|
139 | if (code.startsWith("#!")) {
|
140 | let newlineIndex = code.indexOf("\n");
|
141 | if (newlineIndex === -1) {
|
142 | newlineIndex = code.length;
|
143 | code += "\n";
|
144 | }
|
145 | return code.slice(0, newlineIndex + 1) + prefix + code.slice(newlineIndex + 1) + suffix;
|
146 | } else {
|
147 | return prefix + this.tokens.finish() + suffix;
|
148 | }
|
149 | }
|
150 |
|
151 | processBalancedCode() {
|
152 | let braceDepth = 0;
|
153 | let parenDepth = 0;
|
154 | while (!this.tokens.isAtEnd()) {
|
155 | if (this.tokens.matches1(_types.TokenType.braceL) || this.tokens.matches1(_types.TokenType.dollarBraceL)) {
|
156 | braceDepth++;
|
157 | } else if (this.tokens.matches1(_types.TokenType.braceR)) {
|
158 | if (braceDepth === 0) {
|
159 | return;
|
160 | }
|
161 | braceDepth--;
|
162 | }
|
163 | if (this.tokens.matches1(_types.TokenType.parenL)) {
|
164 | parenDepth++;
|
165 | } else if (this.tokens.matches1(_types.TokenType.parenR)) {
|
166 | if (parenDepth === 0) {
|
167 | return;
|
168 | }
|
169 | parenDepth--;
|
170 | }
|
171 | this.processToken();
|
172 | }
|
173 | }
|
174 |
|
175 | processToken() {
|
176 | if (this.tokens.matches1(_types.TokenType._class)) {
|
177 | this.processClass();
|
178 | return;
|
179 | }
|
180 | for (const transformer of this.transformers) {
|
181 | const wasProcessed = transformer.process();
|
182 | if (wasProcessed) {
|
183 | return;
|
184 | }
|
185 | }
|
186 | this.tokens.copyToken();
|
187 | }
|
188 |
|
189 | |
190 |
|
191 |
|
192 | processNamedClass() {
|
193 | if (!this.tokens.matches2(_types.TokenType._class, _types.TokenType.name)) {
|
194 | throw new Error("Expected identifier for exported class name.");
|
195 | }
|
196 | const name = this.tokens.identifierNameAtIndex(this.tokens.currentIndex() + 1);
|
197 | this.processClass();
|
198 | return name;
|
199 | }
|
200 |
|
201 | processClass() {
|
202 | const classInfo = _getClassInfo2.default.call(void 0, this, this.tokens, this.nameManager, this.disableESTransforms);
|
203 |
|
204 |
|
205 |
|
206 | const needsCommaExpression =
|
207 | (classInfo.headerInfo.isExpression || !classInfo.headerInfo.className) &&
|
208 | classInfo.staticInitializerNames.length + classInfo.instanceInitializerNames.length > 0;
|
209 |
|
210 | let className = classInfo.headerInfo.className;
|
211 | if (needsCommaExpression) {
|
212 | className = this.nameManager.claimFreeName("_class");
|
213 | this.generatedVariables.push(className);
|
214 | this.tokens.appendCode(` (${className} =`);
|
215 | }
|
216 |
|
217 | const classToken = this.tokens.currentToken();
|
218 | const contextId = classToken.contextId;
|
219 | if (contextId == null) {
|
220 | throw new Error("Expected class to have a context ID.");
|
221 | }
|
222 | this.tokens.copyExpectedToken(_types.TokenType._class);
|
223 | while (!this.tokens.matchesContextIdAndLabel(_types.TokenType.braceL, contextId)) {
|
224 | this.processToken();
|
225 | }
|
226 |
|
227 | this.processClassBody(classInfo, className);
|
228 |
|
229 | const staticInitializerStatements = classInfo.staticInitializerNames.map(
|
230 | (name) => `${className}.${name}()`,
|
231 | );
|
232 | if (needsCommaExpression) {
|
233 | this.tokens.appendCode(
|
234 | `, ${staticInitializerStatements.map((s) => `${s}, `).join("")}${className})`,
|
235 | );
|
236 | } else if (classInfo.staticInitializerNames.length > 0) {
|
237 | this.tokens.appendCode(` ${staticInitializerStatements.map((s) => `${s};`).join(" ")}`);
|
238 | }
|
239 | }
|
240 |
|
241 | |
242 |
|
243 |
|
244 |
|
245 | processClassBody(classInfo, className) {
|
246 | const {
|
247 | headerInfo,
|
248 | constructorInsertPos,
|
249 | constructorInitializerStatements,
|
250 | fields,
|
251 | instanceInitializerNames,
|
252 | rangesToRemove,
|
253 | } = classInfo;
|
254 | let fieldIndex = 0;
|
255 | let rangeToRemoveIndex = 0;
|
256 | const classContextId = this.tokens.currentToken().contextId;
|
257 | if (classContextId == null) {
|
258 | throw new Error("Expected non-null context ID on class.");
|
259 | }
|
260 | this.tokens.copyExpectedToken(_types.TokenType.braceL);
|
261 | if (this.isReactHotLoaderTransformEnabled) {
|
262 | this.tokens.appendCode(
|
263 | "__reactstandin__regenerateByEval(key, code) {this[key] = eval(code);}",
|
264 | );
|
265 | }
|
266 |
|
267 | const needsConstructorInit =
|
268 | constructorInitializerStatements.length + instanceInitializerNames.length > 0;
|
269 |
|
270 | if (constructorInsertPos === null && needsConstructorInit) {
|
271 | const constructorInitializersCode = this.makeConstructorInitCode(
|
272 | constructorInitializerStatements,
|
273 | instanceInitializerNames,
|
274 | className,
|
275 | );
|
276 | if (headerInfo.hasSuperclass) {
|
277 | const argsName = this.nameManager.claimFreeName("args");
|
278 | this.tokens.appendCode(
|
279 | `constructor(...${argsName}) { super(...${argsName}); ${constructorInitializersCode}; }`,
|
280 | );
|
281 | } else {
|
282 | this.tokens.appendCode(`constructor() { ${constructorInitializersCode}; }`);
|
283 | }
|
284 | }
|
285 |
|
286 | while (!this.tokens.matchesContextIdAndLabel(_types.TokenType.braceR, classContextId)) {
|
287 | if (fieldIndex < fields.length && this.tokens.currentIndex() === fields[fieldIndex].start) {
|
288 | let needsCloseBrace = false;
|
289 | if (this.tokens.matches1(_types.TokenType.bracketL)) {
|
290 | this.tokens.copyTokenWithPrefix(`${fields[fieldIndex].initializerName}() {this`);
|
291 | } else if (this.tokens.matches1(_types.TokenType.string) || this.tokens.matches1(_types.TokenType.num)) {
|
292 | this.tokens.copyTokenWithPrefix(`${fields[fieldIndex].initializerName}() {this[`);
|
293 | needsCloseBrace = true;
|
294 | } else {
|
295 | this.tokens.copyTokenWithPrefix(`${fields[fieldIndex].initializerName}() {this.`);
|
296 | }
|
297 | while (this.tokens.currentIndex() < fields[fieldIndex].end) {
|
298 | if (needsCloseBrace && this.tokens.currentIndex() === fields[fieldIndex].equalsIndex) {
|
299 | this.tokens.appendCode("]");
|
300 | }
|
301 | this.processToken();
|
302 | }
|
303 | this.tokens.appendCode("}");
|
304 | fieldIndex++;
|
305 | } else if (
|
306 | rangeToRemoveIndex < rangesToRemove.length &&
|
307 | this.tokens.currentIndex() >= rangesToRemove[rangeToRemoveIndex].start
|
308 | ) {
|
309 | if (this.tokens.currentIndex() < rangesToRemove[rangeToRemoveIndex].end) {
|
310 | this.tokens.removeInitialToken();
|
311 | }
|
312 | while (this.tokens.currentIndex() < rangesToRemove[rangeToRemoveIndex].end) {
|
313 | this.tokens.removeToken();
|
314 | }
|
315 | rangeToRemoveIndex++;
|
316 | } else if (this.tokens.currentIndex() === constructorInsertPos) {
|
317 | this.tokens.copyToken();
|
318 | if (needsConstructorInit) {
|
319 | this.tokens.appendCode(
|
320 | `;${this.makeConstructorInitCode(
|
321 | constructorInitializerStatements,
|
322 | instanceInitializerNames,
|
323 | className,
|
324 | )};`,
|
325 | );
|
326 | }
|
327 | this.processToken();
|
328 | } else {
|
329 | this.processToken();
|
330 | }
|
331 | }
|
332 | this.tokens.copyExpectedToken(_types.TokenType.braceR);
|
333 | }
|
334 |
|
335 | makeConstructorInitCode(
|
336 | constructorInitializerStatements,
|
337 | instanceInitializerNames,
|
338 | className,
|
339 | ) {
|
340 | return [
|
341 | ...constructorInitializerStatements,
|
342 | ...instanceInitializerNames.map((name) => `${className}.prototype.${name}.call(this)`),
|
343 | ].join(";");
|
344 | }
|
345 |
|
346 | |
347 |
|
348 |
|
349 |
|
350 |
|
351 |
|
352 |
|
353 | processPossibleArrowParamEnd() {
|
354 | if (this.tokens.matches2(_types.TokenType.parenR, _types.TokenType.colon) && this.tokens.tokenAtRelativeIndex(1).isType) {
|
355 | let nextNonTypeIndex = this.tokens.currentIndex() + 1;
|
356 |
|
357 | while (this.tokens.tokens[nextNonTypeIndex].isType) {
|
358 | nextNonTypeIndex++;
|
359 | }
|
360 | if (this.tokens.matches1AtIndex(nextNonTypeIndex, _types.TokenType.arrow)) {
|
361 | this.tokens.removeInitialToken();
|
362 | while (this.tokens.currentIndex() < nextNonTypeIndex) {
|
363 | this.tokens.removeToken();
|
364 | }
|
365 | this.tokens.replaceTokenTrimmingLeftWhitespace(") =>");
|
366 | return true;
|
367 | }
|
368 | }
|
369 | return false;
|
370 | }
|
371 |
|
372 | |
373 |
|
374 |
|
375 |
|
376 |
|
377 |
|
378 |
|
379 |
|
380 |
|
381 |
|
382 | processPossibleAsyncArrowWithTypeParams() {
|
383 | if (
|
384 | !this.tokens.matchesContextual(_keywords.ContextualKeyword._async) &&
|
385 | !this.tokens.matches1(_types.TokenType._async)
|
386 | ) {
|
387 | return false;
|
388 | }
|
389 | const nextToken = this.tokens.tokenAtRelativeIndex(1);
|
390 | if (nextToken.type !== _types.TokenType.lessThan || !nextToken.isType) {
|
391 | return false;
|
392 | }
|
393 |
|
394 | let nextNonTypeIndex = this.tokens.currentIndex() + 1;
|
395 |
|
396 | while (this.tokens.tokens[nextNonTypeIndex].isType) {
|
397 | nextNonTypeIndex++;
|
398 | }
|
399 | if (this.tokens.matches1AtIndex(nextNonTypeIndex, _types.TokenType.parenL)) {
|
400 | this.tokens.replaceToken("async (");
|
401 | this.tokens.removeInitialToken();
|
402 | while (this.tokens.currentIndex() < nextNonTypeIndex) {
|
403 | this.tokens.removeToken();
|
404 | }
|
405 | this.tokens.removeToken();
|
406 |
|
407 |
|
408 | this.processBalancedCode();
|
409 | this.processToken();
|
410 | return true;
|
411 | }
|
412 | return false;
|
413 | }
|
414 |
|
415 | processPossibleTypeRange() {
|
416 | if (this.tokens.currentToken().isType) {
|
417 | this.tokens.removeInitialToken();
|
418 | while (this.tokens.currentToken().isType) {
|
419 | this.tokens.removeToken();
|
420 | }
|
421 | return true;
|
422 | }
|
423 | return false;
|
424 | }
|
425 | } exports.default = RootTransformer;
|