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 | ),
|
88 | );
|
89 | } else {
|
90 | this.transformers.push(
|
91 | new (0, _ESMImportTransformer2.default)(
|
92 | tokenProcessor,
|
93 | this.nameManager,
|
94 | reactHotLoaderTransformer,
|
95 | transforms.includes("typescript"),
|
96 | options,
|
97 | ),
|
98 | );
|
99 | }
|
100 |
|
101 | if (transforms.includes("flow")) {
|
102 | this.transformers.push(new (0, _FlowTransformer2.default)(this, tokenProcessor));
|
103 | }
|
104 | if (transforms.includes("typescript")) {
|
105 | this.transformers.push(
|
106 | new (0, _TypeScriptTransformer2.default)(this, tokenProcessor, transforms.includes("imports")),
|
107 | );
|
108 | }
|
109 | if (transforms.includes("jest")) {
|
110 | this.transformers.push(
|
111 | new (0, _JestHoistTransformer2.default)(this, tokenProcessor, this.nameManager, importProcessor),
|
112 | );
|
113 | }
|
114 | }
|
115 |
|
116 | transform() {
|
117 | this.tokens.reset();
|
118 | this.processBalancedCode();
|
119 | const shouldAddUseStrict = this.isImportsTransformEnabled;
|
120 |
|
121 | let prefix = shouldAddUseStrict ? '"use strict";' : "";
|
122 | for (const transformer of this.transformers) {
|
123 | prefix += transformer.getPrefixCode();
|
124 | }
|
125 | prefix += this.helperManager.emitHelpers();
|
126 | prefix += this.generatedVariables.map((v) => ` var ${v};`).join("");
|
127 | for (const transformer of this.transformers) {
|
128 | prefix += transformer.getHoistedCode();
|
129 | }
|
130 | let suffix = "";
|
131 | for (const transformer of this.transformers) {
|
132 | suffix += transformer.getSuffixCode();
|
133 | }
|
134 | let code = this.tokens.finish();
|
135 | if (code.startsWith("#!")) {
|
136 | let newlineIndex = code.indexOf("\n");
|
137 | if (newlineIndex === -1) {
|
138 | newlineIndex = code.length;
|
139 | code += "\n";
|
140 | }
|
141 | return code.slice(0, newlineIndex + 1) + prefix + code.slice(newlineIndex + 1) + suffix;
|
142 | } else {
|
143 | return prefix + this.tokens.finish() + suffix;
|
144 | }
|
145 | }
|
146 |
|
147 | processBalancedCode() {
|
148 | let braceDepth = 0;
|
149 | let parenDepth = 0;
|
150 | while (!this.tokens.isAtEnd()) {
|
151 | if (this.tokens.matches1(_types.TokenType.braceL) || this.tokens.matches1(_types.TokenType.dollarBraceL)) {
|
152 | braceDepth++;
|
153 | } else if (this.tokens.matches1(_types.TokenType.braceR)) {
|
154 | if (braceDepth === 0) {
|
155 | return;
|
156 | }
|
157 | braceDepth--;
|
158 | }
|
159 | if (this.tokens.matches1(_types.TokenType.parenL)) {
|
160 | parenDepth++;
|
161 | } else if (this.tokens.matches1(_types.TokenType.parenR)) {
|
162 | if (parenDepth === 0) {
|
163 | return;
|
164 | }
|
165 | parenDepth--;
|
166 | }
|
167 | this.processToken();
|
168 | }
|
169 | }
|
170 |
|
171 | processToken() {
|
172 | if (this.tokens.matches1(_types.TokenType._class)) {
|
173 | this.processClass();
|
174 | return;
|
175 | }
|
176 | for (const transformer of this.transformers) {
|
177 | const wasProcessed = transformer.process();
|
178 | if (wasProcessed) {
|
179 | return;
|
180 | }
|
181 | }
|
182 | this.tokens.copyToken();
|
183 | }
|
184 |
|
185 | |
186 |
|
187 |
|
188 | processNamedClass() {
|
189 | if (!this.tokens.matches2(_types.TokenType._class, _types.TokenType.name)) {
|
190 | throw new Error("Expected identifier for exported class name.");
|
191 | }
|
192 | const name = this.tokens.identifierNameAtIndex(this.tokens.currentIndex() + 1);
|
193 | this.processClass();
|
194 | return name;
|
195 | }
|
196 |
|
197 | processClass() {
|
198 | const classInfo = _getClassInfo2.default.call(void 0, this, this.tokens, this.nameManager, this.disableESTransforms);
|
199 |
|
200 |
|
201 |
|
202 | const needsCommaExpression =
|
203 | classInfo.headerInfo.isExpression &&
|
204 | classInfo.staticInitializerNames.length + classInfo.instanceInitializerNames.length > 0;
|
205 |
|
206 | let className = classInfo.headerInfo.className;
|
207 | if (needsCommaExpression) {
|
208 | className = this.nameManager.claimFreeName("_class");
|
209 | this.generatedVariables.push(className);
|
210 | this.tokens.appendCode(` (${className} =`);
|
211 | }
|
212 |
|
213 | const classToken = this.tokens.currentToken();
|
214 | const contextId = classToken.contextId;
|
215 | if (contextId == null) {
|
216 | throw new Error("Expected class to have a context ID.");
|
217 | }
|
218 | this.tokens.copyExpectedToken(_types.TokenType._class);
|
219 | while (!this.tokens.matchesContextIdAndLabel(_types.TokenType.braceL, contextId)) {
|
220 | this.processToken();
|
221 | }
|
222 |
|
223 | this.processClassBody(classInfo, className);
|
224 |
|
225 | const staticInitializerStatements = classInfo.staticInitializerNames.map(
|
226 | (name) => `${className}.${name}()`,
|
227 | );
|
228 | if (needsCommaExpression) {
|
229 | this.tokens.appendCode(
|
230 | `, ${staticInitializerStatements.map((s) => `${s}, `).join("")}${className})`,
|
231 | );
|
232 | } else if (classInfo.staticInitializerNames.length > 0) {
|
233 | this.tokens.appendCode(` ${staticInitializerStatements.map((s) => `${s};`).join(" ")}`);
|
234 | }
|
235 | }
|
236 |
|
237 | |
238 |
|
239 |
|
240 |
|
241 | processClassBody(classInfo, className) {
|
242 | const {
|
243 | headerInfo,
|
244 | constructorInsertPos,
|
245 | constructorInitializerStatements,
|
246 | fields,
|
247 | instanceInitializerNames,
|
248 | rangesToRemove,
|
249 | } = classInfo;
|
250 | let fieldIndex = 0;
|
251 | let rangeToRemoveIndex = 0;
|
252 | const classContextId = this.tokens.currentToken().contextId;
|
253 | if (classContextId == null) {
|
254 | throw new Error("Expected non-null context ID on class.");
|
255 | }
|
256 | this.tokens.copyExpectedToken(_types.TokenType.braceL);
|
257 | if (this.isReactHotLoaderTransformEnabled) {
|
258 | this.tokens.appendCode(
|
259 | "__reactstandin__regenerateByEval(key, code) {this[key] = eval(code);}",
|
260 | );
|
261 | }
|
262 |
|
263 | const needsConstructorInit =
|
264 | constructorInitializerStatements.length + instanceInitializerNames.length > 0;
|
265 |
|
266 | if (constructorInsertPos === null && needsConstructorInit) {
|
267 | const constructorInitializersCode = this.makeConstructorInitCode(
|
268 | constructorInitializerStatements,
|
269 | instanceInitializerNames,
|
270 | className,
|
271 | );
|
272 | if (headerInfo.hasSuperclass) {
|
273 | const argsName = this.nameManager.claimFreeName("args");
|
274 | this.tokens.appendCode(
|
275 | `constructor(...${argsName}) { super(...${argsName}); ${constructorInitializersCode}; }`,
|
276 | );
|
277 | } else {
|
278 | this.tokens.appendCode(`constructor() { ${constructorInitializersCode}; }`);
|
279 | }
|
280 | }
|
281 |
|
282 | while (!this.tokens.matchesContextIdAndLabel(_types.TokenType.braceR, classContextId)) {
|
283 | if (fieldIndex < fields.length && this.tokens.currentIndex() === fields[fieldIndex].start) {
|
284 | let needsCloseBrace = false;
|
285 | if (this.tokens.matches1(_types.TokenType.bracketL)) {
|
286 | this.tokens.copyTokenWithPrefix(`${fields[fieldIndex].initializerName}() {this`);
|
287 | } else if (this.tokens.matches1(_types.TokenType.string) || this.tokens.matches1(_types.TokenType.num)) {
|
288 | this.tokens.copyTokenWithPrefix(`${fields[fieldIndex].initializerName}() {this[`);
|
289 | needsCloseBrace = true;
|
290 | } else {
|
291 | this.tokens.copyTokenWithPrefix(`${fields[fieldIndex].initializerName}() {this.`);
|
292 | }
|
293 | while (this.tokens.currentIndex() < fields[fieldIndex].end) {
|
294 | if (needsCloseBrace && this.tokens.currentIndex() === fields[fieldIndex].equalsIndex) {
|
295 | this.tokens.appendCode("]");
|
296 | }
|
297 | this.processToken();
|
298 | }
|
299 | this.tokens.appendCode("}");
|
300 | fieldIndex++;
|
301 | } else if (
|
302 | rangeToRemoveIndex < rangesToRemove.length &&
|
303 | this.tokens.currentIndex() >= rangesToRemove[rangeToRemoveIndex].start
|
304 | ) {
|
305 | if (this.tokens.currentIndex() < rangesToRemove[rangeToRemoveIndex].end) {
|
306 | this.tokens.removeInitialToken();
|
307 | }
|
308 | while (this.tokens.currentIndex() < rangesToRemove[rangeToRemoveIndex].end) {
|
309 | this.tokens.removeToken();
|
310 | }
|
311 | rangeToRemoveIndex++;
|
312 | } else if (this.tokens.currentIndex() === constructorInsertPos) {
|
313 | this.tokens.copyToken();
|
314 | if (needsConstructorInit) {
|
315 | this.tokens.appendCode(
|
316 | `;${this.makeConstructorInitCode(
|
317 | constructorInitializerStatements,
|
318 | instanceInitializerNames,
|
319 | className,
|
320 | )};`,
|
321 | );
|
322 | }
|
323 | this.processToken();
|
324 | } else {
|
325 | this.processToken();
|
326 | }
|
327 | }
|
328 | this.tokens.copyExpectedToken(_types.TokenType.braceR);
|
329 | }
|
330 |
|
331 | makeConstructorInitCode(
|
332 | constructorInitializerStatements,
|
333 | instanceInitializerNames,
|
334 | className,
|
335 | ) {
|
336 | return [
|
337 | ...constructorInitializerStatements,
|
338 | ...instanceInitializerNames.map((name) => `${className}.prototype.${name}.call(this)`),
|
339 | ].join(";");
|
340 | }
|
341 |
|
342 | |
343 |
|
344 |
|
345 |
|
346 |
|
347 |
|
348 |
|
349 | processPossibleArrowParamEnd() {
|
350 | if (this.tokens.matches2(_types.TokenType.parenR, _types.TokenType.colon) && this.tokens.tokenAtRelativeIndex(1).isType) {
|
351 | let nextNonTypeIndex = this.tokens.currentIndex() + 1;
|
352 |
|
353 | while (this.tokens.tokens[nextNonTypeIndex].isType) {
|
354 | nextNonTypeIndex++;
|
355 | }
|
356 | if (this.tokens.matches1AtIndex(nextNonTypeIndex, _types.TokenType.arrow)) {
|
357 | this.tokens.removeInitialToken();
|
358 | while (this.tokens.currentIndex() < nextNonTypeIndex) {
|
359 | this.tokens.removeToken();
|
360 | }
|
361 | this.tokens.replaceTokenTrimmingLeftWhitespace(") =>");
|
362 | return true;
|
363 | }
|
364 | }
|
365 | return false;
|
366 | }
|
367 |
|
368 | |
369 |
|
370 |
|
371 |
|
372 |
|
373 |
|
374 |
|
375 |
|
376 |
|
377 |
|
378 | processPossibleAsyncArrowWithTypeParams() {
|
379 | if (
|
380 | !this.tokens.matchesContextual(_keywords.ContextualKeyword._async) &&
|
381 | !this.tokens.matches1(_types.TokenType._async)
|
382 | ) {
|
383 | return false;
|
384 | }
|
385 | const nextToken = this.tokens.tokenAtRelativeIndex(1);
|
386 | if (nextToken.type !== _types.TokenType.lessThan || !nextToken.isType) {
|
387 | return false;
|
388 | }
|
389 |
|
390 | let nextNonTypeIndex = this.tokens.currentIndex() + 1;
|
391 |
|
392 | while (this.tokens.tokens[nextNonTypeIndex].isType) {
|
393 | nextNonTypeIndex++;
|
394 | }
|
395 | if (this.tokens.matches1AtIndex(nextNonTypeIndex, _types.TokenType.parenL)) {
|
396 | this.tokens.replaceToken("async (");
|
397 | this.tokens.removeInitialToken();
|
398 | while (this.tokens.currentIndex() < nextNonTypeIndex) {
|
399 | this.tokens.removeToken();
|
400 | }
|
401 | this.tokens.removeToken();
|
402 |
|
403 |
|
404 | this.processBalancedCode();
|
405 | this.processToken();
|
406 | return true;
|
407 | }
|
408 | return false;
|
409 | }
|
410 |
|
411 | processPossibleTypeRange() {
|
412 | if (this.tokens.currentToken().isType) {
|
413 | this.tokens.removeInitialToken();
|
414 | while (this.tokens.currentToken().isType) {
|
415 | this.tokens.removeToken();
|
416 | }
|
417 | return true;
|
418 | }
|
419 | return false;
|
420 | }
|
421 | } exports.default = RootTransformer;
|