UNPKG

40.9 kBJavaScriptView Raw
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.buildCheckInRHS = buildCheckInRHS;
7exports.buildFieldsInitNodes = buildFieldsInitNodes;
8exports.buildPrivateNamesMap = buildPrivateNamesMap;
9exports.buildPrivateNamesNodes = buildPrivateNamesNodes;
10exports.privateNameVisitorFactory = privateNameVisitorFactory;
11exports.transformPrivateNamesUsage = transformPrivateNamesUsage;
12var _core = require("@babel/core");
13var _traverse = require("@babel/traverse");
14var _helperReplaceSupers = require("@babel/helper-replace-supers");
15var _helperMemberExpressionToFunctions = require("@babel/helper-member-expression-to-functions");
16var _helperOptimiseCallExpression = require("@babel/helper-optimise-call-expression");
17var _helperAnnotateAsPure = require("@babel/helper-annotate-as-pure");
18var _helperSkipTransparentExpressionWrappers = require("@babel/helper-skip-transparent-expression-wrappers");
19var ts = require("./typescript.js");
20{
21 var newHelpers = file => {
22 ;
23 return file.availableHelper("classPrivateFieldGet2");
24 };
25}
26function buildPrivateNamesMap(className, privateFieldsAsSymbolsOrProperties, props, file) {
27 const privateNamesMap = new Map();
28 let classBrandId;
29 for (const prop of props) {
30 if (prop.isPrivate()) {
31 const {
32 name
33 } = prop.node.key.id;
34 let update = privateNamesMap.get(name);
35 if (!update) {
36 const isMethod = !prop.isProperty();
37 const isStatic = prop.node.static;
38 let initAdded = false;
39 let id;
40 if (!privateFieldsAsSymbolsOrProperties && newHelpers(file) && isMethod && !isStatic) {
41 var _classBrandId;
42 initAdded = !!classBrandId;
43 (_classBrandId = classBrandId) != null ? _classBrandId : classBrandId = prop.scope.generateUidIdentifier(`${className}_brand`);
44 id = classBrandId;
45 } else {
46 id = prop.scope.generateUidIdentifier(name);
47 }
48 update = {
49 id,
50 static: isStatic,
51 method: isMethod,
52 initAdded
53 };
54 privateNamesMap.set(name, update);
55 }
56 if (prop.isClassPrivateMethod()) {
57 if (prop.node.kind === "get") {
58 const {
59 body
60 } = prop.node.body;
61 let $;
62 if (body.length === 1 && _core.types.isReturnStatement($ = body[0]) && _core.types.isCallExpression($ = $.argument) && $.arguments.length === 1 && _core.types.isThisExpression($.arguments[0]) && _core.types.isIdentifier($ = $.callee)) {
63 update.getId = _core.types.cloneNode($);
64 update.getterDeclared = true;
65 } else {
66 update.getId = prop.scope.generateUidIdentifier(`get_${name}`);
67 }
68 } else if (prop.node.kind === "set") {
69 const {
70 params
71 } = prop.node;
72 const {
73 body
74 } = prop.node.body;
75 let $;
76 if (body.length === 1 && _core.types.isExpressionStatement($ = body[0]) && _core.types.isCallExpression($ = $.expression) && $.arguments.length === 2 && _core.types.isThisExpression($.arguments[0]) && _core.types.isIdentifier($.arguments[1], {
77 name: params[0].name
78 }) && _core.types.isIdentifier($ = $.callee)) {
79 update.setId = _core.types.cloneNode($);
80 update.setterDeclared = true;
81 } else {
82 update.setId = prop.scope.generateUidIdentifier(`set_${name}`);
83 }
84 } else if (prop.node.kind === "method") {
85 update.methodId = prop.scope.generateUidIdentifier(name);
86 }
87 }
88 privateNamesMap.set(name, update);
89 }
90 }
91 return privateNamesMap;
92}
93function buildPrivateNamesNodes(privateNamesMap, privateFieldsAsProperties, privateFieldsAsSymbols, state) {
94 const initNodes = [];
95 const injectedIds = new Set();
96 for (const [name, value] of privateNamesMap) {
97 const {
98 static: isStatic,
99 method: isMethod,
100 getId,
101 setId
102 } = value;
103 const isGetterOrSetter = getId || setId;
104 const id = _core.types.cloneNode(value.id);
105 let init;
106 if (privateFieldsAsProperties) {
107 init = _core.types.callExpression(state.addHelper("classPrivateFieldLooseKey"), [_core.types.stringLiteral(name)]);
108 } else if (privateFieldsAsSymbols) {
109 init = _core.types.callExpression(_core.types.identifier("Symbol"), [_core.types.stringLiteral(name)]);
110 } else if (!isStatic) {
111 if (injectedIds.has(id.name)) continue;
112 injectedIds.add(id.name);
113 init = _core.types.newExpression(_core.types.identifier(isMethod && (!isGetterOrSetter || newHelpers(state)) ? "WeakSet" : "WeakMap"), []);
114 }
115 if (init) {
116 if (!privateFieldsAsSymbols) {
117 (0, _helperAnnotateAsPure.default)(init);
118 }
119 initNodes.push(_core.template.statement.ast`var ${id} = ${init}`);
120 }
121 }
122 return initNodes;
123}
124function privateNameVisitorFactory(visitor) {
125 const nestedVisitor = _traverse.visitors.environmentVisitor(Object.assign({}, visitor));
126 const privateNameVisitor = Object.assign({}, visitor, {
127 Class(path) {
128 const {
129 privateNamesMap
130 } = this;
131 const body = path.get("body.body");
132 const visiblePrivateNames = new Map(privateNamesMap);
133 const redeclared = [];
134 for (const prop of body) {
135 if (!prop.isPrivate()) continue;
136 const {
137 name
138 } = prop.node.key.id;
139 visiblePrivateNames.delete(name);
140 redeclared.push(name);
141 }
142 if (!redeclared.length) {
143 return;
144 }
145 path.get("body").traverse(nestedVisitor, Object.assign({}, this, {
146 redeclared
147 }));
148 path.traverse(privateNameVisitor, Object.assign({}, this, {
149 privateNamesMap: visiblePrivateNames
150 }));
151 path.skipKey("body");
152 }
153 });
154 return privateNameVisitor;
155}
156const privateNameVisitor = privateNameVisitorFactory({
157 PrivateName(path, {
158 noDocumentAll
159 }) {
160 const {
161 privateNamesMap,
162 redeclared
163 } = this;
164 const {
165 node,
166 parentPath
167 } = path;
168 if (!parentPath.isMemberExpression({
169 property: node
170 }) && !parentPath.isOptionalMemberExpression({
171 property: node
172 })) {
173 return;
174 }
175 const {
176 name
177 } = node.id;
178 if (!privateNamesMap.has(name)) return;
179 if (redeclared != null && redeclared.includes(name)) return;
180 this.handle(parentPath, noDocumentAll);
181 }
182});
183function unshadow(name, scope, innerBinding) {
184 while ((_scope = scope) != null && _scope.hasBinding(name) && !scope.bindingIdentifierEquals(name, innerBinding)) {
185 var _scope;
186 scope.rename(name);
187 scope = scope.parent;
188 }
189}
190function buildCheckInRHS(rhs, file, inRHSIsObject) {
191 if (inRHSIsObject || !(file.availableHelper != null && file.availableHelper("checkInRHS"))) return rhs;
192 return _core.types.callExpression(file.addHelper("checkInRHS"), [rhs]);
193}
194const privateInVisitor = privateNameVisitorFactory({
195 BinaryExpression(path, {
196 file
197 }) {
198 const {
199 operator,
200 left,
201 right
202 } = path.node;
203 if (operator !== "in") return;
204 if (!_core.types.isPrivateName(left)) return;
205 const {
206 privateFieldsAsProperties,
207 privateNamesMap,
208 redeclared
209 } = this;
210 const {
211 name
212 } = left.id;
213 if (!privateNamesMap.has(name)) return;
214 if (redeclared != null && redeclared.includes(name)) return;
215 unshadow(this.classRef.name, path.scope, this.innerBinding);
216 if (privateFieldsAsProperties) {
217 const {
218 id
219 } = privateNamesMap.get(name);
220 path.replaceWith(_core.template.expression.ast`
221 Object.prototype.hasOwnProperty.call(${buildCheckInRHS(right, file)}, ${_core.types.cloneNode(id)})
222 `);
223 return;
224 }
225 const {
226 id,
227 static: isStatic
228 } = privateNamesMap.get(name);
229 if (isStatic) {
230 path.replaceWith(_core.template.expression.ast`${buildCheckInRHS(right, file)} === ${_core.types.cloneNode(this.classRef)}`);
231 return;
232 }
233 path.replaceWith(_core.template.expression.ast`${_core.types.cloneNode(id)}.has(${buildCheckInRHS(right, file)})`);
234 }
235});
236function readOnlyError(file, name) {
237 return _core.types.callExpression(file.addHelper("readOnlyError"), [_core.types.stringLiteral(`#${name}`)]);
238}
239function writeOnlyError(file, name) {
240 if (!file.availableHelper("writeOnlyError")) {
241 console.warn(`@babel/helpers is outdated, update it to silence this warning.`);
242 return _core.types.buildUndefinedNode();
243 }
244 return _core.types.callExpression(file.addHelper("writeOnlyError"), [_core.types.stringLiteral(`#${name}`)]);
245}
246function buildStaticPrivateFieldAccess(expr, noUninitializedPrivateFieldAccess) {
247 if (noUninitializedPrivateFieldAccess) return expr;
248 return _core.types.memberExpression(expr, _core.types.identifier("_"));
249}
250function autoInherits(fn) {
251 return function (member) {
252 return _core.types.inherits(fn.apply(this, arguments), member.node);
253 };
254}
255const privateNameHandlerSpec = {
256 memoise(member, count) {
257 const {
258 scope
259 } = member;
260 const {
261 object
262 } = member.node;
263 const memo = scope.maybeGenerateMemoised(object);
264 if (!memo) {
265 return;
266 }
267 this.memoiser.set(object, memo, count);
268 },
269 receiver(member) {
270 const {
271 object
272 } = member.node;
273 if (this.memoiser.has(object)) {
274 return _core.types.cloneNode(this.memoiser.get(object));
275 }
276 return _core.types.cloneNode(object);
277 },
278 get: autoInherits(function (member) {
279 const {
280 classRef,
281 privateNamesMap,
282 file,
283 innerBinding,
284 noUninitializedPrivateFieldAccess
285 } = this;
286 const privateName = member.node.property;
287 const {
288 name
289 } = privateName.id;
290 const {
291 id,
292 static: isStatic,
293 method: isMethod,
294 methodId,
295 getId,
296 setId
297 } = privateNamesMap.get(name);
298 const isGetterOrSetter = getId || setId;
299 const cloneId = id => _core.types.inherits(_core.types.cloneNode(id), privateName);
300 if (isStatic) {
301 unshadow(classRef.name, member.scope, innerBinding);
302 if (!newHelpers(file)) {
303 const helperName = isMethod && !isGetterOrSetter ? "classStaticPrivateMethodGet" : "classStaticPrivateFieldSpecGet";
304 return _core.types.callExpression(file.addHelper(helperName), [this.receiver(member), _core.types.cloneNode(classRef), cloneId(id)]);
305 }
306 const receiver = this.receiver(member);
307 const skipCheck = _core.types.isIdentifier(receiver) && receiver.name === classRef.name;
308 if (!isMethod) {
309 if (skipCheck) {
310 return buildStaticPrivateFieldAccess(cloneId(id), noUninitializedPrivateFieldAccess);
311 }
312 return buildStaticPrivateFieldAccess(_core.types.callExpression(file.addHelper("assertClassBrand"), [_core.types.cloneNode(classRef), receiver, cloneId(id)]), noUninitializedPrivateFieldAccess);
313 }
314 if (getId) {
315 if (skipCheck) {
316 return _core.types.callExpression(cloneId(getId), [receiver]);
317 }
318 return _core.types.callExpression(file.addHelper("classPrivateGetter"), [_core.types.cloneNode(classRef), receiver, cloneId(getId)]);
319 }
320 if (setId) {
321 const err = _core.types.buildUndefinedNode();
322 if (skipCheck) return err;
323 return _core.types.sequenceExpression([_core.types.callExpression(file.addHelper("assertClassBrand"), [_core.types.cloneNode(classRef), receiver]), err]);
324 }
325 if (skipCheck) return cloneId(id);
326 return _core.types.callExpression(file.addHelper("assertClassBrand"), [_core.types.cloneNode(classRef), receiver, cloneId(id)]);
327 }
328 if (isMethod) {
329 if (isGetterOrSetter) {
330 if (!getId) {
331 return _core.types.sequenceExpression([this.receiver(member), writeOnlyError(file, name)]);
332 }
333 if (!newHelpers(file)) {
334 return _core.types.callExpression(file.addHelper("classPrivateFieldGet"), [this.receiver(member), cloneId(id)]);
335 }
336 return _core.types.callExpression(file.addHelper("classPrivateGetter"), [_core.types.cloneNode(id), this.receiver(member), cloneId(getId)]);
337 }
338 if (!newHelpers(file)) {
339 return _core.types.callExpression(file.addHelper("classPrivateMethodGet"), [this.receiver(member), _core.types.cloneNode(id), cloneId(methodId)]);
340 }
341 return _core.types.callExpression(file.addHelper("assertClassBrand"), [_core.types.cloneNode(id), this.receiver(member), cloneId(methodId)]);
342 }
343 if (newHelpers(file)) {
344 return _core.types.callExpression(file.addHelper("classPrivateFieldGet2"), [cloneId(id), this.receiver(member)]);
345 }
346 return _core.types.callExpression(file.addHelper("classPrivateFieldGet"), [this.receiver(member), cloneId(id)]);
347 }),
348 boundGet(member) {
349 this.memoise(member, 1);
350 return _core.types.callExpression(_core.types.memberExpression(this.get(member), _core.types.identifier("bind")), [this.receiver(member)]);
351 },
352 set: autoInherits(function (member, value) {
353 const {
354 classRef,
355 privateNamesMap,
356 file,
357 noUninitializedPrivateFieldAccess
358 } = this;
359 const privateName = member.node.property;
360 const {
361 name
362 } = privateName.id;
363 const {
364 id,
365 static: isStatic,
366 method: isMethod,
367 setId,
368 getId
369 } = privateNamesMap.get(name);
370 const isGetterOrSetter = getId || setId;
371 const cloneId = id => _core.types.inherits(_core.types.cloneNode(id), privateName);
372 if (isStatic) {
373 if (!newHelpers(file)) {
374 const helperName = isMethod && !isGetterOrSetter ? "classStaticPrivateMethodSet" : "classStaticPrivateFieldSpecSet";
375 return _core.types.callExpression(file.addHelper(helperName), [this.receiver(member), _core.types.cloneNode(classRef), cloneId(id), value]);
376 }
377 const receiver = this.receiver(member);
378 const skipCheck = _core.types.isIdentifier(receiver) && receiver.name === classRef.name;
379 if (isMethod && !setId) {
380 const err = readOnlyError(file, name);
381 if (skipCheck) return _core.types.sequenceExpression([value, err]);
382 return _core.types.sequenceExpression([value, _core.types.callExpression(file.addHelper("assertClassBrand"), [_core.types.cloneNode(classRef), receiver]), readOnlyError(file, name)]);
383 }
384 if (setId) {
385 if (skipCheck) {
386 return _core.types.callExpression(_core.types.cloneNode(setId), [receiver, value]);
387 }
388 return _core.types.callExpression(file.addHelper("classPrivateSetter"), [_core.types.cloneNode(classRef), cloneId(setId), receiver, value]);
389 }
390 return _core.types.assignmentExpression("=", buildStaticPrivateFieldAccess(cloneId(id), noUninitializedPrivateFieldAccess), skipCheck ? value : _core.types.callExpression(file.addHelper("assertClassBrand"), [_core.types.cloneNode(classRef), receiver, value]));
391 }
392 if (isMethod) {
393 if (setId) {
394 if (!newHelpers(file)) {
395 return _core.types.callExpression(file.addHelper("classPrivateFieldSet"), [this.receiver(member), cloneId(id), value]);
396 }
397 return _core.types.callExpression(file.addHelper("classPrivateSetter"), [_core.types.cloneNode(id), cloneId(setId), this.receiver(member), value]);
398 }
399 return _core.types.sequenceExpression([this.receiver(member), value, readOnlyError(file, name)]);
400 }
401 if (newHelpers(file)) {
402 return _core.types.callExpression(file.addHelper("classPrivateFieldSet2"), [cloneId(id), this.receiver(member), value]);
403 }
404 return _core.types.callExpression(file.addHelper("classPrivateFieldSet"), [this.receiver(member), cloneId(id), value]);
405 }),
406 destructureSet(member) {
407 const {
408 classRef,
409 privateNamesMap,
410 file,
411 noUninitializedPrivateFieldAccess
412 } = this;
413 const privateName = member.node.property;
414 const {
415 name
416 } = privateName.id;
417 const {
418 id,
419 static: isStatic,
420 method: isMethod,
421 setId
422 } = privateNamesMap.get(name);
423 const cloneId = id => _core.types.inherits(_core.types.cloneNode(id), privateName);
424 if (!newHelpers(file)) {
425 if (isStatic) {
426 try {
427 var helper = file.addHelper("classStaticPrivateFieldDestructureSet");
428 } catch (_unused) {
429 throw new Error("Babel can not transpile `[C.#p] = [0]` with @babel/helpers < 7.13.10, \n" + "please update @babel/helpers to the latest version.");
430 }
431 return _core.types.memberExpression(_core.types.callExpression(helper, [this.receiver(member), _core.types.cloneNode(classRef), cloneId(id)]), _core.types.identifier("value"));
432 }
433 return _core.types.memberExpression(_core.types.callExpression(file.addHelper("classPrivateFieldDestructureSet"), [this.receiver(member), cloneId(id)]), _core.types.identifier("value"));
434 }
435 if (isMethod && !setId) {
436 return _core.types.memberExpression(_core.types.sequenceExpression([member.node.object, readOnlyError(file, name)]), _core.types.identifier("_"));
437 }
438 if (isStatic && !isMethod) {
439 const getCall = this.get(member);
440 if (!noUninitializedPrivateFieldAccess || !_core.types.isCallExpression(getCall)) {
441 return getCall;
442 }
443 const ref = getCall.arguments.pop();
444 getCall.arguments.push(_core.template.expression.ast`(_) => ${ref} = _`);
445 return _core.types.memberExpression(_core.types.callExpression(file.addHelper("toSetter"), [getCall]), _core.types.identifier("_"));
446 }
447 const setCall = this.set(member, _core.types.identifier("_"));
448 if (!_core.types.isCallExpression(setCall) || !_core.types.isIdentifier(setCall.arguments[setCall.arguments.length - 1], {
449 name: "_"
450 })) {
451 throw member.buildCodeFrameError("Internal Babel error while compiling this code. This is a Babel bug. " + "Please report it at https://github.com/babel/babel/issues.");
452 }
453 let args;
454 if (_core.types.isMemberExpression(setCall.callee, {
455 computed: false
456 }) && _core.types.isIdentifier(setCall.callee.property) && setCall.callee.property.name === "call") {
457 args = [setCall.callee.object, _core.types.arrayExpression(setCall.arguments.slice(1, -1)), setCall.arguments[0]];
458 } else {
459 args = [setCall.callee, _core.types.arrayExpression(setCall.arguments.slice(0, -1))];
460 }
461 return _core.types.memberExpression(_core.types.callExpression(file.addHelper("toSetter"), args), _core.types.identifier("_"));
462 },
463 call(member, args) {
464 this.memoise(member, 1);
465 return (0, _helperOptimiseCallExpression.default)(this.get(member), this.receiver(member), args, false);
466 },
467 optionalCall(member, args) {
468 this.memoise(member, 1);
469 return (0, _helperOptimiseCallExpression.default)(this.get(member), this.receiver(member), args, true);
470 },
471 delete() {
472 throw new Error("Internal Babel error: deleting private elements is a parsing error.");
473 }
474};
475const privateNameHandlerLoose = {
476 get(member) {
477 const {
478 privateNamesMap,
479 file
480 } = this;
481 const {
482 object
483 } = member.node;
484 const {
485 name
486 } = member.node.property.id;
487 return _core.template.expression`BASE(REF, PROP)[PROP]`({
488 BASE: file.addHelper("classPrivateFieldLooseBase"),
489 REF: _core.types.cloneNode(object),
490 PROP: _core.types.cloneNode(privateNamesMap.get(name).id)
491 });
492 },
493 set() {
494 throw new Error("private name handler with loose = true don't need set()");
495 },
496 boundGet(member) {
497 return _core.types.callExpression(_core.types.memberExpression(this.get(member), _core.types.identifier("bind")), [_core.types.cloneNode(member.node.object)]);
498 },
499 simpleSet(member) {
500 return this.get(member);
501 },
502 destructureSet(member) {
503 return this.get(member);
504 },
505 call(member, args) {
506 return _core.types.callExpression(this.get(member), args);
507 },
508 optionalCall(member, args) {
509 return _core.types.optionalCallExpression(this.get(member), args, true);
510 },
511 delete() {
512 throw new Error("Internal Babel error: deleting private elements is a parsing error.");
513 }
514};
515function transformPrivateNamesUsage(ref, path, privateNamesMap, {
516 privateFieldsAsProperties,
517 noUninitializedPrivateFieldAccess,
518 noDocumentAll,
519 innerBinding
520}, state) {
521 if (!privateNamesMap.size) return;
522 const body = path.get("body");
523 const handler = privateFieldsAsProperties ? privateNameHandlerLoose : privateNameHandlerSpec;
524 (0, _helperMemberExpressionToFunctions.default)(body, privateNameVisitor, Object.assign({
525 privateNamesMap,
526 classRef: ref,
527 file: state
528 }, handler, {
529 noDocumentAll,
530 noUninitializedPrivateFieldAccess,
531 innerBinding
532 }));
533 body.traverse(privateInVisitor, {
534 privateNamesMap,
535 classRef: ref,
536 file: state,
537 privateFieldsAsProperties,
538 innerBinding
539 });
540}
541function buildPrivateFieldInitLoose(ref, prop, privateNamesMap) {
542 const {
543 id
544 } = privateNamesMap.get(prop.node.key.id.name);
545 const value = prop.node.value || prop.scope.buildUndefinedNode();
546 return inheritPropComments(_core.template.statement.ast`
547 Object.defineProperty(${ref}, ${_core.types.cloneNode(id)}, {
548 // configurable is false by default
549 // enumerable is false by default
550 writable: true,
551 value: ${value}
552 });
553 `, prop);
554}
555function buildPrivateInstanceFieldInitSpec(ref, prop, privateNamesMap, state) {
556 const {
557 id
558 } = privateNamesMap.get(prop.node.key.id.name);
559 const value = prop.node.value || prop.scope.buildUndefinedNode();
560 {
561 if (!state.availableHelper("classPrivateFieldInitSpec")) {
562 return inheritPropComments(_core.template.statement.ast`${_core.types.cloneNode(id)}.set(${ref}, {
563 // configurable is always false for private elements
564 // enumerable is always false for private elements
565 writable: true,
566 value: ${value},
567 })`, prop);
568 }
569 }
570 const helper = state.addHelper("classPrivateFieldInitSpec");
571 return inheritLoc(inheritPropComments(_core.types.expressionStatement(_core.types.callExpression(helper, [_core.types.thisExpression(), inheritLoc(_core.types.cloneNode(id), prop.node.key), newHelpers(state) ? value : _core.template.expression.ast`{ writable: true, value: ${value} }`])), prop), prop.node);
572}
573function buildPrivateStaticFieldInitSpec(prop, privateNamesMap, noUninitializedPrivateFieldAccess) {
574 const privateName = privateNamesMap.get(prop.node.key.id.name);
575 const value = noUninitializedPrivateFieldAccess ? prop.node.value : _core.template.expression.ast`{
576 _: ${prop.node.value || _core.types.buildUndefinedNode()}
577 }`;
578 return inheritPropComments(_core.types.variableDeclaration("var", [_core.types.variableDeclarator(_core.types.cloneNode(privateName.id), value)]), prop);
579}
580{
581 var buildPrivateStaticFieldInitSpecOld = function (prop, privateNamesMap) {
582 const privateName = privateNamesMap.get(prop.node.key.id.name);
583 const {
584 id,
585 getId,
586 setId,
587 initAdded
588 } = privateName;
589 const isGetterOrSetter = getId || setId;
590 if (!prop.isProperty() && (initAdded || !isGetterOrSetter)) return;
591 if (isGetterOrSetter) {
592 privateNamesMap.set(prop.node.key.id.name, Object.assign({}, privateName, {
593 initAdded: true
594 }));
595 return inheritPropComments(_core.template.statement.ast`
596 var ${_core.types.cloneNode(id)} = {
597 // configurable is false by default
598 // enumerable is false by default
599 // writable is false by default
600 get: ${getId ? getId.name : prop.scope.buildUndefinedNode()},
601 set: ${setId ? setId.name : prop.scope.buildUndefinedNode()}
602 }
603 `, prop);
604 }
605 const value = prop.node.value || prop.scope.buildUndefinedNode();
606 return inheritPropComments(_core.template.statement.ast`
607 var ${_core.types.cloneNode(id)} = {
608 // configurable is false by default
609 // enumerable is false by default
610 writable: true,
611 value: ${value}
612 };
613 `, prop);
614 };
615}
616function buildPrivateMethodInitLoose(ref, prop, privateNamesMap) {
617 const privateName = privateNamesMap.get(prop.node.key.id.name);
618 const {
619 methodId,
620 id,
621 getId,
622 setId,
623 initAdded
624 } = privateName;
625 if (initAdded) return;
626 if (methodId) {
627 return inheritPropComments(_core.template.statement.ast`
628 Object.defineProperty(${ref}, ${id}, {
629 // configurable is false by default
630 // enumerable is false by default
631 // writable is false by default
632 value: ${methodId.name}
633 });
634 `, prop);
635 }
636 const isGetterOrSetter = getId || setId;
637 if (isGetterOrSetter) {
638 privateNamesMap.set(prop.node.key.id.name, Object.assign({}, privateName, {
639 initAdded: true
640 }));
641 return inheritPropComments(_core.template.statement.ast`
642 Object.defineProperty(${ref}, ${id}, {
643 // configurable is false by default
644 // enumerable is false by default
645 // writable is false by default
646 get: ${getId ? getId.name : prop.scope.buildUndefinedNode()},
647 set: ${setId ? setId.name : prop.scope.buildUndefinedNode()}
648 });
649 `, prop);
650 }
651}
652function buildPrivateInstanceMethodInitSpec(ref, prop, privateNamesMap, state) {
653 const privateName = privateNamesMap.get(prop.node.key.id.name);
654 if (privateName.initAdded) return;
655 if (!newHelpers(state)) {
656 const isGetterOrSetter = privateName.getId || privateName.setId;
657 if (isGetterOrSetter) {
658 return buildPrivateAccessorInitialization(ref, prop, privateNamesMap, state);
659 }
660 }
661 return buildPrivateInstanceMethodInitialization(ref, prop, privateNamesMap, state);
662}
663function buildPrivateAccessorInitialization(ref, prop, privateNamesMap, state) {
664 const privateName = privateNamesMap.get(prop.node.key.id.name);
665 const {
666 id,
667 getId,
668 setId
669 } = privateName;
670 privateNamesMap.set(prop.node.key.id.name, Object.assign({}, privateName, {
671 initAdded: true
672 }));
673 {
674 if (!state.availableHelper("classPrivateFieldInitSpec")) {
675 return inheritPropComments(_core.template.statement.ast`
676 ${id}.set(${ref}, {
677 get: ${getId ? getId.name : prop.scope.buildUndefinedNode()},
678 set: ${setId ? setId.name : prop.scope.buildUndefinedNode()}
679 });
680 `, prop);
681 }
682 }
683 const helper = state.addHelper("classPrivateFieldInitSpec");
684 return inheritLoc(inheritPropComments(_core.template.statement.ast`${helper}(
685 ${_core.types.thisExpression()},
686 ${_core.types.cloneNode(id)},
687 {
688 get: ${getId ? getId.name : prop.scope.buildUndefinedNode()},
689 set: ${setId ? setId.name : prop.scope.buildUndefinedNode()}
690 },
691 )`, prop), prop.node);
692}
693function buildPrivateInstanceMethodInitialization(ref, prop, privateNamesMap, state) {
694 const privateName = privateNamesMap.get(prop.node.key.id.name);
695 const {
696 id
697 } = privateName;
698 {
699 if (!state.availableHelper("classPrivateMethodInitSpec")) {
700 return inheritPropComments(_core.template.statement.ast`${id}.add(${ref})`, prop);
701 }
702 }
703 const helper = state.addHelper("classPrivateMethodInitSpec");
704 return inheritPropComments(_core.template.statement.ast`${helper}(
705 ${_core.types.thisExpression()},
706 ${_core.types.cloneNode(id)}
707 )`, prop);
708}
709function buildPublicFieldInitLoose(ref, prop) {
710 const {
711 key,
712 computed
713 } = prop.node;
714 const value = prop.node.value || prop.scope.buildUndefinedNode();
715 return inheritPropComments(_core.types.expressionStatement(_core.types.assignmentExpression("=", _core.types.memberExpression(ref, key, computed || _core.types.isLiteral(key)), value)), prop);
716}
717function buildPublicFieldInitSpec(ref, prop, state) {
718 const {
719 key,
720 computed
721 } = prop.node;
722 const value = prop.node.value || prop.scope.buildUndefinedNode();
723 return inheritPropComments(_core.types.expressionStatement(_core.types.callExpression(state.addHelper("defineProperty"), [ref, computed || _core.types.isLiteral(key) ? key : _core.types.stringLiteral(key.name), value])), prop);
724}
725function buildPrivateStaticMethodInitLoose(ref, prop, state, privateNamesMap) {
726 const privateName = privateNamesMap.get(prop.node.key.id.name);
727 const {
728 id,
729 methodId,
730 getId,
731 setId,
732 initAdded
733 } = privateName;
734 if (initAdded) return;
735 const isGetterOrSetter = getId || setId;
736 if (isGetterOrSetter) {
737 privateNamesMap.set(prop.node.key.id.name, Object.assign({}, privateName, {
738 initAdded: true
739 }));
740 return inheritPropComments(_core.template.statement.ast`
741 Object.defineProperty(${ref}, ${id}, {
742 // configurable is false by default
743 // enumerable is false by default
744 // writable is false by default
745 get: ${getId ? getId.name : prop.scope.buildUndefinedNode()},
746 set: ${setId ? setId.name : prop.scope.buildUndefinedNode()}
747 })
748 `, prop);
749 }
750 return inheritPropComments(_core.template.statement.ast`
751 Object.defineProperty(${ref}, ${id}, {
752 // configurable is false by default
753 // enumerable is false by default
754 // writable is false by default
755 value: ${methodId.name}
756 });
757 `, prop);
758}
759function buildPrivateMethodDeclaration(file, prop, privateNamesMap, privateFieldsAsSymbolsOrProperties = false) {
760 const privateName = privateNamesMap.get(prop.node.key.id.name);
761 const {
762 id,
763 methodId,
764 getId,
765 setId,
766 getterDeclared,
767 setterDeclared,
768 static: isStatic
769 } = privateName;
770 const {
771 params,
772 body,
773 generator,
774 async
775 } = prop.node;
776 const isGetter = getId && params.length === 0;
777 const isSetter = setId && params.length > 0;
778 if (isGetter && getterDeclared || isSetter && setterDeclared) {
779 privateNamesMap.set(prop.node.key.id.name, Object.assign({}, privateName, {
780 initAdded: true
781 }));
782 return null;
783 }
784 if (newHelpers(file) && (isGetter || isSetter) && !privateFieldsAsSymbolsOrProperties) {
785 const scope = prop.get("body").scope;
786 const thisArg = scope.generateUidIdentifier("this");
787 const state = {
788 thisRef: thisArg,
789 argumentsPath: []
790 };
791 prop.traverse(thisContextVisitor, state);
792 if (state.argumentsPath.length) {
793 const argumentsId = scope.generateUidIdentifier("arguments");
794 scope.push({
795 id: argumentsId,
796 init: _core.template.expression.ast`[].slice.call(arguments, 1)`
797 });
798 for (const path of state.argumentsPath) {
799 path.replaceWith(_core.types.cloneNode(argumentsId));
800 }
801 }
802 params.unshift(_core.types.cloneNode(thisArg));
803 }
804 let declId = methodId;
805 if (isGetter) {
806 privateNamesMap.set(prop.node.key.id.name, Object.assign({}, privateName, {
807 getterDeclared: true,
808 initAdded: true
809 }));
810 declId = getId;
811 } else if (isSetter) {
812 privateNamesMap.set(prop.node.key.id.name, Object.assign({}, privateName, {
813 setterDeclared: true,
814 initAdded: true
815 }));
816 declId = setId;
817 } else if (isStatic && !privateFieldsAsSymbolsOrProperties) {
818 declId = id;
819 }
820 return inheritPropComments(_core.types.functionDeclaration(_core.types.cloneNode(declId), params, body, generator, async), prop);
821}
822const thisContextVisitor = _traverse.visitors.environmentVisitor({
823 Identifier(path, state) {
824 if (state.argumentsPath && path.node.name === "arguments") {
825 state.argumentsPath.push(path);
826 }
827 },
828 UnaryExpression(path) {
829 const {
830 node
831 } = path;
832 if (node.operator === "delete") {
833 const argument = (0, _helperSkipTransparentExpressionWrappers.skipTransparentExprWrapperNodes)(node.argument);
834 if (_core.types.isThisExpression(argument)) {
835 path.replaceWith(_core.types.booleanLiteral(true));
836 }
837 }
838 },
839 ThisExpression(path, state) {
840 state.needsClassRef = true;
841 path.replaceWith(_core.types.cloneNode(state.thisRef));
842 },
843 MetaProperty(path) {
844 const {
845 node,
846 scope
847 } = path;
848 if (node.meta.name === "new" && node.property.name === "target") {
849 path.replaceWith(scope.buildUndefinedNode());
850 }
851 }
852});
853const innerReferencesVisitor = {
854 ReferencedIdentifier(path, state) {
855 if (path.scope.bindingIdentifierEquals(path.node.name, state.innerBinding)) {
856 state.needsClassRef = true;
857 path.node.name = state.thisRef.name;
858 }
859 }
860};
861function replaceThisContext(path, ref, innerBindingRef) {
862 var _state$thisRef;
863 const state = {
864 thisRef: ref,
865 needsClassRef: false,
866 innerBinding: innerBindingRef
867 };
868 if (!path.isMethod()) {
869 path.traverse(thisContextVisitor, state);
870 }
871 if (innerBindingRef != null && (_state$thisRef = state.thisRef) != null && _state$thisRef.name && state.thisRef.name !== innerBindingRef.name) {
872 path.traverse(innerReferencesVisitor, state);
873 }
874 return state.needsClassRef;
875}
876function isNameOrLength({
877 key,
878 computed
879}) {
880 if (key.type === "Identifier") {
881 return !computed && (key.name === "name" || key.name === "length");
882 }
883 if (key.type === "StringLiteral") {
884 return key.value === "name" || key.value === "length";
885 }
886 return false;
887}
888function inheritPropComments(node, prop) {
889 _core.types.inheritLeadingComments(node, prop.node);
890 _core.types.inheritInnerComments(node, prop.node);
891 return node;
892}
893function inheritLoc(node, original) {
894 node.start = original.start;
895 node.end = original.end;
896 node.loc = original.loc;
897 return node;
898}
899function buildFieldsInitNodes(ref, superRef, props, privateNamesMap, file, setPublicClassFields, privateFieldsAsSymbolsOrProperties, noUninitializedPrivateFieldAccess, constantSuper, innerBindingRef) {
900 var _ref, _ref2;
901 let classRefFlags = 0;
902 let injectSuperRef;
903 const staticNodes = [];
904 const instanceNodes = [];
905 let lastInstanceNodeReturnsThis = false;
906 const pureStaticNodes = [];
907 let classBindingNode = null;
908 const getSuperRef = _core.types.isIdentifier(superRef) ? () => superRef : () => {
909 var _injectSuperRef;
910 (_injectSuperRef = injectSuperRef) != null ? _injectSuperRef : injectSuperRef = props[0].scope.generateUidIdentifierBasedOnNode(superRef);
911 return injectSuperRef;
912 };
913 const classRefForInnerBinding = (_ref = ref) != null ? _ref : props[0].scope.generateUidIdentifier((innerBindingRef == null ? void 0 : innerBindingRef.name) || "Class");
914 (_ref2 = ref) != null ? _ref2 : ref = _core.types.cloneNode(innerBindingRef);
915 for (const prop of props) {
916 if (prop.isClassProperty()) {
917 ts.assertFieldTransformed(prop);
918 }
919 const isStatic = !(_core.types.isStaticBlock != null && _core.types.isStaticBlock(prop.node)) && prop.node.static;
920 const isInstance = !isStatic;
921 const isPrivate = prop.isPrivate();
922 const isPublic = !isPrivate;
923 const isField = prop.isProperty();
924 const isMethod = !isField;
925 const isStaticBlock = prop.isStaticBlock == null ? void 0 : prop.isStaticBlock();
926 if (isStatic) classRefFlags |= 1;
927 if (isStatic || isMethod && isPrivate || isStaticBlock) {
928 new _helperReplaceSupers.default({
929 methodPath: prop,
930 constantSuper,
931 file: file,
932 refToPreserve: innerBindingRef,
933 getSuperRef,
934 getObjectRef() {
935 classRefFlags |= 2;
936 if (isStatic || isStaticBlock) {
937 return classRefForInnerBinding;
938 } else {
939 return _core.types.memberExpression(classRefForInnerBinding, _core.types.identifier("prototype"));
940 }
941 }
942 }).replace();
943 const replaced = replaceThisContext(prop, classRefForInnerBinding, innerBindingRef);
944 if (replaced) {
945 classRefFlags |= 2;
946 }
947 }
948 lastInstanceNodeReturnsThis = false;
949 switch (true) {
950 case isStaticBlock:
951 {
952 const blockBody = prop.node.body;
953 if (blockBody.length === 1 && _core.types.isExpressionStatement(blockBody[0])) {
954 staticNodes.push(inheritPropComments(blockBody[0], prop));
955 } else {
956 staticNodes.push(_core.types.inheritsComments(_core.template.statement.ast`(() => { ${blockBody} })()`, prop.node));
957 }
958 break;
959 }
960 case isStatic && isPrivate && isField && privateFieldsAsSymbolsOrProperties:
961 staticNodes.push(buildPrivateFieldInitLoose(_core.types.cloneNode(ref), prop, privateNamesMap));
962 break;
963 case isStatic && isPrivate && isField && !privateFieldsAsSymbolsOrProperties:
964 if (!newHelpers(file)) {
965 staticNodes.push(buildPrivateStaticFieldInitSpecOld(prop, privateNamesMap));
966 } else {
967 staticNodes.push(buildPrivateStaticFieldInitSpec(prop, privateNamesMap, noUninitializedPrivateFieldAccess));
968 }
969 break;
970 case isStatic && isPublic && isField && setPublicClassFields:
971 if (!isNameOrLength(prop.node)) {
972 staticNodes.push(buildPublicFieldInitLoose(_core.types.cloneNode(ref), prop));
973 break;
974 }
975 case isStatic && isPublic && isField && !setPublicClassFields:
976 staticNodes.push(buildPublicFieldInitSpec(_core.types.cloneNode(ref), prop, file));
977 break;
978 case isInstance && isPrivate && isField && privateFieldsAsSymbolsOrProperties:
979 instanceNodes.push(buildPrivateFieldInitLoose(_core.types.thisExpression(), prop, privateNamesMap));
980 break;
981 case isInstance && isPrivate && isField && !privateFieldsAsSymbolsOrProperties:
982 instanceNodes.push(buildPrivateInstanceFieldInitSpec(_core.types.thisExpression(), prop, privateNamesMap, file));
983 break;
984 case isInstance && isPrivate && isMethod && privateFieldsAsSymbolsOrProperties:
985 instanceNodes.unshift(buildPrivateMethodInitLoose(_core.types.thisExpression(), prop, privateNamesMap));
986 pureStaticNodes.push(buildPrivateMethodDeclaration(file, prop, privateNamesMap, privateFieldsAsSymbolsOrProperties));
987 break;
988 case isInstance && isPrivate && isMethod && !privateFieldsAsSymbolsOrProperties:
989 instanceNodes.unshift(buildPrivateInstanceMethodInitSpec(_core.types.thisExpression(), prop, privateNamesMap, file));
990 pureStaticNodes.push(buildPrivateMethodDeclaration(file, prop, privateNamesMap, privateFieldsAsSymbolsOrProperties));
991 break;
992 case isStatic && isPrivate && isMethod && !privateFieldsAsSymbolsOrProperties:
993 if (!newHelpers(file)) {
994 staticNodes.unshift(buildPrivateStaticFieldInitSpecOld(prop, privateNamesMap));
995 }
996 pureStaticNodes.push(buildPrivateMethodDeclaration(file, prop, privateNamesMap, privateFieldsAsSymbolsOrProperties));
997 break;
998 case isStatic && isPrivate && isMethod && privateFieldsAsSymbolsOrProperties:
999 staticNodes.unshift(buildPrivateStaticMethodInitLoose(_core.types.cloneNode(ref), prop, file, privateNamesMap));
1000 pureStaticNodes.push(buildPrivateMethodDeclaration(file, prop, privateNamesMap, privateFieldsAsSymbolsOrProperties));
1001 break;
1002 case isInstance && isPublic && isField && setPublicClassFields:
1003 instanceNodes.push(buildPublicFieldInitLoose(_core.types.thisExpression(), prop));
1004 break;
1005 case isInstance && isPublic && isField && !setPublicClassFields:
1006 lastInstanceNodeReturnsThis = true;
1007 instanceNodes.push(buildPublicFieldInitSpec(_core.types.thisExpression(), prop, file));
1008 break;
1009 default:
1010 throw new Error("Unreachable.");
1011 }
1012 }
1013 if (classRefFlags & 2 && innerBindingRef != null) {
1014 classBindingNode = _core.types.expressionStatement(_core.types.assignmentExpression("=", _core.types.cloneNode(classRefForInnerBinding), _core.types.cloneNode(innerBindingRef)));
1015 }
1016 return {
1017 staticNodes: staticNodes.filter(Boolean),
1018 instanceNodes: instanceNodes.filter(Boolean),
1019 lastInstanceNodeReturnsThis,
1020 pureStaticNodes: pureStaticNodes.filter(Boolean),
1021 classBindingNode,
1022 wrapClass(path) {
1023 for (const prop of props) {
1024 prop.node.leadingComments = null;
1025 prop.remove();
1026 }
1027 if (injectSuperRef) {
1028 path.scope.push({
1029 id: _core.types.cloneNode(injectSuperRef)
1030 });
1031 path.set("superClass", _core.types.assignmentExpression("=", injectSuperRef, path.node.superClass));
1032 }
1033 if (classRefFlags !== 0) {
1034 if (path.isClassExpression()) {
1035 path.scope.push({
1036 id: ref
1037 });
1038 path.replaceWith(_core.types.assignmentExpression("=", _core.types.cloneNode(ref), path.node));
1039 } else {
1040 if (innerBindingRef == null) {
1041 path.node.id = ref;
1042 }
1043 if (classBindingNode != null) {
1044 path.scope.push({
1045 id: classRefForInnerBinding
1046 });
1047 }
1048 }
1049 }
1050 return path;
1051 }
1052 };
1053}
1054
1055//# sourceMappingURL=fields.js.map