source: trip-planner-front/node_modules/@babel/plugin-proposal-optional-chaining/lib/index.js@ 6a3a178

Last change on this file since 6a3a178 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

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