1 | "use strict";
|
2 |
|
3 | Object.defineProperty(exports, "__esModule", {
|
4 | value: true
|
5 | });
|
6 | exports.default = void 0;
|
7 |
|
8 | var _helperPluginUtils = require("@babel/helper-plugin-utils");
|
9 |
|
10 | var _pluginSyntaxTypescript = _interopRequireDefault(require("@babel/plugin-syntax-typescript"));
|
11 |
|
12 | var _core = require("@babel/core");
|
13 |
|
14 | var _helperCreateClassFeaturesPlugin = require("@babel/helper-create-class-features-plugin");
|
15 |
|
16 | var _enum = _interopRequireDefault(require("./enum"));
|
17 |
|
18 | var _namespace = _interopRequireDefault(require("./namespace"));
|
19 |
|
20 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
21 |
|
22 | function isInType(path) {
|
23 | switch (path.parent.type) {
|
24 | case "TSTypeReference":
|
25 | case "TSQualifiedName":
|
26 | case "TSExpressionWithTypeArguments":
|
27 | case "TSTypeQuery":
|
28 | return true;
|
29 |
|
30 | case "ExportSpecifier":
|
31 | return path.parentPath.parent.exportKind === "type";
|
32 |
|
33 | default:
|
34 | return false;
|
35 | }
|
36 | }
|
37 |
|
38 | const PARSED_PARAMS = new WeakSet();
|
39 | const GLOBAL_TYPES = new WeakMap();
|
40 |
|
41 | function isGlobalType(path, name) {
|
42 | const program = path.find(path => path.isProgram()).node;
|
43 | if (path.scope.hasOwnBinding(name)) return false;
|
44 | if (GLOBAL_TYPES.get(program).has(name)) return true;
|
45 | console.warn(`The exported identifier "${name}" is not declared in Babel's scope tracker\n` + `as a JavaScript value binding, and "@babel/plugin-transform-typescript"\n` + `never encountered it as a TypeScript type declaration.\n` + `It will be treated as a JavaScript value.\n\n` + `This problem is likely caused by another plugin injecting\n` + `"${name}" without registering it in the scope tracker. If you are the author\n` + ` of that plugin, please use "scope.registerDeclaration(declarationPath)".`);
|
46 | return false;
|
47 | }
|
48 |
|
49 | function registerGlobalType(programScope, name) {
|
50 | GLOBAL_TYPES.get(programScope.path.node).add(name);
|
51 | }
|
52 |
|
53 | var _default = (0, _helperPluginUtils.declare)((api, opts) => {
|
54 | api.assertVersion(7);
|
55 | const JSX_PRAGMA_REGEX = /\*?\s*@jsx((?:Frag)?)\s+([^\s]+)/;
|
56 | const {
|
57 | jsxPragma = "React.createElement",
|
58 | jsxPragmaFrag = "React.Fragment",
|
59 | allowNamespaces = false,
|
60 | onlyRemoveTypeImports = false
|
61 | } = opts;
|
62 | {
|
63 | var {
|
64 | allowDeclareFields = false
|
65 | } = opts;
|
66 | }
|
67 | const classMemberVisitors = {
|
68 | field(path) {
|
69 | const {
|
70 | node
|
71 | } = path;
|
72 | {
|
73 | if (!allowDeclareFields && node.declare) {
|
74 | throw path.buildCodeFrameError(`The 'declare' modifier is only allowed when the 'allowDeclareFields' option of ` + `@babel/plugin-transform-typescript or @babel/preset-typescript is enabled.`);
|
75 | }
|
76 | }
|
77 |
|
78 | if (node.declare) {
|
79 | if (node.value) {
|
80 | throw path.buildCodeFrameError(`Fields with the 'declare' modifier cannot be initialized here, but only in the constructor`);
|
81 | }
|
82 |
|
83 | if (!node.decorators) {
|
84 | path.remove();
|
85 | }
|
86 | } else if (node.definite) {
|
87 | if (node.value) {
|
88 | throw path.buildCodeFrameError(`Definitely assigned fields cannot be initialized here, but only in the constructor`);
|
89 | }
|
90 |
|
91 | {
|
92 | if (!allowDeclareFields && !node.decorators) {
|
93 | path.remove();
|
94 | }
|
95 | }
|
96 | } else {
|
97 | if (!allowDeclareFields && !node.value && !node.decorators && !_core.types.isClassPrivateProperty(node)) {
|
98 | path.remove();
|
99 | }
|
100 | }
|
101 |
|
102 | if (node.accessibility) node.accessibility = null;
|
103 | if (node.abstract) node.abstract = null;
|
104 | if (node.readonly) node.readonly = null;
|
105 | if (node.optional) node.optional = null;
|
106 | if (node.typeAnnotation) node.typeAnnotation = null;
|
107 | if (node.definite) node.definite = null;
|
108 | if (node.declare) node.declare = null;
|
109 | },
|
110 |
|
111 | method({
|
112 | node
|
113 | }) {
|
114 | if (node.accessibility) node.accessibility = null;
|
115 | if (node.abstract) node.abstract = null;
|
116 | if (node.optional) node.optional = null;
|
117 | },
|
118 |
|
119 | constructor(path, classPath) {
|
120 | if (path.node.accessibility) path.node.accessibility = null;
|
121 | const parameterProperties = [];
|
122 |
|
123 | for (const param of path.node.params) {
|
124 | if (param.type === "TSParameterProperty" && !PARSED_PARAMS.has(param.parameter)) {
|
125 | PARSED_PARAMS.add(param.parameter);
|
126 | parameterProperties.push(param.parameter);
|
127 | }
|
128 | }
|
129 |
|
130 | if (parameterProperties.length) {
|
131 | const assigns = parameterProperties.map(p => {
|
132 | let id;
|
133 |
|
134 | if (_core.types.isIdentifier(p)) {
|
135 | id = p;
|
136 | } else if (_core.types.isAssignmentPattern(p) && _core.types.isIdentifier(p.left)) {
|
137 | id = p.left;
|
138 | } else {
|
139 | throw path.buildCodeFrameError("Parameter properties can not be destructuring patterns.");
|
140 | }
|
141 |
|
142 | return _core.template.statement.ast`
|
143 | this.${_core.types.cloneNode(id)} = ${_core.types.cloneNode(id)}`;
|
144 | });
|
145 | (0, _helperCreateClassFeaturesPlugin.injectInitialization)(classPath, path, assigns);
|
146 | }
|
147 | }
|
148 |
|
149 | };
|
150 | return {
|
151 | name: "transform-typescript",
|
152 | inherits: _pluginSyntaxTypescript.default,
|
153 | visitor: {
|
154 | Pattern: visitPattern,
|
155 | Identifier: visitPattern,
|
156 | RestElement: visitPattern,
|
157 |
|
158 | Program(path, state) {
|
159 | const {
|
160 | file
|
161 | } = state;
|
162 | let fileJsxPragma = null;
|
163 | let fileJsxPragmaFrag = null;
|
164 |
|
165 | if (!GLOBAL_TYPES.has(path.node)) {
|
166 | GLOBAL_TYPES.set(path.node, new Set());
|
167 | }
|
168 |
|
169 | if (file.ast.comments) {
|
170 | for (const comment of file.ast.comments) {
|
171 | const jsxMatches = JSX_PRAGMA_REGEX.exec(comment.value);
|
172 |
|
173 | if (jsxMatches) {
|
174 | if (jsxMatches[1]) {
|
175 | fileJsxPragmaFrag = jsxMatches[2];
|
176 | } else {
|
177 | fileJsxPragma = jsxMatches[2];
|
178 | }
|
179 | }
|
180 | }
|
181 | }
|
182 |
|
183 | let pragmaImportName = fileJsxPragma || jsxPragma;
|
184 |
|
185 | if (pragmaImportName) {
|
186 | [pragmaImportName] = pragmaImportName.split(".");
|
187 | }
|
188 |
|
189 | let pragmaFragImportName = fileJsxPragmaFrag || jsxPragmaFrag;
|
190 |
|
191 | if (pragmaFragImportName) {
|
192 | [pragmaFragImportName] = pragmaFragImportName.split(".");
|
193 | }
|
194 |
|
195 | for (let stmt of path.get("body")) {
|
196 | if (_core.types.isImportDeclaration(stmt)) {
|
197 | if (stmt.node.importKind === "type") {
|
198 | stmt.remove();
|
199 | continue;
|
200 | }
|
201 |
|
202 | if (!onlyRemoveTypeImports) {
|
203 | if (stmt.node.specifiers.length === 0) {
|
204 | continue;
|
205 | }
|
206 |
|
207 | let allElided = true;
|
208 | const importsToRemove = [];
|
209 |
|
210 | for (const specifier of stmt.node.specifiers) {
|
211 | const binding = stmt.scope.getBinding(specifier.local.name);
|
212 |
|
213 | if (binding && isImportTypeOnly({
|
214 | binding,
|
215 | programPath: path,
|
216 | pragmaImportName,
|
217 | pragmaFragImportName
|
218 | })) {
|
219 | importsToRemove.push(binding.path);
|
220 | } else {
|
221 | allElided = false;
|
222 | }
|
223 | }
|
224 |
|
225 | if (allElided) {
|
226 | stmt.remove();
|
227 | } else {
|
228 | for (const importPath of importsToRemove) {
|
229 | importPath.remove();
|
230 | }
|
231 | }
|
232 | }
|
233 |
|
234 | continue;
|
235 | }
|
236 |
|
237 | if (stmt.isExportDeclaration()) {
|
238 | stmt = stmt.get("declaration");
|
239 | }
|
240 |
|
241 | if (stmt.isVariableDeclaration({
|
242 | declare: true
|
243 | })) {
|
244 | for (const name of Object.keys(stmt.getBindingIdentifiers())) {
|
245 | registerGlobalType(path.scope, name);
|
246 | }
|
247 | } else if (stmt.isTSTypeAliasDeclaration() || stmt.isTSDeclareFunction() || stmt.isTSInterfaceDeclaration() || stmt.isClassDeclaration({
|
248 | declare: true
|
249 | }) || stmt.isTSEnumDeclaration({
|
250 | declare: true
|
251 | }) || stmt.isTSModuleDeclaration({
|
252 | declare: true
|
253 | }) && stmt.get("id").isIdentifier()) {
|
254 | registerGlobalType(path.scope, stmt.node.id.name);
|
255 | }
|
256 | }
|
257 | },
|
258 |
|
259 | ExportNamedDeclaration(path) {
|
260 | if (path.node.exportKind === "type") {
|
261 | path.remove();
|
262 | return;
|
263 | }
|
264 |
|
265 | if (!path.node.source && path.node.specifiers.length > 0 && path.node.specifiers.every(({
|
266 | local
|
267 | }) => isGlobalType(path, local.name))) {
|
268 | path.remove();
|
269 | }
|
270 | },
|
271 |
|
272 | ExportSpecifier(path) {
|
273 | if (!path.parent.source && isGlobalType(path, path.node.local.name)) {
|
274 | path.remove();
|
275 | }
|
276 | },
|
277 |
|
278 | ExportDefaultDeclaration(path) {
|
279 | if (_core.types.isIdentifier(path.node.declaration) && isGlobalType(path, path.node.declaration.name)) {
|
280 | path.remove();
|
281 | }
|
282 | },
|
283 |
|
284 | TSDeclareFunction(path) {
|
285 | path.remove();
|
286 | },
|
287 |
|
288 | TSDeclareMethod(path) {
|
289 | path.remove();
|
290 | },
|
291 |
|
292 | VariableDeclaration(path) {
|
293 | if (path.node.declare) {
|
294 | path.remove();
|
295 | }
|
296 | },
|
297 |
|
298 | VariableDeclarator({
|
299 | node
|
300 | }) {
|
301 | if (node.definite) node.definite = null;
|
302 | },
|
303 |
|
304 | TSIndexSignature(path) {
|
305 | path.remove();
|
306 | },
|
307 |
|
308 | ClassDeclaration(path) {
|
309 | const {
|
310 | node
|
311 | } = path;
|
312 |
|
313 | if (node.declare) {
|
314 | path.remove();
|
315 | return;
|
316 | }
|
317 | },
|
318 |
|
319 | Class(path) {
|
320 | const {
|
321 | node
|
322 | } = path;
|
323 | if (node.typeParameters) node.typeParameters = null;
|
324 | if (node.superTypeParameters) node.superTypeParameters = null;
|
325 | if (node.implements) node.implements = null;
|
326 | if (node.abstract) node.abstract = null;
|
327 | path.get("body.body").forEach(child => {
|
328 | if (child.isClassMethod() || child.isClassPrivateMethod()) {
|
329 | if (child.node.kind === "constructor") {
|
330 | classMemberVisitors.constructor(child, path);
|
331 | } else {
|
332 | classMemberVisitors.method(child, path);
|
333 | }
|
334 | } else if (child.isClassProperty() || child.isClassPrivateProperty()) {
|
335 | classMemberVisitors.field(child, path);
|
336 | }
|
337 | });
|
338 | },
|
339 |
|
340 | Function({
|
341 | node
|
342 | }) {
|
343 | if (node.typeParameters) node.typeParameters = null;
|
344 | if (node.returnType) node.returnType = null;
|
345 | const p0 = node.params[0];
|
346 |
|
347 | if (p0 && _core.types.isIdentifier(p0) && p0.name === "this") {
|
348 | node.params.shift();
|
349 | }
|
350 |
|
351 | node.params = node.params.map(p => {
|
352 | return p.type === "TSParameterProperty" ? p.parameter : p;
|
353 | });
|
354 | },
|
355 |
|
356 | TSModuleDeclaration(path) {
|
357 | (0, _namespace.default)(path, _core.types, allowNamespaces);
|
358 | },
|
359 |
|
360 | TSInterfaceDeclaration(path) {
|
361 | path.remove();
|
362 | },
|
363 |
|
364 | TSTypeAliasDeclaration(path) {
|
365 | path.remove();
|
366 | },
|
367 |
|
368 | TSEnumDeclaration(path) {
|
369 | (0, _enum.default)(path, _core.types);
|
370 | },
|
371 |
|
372 | TSImportEqualsDeclaration(path) {
|
373 | throw path.buildCodeFrameError("`import =` is not supported by @babel/plugin-transform-typescript\n" + "Please consider using " + "`import <moduleName> from '<moduleName>';` alongside " + "Typescript's --allowSyntheticDefaultImports option.");
|
374 | },
|
375 |
|
376 | TSExportAssignment(path) {
|
377 | throw path.buildCodeFrameError("`export =` is not supported by @babel/plugin-transform-typescript\n" + "Please consider using `export <value>;`.");
|
378 | },
|
379 |
|
380 | TSTypeAssertion(path) {
|
381 | path.replaceWith(path.node.expression);
|
382 | },
|
383 |
|
384 | TSAsExpression(path) {
|
385 | let {
|
386 | node
|
387 | } = path;
|
388 |
|
389 | do {
|
390 | node = node.expression;
|
391 | } while (_core.types.isTSAsExpression(node));
|
392 |
|
393 | path.replaceWith(node);
|
394 | },
|
395 |
|
396 | TSNonNullExpression(path) {
|
397 | path.replaceWith(path.node.expression);
|
398 | },
|
399 |
|
400 | CallExpression(path) {
|
401 | path.node.typeParameters = null;
|
402 | },
|
403 |
|
404 | OptionalCallExpression(path) {
|
405 | path.node.typeParameters = null;
|
406 | },
|
407 |
|
408 | NewExpression(path) {
|
409 | path.node.typeParameters = null;
|
410 | },
|
411 |
|
412 | JSXOpeningElement(path) {
|
413 | path.node.typeParameters = null;
|
414 | },
|
415 |
|
416 | TaggedTemplateExpression(path) {
|
417 | path.node.typeParameters = null;
|
418 | }
|
419 |
|
420 | }
|
421 | };
|
422 |
|
423 | function visitPattern({
|
424 | node
|
425 | }) {
|
426 | if (node.typeAnnotation) node.typeAnnotation = null;
|
427 | if (_core.types.isIdentifier(node) && node.optional) node.optional = null;
|
428 | }
|
429 |
|
430 | function isImportTypeOnly({
|
431 | binding,
|
432 | programPath,
|
433 | pragmaImportName,
|
434 | pragmaFragImportName
|
435 | }) {
|
436 | for (const path of binding.referencePaths) {
|
437 | if (!isInType(path)) {
|
438 | return false;
|
439 | }
|
440 | }
|
441 |
|
442 | if (binding.identifier.name !== pragmaImportName && binding.identifier.name !== pragmaFragImportName) {
|
443 | return true;
|
444 | }
|
445 |
|
446 | let sourceFileHasJsx = false;
|
447 | programPath.traverse({
|
448 | "JSXElement|JSXFragment"(path) {
|
449 | sourceFileHasJsx = true;
|
450 | path.stop();
|
451 | }
|
452 |
|
453 | });
|
454 | return !sourceFileHasJsx;
|
455 | }
|
456 | });
|
457 |
|
458 | exports.default = _default; |
\ | No newline at end of file |