1 | "use strict";
|
2 |
|
3 | Object.defineProperty(exports, "__esModule", {
|
4 | value: true
|
5 | });
|
6 | exports.default = void 0;
|
7 |
|
8 | var _core = require("@babel/core");
|
9 |
|
10 | const buildClassDecorator = (0, _core.template)(`
|
11 | DECORATOR(CLASS_REF = INNER) || CLASS_REF;
|
12 | `);
|
13 | const buildClassPrototype = (0, _core.template)(`
|
14 | CLASS_REF.prototype;
|
15 | `);
|
16 | const buildGetDescriptor = (0, _core.template)(`
|
17 | Object.getOwnPropertyDescriptor(TARGET, PROPERTY);
|
18 | `);
|
19 | const buildGetObjectInitializer = (0, _core.template)(`
|
20 | (TEMP = Object.getOwnPropertyDescriptor(TARGET, PROPERTY), (TEMP = TEMP ? TEMP.value : undefined), {
|
21 | enumerable: true,
|
22 | configurable: true,
|
23 | writable: true,
|
24 | initializer: function(){
|
25 | return TEMP;
|
26 | }
|
27 | })
|
28 | `);
|
29 | const WARNING_CALLS = new WeakSet();
|
30 |
|
31 | function applyEnsureOrdering(path) {
|
32 | const decorators = (path.isClass() ? [path].concat(path.get("body.body")) : path.get("properties")).reduce((acc, prop) => acc.concat(prop.node.decorators || []), []);
|
33 | const identDecorators = decorators.filter(decorator => !_core.types.isIdentifier(decorator.expression));
|
34 | if (identDecorators.length === 0) return;
|
35 | return _core.types.sequenceExpression(identDecorators.map(decorator => {
|
36 | const expression = decorator.expression;
|
37 | const id = decorator.expression = path.scope.generateDeclaredUidIdentifier("dec");
|
38 | return _core.types.assignmentExpression("=", id, expression);
|
39 | }).concat([path.node]));
|
40 | }
|
41 |
|
42 | function applyClassDecorators(classPath) {
|
43 | if (!hasClassDecorators(classPath.node)) return;
|
44 | const decorators = classPath.node.decorators || [];
|
45 | classPath.node.decorators = null;
|
46 | const name = classPath.scope.generateDeclaredUidIdentifier("class");
|
47 | return decorators.map(dec => dec.expression).reverse().reduce(function (acc, decorator) {
|
48 | return buildClassDecorator({
|
49 | CLASS_REF: _core.types.cloneNode(name),
|
50 | DECORATOR: _core.types.cloneNode(decorator),
|
51 | INNER: acc
|
52 | }).expression;
|
53 | }, classPath.node);
|
54 | }
|
55 |
|
56 | function hasClassDecorators(classNode) {
|
57 | return !!(classNode.decorators && classNode.decorators.length);
|
58 | }
|
59 |
|
60 | function applyMethodDecorators(path, state) {
|
61 | if (!hasMethodDecorators(path.node.body.body)) return;
|
62 | return applyTargetDecorators(path, state, path.node.body.body);
|
63 | }
|
64 |
|
65 | function hasMethodDecorators(body) {
|
66 | return body.some(node => {
|
67 | var _node$decorators;
|
68 |
|
69 | return (_node$decorators = node.decorators) == null ? void 0 : _node$decorators.length;
|
70 | });
|
71 | }
|
72 |
|
73 | function applyObjectDecorators(path, state) {
|
74 | if (!hasMethodDecorators(path.node.properties)) return;
|
75 | return applyTargetDecorators(path, state, path.node.properties);
|
76 | }
|
77 |
|
78 | function applyTargetDecorators(path, state, decoratedProps) {
|
79 | const name = path.scope.generateDeclaredUidIdentifier(path.isClass() ? "class" : "obj");
|
80 | const exprs = decoratedProps.reduce(function (acc, node) {
|
81 | const decorators = node.decorators || [];
|
82 | node.decorators = null;
|
83 | if (decorators.length === 0) return acc;
|
84 |
|
85 | if (node.computed) {
|
86 | throw path.buildCodeFrameError("Computed method/property decorators are not yet supported.");
|
87 | }
|
88 |
|
89 | const property = _core.types.isLiteral(node.key) ? node.key : _core.types.stringLiteral(node.key.name);
|
90 | const target = path.isClass() && !node.static ? buildClassPrototype({
|
91 | CLASS_REF: name
|
92 | }).expression : name;
|
93 |
|
94 | if (_core.types.isClassProperty(node, {
|
95 | static: false
|
96 | })) {
|
97 | const descriptor = path.scope.generateDeclaredUidIdentifier("descriptor");
|
98 | const initializer = node.value ? _core.types.functionExpression(null, [], _core.types.blockStatement([_core.types.returnStatement(node.value)])) : _core.types.nullLiteral();
|
99 | node.value = _core.types.callExpression(state.addHelper("initializerWarningHelper"), [descriptor, _core.types.thisExpression()]);
|
100 | WARNING_CALLS.add(node.value);
|
101 | acc = acc.concat([_core.types.assignmentExpression("=", descriptor, _core.types.callExpression(state.addHelper("applyDecoratedDescriptor"), [_core.types.cloneNode(target), _core.types.cloneNode(property), _core.types.arrayExpression(decorators.map(dec => _core.types.cloneNode(dec.expression))), _core.types.objectExpression([_core.types.objectProperty(_core.types.identifier("configurable"), _core.types.booleanLiteral(true)), _core.types.objectProperty(_core.types.identifier("enumerable"), _core.types.booleanLiteral(true)), _core.types.objectProperty(_core.types.identifier("writable"), _core.types.booleanLiteral(true)), _core.types.objectProperty(_core.types.identifier("initializer"), initializer)])]))]);
|
102 | } else {
|
103 | acc = acc.concat(_core.types.callExpression(state.addHelper("applyDecoratedDescriptor"), [_core.types.cloneNode(target), _core.types.cloneNode(property), _core.types.arrayExpression(decorators.map(dec => _core.types.cloneNode(dec.expression))), _core.types.isObjectProperty(node) || _core.types.isClassProperty(node, {
|
104 | static: true
|
105 | }) ? buildGetObjectInitializer({
|
106 | TEMP: path.scope.generateDeclaredUidIdentifier("init"),
|
107 | TARGET: _core.types.cloneNode(target),
|
108 | PROPERTY: _core.types.cloneNode(property)
|
109 | }).expression : buildGetDescriptor({
|
110 | TARGET: _core.types.cloneNode(target),
|
111 | PROPERTY: _core.types.cloneNode(property)
|
112 | }).expression, _core.types.cloneNode(target)]));
|
113 | }
|
114 |
|
115 | return acc;
|
116 | }, []);
|
117 | return _core.types.sequenceExpression([_core.types.assignmentExpression("=", _core.types.cloneNode(name), path.node), _core.types.sequenceExpression(exprs), _core.types.cloneNode(name)]);
|
118 | }
|
119 |
|
120 | function decoratedClassToExpression({
|
121 | node,
|
122 | scope
|
123 | }) {
|
124 | if (!hasClassDecorators(node) && !hasMethodDecorators(node.body.body)) {
|
125 | return;
|
126 | }
|
127 |
|
128 | const ref = node.id ? _core.types.cloneNode(node.id) : scope.generateUidIdentifier("class");
|
129 | return _core.types.variableDeclaration("let", [_core.types.variableDeclarator(ref, _core.types.toExpression(node))]);
|
130 | }
|
131 |
|
132 | var _default = {
|
133 | ExportDefaultDeclaration(path) {
|
134 | const decl = path.get("declaration");
|
135 | if (!decl.isClassDeclaration()) return;
|
136 | const replacement = decoratedClassToExpression(decl);
|
137 |
|
138 | if (replacement) {
|
139 | const [varDeclPath] = path.replaceWithMultiple([replacement, _core.types.exportNamedDeclaration(null, [_core.types.exportSpecifier(_core.types.cloneNode(replacement.declarations[0].id), _core.types.identifier("default"))])]);
|
140 |
|
141 | if (!decl.node.id) {
|
142 | path.scope.registerDeclaration(varDeclPath);
|
143 | }
|
144 | }
|
145 | },
|
146 |
|
147 | ClassDeclaration(path) {
|
148 | const replacement = decoratedClassToExpression(path);
|
149 |
|
150 | if (replacement) {
|
151 | path.replaceWith(replacement);
|
152 | }
|
153 | },
|
154 |
|
155 | ClassExpression(path, state) {
|
156 | const decoratedClass = applyEnsureOrdering(path) || applyClassDecorators(path, state) || applyMethodDecorators(path, state);
|
157 | if (decoratedClass) path.replaceWith(decoratedClass);
|
158 | },
|
159 |
|
160 | ObjectExpression(path, state) {
|
161 | const decoratedObject = applyEnsureOrdering(path) || applyObjectDecorators(path, state);
|
162 | if (decoratedObject) path.replaceWith(decoratedObject);
|
163 | },
|
164 |
|
165 | AssignmentExpression(path, state) {
|
166 | if (!WARNING_CALLS.has(path.node.right)) return;
|
167 | path.replaceWith(_core.types.callExpression(state.addHelper("initializerDefineProperty"), [_core.types.cloneNode(path.get("left.object").node), _core.types.stringLiteral(path.get("left.property").node.name || path.get("left.property").node.value), _core.types.cloneNode(path.get("right.arguments")[0].node), _core.types.cloneNode(path.get("right.arguments")[1].node)]));
|
168 | },
|
169 |
|
170 | CallExpression(path, state) {
|
171 | if (path.node.arguments.length !== 3) return;
|
172 | if (!WARNING_CALLS.has(path.node.arguments[2])) return;
|
173 |
|
174 | if (path.node.callee.name !== state.addHelper("defineProperty").name) {
|
175 | return;
|
176 | }
|
177 |
|
178 | path.replaceWith(_core.types.callExpression(state.addHelper("initializerDefineProperty"), [_core.types.cloneNode(path.get("arguments")[0].node), _core.types.cloneNode(path.get("arguments")[1].node), _core.types.cloneNode(path.get("arguments.2.arguments")[0].node), _core.types.cloneNode(path.get("arguments.2.arguments")[1].node)]));
|
179 | }
|
180 |
|
181 | };
|
182 | exports.default = _default; |
\ | No newline at end of file |