source: frontend/node_modules/@babel/plugin-transform-react-jsx/lib/create-plugin.js

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 12 days ago

Fix frontend appearance

  • Property mode set to 100644
File size: 22.0 KB
RevLine 
[9af201e]1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.default = createPlugin;
7var _pluginSyntaxJsx = require("@babel/plugin-syntax-jsx");
8var _helperPluginUtils = require("@babel/helper-plugin-utils");
9var _core = require("@babel/core");
10var _helperModuleImports = require("@babel/helper-module-imports");
11var _helperAnnotateAsPure = require("@babel/helper-annotate-as-pure");
12const DEFAULT = {
13 importSource: "react",
14 runtime: "automatic",
15 pragma: "React.createElement",
16 pragmaFrag: "React.Fragment"
17};
18const JSX_SOURCE_ANNOTATION_REGEX = /^\s*(?:\*\s*)?@jsxImportSource\s+(\S+)\s*$/m;
19const JSX_RUNTIME_ANNOTATION_REGEX = /^\s*(?:\*\s*)?@jsxRuntime\s+(\S+)\s*$/m;
20const JSX_ANNOTATION_REGEX = /^\s*(?:\*\s*)?@jsx\s+(\S+)\s*$/m;
21const JSX_FRAG_ANNOTATION_REGEX = /^\s*(?:\*\s*)?@jsxFrag\s+(\S+)\s*$/m;
22const get = (pass, name) => pass.get(`@babel/plugin-react-jsx/${name}`);
23const set = (pass, name, v) => pass.set(`@babel/plugin-react-jsx/${name}`, v);
24function hasProto(node) {
25 return node.properties.some(value => _core.types.isObjectProperty(value, {
26 computed: false,
27 shorthand: false
28 }) && (_core.types.isIdentifier(value.key, {
29 name: "__proto__"
30 }) || _core.types.isStringLiteral(value.key, {
31 value: "__proto__"
32 })));
33}
34function createPlugin({
35 name,
36 development
37}) {
38 return (0, _helperPluginUtils.declare)((_, options) => {
39 const {
40 pure: PURE_ANNOTATION,
41 throwIfNamespace = true,
42 filter,
43 runtime: RUNTIME_DEFAULT = development ? "automatic" : "classic",
44 importSource: IMPORT_SOURCE_DEFAULT = DEFAULT.importSource,
45 pragma: PRAGMA_DEFAULT = DEFAULT.pragma,
46 pragmaFrag: PRAGMA_FRAG_DEFAULT = DEFAULT.pragmaFrag
47 } = options;
48 var {
49 useSpread = false,
50 useBuiltIns = false
51 } = options;
52 if (RUNTIME_DEFAULT === "classic") {
53 if (typeof useSpread !== "boolean") {
54 throw new Error("transform-react-jsx currently only accepts a boolean option for " + "useSpread (defaults to false)");
55 }
56 if (typeof useBuiltIns !== "boolean") {
57 throw new Error("transform-react-jsx currently only accepts a boolean option for " + "useBuiltIns (defaults to false)");
58 }
59 if (useSpread && useBuiltIns) {
60 throw new Error("transform-react-jsx currently only accepts useBuiltIns or useSpread " + "but not both");
61 }
62 }
63 let commentsNode = null;
64 return {
65 name,
66 inherits: _pluginSyntaxJsx.default,
67 visitor: {
68 JSXNamespacedName(path) {
69 if (throwIfNamespace) {
70 throw path.buildCodeFrameError(`Namespace tags are not supported by default. React's JSX doesn't support namespace tags. \
71You can set \`throwIfNamespace: false\` to bypass this warning.`);
72 }
73 },
74 JSXSpreadChild(path) {
75 throw path.buildCodeFrameError("Spread children are not supported in React.");
76 },
77 Program: {
78 enter(path, state) {
79 const {
80 file
81 } = state;
82 let runtime = RUNTIME_DEFAULT;
83 let source = IMPORT_SOURCE_DEFAULT;
84 let pragma = PRAGMA_DEFAULT;
85 let pragmaFrag = PRAGMA_FRAG_DEFAULT;
86 let sourceSet = !!options.importSource;
87 let pragmaSet = !!options.pragma;
88 let pragmaFragSet = !!options.pragmaFrag;
89 if (file.ast.comments) {
90 for (const comment of file.ast.comments) {
91 const sourceMatches = JSX_SOURCE_ANNOTATION_REGEX.exec(comment.value);
92 if (sourceMatches) {
93 source = sourceMatches[1];
94 sourceSet = true;
95 }
96 const runtimeMatches = JSX_RUNTIME_ANNOTATION_REGEX.exec(comment.value);
97 if (runtimeMatches) {
98 runtime = runtimeMatches[1];
99 }
100 const jsxMatches = JSX_ANNOTATION_REGEX.exec(comment.value);
101 if (jsxMatches) {
102 pragma = jsxMatches[1];
103 pragmaSet = true;
104 }
105 const jsxFragMatches = JSX_FRAG_ANNOTATION_REGEX.exec(comment.value);
106 if (jsxFragMatches) {
107 pragmaFrag = jsxFragMatches[1];
108 pragmaFragSet = true;
109 }
110 }
111 }
112 set(state, "runtime", runtime);
113 if (runtime === "classic") {
114 if (sourceSet) {
115 throw path.buildCodeFrameError(`importSource cannot be set when runtime is classic.`);
116 }
117 const createElement = toMemberExpression(pragma);
118 const fragment = toMemberExpression(pragmaFrag);
119 set(state, "id/createElement", () => _core.types.cloneNode(createElement));
120 set(state, "id/fragment", () => _core.types.cloneNode(fragment));
121 set(state, "defaultPure", pragma === DEFAULT.pragma);
122 } else if (runtime === "automatic") {
123 if (pragmaSet || pragmaFragSet) {
124 throw path.buildCodeFrameError(`pragma and pragmaFrag cannot be set when runtime is automatic.`);
125 }
126 const define = (name, id) => set(state, name, createImportLazily(state, path, id, source));
127 define("id/jsx", development ? "jsxDEV" : "jsx");
128 define("id/jsxs", development ? "jsxDEV" : "jsxs");
129 define("id/createElement", "createElement");
130 define("id/fragment", "Fragment");
131 set(state, "defaultPure", source === DEFAULT.importSource);
132 } else {
133 throw path.buildCodeFrameError(`Runtime must be either "classic" or "automatic".`);
134 }
135 if (development) {
136 function isDerivedClass(classNode) {
137 return classNode.superClass !== null;
138 }
139 function isThisAllowed(parents) {
140 let i = parents.length - 1;
141 do {
142 const {
143 node
144 } = parents[i];
145 if (_core.types.isFunctionParent(node) && !_core.types.isArrowFunctionExpression(node)) {
146 if (!_core.types.isMethod(node)) {
147 return true;
148 }
149 if (node.kind !== "constructor") {
150 return true;
151 }
152 return !isDerivedClass(parents[i - 2].node);
153 }
154 if (_core.types.isTSModuleBlock(node)) {
155 return false;
156 }
157 } while (i-- > 0);
158 return true;
159 }
160 let fileNameIdentifier;
161 function makeSource(node) {
162 const location = node.loc;
163 if (!location) {
164 return path.scope.buildUndefinedNode();
165 }
166 if (!fileNameIdentifier) {
167 fileNameIdentifier = path.scope.generateUidIdentifier("_jsxFileName");
168 }
169 return makeTrace(_core.types.cloneNode(fileNameIdentifier), location.start.line, location.start.column);
170 }
171 function makeTrace(fileNameIdentifier, lineNumber, column0Based) {
172 const fileLineLiteral = lineNumber != null ? _core.types.numericLiteral(lineNumber) : _core.types.nullLiteral();
173 const fileColumnLiteral = column0Based != null ? _core.types.numericLiteral(column0Based + 1) : _core.types.nullLiteral();
174 return _core.template.expression.ast`{
175 fileName: ${fileNameIdentifier},
176 lineNumber: ${fileLineLiteral},
177 columnNumber: ${fileColumnLiteral},
178 }`;
179 }
180 _core.types.traverse(path.node, {
181 enter(node, parents) {
182 if (!_core.types.isJSXOpeningElement(node)) {
183 return;
184 }
185 const attributes = node.attributes;
186 if (isThisAllowed(parents)) {
187 attributes.push(_core.types.jsxAttribute(_core.types.jsxIdentifier("__self"), _core.types.jsxExpressionContainer(_core.types.thisExpression())));
188 }
189 attributes.push(_core.types.jsxAttribute(_core.types.jsxIdentifier("__source"), _core.types.jsxExpressionContainer(makeSource(node))));
190 }
191 });
192 if (fileNameIdentifier) {
193 const {
194 filename = ""
195 } = state;
196 path.scope.push({
197 id: fileNameIdentifier,
198 init: _core.types.stringLiteral(filename)
199 });
200 }
201 }
202 }
203 },
204 JSXFragment: {
205 exit(path, file) {
206 let callExpr;
207 if (get(file, "runtime") === "classic") {
208 callExpr = buildCreateElementFragmentCall(path, file);
209 } else {
210 callExpr = buildJSXFragmentCall(path, file);
211 }
212 path.replaceWith(_core.types.inherits(callExpr, path.node));
213 }
214 },
215 JSXElement: {
216 exit(path, file) {
217 let callExpr;
218 if (get(file, "runtime") === "classic" || shouldUseCreateElement(path)) {
219 callExpr = buildCreateElementCall(path, file);
220 } else {
221 callExpr = buildJSXElementCall(path, file);
222 }
223 path.replaceWith(_core.types.inherits(callExpr, path.node));
224 }
225 },
226 JSXAttribute(path) {
227 if (_core.types.isJSXElement(path.node.value)) {
228 path.node.value = _core.types.jsxExpressionContainer(path.node.value);
229 }
230 }
231 }
232 };
233 function call(pass, name, args) {
234 const node = _core.types.callExpression(get(pass, `id/${name}`)(), args);
235 if (PURE_ANNOTATION != null ? PURE_ANNOTATION : get(pass, "defaultPure")) (0, _helperAnnotateAsPure.default)(node);
236 return node;
237 }
238 function shouldUseCreateElement(path) {
239 const openingPath = path.get("openingElement");
240 const attributes = openingPath.node.attributes;
241 let seenPropsSpread = false;
242 for (let i = 0; i < attributes.length; i++) {
243 const attr = attributes[i];
244 if (seenPropsSpread && _core.types.isJSXAttribute(attr) && attr.name.name === "key") {
245 return true;
246 } else if (_core.types.isJSXSpreadAttribute(attr)) {
247 seenPropsSpread = true;
248 }
249 }
250 return false;
251 }
252 function convertJSXIdentifier(node, parent) {
253 if (_core.types.isJSXIdentifier(node)) {
254 if (node.name === "this" && _core.types.isReferenced(node, parent)) {
255 return _core.types.thisExpression();
256 } else if (_core.types.isValidIdentifier(node.name, false)) {
257 node.type = "Identifier";
258 return node;
259 } else {
260 return _core.types.stringLiteral(node.name);
261 }
262 } else if (_core.types.isJSXMemberExpression(node)) {
263 return _core.types.memberExpression(convertJSXIdentifier(node.object, node), convertJSXIdentifier(node.property, node));
264 } else if (_core.types.isJSXNamespacedName(node)) {
265 return _core.types.stringLiteral(`${node.namespace.name}:${node.name.name}`);
266 }
267 return node;
268 }
269 function convertAttributeValue(node) {
270 if (_core.types.isJSXExpressionContainer(node)) {
271 return node.expression;
272 } else {
273 return node;
274 }
275 }
276 function processComments(attribs) {
277 commentsNode = null;
278 if (attribs.length && attribs[0].isJSXSpreadAttribute()) {
279 const node = attribs[0].node.argument;
280 if (node.leadingComments || node.trailingComments) {
281 commentsNode = _core.types.cloneNode(node);
282 }
283 }
284 }
285 function accumulateAttribute(array, attribute) {
286 if (_core.types.isJSXSpreadAttribute(attribute.node)) {
287 const arg = attribute.node.argument;
288 if (_core.types.isObjectExpression(arg) && !hasProto(arg)) {
289 array.push(...arg.properties);
290 } else {
291 array.push(_core.types.spreadElement(arg));
292 }
293 return array;
294 }
295 const value = convertAttributeValue(attribute.node.name.name !== "key" ? attribute.node.value || _core.types.booleanLiteral(true) : attribute.node.value);
296 if (attribute.node.name.name === "key" && value === null) {
297 throw attribute.buildCodeFrameError('Please provide an explicit key value. Using "key" as a shorthand for "key={true}" is not allowed.');
298 }
299 if (_core.types.isStringLiteral(value) && !_core.types.isJSXExpressionContainer(attribute.node.value)) {
300 var _value$extra;
301 value.value = value.value.replace(/\n\s+/g, " ");
302 (_value$extra = value.extra) == null || delete _value$extra.raw;
303 }
304 if (_core.types.isJSXNamespacedName(attribute.node.name)) {
305 attribute.node.name = _core.types.stringLiteral(attribute.node.name.namespace.name + ":" + attribute.node.name.name.name);
306 } else if (_core.types.isValidIdentifier(attribute.node.name.name, false)) {
307 attribute.node.name.type = "Identifier";
308 } else {
309 attribute.node.name = _core.types.stringLiteral(attribute.node.name.name);
310 }
311 array.push(_core.types.inherits(_core.types.objectProperty(attribute.node.name, value), attribute.node));
312 return array;
313 }
314 function buildChildrenProperty(children) {
315 let childrenNode;
316 if (children.length === 1) {
317 childrenNode = children[0];
318 } else if (children.length > 1) {
319 childrenNode = _core.types.arrayExpression(children);
320 } else {
321 return undefined;
322 }
323 return _core.types.objectProperty(_core.types.identifier("children"), childrenNode);
324 }
325 function buildJSXElementCall(path, file) {
326 const openingPath = path.get("openingElement");
327 const args = [getTag(openingPath)];
328 const attribsArray = [];
329 const extracted = Object.create(null);
330 for (const attr of openingPath.get("attributes")) {
331 if (attr.isJSXAttribute() && _core.types.isJSXIdentifier(attr.node.name)) {
332 const {
333 name
334 } = attr.node.name;
335 switch (name) {
336 case "__source":
337 case "__self":
338 if (extracted[name]) throw sourceSelfError(path, name);
339 case "key":
340 {
341 const keyValue = convertAttributeValue(attr.node.value);
342 if (keyValue === null) {
343 throw attr.buildCodeFrameError('Please provide an explicit key value. Using "key" as a shorthand for "key={true}" is not allowed.');
344 }
345 extracted[name] = keyValue;
346 break;
347 }
348 default:
349 attribsArray.push(attr);
350 }
351 } else {
352 attribsArray.push(attr);
353 }
354 }
355 const children = _core.types.react.buildChildren(path.node);
356 let attribs;
357 if (attribsArray.length || children.length) {
358 attribs = buildJSXOpeningElementAttributes(attribsArray, children);
359 if (commentsNode) {
360 _core.types.inheritsComments(attribs, commentsNode);
361 }
362 } else {
363 attribs = _core.types.objectExpression([]);
364 }
365 args.push(attribs);
366 if (development) {
367 var _extracted$key;
368 args.push((_extracted$key = extracted.key) != null ? _extracted$key : path.scope.buildUndefinedNode(), _core.types.booleanLiteral(children.length > 1));
369 if (extracted.__source) {
370 args.push(extracted.__source);
371 if (extracted.__self) args.push(extracted.__self);
372 } else if (extracted.__self) {
373 args.push(path.scope.buildUndefinedNode(), extracted.__self);
374 }
375 } else if (extracted.key !== undefined) {
376 args.push(extracted.key);
377 }
378 return call(file, children.length > 1 ? "jsxs" : "jsx", args);
379 }
380 function buildJSXOpeningElementAttributes(attribs, children) {
381 processComments(attribs);
382 const props = attribs.reduce(accumulateAttribute, []);
383 if ((children == null ? void 0 : children.length) > 0) {
384 props.push(buildChildrenProperty(children));
385 }
386 return _core.types.objectExpression(props);
387 }
388 function buildJSXFragmentCall(path, file) {
389 const args = [get(file, "id/fragment")()];
390 const children = _core.types.react.buildChildren(path.node);
391 args.push(_core.types.objectExpression(children.length > 0 ? [buildChildrenProperty(children)] : []));
392 if (development) {
393 args.push(path.scope.buildUndefinedNode(), _core.types.booleanLiteral(children.length > 1));
394 }
395 return call(file, children.length > 1 ? "jsxs" : "jsx", args);
396 }
397 function buildCreateElementFragmentCall(path, file) {
398 if (filter && !filter(path.node, file)) return;
399 return call(file, "createElement", [get(file, "id/fragment")(), _core.types.nullLiteral(), ..._core.types.react.buildChildren(path.node)]);
400 }
401 function buildCreateElementCall(path, file) {
402 const openingPath = path.get("openingElement");
403 return call(file, "createElement", [getTag(openingPath), buildCreateElementOpeningElementAttributes(file, path, openingPath.get("attributes")), ..._core.types.react.buildChildren(path.node)]);
404 }
405 function getTag(openingPath) {
406 const tagExpr = convertJSXIdentifier(openingPath.node.name, openingPath.node);
407 let tagName;
408 if (_core.types.isIdentifier(tagExpr)) {
409 tagName = tagExpr.name;
410 } else if (_core.types.isStringLiteral(tagExpr)) {
411 tagName = tagExpr.value;
412 }
413 if (_core.types.react.isCompatTag(tagName)) {
414 return _core.types.stringLiteral(tagName);
415 } else {
416 return tagExpr;
417 }
418 }
419 function buildCreateElementOpeningElementAttributes(file, path, attribs) {
420 const runtime = get(file, "runtime");
421 if (runtime !== "automatic") {
422 const objs = [];
423 processComments(attribs);
424 const props = attribs.reduce(accumulateAttribute, []);
425 if (!useSpread) {
426 let start = 0;
427 props.forEach((prop, i) => {
428 if (_core.types.isSpreadElement(prop)) {
429 if (i > start) {
430 objs.push(_core.types.objectExpression(props.slice(start, i)));
431 }
432 objs.push(prop.argument);
433 start = i + 1;
434 }
435 });
436 if (props.length > start) {
437 objs.push(_core.types.objectExpression(props.slice(start)));
438 }
439 } else if (props.length) {
440 objs.push(_core.types.objectExpression(props));
441 }
442 if (!objs.length) {
443 return _core.types.nullLiteral();
444 }
445 if (commentsNode) {
446 _core.types.inheritsComments(objs[0], commentsNode);
447 }
448 if (objs.length === 1) {
449 if (!(_core.types.isSpreadElement(props[0]) && _core.types.isObjectExpression(props[0].argument))) {
450 return objs[0];
451 }
452 }
453 if (!_core.types.isObjectExpression(objs[0])) {
454 objs.unshift(_core.types.objectExpression([]));
455 }
456 const helper = useBuiltIns ? _core.types.memberExpression(_core.types.identifier("Object"), _core.types.identifier("assign")) : file.addHelper("extends");
457 return _core.types.callExpression(helper, objs);
458 }
459 const props = [];
460 const found = Object.create(null);
461 processComments(attribs);
462 for (const attr of attribs) {
463 const {
464 node
465 } = attr;
466 const name = _core.types.isJSXAttribute(node) && _core.types.isJSXIdentifier(node.name) && node.name.name;
467 if (runtime === "automatic" && (name === "__source" || name === "__self")) {
468 if (found[name]) throw sourceSelfError(path, name);
469 found[name] = true;
470 }
471 accumulateAttribute(props, attr);
472 }
473 const ret = props.length === 1 && _core.types.isSpreadElement(props[0]) && !_core.types.isObjectExpression(props[0].argument) ? props[0].argument : props.length > 0 ? _core.types.objectExpression(props) : _core.types.nullLiteral();
474 if (commentsNode) {
475 _core.types.inheritsComments(ret, commentsNode);
476 }
477 return ret;
478 }
479 });
480 function getSource(source, importName) {
481 switch (importName) {
482 case "Fragment":
483 return `${source}/${development ? "jsx-dev-runtime" : "jsx-runtime"}`;
484 case "jsxDEV":
485 return `${source}/jsx-dev-runtime`;
486 case "jsx":
487 case "jsxs":
488 return `${source}/jsx-runtime`;
489 case "createElement":
490 return source;
491 }
492 }
493 function createImportLazily(pass, path, importName, source) {
494 return () => {
495 const actualSource = getSource(source, importName);
496 if ((0, _helperModuleImports.isModule)(path)) {
497 let reference = get(pass, `imports/${importName}`);
498 if (reference) return _core.types.cloneNode(reference);
499 reference = (0, _helperModuleImports.addNamed)(path, importName, actualSource, {
500 importedInterop: "uncompiled",
501 importPosition: "after"
502 });
503 set(pass, `imports/${importName}`, reference);
504 return reference;
505 } else {
506 let reference = get(pass, `requires/${actualSource}`);
507 if (reference) {
508 reference = _core.types.cloneNode(reference);
509 } else {
510 reference = (0, _helperModuleImports.addNamespace)(path, actualSource, {
511 importedInterop: "uncompiled"
512 });
513 set(pass, `requires/${actualSource}`, reference);
514 }
515 return _core.types.memberExpression(reference, _core.types.identifier(importName));
516 }
517 };
518 }
519}
520function toMemberExpression(id) {
521 return id.split(".").map(name => _core.types.identifier(name)).reduce((object, property) => _core.types.memberExpression(object, property));
522}
523function sourceSelfError(path, name) {
524 const pluginName = `transform-react-jsx-${name.slice(2)}`;
525 return path.buildCodeFrameError(`Duplicate ${name} prop found. You are most likely using the deprecated ${pluginName} Babel plugin. Both __source and __self are automatically set when using the automatic runtime. Please remove transform-react-jsx-source and transform-react-jsx-self from your Babel config.`);
526}
527
528//# sourceMappingURL=create-plugin.js.map
Note: See TracBrowser for help on using the repository browser.