source: frontend/node_modules/@babel/plugin-proposal-optional-chaining/lib/index.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: 7.8 KB
Line 
1'use strict';
2
3Object.defineProperty(exports, '__esModule', { value: true });
4
5var helperPluginUtils = require('@babel/helper-plugin-utils');
6var syntaxOptionalChaining = require('@babel/plugin-syntax-optional-chaining');
7var core = require('@babel/core');
8var helperSkipTransparentExpressionWrappers = require('@babel/helper-skip-transparent-expression-wrappers');
9
10function willPathCastToBoolean(path) {
11 const maybeWrapped = findOutermostTransparentParent(path);
12 const {
13 node,
14 parentPath
15 } = maybeWrapped;
16 if (parentPath.isLogicalExpression()) {
17 const {
18 operator,
19 right
20 } = parentPath.node;
21 if (operator === "&&" || operator === "||" || operator === "??" && node === right) {
22 return willPathCastToBoolean(parentPath);
23 }
24 }
25 if (parentPath.isSequenceExpression()) {
26 const {
27 expressions
28 } = parentPath.node;
29 if (expressions[expressions.length - 1] === node) {
30 return willPathCastToBoolean(parentPath);
31 } else {
32 return true;
33 }
34 }
35 return parentPath.isConditional({
36 test: node
37 }) || parentPath.isUnaryExpression({
38 operator: "!"
39 }) || parentPath.isLoop({
40 test: node
41 });
42}
43function findOutermostTransparentParent(path) {
44 let maybeWrapped = path;
45 path.findParent(p => {
46 if (!helperSkipTransparentExpressionWrappers.isTransparentExprWrapper(p.node)) return true;
47 maybeWrapped = p;
48 });
49 return maybeWrapped;
50}
51
52const {
53 ast
54} = core.template.expression;
55function isSimpleMemberExpression(expression) {
56 expression = helperSkipTransparentExpressionWrappers.skipTransparentExprWrapperNodes(expression);
57 return core.types.isIdentifier(expression) || core.types.isSuper(expression) || core.types.isMemberExpression(expression) && !expression.computed && isSimpleMemberExpression(expression.object);
58}
59function needsMemoize(path) {
60 let optionalPath = path;
61 const {
62 scope
63 } = path;
64 while (optionalPath.isOptionalMemberExpression() || optionalPath.isOptionalCallExpression()) {
65 const {
66 node
67 } = optionalPath;
68 const childPath = helperSkipTransparentExpressionWrappers.skipTransparentExprWrappers(optionalPath.isOptionalMemberExpression() ? optionalPath.get("object") : optionalPath.get("callee"));
69 if (node.optional) {
70 return !scope.isStatic(childPath.node);
71 }
72 optionalPath = childPath;
73 }
74}
75function transform(path, {
76 pureGetters,
77 noDocumentAll
78}) {
79 const {
80 scope
81 } = path;
82 const maybeWrapped = findOutermostTransparentParent(path);
83 const {
84 parentPath
85 } = maybeWrapped;
86 const willReplacementCastToBoolean = willPathCastToBoolean(maybeWrapped);
87 let isDeleteOperation = false;
88 const parentIsCall = parentPath.isCallExpression({
89 callee: maybeWrapped.node
90 }) && path.isOptionalMemberExpression();
91 const optionals = [];
92 let optionalPath = path;
93 if (scope.path.isPattern() && needsMemoize(optionalPath)) {
94 path.replaceWith(core.template.ast`(() => ${path.node})()`);
95 return;
96 }
97 while (optionalPath.isOptionalMemberExpression() || optionalPath.isOptionalCallExpression()) {
98 const {
99 node
100 } = optionalPath;
101 if (node.optional) {
102 optionals.push(node);
103 }
104 if (optionalPath.isOptionalMemberExpression()) {
105 optionalPath.node.type = "MemberExpression";
106 optionalPath = helperSkipTransparentExpressionWrappers.skipTransparentExprWrappers(optionalPath.get("object"));
107 } else if (optionalPath.isOptionalCallExpression()) {
108 optionalPath.node.type = "CallExpression";
109 optionalPath = helperSkipTransparentExpressionWrappers.skipTransparentExprWrappers(optionalPath.get("callee"));
110 }
111 }
112 let replacementPath = path;
113 if (parentPath.isUnaryExpression({
114 operator: "delete"
115 })) {
116 replacementPath = parentPath;
117 isDeleteOperation = true;
118 }
119 for (let i = optionals.length - 1; i >= 0; i--) {
120 const node = optionals[i];
121 const isCall = core.types.isCallExpression(node);
122 const chainWithTypes = isCall ? node.callee : node.object;
123 const chain = helperSkipTransparentExpressionWrappers.skipTransparentExprWrapperNodes(chainWithTypes);
124 let ref;
125 let check;
126 if (isCall && core.types.isIdentifier(chain, {
127 name: "eval"
128 })) {
129 check = ref = chain;
130 node.callee = core.types.sequenceExpression([core.types.numericLiteral(0), ref]);
131 } else if (pureGetters && isCall && isSimpleMemberExpression(chain)) {
132 check = ref = node.callee;
133 } else {
134 ref = scope.maybeGenerateMemoised(chain);
135 if (ref) {
136 check = core.types.assignmentExpression("=", core.types.cloneNode(ref), chainWithTypes);
137 isCall ? node.callee = ref : node.object = ref;
138 } else {
139 check = ref = chainWithTypes;
140 }
141 }
142 if (isCall && core.types.isMemberExpression(chain)) {
143 if (pureGetters && isSimpleMemberExpression(chain)) {
144 node.callee = chainWithTypes;
145 } else {
146 const {
147 object
148 } = chain;
149 let context;
150 if (core.types.isSuper(object)) {
151 context = core.types.thisExpression();
152 } else {
153 const memoized = scope.maybeGenerateMemoised(object);
154 if (memoized) {
155 context = memoized;
156 chain.object = core.types.assignmentExpression("=", memoized, object);
157 } else {
158 context = object;
159 }
160 }
161 node.arguments.unshift(core.types.cloneNode(context));
162 node.callee = core.types.memberExpression(node.callee, core.types.identifier("call"));
163 }
164 }
165 let replacement = replacementPath.node;
166 if (i === 0 && parentIsCall) {
167 var _baseRef;
168 const object = helperSkipTransparentExpressionWrappers.skipTransparentExprWrapperNodes(replacement.object);
169 let baseRef;
170 if (!pureGetters || !isSimpleMemberExpression(object)) {
171 baseRef = scope.maybeGenerateMemoised(object);
172 if (baseRef) {
173 replacement.object = core.types.assignmentExpression("=", baseRef, object);
174 }
175 }
176 replacement = core.types.callExpression(core.types.memberExpression(replacement, core.types.identifier("bind")), [core.types.cloneNode((_baseRef = baseRef) != null ? _baseRef : object)]);
177 }
178 if (willReplacementCastToBoolean) {
179 const nonNullishCheck = noDocumentAll ? ast`${core.types.cloneNode(check)} != null` : ast`
180 ${core.types.cloneNode(check)} !== null && ${core.types.cloneNode(ref)} !== void 0`;
181 replacementPath.replaceWith(core.types.logicalExpression("&&", nonNullishCheck, replacement));
182 replacementPath = helperSkipTransparentExpressionWrappers.skipTransparentExprWrappers(replacementPath.get("right"));
183 } else {
184 const nullishCheck = noDocumentAll ? ast`${core.types.cloneNode(check)} == null` : ast`
185 ${core.types.cloneNode(check)} === null || ${core.types.cloneNode(ref)} === void 0`;
186 const returnValue = isDeleteOperation ? ast`true` : ast`void 0`;
187 replacementPath.replaceWith(core.types.conditionalExpression(nullishCheck, returnValue, replacement));
188 replacementPath = helperSkipTransparentExpressionWrappers.skipTransparentExprWrappers(replacementPath.get("alternate"));
189 }
190 }
191}
192
193var index = helperPluginUtils.declare((api, options) => {
194 var _api$assumption, _api$assumption2;
195 api.assertVersion(7);
196 const {
197 loose = false
198 } = options;
199 const noDocumentAll = (_api$assumption = api.assumption("noDocumentAll")) != null ? _api$assumption : loose;
200 const pureGetters = (_api$assumption2 = api.assumption("pureGetters")) != null ? _api$assumption2 : loose;
201 return {
202 name: "proposal-optional-chaining",
203 inherits: syntaxOptionalChaining.default,
204 visitor: {
205 "OptionalCallExpression|OptionalMemberExpression"(path) {
206 transform(path, {
207 noDocumentAll,
208 pureGetters
209 });
210 }
211 }
212 };
213});
214
215exports["default"] = index;
216exports.transform = transform;
217//# sourceMappingURL=index.js.map
Note: See TracBrowser for help on using the repository browser.