UNPKG

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