1 | "use strict";
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 | var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
10 | if (k2 === undefined) k2 = k;
|
11 | Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
12 | }) : (function(o, m, k, k2) {
|
13 | if (k2 === undefined) k2 = k;
|
14 | o[k2] = m[k];
|
15 | }));
|
16 | var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
17 | Object.defineProperty(o, "default", { enumerable: true, value: v });
|
18 | }) : function(o, v) {
|
19 | o["default"] = v;
|
20 | });
|
21 | var __importStar = (this && this.__importStar) || function (mod) {
|
22 | if (mod && mod.__esModule) return mod;
|
23 | var result = {};
|
24 | if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
25 | __setModuleDefault(result, mod);
|
26 | return result;
|
27 | };
|
28 | Object.defineProperty(exports, "__esModule", { value: true });
|
29 | exports.getWrapEnumsTransformer = void 0;
|
30 | const ts = __importStar(require("typescript"));
|
31 | const ast_utils_1 = require("../helpers/ast-utils");
|
32 | function isBlockLike(node) {
|
33 | return (node.kind === ts.SyntaxKind.Block ||
|
34 | node.kind === ts.SyntaxKind.ModuleBlock ||
|
35 | node.kind === ts.SyntaxKind.CaseClause ||
|
36 | node.kind === ts.SyntaxKind.DefaultClause ||
|
37 | node.kind === ts.SyntaxKind.SourceFile);
|
38 | }
|
39 | function getWrapEnumsTransformer() {
|
40 | return (context) => {
|
41 | const transformer = (sf) => {
|
42 | const result = visitBlockStatements(sf.statements, context);
|
43 | return context.factory.updateSourceFile(sf, ts.setTextRange(result, sf.statements));
|
44 | };
|
45 | return transformer;
|
46 | };
|
47 | }
|
48 | exports.getWrapEnumsTransformer = getWrapEnumsTransformer;
|
49 | function visitBlockStatements(statements, context) {
|
50 |
|
51 | let updatedStatements;
|
52 | const nodeFactory = context.factory;
|
53 | const visitor = (node) => {
|
54 | if (isBlockLike(node)) {
|
55 | let result = visitBlockStatements(node.statements, context);
|
56 | if (result === node.statements) {
|
57 | return node;
|
58 | }
|
59 | result = ts.setTextRange(result, node.statements);
|
60 | switch (node.kind) {
|
61 | case ts.SyntaxKind.Block:
|
62 | return nodeFactory.updateBlock(node, result);
|
63 | case ts.SyntaxKind.ModuleBlock:
|
64 | return nodeFactory.updateModuleBlock(node, result);
|
65 | case ts.SyntaxKind.CaseClause:
|
66 | return nodeFactory.updateCaseClause(node, node.expression, result);
|
67 | case ts.SyntaxKind.DefaultClause:
|
68 | return nodeFactory.updateDefaultClause(node, result);
|
69 | default:
|
70 | return node;
|
71 | }
|
72 | }
|
73 | else {
|
74 | return node;
|
75 | }
|
76 | };
|
77 |
|
78 | for (let oIndex = 0, uIndex = 0; oIndex < statements.length - 1; oIndex++, uIndex++) {
|
79 | const currentStatement = statements[oIndex];
|
80 | let newStatement;
|
81 | let oldStatementsLength = 0;
|
82 |
|
83 | if (currentStatement.kind === ts.SyntaxKind.ImportDeclaration) {
|
84 | continue;
|
85 | }
|
86 |
|
87 |
|
88 |
|
89 |
|
90 |
|
91 |
|
92 |
|
93 |
|
94 |
|
95 |
|
96 |
|
97 | if (ts.isVariableStatement(currentStatement) &&
|
98 | currentStatement.declarationList.declarations.length === 1) {
|
99 | const variableDeclaration = currentStatement.declarationList.declarations[0];
|
100 | const initializer = variableDeclaration.initializer;
|
101 | if (ts.isIdentifier(variableDeclaration.name)) {
|
102 | const name = variableDeclaration.name.text;
|
103 | if (!initializer) {
|
104 | const iife = findEnumIife(name, statements[oIndex + 1]);
|
105 | if (iife) {
|
106 |
|
107 | oldStatementsLength = 2;
|
108 | newStatement = updateEnumIife(nodeFactory, currentStatement, iife[0], iife[1]);
|
109 |
|
110 | oIndex++;
|
111 | }
|
112 | }
|
113 | else if (ts.isClassExpression(initializer) ||
|
114 | (ts.isBinaryExpression(initializer) && ts.isClassExpression(initializer.right))) {
|
115 | const classStatements = findStatements(name, statements, oIndex);
|
116 | if (!classStatements) {
|
117 | continue;
|
118 | }
|
119 | oldStatementsLength = classStatements.length;
|
120 | newStatement = createWrappedClass(nodeFactory, variableDeclaration, classStatements);
|
121 | oIndex += classStatements.length - 1;
|
122 | }
|
123 | }
|
124 | }
|
125 | else if (ts.isClassDeclaration(currentStatement)) {
|
126 | const name = currentStatement.name.text;
|
127 | const classStatements = findStatements(name, statements, oIndex);
|
128 | if (!classStatements) {
|
129 | continue;
|
130 | }
|
131 | oldStatementsLength = classStatements.length;
|
132 | newStatement = createWrappedClass(nodeFactory, currentStatement, classStatements);
|
133 | oIndex += oldStatementsLength - 1;
|
134 | }
|
135 | if (newStatement && newStatement.length > 0) {
|
136 | if (!updatedStatements) {
|
137 | updatedStatements = [...statements];
|
138 | }
|
139 | updatedStatements.splice(uIndex, oldStatementsLength, ...newStatement);
|
140 |
|
141 |
|
142 | uIndex += newStatement ? newStatement.length - 1 : 0;
|
143 | }
|
144 | const result = ts.visitNode(currentStatement, visitor);
|
145 | if (result !== currentStatement) {
|
146 | if (!updatedStatements) {
|
147 | updatedStatements = statements.slice();
|
148 | }
|
149 | updatedStatements[uIndex] = result;
|
150 | }
|
151 | }
|
152 |
|
153 |
|
154 | return updatedStatements ? nodeFactory.createNodeArray(updatedStatements) : statements;
|
155 | }
|
156 |
|
157 | function findEnumIife(name, statement) {
|
158 | if (!ts.isExpressionStatement(statement)) {
|
159 | return null;
|
160 | }
|
161 | const expression = statement.expression;
|
162 | if (!expression || !ts.isCallExpression(expression) || expression.arguments.length !== 1) {
|
163 | return null;
|
164 | }
|
165 | const callExpression = expression;
|
166 | let exportExpression;
|
167 | if (!ts.isParenthesizedExpression(callExpression.expression)) {
|
168 | return null;
|
169 | }
|
170 | const functionExpression = callExpression.expression.expression;
|
171 | if (!ts.isFunctionExpression(functionExpression)) {
|
172 | return null;
|
173 | }
|
174 |
|
175 |
|
176 | const parameter = functionExpression.parameters[0];
|
177 | if (!ts.isIdentifier(parameter.name)) {
|
178 | return null;
|
179 | }
|
180 | const parameterName = parameter.name.text;
|
181 | let argument = callExpression.arguments[0];
|
182 | if (!ts.isBinaryExpression(argument) ||
|
183 | !ts.isIdentifier(argument.left) ||
|
184 | argument.left.text !== name) {
|
185 | return null;
|
186 | }
|
187 | let potentialExport = false;
|
188 | if (argument.operatorToken.kind === ts.SyntaxKind.FirstAssignment) {
|
189 | if (ts.isBinaryExpression(argument.right) &&
|
190 | argument.right.operatorToken.kind !== ts.SyntaxKind.BarBarToken) {
|
191 | return null;
|
192 | }
|
193 | potentialExport = true;
|
194 | argument = argument.right;
|
195 | }
|
196 | if (!ts.isBinaryExpression(argument)) {
|
197 | return null;
|
198 | }
|
199 | if (argument.operatorToken.kind !== ts.SyntaxKind.BarBarToken) {
|
200 | return null;
|
201 | }
|
202 | if (potentialExport && !ts.isIdentifier(argument.left)) {
|
203 | exportExpression = argument.left;
|
204 | }
|
205 |
|
206 | for (const statement of functionExpression.body.statements) {
|
207 | if (!ts.isExpressionStatement(statement) ||
|
208 | !ts.isBinaryExpression(statement.expression) ||
|
209 | !ts.isElementAccessExpression(statement.expression.left)) {
|
210 | return null;
|
211 | }
|
212 | const leftExpression = statement.expression.left.expression;
|
213 | if (!ts.isIdentifier(leftExpression) || leftExpression.text !== parameterName) {
|
214 | return null;
|
215 | }
|
216 | }
|
217 | return [callExpression, exportExpression];
|
218 | }
|
219 | function updateHostNode(nodeFactory, hostNode, expression) {
|
220 |
|
221 | const variableDeclaration = hostNode.declarationList.declarations[0];
|
222 | const outerVarStmt = nodeFactory.updateVariableStatement(hostNode, hostNode.modifiers, nodeFactory.updateVariableDeclarationList(hostNode.declarationList, [
|
223 | nodeFactory.updateVariableDeclaration(variableDeclaration, variableDeclaration.name, variableDeclaration.exclamationToken, variableDeclaration.type, expression),
|
224 | ]));
|
225 | return outerVarStmt;
|
226 | }
|
227 |
|
228 |
|
229 |
|
230 |
|
231 |
|
232 |
|
233 |
|
234 |
|
235 |
|
236 |
|
237 |
|
238 |
|
239 |
|
240 | function findStatements(name, statements, statementIndex, offset = 0) {
|
241 | let count = 1;
|
242 | for (let index = statementIndex + 1; index < statements.length; ++index) {
|
243 | const statement = statements[index];
|
244 | if (!ts.isExpressionStatement(statement)) {
|
245 | break;
|
246 | }
|
247 | const expression = statement.expression;
|
248 | if (ts.isCallExpression(expression)) {
|
249 |
|
250 |
|
251 |
|
252 |
|
253 |
|
254 | const args = expression.arguments;
|
255 | if (args.length > 2) {
|
256 | const isReferenced = args.some((arg) => {
|
257 | const potentialIdentifier = ts.isPropertyAccessExpression(arg) ? arg.expression : arg;
|
258 | return ts.isIdentifier(potentialIdentifier) && potentialIdentifier.text === name;
|
259 | });
|
260 | if (isReferenced) {
|
261 | count++;
|
262 | continue;
|
263 | }
|
264 | }
|
265 | }
|
266 | else if (ts.isBinaryExpression(expression)) {
|
267 | const node = ts.isBinaryExpression(expression.left) ? expression.left.left : expression.left;
|
268 | const leftExpression = ts.isPropertyAccessExpression(node) || ts.isElementAccessExpression(node)
|
269 | ?
|
270 |
|
271 | node.expression
|
272 | :
|
273 | node;
|
274 | if (ts.isIdentifier(leftExpression) && leftExpression.text === name) {
|
275 | count++;
|
276 | continue;
|
277 | }
|
278 | }
|
279 | break;
|
280 | }
|
281 | if (count > 1) {
|
282 | return statements.slice(statementIndex + offset, statementIndex + count);
|
283 | }
|
284 | return undefined;
|
285 | }
|
286 | function updateEnumIife(nodeFactory, hostNode, iife, exportAssignment) {
|
287 | if (!ts.isParenthesizedExpression(iife.expression) ||
|
288 | !ts.isFunctionExpression(iife.expression.expression)) {
|
289 | throw new Error('Invalid IIFE Structure');
|
290 | }
|
291 |
|
292 | if (hostNode.modifiers &&
|
293 | hostNode.modifiers.findIndex((m) => m.kind == ts.SyntaxKind.ExportKeyword) != -1) {
|
294 | exportAssignment = undefined;
|
295 | }
|
296 | const expression = iife.expression.expression;
|
297 | const updatedFunction = nodeFactory.updateFunctionExpression(expression, expression.modifiers, expression.asteriskToken, expression.name, expression.typeParameters, expression.parameters, expression.type, nodeFactory.updateBlock(expression.body, [
|
298 | ...expression.body.statements,
|
299 | nodeFactory.createReturnStatement(expression.parameters[0].name),
|
300 | ]));
|
301 | let arg = nodeFactory.createObjectLiteralExpression();
|
302 | if (exportAssignment) {
|
303 | arg = nodeFactory.createBinaryExpression(exportAssignment, ts.SyntaxKind.BarBarToken, arg);
|
304 | }
|
305 | const updatedIife = nodeFactory.updateCallExpression(iife, nodeFactory.updateParenthesizedExpression(iife.expression, updatedFunction), iife.typeArguments, [arg]);
|
306 | let value = ast_utils_1.addPureComment(updatedIife);
|
307 | if (exportAssignment) {
|
308 | value = nodeFactory.createBinaryExpression(exportAssignment, ts.SyntaxKind.FirstAssignment, updatedIife);
|
309 | }
|
310 | return [updateHostNode(nodeFactory, hostNode, value)];
|
311 | }
|
312 | function createWrappedClass(nodeFactory, hostNode, statements) {
|
313 | const name = hostNode.name.text;
|
314 | const updatedStatements = [...statements];
|
315 | if (ts.isClassDeclaration(hostNode)) {
|
316 | updatedStatements[0] = nodeFactory.createClassDeclaration(hostNode.decorators, undefined, hostNode.name, hostNode.typeParameters, hostNode.heritageClauses, hostNode.members);
|
317 | }
|
318 | const pureIife = ast_utils_1.addPureComment(nodeFactory.createImmediatelyInvokedArrowFunction([
|
319 | ...updatedStatements,
|
320 | nodeFactory.createReturnStatement(nodeFactory.createIdentifier(name)),
|
321 | ]));
|
322 | const modifiers = hostNode.modifiers;
|
323 | const isDefault = !!modifiers && modifiers.some((x) => x.kind === ts.SyntaxKind.DefaultKeyword);
|
324 | const newStatement = [];
|
325 | newStatement.push(nodeFactory.createVariableStatement(isDefault ? undefined : modifiers, nodeFactory.createVariableDeclarationList([nodeFactory.createVariableDeclaration(name, undefined, undefined, pureIife)], ts.NodeFlags.Let)));
|
326 | if (isDefault) {
|
327 | newStatement.push(nodeFactory.createExportAssignment(undefined, undefined, false, nodeFactory.createIdentifier(name)));
|
328 | }
|
329 | return newStatement;
|
330 | }
|