source: imaps-frontend/node_modules/@babel/plugin-transform-optional-chaining/lib/index.js

main
Last change on this file was 79a0317, checked in by stefan toskovski <stefantoska84@…>, 4 days ago

F4 Finalna Verzija

  • Property mode set to 100644
File size: 9.0 KB
Line 
1'use strict';
2
3Object.defineProperty(exports, '__esModule', { value: true });
4
5var helperPluginUtils = require('@babel/helper-plugin-utils');
6var core = require('@babel/core');
7var helperSkipTransparentExpressionWrappers = require('@babel/helper-skip-transparent-expression-wrappers');
8
9function willPathCastToBoolean(path) {
10 const maybeWrapped = findOutermostTransparentParent(path);
11 const {
12 node,
13 parentPath
14 } = maybeWrapped;
15 if (parentPath.isLogicalExpression()) {
16 const {
17 operator,
18 right
19 } = parentPath.node;
20 if (operator === "&&" || operator === "||" || operator === "??" && node === right) {
21 return willPathCastToBoolean(parentPath);
22 }
23 }
24 if (parentPath.isSequenceExpression()) {
25 const {
26 expressions
27 } = parentPath.node;
28 if (expressions[expressions.length - 1] === node) {
29 return willPathCastToBoolean(parentPath);
30 } else {
31 return true;
32 }
33 }
34 return parentPath.isConditional({
35 test: node
36 }) || parentPath.isUnaryExpression({
37 operator: "!"
38 }) || parentPath.isLoop({
39 test: node
40 });
41}
42function findOutermostTransparentParent(path) {
43 let maybeWrapped = path;
44 path.findParent(p => {
45 if (!helperSkipTransparentExpressionWrappers.isTransparentExprWrapper(p.node)) return true;
46 maybeWrapped = p;
47 });
48 return maybeWrapped;
49}
50
51const last = arr => arr[arr.length - 1];
52function isSimpleMemberExpression(expression) {
53 expression = helperSkipTransparentExpressionWrappers.skipTransparentExprWrapperNodes(expression);
54 return core.types.isIdentifier(expression) || core.types.isSuper(expression) || core.types.isMemberExpression(expression) && !expression.computed && isSimpleMemberExpression(expression.object);
55}
56function needsMemoize(path) {
57 let optionalPath = path;
58 const {
59 scope
60 } = path;
61 while (optionalPath.isOptionalMemberExpression() || optionalPath.isOptionalCallExpression()) {
62 const {
63 node
64 } = optionalPath;
65 const childPath = helperSkipTransparentExpressionWrappers.skipTransparentExprWrappers(optionalPath.isOptionalMemberExpression() ? optionalPath.get("object") : optionalPath.get("callee"));
66 if (node.optional) {
67 return !scope.isStatic(childPath.node);
68 }
69 optionalPath = childPath;
70 }
71}
72const NULLISH_CHECK = core.template.expression(`%%check%% === null || %%ref%% === void 0`);
73const NULLISH_CHECK_NO_DDA = core.template.expression(`%%check%% == null`);
74const NULLISH_CHECK_NEG = core.template.expression(`%%check%% !== null && %%ref%% !== void 0`);
75const NULLISH_CHECK_NO_DDA_NEG = core.template.expression(`%%check%% != null`);
76function transformOptionalChain(path, {
77 pureGetters,
78 noDocumentAll
79}, replacementPath, ifNullish, wrapLast) {
80 const {
81 scope
82 } = path;
83 if (scope.path.isPattern() && needsMemoize(path)) {
84 replacementPath.replaceWith(core.template.expression.ast`(() => ${replacementPath.node})()`);
85 return;
86 }
87 const optionals = [];
88 let optionalPath = path;
89 while (optionalPath.isOptionalMemberExpression() || optionalPath.isOptionalCallExpression()) {
90 const {
91 node
92 } = optionalPath;
93 if (node.optional) {
94 optionals.push(node);
95 }
96 if (optionalPath.isOptionalMemberExpression()) {
97 optionalPath.node.type = "MemberExpression";
98 optionalPath = helperSkipTransparentExpressionWrappers.skipTransparentExprWrappers(optionalPath.get("object"));
99 } else if (optionalPath.isOptionalCallExpression()) {
100 optionalPath.node.type = "CallExpression";
101 optionalPath = helperSkipTransparentExpressionWrappers.skipTransparentExprWrappers(optionalPath.get("callee"));
102 }
103 }
104 if (optionals.length === 0) {
105 return;
106 }
107 const checks = [];
108 let tmpVar;
109 for (let i = optionals.length - 1; i >= 0; i--) {
110 const node = optionals[i];
111 const isCall = core.types.isCallExpression(node);
112 const chainWithTypes = isCall ? node.callee : node.object;
113 const chain = helperSkipTransparentExpressionWrappers.skipTransparentExprWrapperNodes(chainWithTypes);
114 let ref;
115 let check;
116 if (isCall && core.types.isIdentifier(chain, {
117 name: "eval"
118 })) {
119 check = ref = chain;
120 node.callee = core.types.sequenceExpression([core.types.numericLiteral(0), ref]);
121 } else if (pureGetters && isCall && isSimpleMemberExpression(chain)) {
122 check = ref = node.callee;
123 } else if (scope.isStatic(chain)) {
124 check = ref = chainWithTypes;
125 } else {
126 if (!tmpVar || isCall) {
127 tmpVar = scope.generateUidIdentifierBasedOnNode(chain);
128 scope.push({
129 id: core.types.cloneNode(tmpVar)
130 });
131 }
132 ref = tmpVar;
133 check = core.types.assignmentExpression("=", core.types.cloneNode(tmpVar), chainWithTypes);
134 if (isCall) {
135 node.callee = ref;
136 } else {
137 node.object = ref;
138 }
139 }
140 if (isCall && core.types.isMemberExpression(chain)) {
141 if (pureGetters && isSimpleMemberExpression(chain)) {
142 node.callee = chainWithTypes;
143 } else {
144 const {
145 object
146 } = chain;
147 let context;
148 if (core.types.isSuper(object)) {
149 context = core.types.thisExpression();
150 } else {
151 const memoized = scope.maybeGenerateMemoised(object);
152 if (memoized) {
153 context = memoized;
154 chain.object = core.types.assignmentExpression("=", memoized, object);
155 } else {
156 context = object;
157 }
158 }
159 node.arguments.unshift(core.types.cloneNode(context));
160 node.callee = core.types.memberExpression(node.callee, core.types.identifier("call"));
161 }
162 }
163 const data = {
164 check: core.types.cloneNode(check),
165 ref: core.types.cloneNode(ref)
166 };
167 Object.defineProperty(data, "ref", {
168 enumerable: false
169 });
170 checks.push(data);
171 }
172 let result = replacementPath.node;
173 if (wrapLast) result = wrapLast(result);
174 const ifNullishBoolean = core.types.isBooleanLiteral(ifNullish);
175 const ifNullishFalse = ifNullishBoolean && ifNullish.value === false;
176 const ifNullishVoid = !ifNullishBoolean && core.types.isUnaryExpression(ifNullish, {
177 operator: "void"
178 });
179 const isEvaluationValueIgnored = core.types.isExpressionStatement(replacementPath.parent) && !replacementPath.isCompletionRecord() || core.types.isSequenceExpression(replacementPath.parent) && last(replacementPath.parent.expressions) !== replacementPath.node;
180 const tpl = ifNullishFalse ? noDocumentAll ? NULLISH_CHECK_NO_DDA_NEG : NULLISH_CHECK_NEG : noDocumentAll ? NULLISH_CHECK_NO_DDA : NULLISH_CHECK;
181 const logicalOp = ifNullishFalse ? "&&" : "||";
182 const check = checks.map(tpl).reduce((expr, check) => core.types.logicalExpression(logicalOp, expr, check));
183 replacementPath.replaceWith(ifNullishBoolean || ifNullishVoid && isEvaluationValueIgnored ? core.types.logicalExpression(logicalOp, check, result) : core.types.conditionalExpression(check, ifNullish, result));
184}
185function transform(path, assumptions) {
186 const {
187 scope
188 } = path;
189 const maybeWrapped = findOutermostTransparentParent(path);
190 const {
191 parentPath
192 } = maybeWrapped;
193 if (parentPath.isUnaryExpression({
194 operator: "delete"
195 })) {
196 transformOptionalChain(path, assumptions, parentPath, core.types.booleanLiteral(true));
197 } else {
198 let wrapLast;
199 if (parentPath.isCallExpression({
200 callee: maybeWrapped.node
201 }) && path.isOptionalMemberExpression()) {
202 wrapLast = replacement => {
203 var _baseRef;
204 const object = helperSkipTransparentExpressionWrappers.skipTransparentExprWrapperNodes(replacement.object);
205 let baseRef;
206 if (!assumptions.pureGetters || !isSimpleMemberExpression(object)) {
207 baseRef = scope.maybeGenerateMemoised(object);
208 if (baseRef) {
209 replacement.object = core.types.assignmentExpression("=", baseRef, object);
210 }
211 }
212 return core.types.callExpression(core.types.memberExpression(replacement, core.types.identifier("bind")), [core.types.cloneNode((_baseRef = baseRef) != null ? _baseRef : object)]);
213 };
214 }
215 transformOptionalChain(path, assumptions, path, willPathCastToBoolean(maybeWrapped) ? core.types.booleanLiteral(false) : scope.buildUndefinedNode(), wrapLast);
216 }
217}
218
219var index = helperPluginUtils.declare((api, options) => {
220 var _api$assumption, _api$assumption2;
221 api.assertVersion("^7.0.0-0 || >8.0.0-alpha <8.0.0-beta");
222 const {
223 loose = false
224 } = options;
225 const noDocumentAll = (_api$assumption = api.assumption("noDocumentAll")) != null ? _api$assumption : loose;
226 const pureGetters = (_api$assumption2 = api.assumption("pureGetters")) != null ? _api$assumption2 : loose;
227 return {
228 name: "transform-optional-chaining",
229 manipulateOptions: (_, parser) => parser.plugins.push("optionalChaining"),
230 visitor: {
231 "OptionalCallExpression|OptionalMemberExpression"(path) {
232 transform(path, {
233 noDocumentAll,
234 pureGetters
235 });
236 }
237 }
238 };
239});
240
241exports.default = index;
242exports.transform = transform;
243exports.transformOptionalChain = transformOptionalChain;
244//# sourceMappingURL=index.js.map
Note: See TracBrowser for help on using the repository browser.