source: frontend/node_modules/@babel/plugin-transform-react-constant-elements/lib/index.js

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

Fix frontend appearance

  • Property mode set to 100644
File size: 5.7 KB
RevLine 
[9af201e]1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.default = void 0;
7var _helperPluginUtils = require("@babel/helper-plugin-utils");
8var _core = require("@babel/core");
9var _default = exports.default = (0, _helperPluginUtils.declare)((api, options) => {
10 api.assertVersion(7);
11 const {
12 allowMutablePropsOnTags
13 } = options;
14 if (allowMutablePropsOnTags != null && !Array.isArray(allowMutablePropsOnTags)) {
15 throw new Error(".allowMutablePropsOnTags must be an array, null, or undefined.");
16 }
17 const HOISTED = new WeakMap();
18 function declares(node, scope) {
19 if (_core.types.isJSXIdentifier(node, {
20 name: "this"
21 }) || _core.types.isJSXIdentifier(node, {
22 name: "arguments"
23 }) || _core.types.isJSXIdentifier(node, {
24 name: "super"
25 }) || _core.types.isJSXIdentifier(node, {
26 name: "new"
27 })) {
28 const {
29 path
30 } = scope;
31 return path.isFunctionParent() && !path.isArrowFunctionExpression();
32 }
33 return scope.hasOwnBinding(node.name);
34 }
35 function isHoistingScope({
36 path
37 }) {
38 return path.isFunctionParent() || path.isLoop() || path.isProgram();
39 }
40 function getHoistingScope(scope) {
41 while (!isHoistingScope(scope)) scope = scope.parent;
42 return scope;
43 }
44 const targetScopeVisitor = {
45 ReferencedIdentifier(path, state) {
46 const {
47 node
48 } = path;
49 let {
50 scope
51 } = path;
52 while (scope !== state.jsxScope) {
53 if (declares(node, scope)) return;
54 scope = scope.parent;
55 }
56 while (scope) {
57 if (scope === state.targetScope) return;
58 if (declares(node, scope)) break;
59 scope = scope.parent;
60 }
61 state.targetScope = getHoistingScope(scope);
62 }
63 };
64 const immutabilityVisitor = {
65 enter(path, state) {
66 var _expressionResult$deo;
67 const stop = () => {
68 state.isImmutable = false;
69 path.stop();
70 };
71 const skip = () => {
72 path.skip();
73 };
74 if (path.isJSXClosingElement()) {
75 skip();
76 return;
77 }
78 if (path.isJSXIdentifier({
79 name: "ref"
80 }) && path.parentPath.isJSXAttribute({
81 name: path.node
82 })) {
83 stop();
84 return;
85 }
86 if (path.isJSXIdentifier() || path.isJSXMemberExpression() || path.isJSXNamespacedName() || path.isImmutable()) {
87 return;
88 }
89 if (path.isIdentifier()) {
90 const binding = path.scope.getBinding(path.node.name);
91 if (binding != null && binding.constant) return;
92 }
93 const {
94 mutablePropsAllowed
95 } = state;
96 if (mutablePropsAllowed && path.isFunction()) {
97 path.traverse(targetScopeVisitor, state);
98 skip();
99 return;
100 }
101 if (!path.isPure()) {
102 stop();
103 return;
104 }
105 const expressionResult = path.evaluate();
106 if (expressionResult.confident) {
107 const {
108 value
109 } = expressionResult;
110 if (mutablePropsAllowed || value === null || typeof value !== "object" && typeof value !== "function") {
111 skip();
112 return;
113 }
114 } else if ((_expressionResult$deo = expressionResult.deopt) != null && _expressionResult$deo.isIdentifier()) {
115 return;
116 }
117 stop();
118 }
119 };
120 const hoistingVisitor = Object.assign({}, immutabilityVisitor, targetScopeVisitor);
121 return {
122 name: "transform-react-constant-elements",
123 visitor: {
124 "JSXElement|JSXFragment"(path) {
125 if (HOISTED.has(path.node)) return;
126 let mutablePropsAllowed = false;
127 let name;
128 if (path.isJSXElement()) {
129 name = path.node.openingElement.name;
130 if (allowMutablePropsOnTags != null) {
131 let lastSegment = name;
132 while (_core.types.isJSXMemberExpression(lastSegment)) {
133 lastSegment = lastSegment.property;
134 }
135 const elementName = lastSegment.name;
136 mutablePropsAllowed = allowMutablePropsOnTags.includes(elementName);
137 }
138 } else {
139 name = path.node;
140 }
141 let jsxScope;
142 let current = path;
143 while (!jsxScope && current.parentPath.isJSX()) {
144 current = current.parentPath;
145 jsxScope = HOISTED.get(current.node);
146 }
147 jsxScope != null ? jsxScope : jsxScope = path.scope;
148 HOISTED.set(path.node, jsxScope);
149 const visitorState = {
150 isImmutable: true,
151 mutablePropsAllowed,
152 jsxScope,
153 targetScope: path.scope.getProgramParent()
154 };
155 path.traverse(hoistingVisitor, visitorState);
156 if (!visitorState.isImmutable) return;
157 const {
158 targetScope
159 } = visitorState;
160 for (let currentScope = jsxScope;;) {
161 if (targetScope === currentScope) return;
162 if (isHoistingScope(currentScope)) break;
163 currentScope = currentScope.parent;
164 if (!currentScope) {
165 throw new Error("Internal @babel/plugin-transform-react-constant-elements error: " + "targetScope must be an ancestor of jsxScope. " + "This is a Babel bug, please report it.");
166 }
167 }
168 const id = path.scope.generateUidBasedOnNode(name);
169 targetScope.push({
170 id: _core.types.identifier(id)
171 });
172 HOISTED.set(path.node, targetScope);
173 let replacement = _core.template.expression.ast`
174 ${_core.types.identifier(id)} || (${_core.types.identifier(id)} = ${path.node})
175 `;
176 if (path.parentPath.isJSXElement() || path.parentPath.isJSXAttribute() || path.parentPath.isJSXFragment()) {
177 replacement = _core.types.jsxExpressionContainer(replacement);
178 }
179 path.replaceWith(replacement);
180 }
181 }
182 };
183});
184
185//# sourceMappingURL=index.js.map
Note: See TracBrowser for help on using the repository browser.