1 | "use strict";
|
2 |
|
3 | Object.defineProperty(exports, "__esModule", {
|
4 | value: true
|
5 | });
|
6 | exports.default = _default;
|
7 | var _core = require("@babel/core");
|
8 | var _pluginSyntaxDecorators = require("@babel/plugin-syntax-decorators");
|
9 | var _helperReplaceSupers = require("@babel/helper-replace-supers");
|
10 | var _helperSplitExportDeclaration = require("@babel/helper-split-export-declaration");
|
11 | function incrementId(id, idx = id.length - 1) {
|
12 | if (idx === -1) {
|
13 | id.unshift(65);
|
14 | return;
|
15 | }
|
16 | const current = id[idx];
|
17 | if (current === 90) {
|
18 | id[idx] = 97;
|
19 | } else if (current === 122) {
|
20 | id[idx] = 65;
|
21 | incrementId(id, idx - 1);
|
22 | } else {
|
23 | id[idx] = current + 1;
|
24 | }
|
25 | }
|
26 | function createPrivateUidGeneratorForClass(classPath) {
|
27 | const currentPrivateId = [];
|
28 | const privateNames = new Set();
|
29 | classPath.traverse({
|
30 | PrivateName(path) {
|
31 | privateNames.add(path.node.id.name);
|
32 | }
|
33 | });
|
34 | return () => {
|
35 | let reifiedId;
|
36 | do {
|
37 | incrementId(currentPrivateId);
|
38 | reifiedId = String.fromCharCode(...currentPrivateId);
|
39 | } while (privateNames.has(reifiedId));
|
40 | return _core.types.privateName(_core.types.identifier(reifiedId));
|
41 | };
|
42 | }
|
43 | function createLazyPrivateUidGeneratorForClass(classPath) {
|
44 | let generator;
|
45 | return () => {
|
46 | if (!generator) {
|
47 | generator = createPrivateUidGeneratorForClass(classPath);
|
48 | }
|
49 | return generator();
|
50 | };
|
51 | }
|
52 | function replaceClassWithVar(path) {
|
53 | if (path.type === "ClassDeclaration") {
|
54 | const varId = path.scope.generateUidIdentifierBasedOnNode(path.node.id);
|
55 | const classId = _core.types.identifier(path.node.id.name);
|
56 | path.scope.rename(classId.name, varId.name);
|
57 | path.insertBefore(_core.types.variableDeclaration("let", [_core.types.variableDeclarator(varId)]));
|
58 | path.get("id").replaceWith(classId);
|
59 | return [_core.types.cloneNode(varId), path];
|
60 | } else {
|
61 | let className;
|
62 | let varId;
|
63 | if (path.node.id) {
|
64 | className = path.node.id.name;
|
65 | varId = path.scope.parent.generateDeclaredUidIdentifier(className);
|
66 | path.scope.rename(className, varId.name);
|
67 | } else if (path.parentPath.node.type === "VariableDeclarator" && path.parentPath.node.id.type === "Identifier") {
|
68 | className = path.parentPath.node.id.name;
|
69 | varId = path.scope.parent.generateDeclaredUidIdentifier(className);
|
70 | } else {
|
71 | varId = path.scope.parent.generateDeclaredUidIdentifier("decorated_class");
|
72 | }
|
73 | const newClassExpr = _core.types.classExpression(className && _core.types.identifier(className), path.node.superClass, path.node.body);
|
74 | const [newPath] = path.replaceWith(_core.types.sequenceExpression([newClassExpr, varId]));
|
75 | return [_core.types.cloneNode(varId), newPath.get("expressions.0")];
|
76 | }
|
77 | }
|
78 | function generateClassProperty(key, value, isStatic) {
|
79 | if (key.type === "PrivateName") {
|
80 | return _core.types.classPrivateProperty(key, value, undefined, isStatic);
|
81 | } else {
|
82 | return _core.types.classProperty(key, value, undefined, undefined, isStatic);
|
83 | }
|
84 | }
|
85 | function addProxyAccessorsFor(className, element, originalKey, targetKey, version, isComputed = false) {
|
86 | const {
|
87 | static: isStatic
|
88 | } = element.node;
|
89 | const thisArg = version === "2023-05" && isStatic ? className : _core.types.thisExpression();
|
90 | const getterBody = _core.types.blockStatement([_core.types.returnStatement(_core.types.memberExpression(_core.types.cloneNode(thisArg), _core.types.cloneNode(targetKey)))]);
|
91 | const setterBody = _core.types.blockStatement([_core.types.expressionStatement(_core.types.assignmentExpression("=", _core.types.memberExpression(_core.types.cloneNode(thisArg), _core.types.cloneNode(targetKey)), _core.types.identifier("v")))]);
|
92 | let getter, setter;
|
93 | if (originalKey.type === "PrivateName") {
|
94 | getter = _core.types.classPrivateMethod("get", _core.types.cloneNode(originalKey), [], getterBody, isStatic);
|
95 | setter = _core.types.classPrivateMethod("set", _core.types.cloneNode(originalKey), [_core.types.identifier("v")], setterBody, isStatic);
|
96 | } else {
|
97 | getter = _core.types.classMethod("get", _core.types.cloneNode(originalKey), [], getterBody, isComputed, isStatic);
|
98 | setter = _core.types.classMethod("set", _core.types.cloneNode(originalKey), [_core.types.identifier("v")], setterBody, isComputed, isStatic);
|
99 | }
|
100 | element.insertAfter(setter);
|
101 | element.insertAfter(getter);
|
102 | }
|
103 | function extractProxyAccessorsFor(targetKey, version) {
|
104 | if (version !== "2023-05" && version !== "2023-01") {
|
105 | return [_core.template.expression.ast`
|
106 | function () {
|
107 | return this.${_core.types.cloneNode(targetKey)};
|
108 | }
|
109 | `, _core.template.expression.ast`
|
110 | function (value) {
|
111 | this.${_core.types.cloneNode(targetKey)} = value;
|
112 | }
|
113 | `];
|
114 | }
|
115 | return [_core.template.expression.ast`
|
116 | o => o.${_core.types.cloneNode(targetKey)}
|
117 | `, _core.template.expression.ast`
|
118 | (o, v) => o.${_core.types.cloneNode(targetKey)} = v
|
119 | `];
|
120 | }
|
121 | const FIELD = 0;
|
122 | const ACCESSOR = 1;
|
123 | const METHOD = 2;
|
124 | const GETTER = 3;
|
125 | const SETTER = 4;
|
126 | const STATIC_OLD_VERSION = 5;
|
127 | const STATIC = 8;
|
128 | const DECORATORS_HAVE_THIS = 16;
|
129 | function getElementKind(element) {
|
130 | switch (element.node.type) {
|
131 | case "ClassProperty":
|
132 | case "ClassPrivateProperty":
|
133 | return FIELD;
|
134 | case "ClassAccessorProperty":
|
135 | return ACCESSOR;
|
136 | case "ClassMethod":
|
137 | case "ClassPrivateMethod":
|
138 | if (element.node.kind === "get") {
|
139 | return GETTER;
|
140 | } else if (element.node.kind === "set") {
|
141 | return SETTER;
|
142 | } else {
|
143 | return METHOD;
|
144 | }
|
145 | }
|
146 | }
|
147 | function isDecoratorInfo(info) {
|
148 | return "decorators" in info;
|
149 | }
|
150 | function filteredOrderedDecoratorInfo(info) {
|
151 | const filtered = info.filter(isDecoratorInfo);
|
152 | return [...filtered.filter(el => el.isStatic && el.kind >= ACCESSOR && el.kind <= SETTER), ...filtered.filter(el => !el.isStatic && el.kind >= ACCESSOR && el.kind <= SETTER), ...filtered.filter(el => el.isStatic && el.kind === FIELD), ...filtered.filter(el => !el.isStatic && el.kind === FIELD)];
|
153 | }
|
154 | function generateDecorationList(decorators, decoratorsThis, version) {
|
155 | const decsCount = decorators.length;
|
156 | const hasOneThis = decoratorsThis.some(Boolean);
|
157 | const decs = [];
|
158 | for (let i = 0; i < decsCount; i++) {
|
159 | if (version === "2023-05" && hasOneThis) {
|
160 | decs.push(decoratorsThis[i] || _core.types.unaryExpression("void", _core.types.numericLiteral(0)));
|
161 | }
|
162 | decs.push(decorators[i]);
|
163 | }
|
164 | return {
|
165 | hasThis: hasOneThis,
|
166 | decs
|
167 | };
|
168 | }
|
169 | function generateDecorationExprs(info, version) {
|
170 | return _core.types.arrayExpression(filteredOrderedDecoratorInfo(info).map(el => {
|
171 | const {
|
172 | decs,
|
173 | hasThis
|
174 | } = generateDecorationList(el.decorators, el.decoratorsThis, version);
|
175 | let flag = el.kind;
|
176 | if (el.isStatic) {
|
177 | flag += version === "2023-05" ? STATIC : STATIC_OLD_VERSION;
|
178 | }
|
179 | if (hasThis) flag += DECORATORS_HAVE_THIS;
|
180 | return _core.types.arrayExpression([decs.length === 1 ? decs[0] : _core.types.arrayExpression(decs), _core.types.numericLiteral(flag), el.name, ...(el.privateMethods || [])]);
|
181 | }));
|
182 | }
|
183 | function extractElementLocalAssignments(decorationInfo) {
|
184 | const localIds = [];
|
185 | for (const el of filteredOrderedDecoratorInfo(decorationInfo)) {
|
186 | const {
|
187 | locals
|
188 | } = el;
|
189 | if (Array.isArray(locals)) {
|
190 | localIds.push(...locals);
|
191 | } else if (locals !== undefined) {
|
192 | localIds.push(locals);
|
193 | }
|
194 | }
|
195 | return localIds;
|
196 | }
|
197 | function addCallAccessorsFor(element, key, getId, setId) {
|
198 | element.insertAfter(_core.types.classPrivateMethod("get", _core.types.cloneNode(key), [], _core.types.blockStatement([_core.types.returnStatement(_core.types.callExpression(_core.types.cloneNode(getId), [_core.types.thisExpression()]))])));
|
199 | element.insertAfter(_core.types.classPrivateMethod("set", _core.types.cloneNode(key), [_core.types.identifier("v")], _core.types.blockStatement([_core.types.expressionStatement(_core.types.callExpression(_core.types.cloneNode(setId), [_core.types.thisExpression(), _core.types.identifier("v")]))])));
|
200 | }
|
201 | function isNotTsParameter(node) {
|
202 | return node.type !== "TSParameterProperty";
|
203 | }
|
204 | function movePrivateAccessor(element, key, methodLocalVar, isStatic) {
|
205 | let params;
|
206 | let block;
|
207 | if (element.node.kind === "set") {
|
208 | params = [_core.types.identifier("v")];
|
209 | block = [_core.types.expressionStatement(_core.types.callExpression(methodLocalVar, [_core.types.thisExpression(), _core.types.identifier("v")]))];
|
210 | } else {
|
211 | params = [];
|
212 | block = [_core.types.returnStatement(_core.types.callExpression(methodLocalVar, [_core.types.thisExpression()]))];
|
213 | }
|
214 | element.replaceWith(_core.types.classPrivateMethod(element.node.kind, _core.types.cloneNode(key), params, _core.types.blockStatement(block), isStatic));
|
215 | }
|
216 | function isClassDecoratableElementPath(path) {
|
217 | const {
|
218 | type
|
219 | } = path;
|
220 | return type !== "TSDeclareMethod" && type !== "TSIndexSignature" && type !== "StaticBlock";
|
221 | }
|
222 | function staticBlockToIIFE(block) {
|
223 | return _core.types.callExpression(_core.types.arrowFunctionExpression([], _core.types.blockStatement(block.body)), []);
|
224 | }
|
225 | function maybeSequenceExpression(exprs) {
|
226 | if (exprs.length === 0) return _core.types.unaryExpression("void", _core.types.numericLiteral(0));
|
227 | if (exprs.length === 1) return exprs[0];
|
228 | return _core.types.sequenceExpression(exprs);
|
229 | }
|
230 | function transformClass(path, state, constantSuper, version) {
|
231 | const body = path.get("body.body");
|
232 | const classDecorators = path.node.decorators;
|
233 | let hasElementDecorators = false;
|
234 | const generateClassPrivateUid = createLazyPrivateUidGeneratorForClass(path);
|
235 | for (const element of body) {
|
236 | if (!isClassDecoratableElementPath(element)) {
|
237 | continue;
|
238 | }
|
239 | if (element.node.decorators && element.node.decorators.length > 0) {
|
240 | hasElementDecorators = true;
|
241 | } else if (element.node.type === "ClassAccessorProperty") {
|
242 | const {
|
243 | key,
|
244 | value,
|
245 | static: isStatic,
|
246 | computed
|
247 | } = element.node;
|
248 | const newId = generateClassPrivateUid();
|
249 | const valueNode = value ? _core.types.cloneNode(value) : undefined;
|
250 | const newField = generateClassProperty(newId, valueNode, isStatic);
|
251 | const [newPath] = element.replaceWith(newField);
|
252 | addProxyAccessorsFor(path.node.id, newPath, key, newId, version, computed);
|
253 | }
|
254 | }
|
255 | if (!classDecorators && !hasElementDecorators) return;
|
256 | const elementDecoratorInfo = [];
|
257 | let firstFieldPath;
|
258 | let constructorPath;
|
259 | let requiresProtoInit = false;
|
260 | let requiresStaticInit = false;
|
261 | const decoratedPrivateMethods = new Set();
|
262 | let protoInitLocal, staticInitLocal, classInitLocal, classIdLocal;
|
263 | const assignments = [];
|
264 | const scopeParent = path.scope.parent;
|
265 | const memoiseExpression = (expression, hint) => {
|
266 | const localEvaluatedId = scopeParent.generateDeclaredUidIdentifier(hint);
|
267 | assignments.push(_core.types.assignmentExpression("=", localEvaluatedId, expression));
|
268 | return _core.types.cloneNode(localEvaluatedId);
|
269 | };
|
270 | const decoratorsThis = new Map();
|
271 | const maybeExtractDecorator = decorator => {
|
272 | const {
|
273 | expression
|
274 | } = decorator;
|
275 | if (version === "2023-05" && _core.types.isMemberExpression(expression)) {
|
276 | let object;
|
277 | if (_core.types.isSuper(expression.object) || _core.types.isThisExpression(expression.object)) {
|
278 | object = memoiseExpression(_core.types.thisExpression(), "obj");
|
279 | } else if (!scopeParent.isStatic(expression.object)) {
|
280 | object = memoiseExpression(expression.object, "obj");
|
281 | expression.object = object;
|
282 | } else {
|
283 | object = expression.object;
|
284 | }
|
285 | decoratorsThis.set(decorator, _core.types.cloneNode(object));
|
286 | }
|
287 | if (!scopeParent.isStatic(expression)) {
|
288 | decorator.expression = memoiseExpression(expression, "dec");
|
289 | }
|
290 | };
|
291 | if (classDecorators) {
|
292 | classInitLocal = scopeParent.generateDeclaredUidIdentifier("initClass");
|
293 | const [classId, classPath] = replaceClassWithVar(path);
|
294 | path = classPath;
|
295 | classIdLocal = classId;
|
296 | path.node.decorators = null;
|
297 | for (const classDecorator of classDecorators) {
|
298 | maybeExtractDecorator(classDecorator);
|
299 | }
|
300 | } else {
|
301 | if (!path.node.id) {
|
302 | path.node.id = path.scope.generateUidIdentifier("Class");
|
303 | }
|
304 | classIdLocal = _core.types.cloneNode(path.node.id);
|
305 | }
|
306 | let lastInstancePrivateName;
|
307 | let needsInstancePrivateBrandCheck = false;
|
308 | if (hasElementDecorators) {
|
309 | for (const element of body) {
|
310 | if (!isClassDecoratableElementPath(element)) {
|
311 | continue;
|
312 | }
|
313 | const {
|
314 | node
|
315 | } = element;
|
316 | const decorators = element.get("decorators");
|
317 | const hasDecorators = Array.isArray(decorators) && decorators.length > 0;
|
318 | if (hasDecorators) {
|
319 | for (const decoratorPath of decorators) {
|
320 | maybeExtractDecorator(decoratorPath.node);
|
321 | }
|
322 | }
|
323 | const isComputed = "computed" in element.node && element.node.computed === true;
|
324 | if (isComputed) {
|
325 | if (!scopeParent.isStatic(node.key)) {
|
326 | node.key = memoiseExpression(node.key, "computedKey");
|
327 | }
|
328 | }
|
329 | const kind = getElementKind(element);
|
330 | const {
|
331 | key
|
332 | } = node;
|
333 | const isPrivate = key.type === "PrivateName";
|
334 | const isStatic = !!element.node.static;
|
335 | let name = "computedKey";
|
336 | if (isPrivate) {
|
337 | name = key.id.name;
|
338 | } else if (!isComputed && key.type === "Identifier") {
|
339 | name = key.name;
|
340 | }
|
341 | if (isPrivate && !isStatic) {
|
342 | if (hasDecorators) {
|
343 | needsInstancePrivateBrandCheck = true;
|
344 | }
|
345 | if (_core.types.isClassPrivateProperty(node) || !lastInstancePrivateName) {
|
346 | lastInstancePrivateName = key;
|
347 | }
|
348 | }
|
349 | if (element.isClassMethod({
|
350 | kind: "constructor"
|
351 | })) {
|
352 | constructorPath = element;
|
353 | }
|
354 | if (hasDecorators) {
|
355 | let locals;
|
356 | let privateMethods;
|
357 | if (kind === ACCESSOR) {
|
358 | const {
|
359 | value
|
360 | } = element.node;
|
361 | const params = [_core.types.thisExpression()];
|
362 | if (value) {
|
363 | params.push(_core.types.cloneNode(value));
|
364 | }
|
365 | const newId = generateClassPrivateUid();
|
366 | const newFieldInitId = element.scope.parent.generateDeclaredUidIdentifier(`init_${name}`);
|
367 | const newValue = _core.types.callExpression(_core.types.cloneNode(newFieldInitId), params);
|
368 | const newField = generateClassProperty(newId, newValue, isStatic);
|
369 | const [newPath] = element.replaceWith(newField);
|
370 | if (isPrivate) {
|
371 | privateMethods = extractProxyAccessorsFor(newId, version);
|
372 | const getId = newPath.scope.parent.generateDeclaredUidIdentifier(`get_${name}`);
|
373 | const setId = newPath.scope.parent.generateDeclaredUidIdentifier(`set_${name}`);
|
374 | addCallAccessorsFor(newPath, key, getId, setId);
|
375 | locals = [newFieldInitId, getId, setId];
|
376 | } else {
|
377 | addProxyAccessorsFor(path.node.id, newPath, key, newId, version, isComputed);
|
378 | locals = newFieldInitId;
|
379 | }
|
380 | } else if (kind === FIELD) {
|
381 | const initId = element.scope.parent.generateDeclaredUidIdentifier(`init_${name}`);
|
382 | const valuePath = element.get("value");
|
383 | valuePath.replaceWith(_core.types.callExpression(_core.types.cloneNode(initId), [_core.types.thisExpression(), valuePath.node].filter(v => v)));
|
384 | locals = initId;
|
385 | if (isPrivate) {
|
386 | privateMethods = extractProxyAccessorsFor(key, version);
|
387 | }
|
388 | } else if (isPrivate) {
|
389 | locals = element.scope.parent.generateDeclaredUidIdentifier(`call_${name}`);
|
390 | const replaceSupers = new _helperReplaceSupers.default({
|
391 | constantSuper,
|
392 | methodPath: element,
|
393 | objectRef: classIdLocal,
|
394 | superRef: path.node.superClass,
|
395 | file: state.file,
|
396 | refToPreserve: classIdLocal
|
397 | });
|
398 | replaceSupers.replace();
|
399 | const {
|
400 | params,
|
401 | body,
|
402 | async: isAsync
|
403 | } = element.node;
|
404 | privateMethods = [_core.types.functionExpression(undefined, params.filter(isNotTsParameter), body, isAsync)];
|
405 | if (kind === GETTER || kind === SETTER) {
|
406 | movePrivateAccessor(element, _core.types.cloneNode(key), _core.types.cloneNode(locals), isStatic);
|
407 | } else {
|
408 | const node = element.node;
|
409 | path.node.body.body.unshift(_core.types.classPrivateProperty(key, _core.types.cloneNode(locals), [], node.static));
|
410 | decoratedPrivateMethods.add(key.id.name);
|
411 | element.remove();
|
412 | }
|
413 | }
|
414 | let nameExpr;
|
415 | if (isComputed) {
|
416 | nameExpr = _core.types.cloneNode(key);
|
417 | } else if (key.type === "PrivateName") {
|
418 | nameExpr = _core.types.stringLiteral(key.id.name);
|
419 | } else if (key.type === "Identifier") {
|
420 | nameExpr = _core.types.stringLiteral(key.name);
|
421 | } else {
|
422 | nameExpr = _core.types.cloneNode(key);
|
423 | }
|
424 | elementDecoratorInfo.push({
|
425 | kind,
|
426 | decorators: decorators.map(d => d.node.expression),
|
427 | decoratorsThis: decorators.map(d => decoratorsThis.get(d.node)),
|
428 | name: nameExpr,
|
429 | isStatic,
|
430 | privateMethods,
|
431 | locals
|
432 | });
|
433 | if (kind !== FIELD) {
|
434 | if (isStatic) {
|
435 | requiresStaticInit = true;
|
436 | } else {
|
437 | requiresProtoInit = true;
|
438 | }
|
439 | }
|
440 | if (element.node) {
|
441 | element.node.decorators = null;
|
442 | }
|
443 | if (!firstFieldPath && !isStatic && (kind === FIELD || kind === ACCESSOR)) {
|
444 | firstFieldPath = element;
|
445 | }
|
446 | }
|
447 | }
|
448 | }
|
449 | const elementDecorations = generateDecorationExprs(elementDecoratorInfo, version);
|
450 | let classDecorationsFlag = 0;
|
451 | let classDecorations = [];
|
452 | if (classDecorators) {
|
453 | const {
|
454 | hasThis,
|
455 | decs
|
456 | } = generateDecorationList(classDecorators.map(el => el.expression), classDecorators.map(dec => decoratorsThis.get(dec)), version);
|
457 | classDecorationsFlag = hasThis ? 1 : 0;
|
458 | classDecorations = decs;
|
459 | }
|
460 | const elementLocals = extractElementLocalAssignments(elementDecoratorInfo);
|
461 | if (requiresProtoInit) {
|
462 | protoInitLocal = scopeParent.generateDeclaredUidIdentifier("initProto");
|
463 | elementLocals.push(protoInitLocal);
|
464 | const protoInitCall = _core.types.callExpression(_core.types.cloneNode(protoInitLocal), [_core.types.thisExpression()]);
|
465 | if (firstFieldPath) {
|
466 | const value = firstFieldPath.get("value");
|
467 | const body = [protoInitCall];
|
468 | if (value.node) {
|
469 | body.push(value.node);
|
470 | }
|
471 | value.replaceWith(_core.types.sequenceExpression(body));
|
472 | } else if (constructorPath) {
|
473 | if (path.node.superClass) {
|
474 | path.traverse({
|
475 | CallExpression: {
|
476 | exit(path) {
|
477 | if (!path.get("callee").isSuper()) return;
|
478 | path.replaceWith(_core.types.callExpression(_core.types.cloneNode(protoInitLocal), [path.node]));
|
479 | path.skip();
|
480 | }
|
481 | }
|
482 | });
|
483 | } else {
|
484 | constructorPath.node.body.body.unshift(_core.types.expressionStatement(protoInitCall));
|
485 | }
|
486 | } else {
|
487 | const body = [_core.types.expressionStatement(protoInitCall)];
|
488 | if (path.node.superClass) {
|
489 | body.unshift(_core.types.expressionStatement(_core.types.callExpression(_core.types.super(), [_core.types.spreadElement(_core.types.identifier("args"))])));
|
490 | }
|
491 | path.node.body.body.unshift(_core.types.classMethod("constructor", _core.types.identifier("constructor"), [_core.types.restElement(_core.types.identifier("args"))], _core.types.blockStatement(body)));
|
492 | }
|
493 | }
|
494 | if (requiresStaticInit) {
|
495 | staticInitLocal = scopeParent.generateDeclaredUidIdentifier("initStatic");
|
496 | elementLocals.push(staticInitLocal);
|
497 | }
|
498 | if (decoratedPrivateMethods.size > 0) {
|
499 | path.traverse({
|
500 | PrivateName(path) {
|
501 | if (!decoratedPrivateMethods.has(path.node.id.name)) return;
|
502 | const parentPath = path.parentPath;
|
503 | const parentParentPath = parentPath.parentPath;
|
504 | if (parentParentPath.node.type === "AssignmentExpression" && parentParentPath.node.left === parentPath.node || parentParentPath.node.type === "UpdateExpression" || parentParentPath.node.type === "RestElement" || parentParentPath.node.type === "ArrayPattern" || parentParentPath.node.type === "ObjectProperty" && parentParentPath.node.value === parentPath.node && parentParentPath.parentPath.type === "ObjectPattern" || parentParentPath.node.type === "ForOfStatement" && parentParentPath.node.left === parentPath.node) {
|
505 | throw path.buildCodeFrameError(`Decorated private methods are not updatable, but "#${path.node.id.name}" is updated via this expression.`);
|
506 | }
|
507 | }
|
508 | });
|
509 | }
|
510 | const classLocals = [];
|
511 | let classInitInjected = false;
|
512 | const classInitCall = classInitLocal && _core.types.callExpression(_core.types.cloneNode(classInitLocal), []);
|
513 | const originalClass = path.node;
|
514 | if (classDecorators) {
|
515 | classLocals.push(classIdLocal, classInitLocal);
|
516 | const statics = [];
|
517 | let staticBlocks = [];
|
518 | path.get("body.body").forEach(element => {
|
519 | if (element.isStaticBlock()) {
|
520 | staticBlocks.push(element.node);
|
521 | element.remove();
|
522 | return;
|
523 | }
|
524 | const isProperty = element.isClassProperty() || element.isClassPrivateProperty();
|
525 | if ((isProperty || element.isClassPrivateMethod()) && element.node.static) {
|
526 | if (isProperty && staticBlocks.length > 0) {
|
527 | const allValues = staticBlocks.map(staticBlockToIIFE);
|
528 | if (element.node.value) allValues.push(element.node.value);
|
529 | element.node.value = maybeSequenceExpression(allValues);
|
530 | staticBlocks = [];
|
531 | }
|
532 | element.node.static = false;
|
533 | statics.push(element.node);
|
534 | element.remove();
|
535 | }
|
536 | });
|
537 | if (statics.length > 0 || staticBlocks.length > 0) {
|
538 | const staticsClass = _core.template.expression.ast`
|
539 | class extends ${state.addHelper("identity")} {}
|
540 | `;
|
541 | staticsClass.body.body = [_core.types.staticBlock([_core.types.toStatement(originalClass, true) || _core.types.expressionStatement(originalClass)]), ...statics];
|
542 | const constructorBody = [];
|
543 | const newExpr = _core.types.newExpression(staticsClass, []);
|
544 | if (staticBlocks.length > 0) {
|
545 | constructorBody.push(...staticBlocks.map(staticBlockToIIFE));
|
546 | }
|
547 | if (classInitCall) {
|
548 | classInitInjected = true;
|
549 | constructorBody.push(classInitCall);
|
550 | }
|
551 | if (constructorBody.length > 0) {
|
552 | constructorBody.unshift(_core.types.callExpression(_core.types.super(), [_core.types.cloneNode(classIdLocal)]));
|
553 | staticsClass.body.body.push(_core.types.classMethod("constructor", _core.types.identifier("constructor"), [], _core.types.blockStatement([_core.types.expressionStatement(_core.types.sequenceExpression(constructorBody))])));
|
554 | } else {
|
555 | newExpr.arguments.push(_core.types.cloneNode(classIdLocal));
|
556 | }
|
557 | path.replaceWith(newExpr);
|
558 | }
|
559 | }
|
560 | if (!classInitInjected && classInitCall) {
|
561 | path.node.body.body.push(_core.types.staticBlock([_core.types.expressionStatement(classInitCall)]));
|
562 | }
|
563 | originalClass.body.body.unshift(_core.types.staticBlock([_core.types.expressionStatement(createLocalsAssignment(elementLocals, classLocals, elementDecorations, _core.types.arrayExpression(classDecorations), _core.types.numericLiteral(classDecorationsFlag), needsInstancePrivateBrandCheck ? lastInstancePrivateName : null, state, version)), requiresStaticInit && _core.types.expressionStatement(_core.types.callExpression(_core.types.cloneNode(staticInitLocal), [_core.types.thisExpression()]))].filter(Boolean)));
|
564 | path.insertBefore(assignments.map(expr => _core.types.expressionStatement(expr)));
|
565 | path.scope.crawl();
|
566 | return path;
|
567 | }
|
568 | function createLocalsAssignment(elementLocals, classLocals, elementDecorations, classDecorations, classDecorationsFlag, maybePrivateBranName, state, version) {
|
569 | let lhs, rhs;
|
570 | const args = [_core.types.thisExpression(), elementDecorations, classDecorations];
|
571 | if (version === "2021-12" || version === "2022-03" && !state.availableHelper("applyDecs2203R")) {
|
572 | lhs = _core.types.arrayPattern([...elementLocals, ...classLocals]);
|
573 | rhs = _core.types.callExpression(state.addHelper(version === "2021-12" ? "applyDecs" : "applyDecs2203"), args);
|
574 | } else {
|
575 | if (version === "2023-05") {
|
576 | if (maybePrivateBranName || classDecorationsFlag.value !== 0) {
|
577 | args.push(classDecorationsFlag);
|
578 | }
|
579 | if (maybePrivateBranName) {
|
580 | args.push(_core.template.expression.ast`
|
581 | _ => ${_core.types.cloneNode(maybePrivateBranName)} in _
|
582 | `);
|
583 | }
|
584 | rhs = _core.types.callExpression(state.addHelper("applyDecs2305"), args);
|
585 | } else if (version === "2023-01") {
|
586 | if (maybePrivateBranName) {
|
587 | args.push(_core.template.expression.ast`
|
588 | _ => ${_core.types.cloneNode(maybePrivateBranName)} in _
|
589 | `);
|
590 | }
|
591 | rhs = _core.types.callExpression(state.addHelper("applyDecs2301"), args);
|
592 | } else {
|
593 | rhs = _core.types.callExpression(state.addHelper("applyDecs2203R"), args);
|
594 | }
|
595 | if (elementLocals.length > 0) {
|
596 | if (classLocals.length > 0) {
|
597 | lhs = _core.types.objectPattern([_core.types.objectProperty(_core.types.identifier("e"), _core.types.arrayPattern(elementLocals)), _core.types.objectProperty(_core.types.identifier("c"), _core.types.arrayPattern(classLocals))]);
|
598 | } else {
|
599 | lhs = _core.types.arrayPattern(elementLocals);
|
600 | rhs = _core.types.memberExpression(rhs, _core.types.identifier("e"), false, false);
|
601 | }
|
602 | } else {
|
603 | lhs = _core.types.arrayPattern(classLocals);
|
604 | rhs = _core.types.memberExpression(rhs, _core.types.identifier("c"), false, false);
|
605 | }
|
606 | }
|
607 | return _core.types.assignmentExpression("=", lhs, rhs);
|
608 | }
|
609 | function _default({
|
610 | assertVersion,
|
611 | assumption
|
612 | }, {
|
613 | loose
|
614 | }, version) {
|
615 | var _assumption;
|
616 | if (version === "2023-05" || version === "2023-01") {
|
617 | assertVersion("^7.21.0");
|
618 | } else if (version === "2021-12") {
|
619 | assertVersion("^7.16.0");
|
620 | } else {
|
621 | assertVersion("^7.19.0");
|
622 | }
|
623 | const VISITED = new WeakSet();
|
624 | const constantSuper = (_assumption = assumption("constantSuper")) != null ? _assumption : loose;
|
625 | return {
|
626 | name: "proposal-decorators",
|
627 | inherits: _pluginSyntaxDecorators.default,
|
628 | visitor: {
|
629 | "ExportNamedDeclaration|ExportDefaultDeclaration"(path) {
|
630 | var _declaration$decorato;
|
631 | const {
|
632 | declaration
|
633 | } = path.node;
|
634 | if ((declaration == null ? void 0 : declaration.type) === "ClassDeclaration" && ((_declaration$decorato = declaration.decorators) == null ? void 0 : _declaration$decorato.length) > 0) {
|
635 | (0, _helperSplitExportDeclaration.default)(path);
|
636 | }
|
637 | },
|
638 | Class(path, state) {
|
639 | if (VISITED.has(path)) return;
|
640 | const newPath = transformClass(path, state, constantSuper, version);
|
641 | if (newPath) VISITED.add(newPath);
|
642 | }
|
643 | }
|
644 | };
|
645 | }
|
646 |
|
647 |
|