@jay-framework/compiler 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,1918 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
4
+ var __publicField = (obj, key, value) => {
5
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
6
+ return value;
7
+ };
8
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
9
+ const ts = require("typescript");
10
+ const compilerShared = require("@jay-framework/compiler-shared");
11
+ const changeCase = require("change-case");
12
+ const path = require("node:path");
13
+ const compilerJayHtml = require("@jay-framework/compiler-jay-html");
14
+ function _interopNamespaceDefault(e) {
15
+ const n = Object.create(null, { [Symbol.toStringTag]: { value: "Module" } });
16
+ if (e) {
17
+ for (const k in e) {
18
+ if (k !== "default") {
19
+ const d = Object.getOwnPropertyDescriptor(e, k);
20
+ Object.defineProperty(n, k, d.get ? d : {
21
+ enumerable: true,
22
+ get: () => e[k]
23
+ });
24
+ }
25
+ }
26
+ }
27
+ n.default = e;
28
+ return Object.freeze(n);
29
+ }
30
+ const ts__namespace = /* @__PURE__ */ _interopNamespaceDefault(ts);
31
+ const printer = ts.createPrinter({
32
+ newLine: ts.NewLineKind.LineFeed
33
+ });
34
+ function astToCode(node) {
35
+ return printer.printNode(ts.EmitHint.Unspecified, node, void 0);
36
+ }
37
+ function codeToAst(code, context) {
38
+ let dummySourceFile = ts.createSourceFile("dummy.ts", code, ts.ScriptTarget.Latest, true);
39
+ function visitor(node) {
40
+ let updatedNode = ts.setTextRange(node, { pos: -1, end: -1 });
41
+ return ts.visitEachChild(updatedNode, visitor, context);
42
+ }
43
+ return ts.visitEachChild(dummySourceFile, visitor, context).statements;
44
+ }
45
+ function isFunctionLikeDeclarationBase(node) {
46
+ return ts.isFunctionExpression(node) || ts.isArrowFunction(node) || ts.isFunctionDeclaration(node) || ts.isMethodDeclaration(node) || ts.isConstructorDeclaration(node) || ts.isGetAccessorDeclaration(node) || ts.isSetAccessorDeclaration(node);
47
+ }
48
+ function mkTransformer(fileTransformer, config) {
49
+ return (context) => {
50
+ const { factory } = context;
51
+ return (sourceFile) => {
52
+ return fileTransformer({ factory, context, sourceFile, ...config || {} });
53
+ };
54
+ };
55
+ }
56
+ function extractImportDeclarations(sourceFile) {
57
+ const importDeclarations = [];
58
+ function visit(node) {
59
+ if (ts__namespace.isImportDeclaration(node)) {
60
+ importDeclarations.push(node);
61
+ }
62
+ ts__namespace.forEachChild(node, visit);
63
+ }
64
+ ts__namespace.forEachChild(sourceFile, visit);
65
+ return importDeclarations;
66
+ }
67
+ function extractImportedModules(sourceFile) {
68
+ return extractImportDeclarations(sourceFile).filter((node) => ts__namespace.isStringLiteral(node.moduleSpecifier)).map((node) => node.moduleSpecifier.text);
69
+ }
70
+ function isRelativeImport(module2) {
71
+ return module2.startsWith(".");
72
+ }
73
+ function getImportSpecifiers(importDeclaration) {
74
+ const namedBindings = importDeclaration.importClause?.namedBindings;
75
+ return namedBindings && ts__namespace.isNamedImports(namedBindings) ? namedBindings.elements : void 0;
76
+ }
77
+ function getImportName(importSpecifier) {
78
+ return importSpecifier.propertyName?.text ?? importSpecifier.name.text;
79
+ }
80
+ function findMakeJayComponentImport(makeJayComponentName, node) {
81
+ if (ts.isImportDeclaration(node) && ts.isStringLiteral(node.moduleSpecifier) && node.moduleSpecifier.text === compilerShared.JAY_COMPONENT) {
82
+ let importSpecifier = getImportSpecifiers(node)?.find(
83
+ (element) => getImportName(element) === makeJayComponentName
84
+ );
85
+ if (importSpecifier) {
86
+ return importSpecifier.name.text;
87
+ }
88
+ }
89
+ return void 0;
90
+ }
91
+ function findComponentConstructorsBlock(componentFunctionExpressions, sourceFile) {
92
+ const foundConstructors = [];
93
+ const namedConstructors = new Set(
94
+ componentFunctionExpressions.filter((expression) => ts.isIdentifier(expression)).map((expression) => ts.isIdentifier(expression) && expression.text)
95
+ );
96
+ const inlineConstructors = componentFunctionExpressions.filter(
97
+ isFunctionLikeDeclarationBase
98
+ );
99
+ function visit(node) {
100
+ if (ts.isFunctionDeclaration(node)) {
101
+ if (namedConstructors.has(node?.name.text))
102
+ foundConstructors.push(node);
103
+ } else if (ts.isVariableStatement(node)) {
104
+ node.declarationList.declarations.forEach((declaration) => {
105
+ if (ts.isIdentifier(declaration.name) && namedConstructors.has(declaration.name.text) && declaration.initializer && ts.isArrowFunction(declaration.initializer))
106
+ foundConstructors.push(declaration.initializer);
107
+ });
108
+ }
109
+ ts.forEachChild(node, visit);
110
+ }
111
+ ts.forEachChild(sourceFile, visit);
112
+ return [...foundConstructors, ...inlineConstructors];
113
+ }
114
+ function mkParameterVariableRoot(param, paramIndex) {
115
+ return { kind: 0, param, paramIndex };
116
+ }
117
+ function mkFunctionVariableRoot(func) {
118
+ return { kind: 1, func };
119
+ }
120
+ function mkLiteralVariableRoot(literal) {
121
+ return { kind: 2, literal };
122
+ }
123
+ function mkImportModuleVariableRoot(module2, importType) {
124
+ return { kind: 3, module: module2, importType };
125
+ }
126
+ function mkFunctionCallVariableRoot(node) {
127
+ return { kind: 4, node };
128
+ }
129
+ function mkGlobalVariableRoot(name) {
130
+ return { kind: 5, name };
131
+ }
132
+ function mkOtherVariableRoot(node) {
133
+ return { kind: 6, node };
134
+ }
135
+ function isParamVariableRoot(vr) {
136
+ return vr.kind === 0;
137
+ }
138
+ function isFunctionVariableRoot(vr) {
139
+ return vr.kind === 1;
140
+ }
141
+ function isImportModuleVariableRoot(vr) {
142
+ return vr.kind === 3;
143
+ }
144
+ function isLiteralVariableRoot(vr) {
145
+ return vr.kind === 2;
146
+ }
147
+ function isFunctionCallVariableRoot(vr) {
148
+ return vr.kind === 4;
149
+ }
150
+ function isGlobalVariableRoot(vr) {
151
+ return vr.kind === 5;
152
+ }
153
+ var LetOrConst = /* @__PURE__ */ ((LetOrConst2) => {
154
+ LetOrConst2[LetOrConst2["LET"] = 0] = "LET";
155
+ LetOrConst2[LetOrConst2["CONST"] = 1] = "CONST";
156
+ return LetOrConst2;
157
+ })(LetOrConst || {});
158
+ function mkVariable(members) {
159
+ return Object.fromEntries(Object.entries(members).filter(([, value]) => value !== void 0));
160
+ }
161
+ const UNKNOWN_VARIABLE = {};
162
+ const getAccessedByProperty = (binding, accessedFrom, propertyName) => {
163
+ return accessedFrom ? propertyName ? ts.isIdentifier(propertyName) ? propertyName.text : void 0 : binding.text : void 0;
164
+ };
165
+ function findDeclaringStatement(node) {
166
+ if (!node)
167
+ return void 0;
168
+ else if (ts.isStatement(node))
169
+ return node;
170
+ else
171
+ return findDeclaringStatement(node.parent);
172
+ }
173
+ function tsBindingNameToVariable(binding, accessedFrom, assignedFrom, propertyName, root) {
174
+ if (ts.isIdentifier(binding)) {
175
+ return [
176
+ mkVariable({
177
+ name: binding.text,
178
+ accessedFrom,
179
+ accessedByProperty: getAccessedByProperty(binding, accessedFrom, propertyName),
180
+ assignedFrom,
181
+ root,
182
+ definingStatement: findDeclaringStatement(binding)
183
+ })
184
+ ];
185
+ } else if (ts.isObjectBindingPattern(binding)) {
186
+ let variable = mkVariable({
187
+ accessedFrom,
188
+ accessedByProperty: propertyName ? ts.isIdentifier(propertyName) ? propertyName.text : void 0 : void 0,
189
+ assignedFrom,
190
+ root,
191
+ definingStatement: findDeclaringStatement(binding)
192
+ });
193
+ return binding.elements.flatMap((element) => {
194
+ return tsBindingNameToVariable(element.name, variable, void 0, element.propertyName);
195
+ });
196
+ } else if (ts.isArrayBindingPattern(binding)) {
197
+ let variable = mkVariable({
198
+ accessedFrom,
199
+ accessedByProperty: propertyName ? ts.isIdentifier(propertyName) ? propertyName.text : void 0 : void 0,
200
+ assignedFrom,
201
+ root,
202
+ definingStatement: findDeclaringStatement(binding)
203
+ });
204
+ return binding.elements.flatMap((element, index) => {
205
+ return ts.isBindingElement(element) && tsBindingNameToVariable(element.name, variable, void 0, {
206
+ kind: 80,
207
+ text: "" + index
208
+ });
209
+ }).filter((variable2) => !!variable2);
210
+ }
211
+ }
212
+ class NameBindingResolver {
213
+ constructor(parentNameResolver) {
214
+ __publicField(this, "variables", /* @__PURE__ */ new Map());
215
+ this.parentNameResolver = parentNameResolver;
216
+ }
217
+ addVariable(name, variable) {
218
+ this.variables.set(name, variable);
219
+ }
220
+ addFunctionParams(functionDeclaration) {
221
+ functionDeclaration.parameters.map((param, paramIndex) => {
222
+ let paramVariables = tsBindingNameToVariable(
223
+ param.name,
224
+ void 0,
225
+ void 0,
226
+ void 0,
227
+ mkParameterVariableRoot(param, paramIndex)
228
+ );
229
+ paramVariables.forEach((variable) => {
230
+ if (variable.name)
231
+ this.variables.set(variable.name, variable);
232
+ });
233
+ });
234
+ }
235
+ addFunctionDeclaration(statement) {
236
+ if (statement.name) {
237
+ let functionVariable = mkVariable({
238
+ name: statement.name.text,
239
+ root: mkFunctionVariableRoot(statement),
240
+ definingStatement: statement
241
+ });
242
+ this.variables.set(statement.name.text, functionVariable);
243
+ }
244
+ }
245
+ addVariableDeclarationList(declarationList) {
246
+ const letOrConst = declarationList.flags === ts.NodeFlags.Const ? 1 : 0;
247
+ declarationList.declarations.forEach((declaration) => {
248
+ let rightSide = declaration.initializer ? this.resolvePropertyAccessChain(declaration.initializer) : void 0;
249
+ let declaredVariable = tsBindingNameToVariable(
250
+ declaration.name,
251
+ void 0,
252
+ rightSide,
253
+ void 0
254
+ );
255
+ declaredVariable.forEach(
256
+ (variable) => this.variables.set(variable.name, { ...variable, letOrConst })
257
+ );
258
+ });
259
+ }
260
+ addVariableStatement(variableStatement) {
261
+ this.addVariableDeclarationList(variableStatement.declarationList);
262
+ }
263
+ getVariable(name) {
264
+ return this.variables.get(name) || UNKNOWN_VARIABLE;
265
+ }
266
+ resolvePropertyAccessChain(expression) {
267
+ if (ts.isPropertyAccessExpression(expression)) {
268
+ const name = expression.name.text;
269
+ const identifiersFromObject = this.resolvePropertyAccessChain(expression.expression);
270
+ return { accessedFrom: identifiersFromObject, accessedByProperty: name };
271
+ } else if (ts.isElementAccessExpression(expression) && ts.isStringLiteral(expression.argumentExpression)) {
272
+ const name = expression.argumentExpression.text;
273
+ const identifiersFromObject = this.resolvePropertyAccessChain(expression.expression);
274
+ return { accessedFrom: identifiersFromObject, accessedByProperty: name };
275
+ } else if (ts.isIdentifier(expression)) {
276
+ return this.resolveIdentifier(expression);
277
+ } else if (ts.isParenthesizedExpression(expression)) {
278
+ return this.resolvePropertyAccessChain(expression.expression);
279
+ } else if (ts.isAsExpression(expression)) {
280
+ return this.resolvePropertyAccessChain(expression.expression);
281
+ } else if (ts.isObjectLiteralExpression(expression)) {
282
+ return {
283
+ properties: expression.properties.map((property) => {
284
+ if (ts.isPropertyAssignment(property) && (ts.isStringLiteral(property.name) || ts.isIdentifier(property.name))) {
285
+ if (ts.isIdentifier(property.initializer))
286
+ return {
287
+ name: property.name.text,
288
+ assignedFrom: this.resolveIdentifier(property.initializer)
289
+ };
290
+ else if (ts.isObjectLiteralExpression(property.initializer)) {
291
+ let nestedProperty = this.resolvePropertyAccessChain(
292
+ property.initializer
293
+ );
294
+ nestedProperty.name = property.name.text;
295
+ return nestedProperty;
296
+ } else if (ts.isArrowFunction(property.initializer) || ts.isFunctionExpression(property.initializer)) {
297
+ return {
298
+ name: property.name.text,
299
+ root: mkFunctionVariableRoot(property.initializer)
300
+ };
301
+ } else
302
+ return {
303
+ name: property.name.text,
304
+ root: mkLiteralVariableRoot(property.initializer)
305
+ };
306
+ } else if (ts.isShorthandPropertyAssignment(property))
307
+ return {
308
+ name: property.name.text,
309
+ assignedFrom: this.resolveIdentifier(property.name)
310
+ };
311
+ })
312
+ };
313
+ } else if (ts.isArrowFunction(expression) || ts.isFunctionExpression(expression)) {
314
+ return { root: mkFunctionVariableRoot(expression) };
315
+ } else if (ts.isCallExpression(expression)) {
316
+ return { root: mkFunctionCallVariableRoot(expression) };
317
+ } else if (ts.isStringLiteral(expression) || ts.isNumericLiteral(expression) || ts.isToken(expression) && expression.kind === ts.SyntaxKind.TrueKeyword || ts.isToken(expression) && expression.kind === ts.SyntaxKind.FalseKeyword) {
318
+ return { root: mkLiteralVariableRoot(expression) };
319
+ } else {
320
+ return { root: mkOtherVariableRoot(expression) };
321
+ }
322
+ }
323
+ resolvePropertyAccess(expression) {
324
+ return this.resolvePropertyAccessChain(expression);
325
+ }
326
+ resolveIdentifier(expression) {
327
+ let variableName = expression.text;
328
+ let nameResolver = this;
329
+ let resolved;
330
+ while ((resolved = nameResolver.getVariable(variableName)) === UNKNOWN_VARIABLE && nameResolver.parentNameResolver)
331
+ nameResolver = nameResolver.parentNameResolver;
332
+ if (resolved === UNKNOWN_VARIABLE)
333
+ return { root: mkGlobalVariableRoot(variableName) };
334
+ return resolved;
335
+ }
336
+ addImportDeclaration(node) {
337
+ if (node.importClause?.name) {
338
+ let root = mkImportModuleVariableRoot(
339
+ node.moduleSpecifier,
340
+ 0
341
+ /* defaultImport */
342
+ );
343
+ let variable = mkVariable({
344
+ name: node.importClause.name.text,
345
+ definingStatement: node,
346
+ root
347
+ });
348
+ this.variables.set(node.importClause.name.text, variable);
349
+ }
350
+ if (node.importClause?.namedBindings) {
351
+ let root = mkImportModuleVariableRoot(
352
+ node.moduleSpecifier,
353
+ 1
354
+ /* namedImport */
355
+ );
356
+ let namedBindings = node.importClause.namedBindings;
357
+ if (ts.isNamespaceImport(namedBindings)) {
358
+ let variable = mkVariable({
359
+ name: namedBindings.name.text,
360
+ definingStatement: node,
361
+ root
362
+ });
363
+ this.variables.set(namedBindings.name.text, variable);
364
+ } else if (ts.isNamedImports(namedBindings)) {
365
+ namedBindings.elements.forEach((importSpecifier) => {
366
+ if (!importSpecifier.isTypeOnly) {
367
+ let variable = mkVariable({
368
+ name: importSpecifier.name.text,
369
+ accessedByProperty: (importSpecifier.propertyName || importSpecifier.name).text,
370
+ accessedFrom: {
371
+ definingStatement: node,
372
+ root
373
+ },
374
+ definingStatement: node
375
+ });
376
+ this.variables.set(importSpecifier.name.text, variable);
377
+ }
378
+ });
379
+ }
380
+ }
381
+ }
382
+ }
383
+ function flattenVariable(variable, path2 = []) {
384
+ if (variable.assignedFrom)
385
+ return flattenVariable(variable.assignedFrom, path2);
386
+ else if (variable.accessedFrom) {
387
+ return flattenVariable(variable.accessedFrom, [variable.accessedByProperty, ...path2]);
388
+ } else if (variable.properties && !!variable.properties.find((_) => _.name === path2[0])) {
389
+ return flattenVariable(
390
+ variable.properties.find((_) => _.name === path2[0]),
391
+ path2.slice(1)
392
+ );
393
+ } else
394
+ return { path: path2, root: variable.root };
395
+ }
396
+ function isIdentifierOrPropertyAccessExpression(node) {
397
+ return ts.isIdentifier(node) || ts.isPropertyAccessExpression(node);
398
+ }
399
+ function byAnd() {
400
+ return (agg, value) => agg && value;
401
+ }
402
+ function findEventHandlersBlock(functionDeclaration, bindingResolver) {
403
+ const foundEventHandlers = [];
404
+ const foundEventHandlerFunctionsToHandlerIndex = /* @__PURE__ */ new Map();
405
+ let nextEventHandlerIndex = 0;
406
+ if (ts.isBlock(functionDeclaration.body)) {
407
+ functionDeclaration.body.statements.forEach((statement) => {
408
+ if (ts.isExpressionStatement(statement) && ts.isCallExpression(statement.expression)) {
409
+ if (isIdentifierOrPropertyAccessExpression(statement.expression.expression)) {
410
+ let functionVariable = bindingResolver.explain(statement.expression.expression);
411
+ let accessChain = flattenVariable(functionVariable);
412
+ if (accessChain.path.length === 2 && isParamVariableRoot(accessChain.root) && accessChain.root.param === functionDeclaration.parameters[1]) {
413
+ let handler = statement.expression.arguments[0];
414
+ if (isFunctionLikeDeclarationBase(handler))
415
+ foundEventHandlers.push({
416
+ eventHandler: handler,
417
+ eventHandlerCallStatement: statement,
418
+ handlerIndex: nextEventHandlerIndex++
419
+ });
420
+ else if (ts.isIdentifier(handler) || ts.isPropertyAccessExpression(handler)) {
421
+ let flattenedHandler = flattenVariable(
422
+ bindingResolver.explain(handler)
423
+ );
424
+ if (flattenedHandler.path.length === 0 && isFunctionVariableRoot(flattenedHandler.root))
425
+ foundEventHandlers.push({
426
+ eventHandler: flattenedHandler.root.func,
427
+ eventHandlerCallStatement: statement,
428
+ handlerIndex: foundEventHandlerFunctionsToHandlerIndex.get(
429
+ flattenedHandler.root
430
+ ) ?? foundEventHandlerFunctionsToHandlerIndex.set(flattenedHandler.root, nextEventHandlerIndex++).get(flattenedHandler.root)
431
+ });
432
+ }
433
+ }
434
+ }
435
+ }
436
+ });
437
+ }
438
+ return foundEventHandlers;
439
+ }
440
+ const BUILT_IN_TYPES = ["RegExp", "Date"];
441
+ function builtInType(text) {
442
+ return BUILT_IN_TYPES.findIndex((_) => _ === text) > -1;
443
+ }
444
+ class BuiltInResolvedType {
445
+ constructor(name) {
446
+ this.name = name;
447
+ }
448
+ canBeAssignedFrom(rightSide) {
449
+ return rightSide instanceof BuiltInResolvedType && this.name === rightSide.name;
450
+ }
451
+ }
452
+ class ImportFromModuleResolvedType {
453
+ constructor(module2, path2) {
454
+ this.module = module2;
455
+ this.path = path2;
456
+ }
457
+ canBeAssignedFrom(rightSide) {
458
+ if (rightSide instanceof ImportFromModuleResolvedType) {
459
+ let pathEqual = this.path.length === rightSide.path.length;
460
+ if (pathEqual) {
461
+ pathEqual = this.path.map((value, index) => value === rightSide.path[index]).reduce(byAnd(), true);
462
+ }
463
+ return pathEqual && this.module === rightSide.module;
464
+ }
465
+ return false;
466
+ }
467
+ }
468
+ class ArrayResolvedType {
469
+ constructor(itemType) {
470
+ this.itemType = itemType;
471
+ }
472
+ canBeAssignedFrom(rightSide) {
473
+ return rightSide instanceof ArrayResolvedType && this.itemType === rightSide.itemType;
474
+ }
475
+ }
476
+ class FunctionResolvedType {
477
+ constructor(params, returns) {
478
+ this.params = params;
479
+ this.returns = returns;
480
+ }
481
+ canBeAssignedFrom(rightSide) {
482
+ return rightSide instanceof FunctionResolvedType && this.returns.canBeAssignedFrom(rightSide.returns);
483
+ }
484
+ }
485
+ class UnionResolvedType {
486
+ constructor(types) {
487
+ this.types = types;
488
+ }
489
+ canBeAssignedFrom(rightSide) {
490
+ if (rightSide instanceof UnionResolvedType) {
491
+ for (const item1 of this.types)
492
+ for (const item2 of rightSide.types)
493
+ if (item1.canBeAssignedFrom(item2))
494
+ return true;
495
+ } else
496
+ for (const item1 of this.types)
497
+ if (item1.canBeAssignedFrom(rightSide))
498
+ return true;
499
+ return false;
500
+ }
501
+ }
502
+ class GlobalResolvedType {
503
+ constructor(name) {
504
+ this.name = name;
505
+ }
506
+ canBeAssignedFrom(rightSide) {
507
+ return rightSide instanceof GlobalResolvedType && this.name === rightSide.name;
508
+ }
509
+ }
510
+ class SpreadResolvedType {
511
+ constructor(arrayType) {
512
+ this.arrayType = arrayType;
513
+ }
514
+ canBeAssignedFrom(rightSide) {
515
+ return rightSide instanceof SpreadResolvedType && this.arrayType.canBeAssignedFrom(rightSide.arrayType);
516
+ }
517
+ }
518
+ class SourceFileBindingResolver {
519
+ constructor(sourceFile) {
520
+ __publicField(this, "nameBindingResolvers", /* @__PURE__ */ new Map());
521
+ this.nameBindingResolvers.set(sourceFile, new NameBindingResolver());
522
+ const nbResolversQueue = [
523
+ this.nameBindingResolvers.get(sourceFile)
524
+ ];
525
+ const doWithChildBindingResolver = (node, callback) => {
526
+ nbResolversQueue.unshift(new NameBindingResolver(nbResolversQueue[0]));
527
+ this.nameBindingResolvers.set(node, nbResolversQueue[0]);
528
+ callback();
529
+ node.getChildren().forEach((child) => ts.visitNode(child, visitor));
530
+ nbResolversQueue.shift();
531
+ return node;
532
+ };
533
+ const visitor = (node) => {
534
+ if (ts.isFunctionDeclaration(node))
535
+ nbResolversQueue[0].addFunctionDeclaration(node);
536
+ if (ts.isVariableStatement(node))
537
+ nbResolversQueue[0].addVariableStatement(node);
538
+ else if (ts.isImportDeclaration(node))
539
+ nbResolversQueue[0].addImportDeclaration(node);
540
+ else if (ts.isBlock(node))
541
+ return doWithChildBindingResolver(node, () => {
542
+ });
543
+ else if (isFunctionLikeDeclarationBase(node)) {
544
+ return doWithChildBindingResolver(
545
+ node,
546
+ () => nbResolversQueue[0].addFunctionParams(node)
547
+ );
548
+ } else if (ts.isForStatement(node) && ts.isVariableDeclarationList(node.initializer)) {
549
+ return doWithChildBindingResolver(
550
+ node,
551
+ () => nbResolversQueue[0].addVariableDeclarationList(
552
+ node.initializer
553
+ )
554
+ );
555
+ } else if ((ts.isForInStatement(node) || ts.isForOfStatement(node)) && ts.isVariableDeclarationList(node.initializer) && node.initializer.declarations.length === 1 && ts.isIdentifier(node.initializer.declarations[0].name)) {
556
+ return doWithChildBindingResolver(node, () => {
557
+ let name = node.initializer.declarations[0].name.text;
558
+ nbResolversQueue[0].addVariable(
559
+ name,
560
+ mkVariable({
561
+ name,
562
+ root: mkOtherVariableRoot(node),
563
+ definingStatement: node
564
+ })
565
+ );
566
+ });
567
+ }
568
+ node.getChildren().forEach((child) => ts.visitNode(child, visitor));
569
+ return node;
570
+ };
571
+ ts.visitNode(sourceFile, visitor);
572
+ }
573
+ findBindingResolver(node) {
574
+ let found;
575
+ while (!(found = this.nameBindingResolvers.get(node)) && node.parent)
576
+ node = node.parent;
577
+ return found;
578
+ }
579
+ explain(identifier) {
580
+ return this.findBindingResolver(identifier).resolvePropertyAccessChain(identifier);
581
+ }
582
+ explainFlattenedVariableType(flattened) {
583
+ if (!!flattened.root) {
584
+ if (isImportModuleVariableRoot(flattened.root) && ts.isStringLiteral(flattened.root.module)) {
585
+ return new ImportFromModuleResolvedType(flattened.root.module.text, flattened.path);
586
+ }
587
+ } else
588
+ return void 0;
589
+ }
590
+ explainType(type) {
591
+ if (type) {
592
+ if (ts.isTypeReferenceNode(type)) {
593
+ let typeName = type.typeName;
594
+ if (ts.isIdentifier(typeName)) {
595
+ let resolved = this.findBindingResolver(typeName).resolveIdentifier(typeName);
596
+ let flattened = flattenVariable(resolved);
597
+ let typeFromFlattened = this.explainFlattenedVariableType(flattened);
598
+ if (typeFromFlattened)
599
+ return typeFromFlattened;
600
+ if (builtInType(typeName.text))
601
+ return new BuiltInResolvedType(typeName.text);
602
+ }
603
+ } else if (type.kind === ts.SyntaxKind.StringKeyword)
604
+ return new BuiltInResolvedType("string");
605
+ else if (type.kind === ts.SyntaxKind.NumberKeyword)
606
+ return new BuiltInResolvedType("number");
607
+ else if (type.kind === ts.SyntaxKind.BooleanKeyword)
608
+ return new BuiltInResolvedType("boolean");
609
+ else if (type.kind === ts.SyntaxKind.AnyKeyword)
610
+ return new BuiltInResolvedType("any");
611
+ else if (type.kind === ts.SyntaxKind.VoidKeyword)
612
+ return new BuiltInResolvedType("void");
613
+ else if (ts.isArrayTypeNode(type))
614
+ return new ArrayResolvedType(this.explainType(type.elementType));
615
+ else if (ts.isFunctionTypeNode(type)) {
616
+ const params = type.parameters.map((param) => this.explainType(param.type));
617
+ const ret = this.explainType(type.type);
618
+ return new FunctionResolvedType(params, ret);
619
+ } else if (ts.isUnionTypeNode(type))
620
+ return new UnionResolvedType(type.types.map((aType) => this.explainType(aType)));
621
+ }
622
+ return new BuiltInResolvedType("void");
623
+ }
624
+ globalType(globalVariableRoot) {
625
+ return new GlobalResolvedType(globalVariableRoot.name);
626
+ }
627
+ }
628
+ function areResolvedTypesCompatible(type1, type2) {
629
+ return type1.canBeAssignedFrom(type2);
630
+ }
631
+ var CompilePatternType = /* @__PURE__ */ ((CompilePatternType2) => {
632
+ CompilePatternType2[CompilePatternType2["RETURN"] = 0] = "RETURN";
633
+ CompilePatternType2[CompilePatternType2["CALL"] = 1] = "CALL";
634
+ CompilePatternType2[CompilePatternType2["CHAINABLE_CALL"] = 2] = "CHAINABLE_CALL";
635
+ CompilePatternType2[CompilePatternType2["ASSIGNMENT_LEFT_SIDE"] = 3] = "ASSIGNMENT_LEFT_SIDE";
636
+ CompilePatternType2[CompilePatternType2["KNOWN_VARIABLE_READ"] = 4] = "KNOWN_VARIABLE_READ";
637
+ CompilePatternType2[CompilePatternType2["CONST_READ"] = 5] = "CONST_READ";
638
+ CompilePatternType2[CompilePatternType2["INLINE_ARROW_FUNCTION"] = 6] = "INLINE_ARROW_FUNCTION";
639
+ return CompilePatternType2;
640
+ })(CompilePatternType || {});
641
+ function areCompatiblePatternTypes(type1, type2) {
642
+ if (type1 === type2)
643
+ return true;
644
+ if (type1 === 1 && type2 === 2)
645
+ return true;
646
+ return type1 === 2 && type2 === 1;
647
+ }
648
+ const KNOWN_VARIABLE_READ_NAME = "knownVariableReadPattern";
649
+ const CONST_READ_NAME = "knownVariableReadPattern";
650
+ const INLINE_ARROW_FUNCTION = "inlineArrowFunctionPattern";
651
+ var JayTargetEnv = /* @__PURE__ */ ((JayTargetEnv2) => {
652
+ JayTargetEnv2[JayTargetEnv2["main"] = 0] = "main";
653
+ JayTargetEnv2[JayTargetEnv2["any"] = 1] = "any";
654
+ JayTargetEnv2[JayTargetEnv2["sandbox"] = 2] = "sandbox";
655
+ return JayTargetEnv2;
656
+ })(JayTargetEnv || {});
657
+ function intersectJayTargetEnv(a, b) {
658
+ if (a === b && a === 1)
659
+ return 1;
660
+ if (a === 0 && b === 0 || a === 0 && b === 1 || a === 1 && b === 0)
661
+ return 0;
662
+ else
663
+ return 2;
664
+ }
665
+ function extractArgumentType(argument, sourceFileBinding, node) {
666
+ if (isIdentifierOrPropertyAccessExpression(argument)) {
667
+ const explainedArgument = flattenVariable(sourceFileBinding.explain(argument));
668
+ if (isParamVariableRoot(explainedArgument.root)) {
669
+ const paramIndex = explainedArgument.root.paramIndex;
670
+ return sourceFileBinding.explainType(node.parameters[paramIndex].type);
671
+ }
672
+ }
673
+ if (ts.isSpreadElement(argument)) {
674
+ return new SpreadResolvedType(
675
+ extractArgumentType(argument.expression, sourceFileBinding, node)
676
+ );
677
+ }
678
+ return void 0;
679
+ }
680
+ function extractArgumentTypes(callArgs, sourceFileBinding, node) {
681
+ return callArgs.map((argument) => {
682
+ return extractArgumentType(argument, sourceFileBinding, node);
683
+ });
684
+ }
685
+ function compileFunctionSplitPatternsBlock(patternFiles) {
686
+ const validations = [];
687
+ const compiledPatterns = [];
688
+ patternFiles.forEach((patternsFile) => {
689
+ const sourceFileBinding = new SourceFileBindingResolver(patternsFile);
690
+ const findPatternFunctions = (node) => {
691
+ if (ts.isFunctionDeclaration(node)) {
692
+ let declaredTargetEnv = 0;
693
+ node.modifiers && node.modifiers.forEach((modifier) => {
694
+ if (ts.isDecorator(modifier) && ts.isCallExpression(modifier.expression) && ts.isIdentifier(modifier.expression.expression) && modifier.expression.expression.text === "JayPattern" && modifier.expression.arguments.length === 1 && ts.isPropertyAccessExpression(modifier.expression.arguments[0]) && ts.isIdentifier(modifier.expression.arguments[0].expression) && modifier.expression.arguments[0].expression.text === "JayTargetEnv" && modifier.expression.arguments[0].name.text === "any")
695
+ declaredTargetEnv = 1;
696
+ });
697
+ let name = node.name.text;
698
+ node.body.statements.forEach((statement, index) => {
699
+ let patternTargetEnv = declaredTargetEnv;
700
+ let patternType;
701
+ let leftHandSide;
702
+ let callArgumentTypes = [];
703
+ if (ts.isReturnStatement(statement) && isIdentifierOrPropertyAccessExpression(statement.expression)) {
704
+ patternType = 0;
705
+ leftHandSide = statement.expression;
706
+ patternTargetEnv = 1;
707
+ } else if (ts.isReturnStatement(statement) && ts.isCallExpression(statement.expression) && isIdentifierOrPropertyAccessExpression(statement.expression.expression) && node.type) {
708
+ patternType = 2;
709
+ leftHandSide = statement.expression.expression;
710
+ callArgumentTypes = extractArgumentTypes(
711
+ statement.expression.arguments,
712
+ sourceFileBinding,
713
+ node
714
+ );
715
+ } else if (ts.isReturnStatement(statement) && ts.isNewExpression(statement.expression) && isIdentifierOrPropertyAccessExpression(statement.expression.expression)) {
716
+ patternType = 2;
717
+ leftHandSide = statement.expression.expression;
718
+ callArgumentTypes = extractArgumentTypes(
719
+ statement.expression.arguments,
720
+ sourceFileBinding,
721
+ node
722
+ );
723
+ } else if (ts.isExpressionStatement(statement) && ts.isCallExpression(statement.expression) && isIdentifierOrPropertyAccessExpression(statement.expression.expression)) {
724
+ patternType = 1;
725
+ leftHandSide = statement.expression.expression;
726
+ callArgumentTypes = extractArgumentTypes(
727
+ statement.expression.arguments,
728
+ sourceFileBinding,
729
+ node
730
+ );
731
+ } else if (ts.isExpressionStatement(statement) && ts.isBinaryExpression(statement.expression) && ts.isPropertyAccessExpression(statement.expression.left) && statement.expression.operatorToken.kind === ts.SyntaxKind.EqualsToken && ts.isIdentifier(statement.expression.right)) {
732
+ patternType = 3;
733
+ leftHandSide = statement.expression.left;
734
+ callArgumentTypes = [
735
+ extractArgumentType(
736
+ statement.expression.right,
737
+ sourceFileBinding,
738
+ node
739
+ )
740
+ ];
741
+ }
742
+ let resolvedLeftHandSide = flattenVariable(
743
+ sourceFileBinding.findBindingResolver(statement).resolvePropertyAccessChain(leftHandSide)
744
+ );
745
+ let leftSideType = void 0;
746
+ if (isParamVariableRoot(resolvedLeftHandSide.root)) {
747
+ const paramIndex = resolvedLeftHandSide.root.paramIndex;
748
+ leftSideType = sourceFileBinding.explainType(
749
+ node.parameters[paramIndex].type
750
+ );
751
+ } else if (isGlobalVariableRoot(resolvedLeftHandSide.root))
752
+ leftSideType = sourceFileBinding.globalType(resolvedLeftHandSide.root);
753
+ else if (isImportModuleVariableRoot(resolvedLeftHandSide.root))
754
+ leftSideType = sourceFileBinding.explainFlattenedVariableType(resolvedLeftHandSide);
755
+ if (patternType !== void 0 && leftSideType !== void 0) {
756
+ compiledPatterns.push({
757
+ patternType,
758
+ leftSidePath: resolvedLeftHandSide.path,
759
+ leftSideType,
760
+ returnType: sourceFileBinding.explainType(node.type),
761
+ callArgumentTypes,
762
+ targetEnvForStatement: patternTargetEnv,
763
+ name
764
+ });
765
+ } else
766
+ validations.push(
767
+ `unsupported statement, at pattern [${node.name?.text}] statement [${index}]: `,
768
+ astToCode(statement)
769
+ );
770
+ });
771
+ }
772
+ return node;
773
+ };
774
+ ts.transform(patternsFile, [
775
+ mkTransformer(({ context, sourceFile }) => {
776
+ ts.visitEachChild(patternsFile, findPatternFunctions, context);
777
+ return sourceFile;
778
+ })
779
+ ]);
780
+ });
781
+ return new compilerShared.WithValidations(compiledPatterns, validations);
782
+ }
783
+ function visitWithContext(node, initialContext, contextualVisitor) {
784
+ return visitWithContext2(node, initialContext, void 0, contextualVisitor);
785
+ }
786
+ function visitWithContext2(node, initialContext, transformationContext, contextualVisitor) {
787
+ let contexts = [initialContext];
788
+ const visitChild = (node2, childContext) => {
789
+ if (childContext)
790
+ contexts.push(childContext);
791
+ let visitedNode = ts.visitNode(node2, visitor);
792
+ if (childContext)
793
+ contexts.pop();
794
+ return visitedNode;
795
+ };
796
+ const visitEachChild = (node2, childContext) => {
797
+ if (childContext)
798
+ contexts.push(childContext);
799
+ let visitedNode = ts.visitEachChild(node2, visitor, transformationContext);
800
+ if (childContext)
801
+ contexts.pop();
802
+ return visitedNode;
803
+ };
804
+ const visitor = (node2) => {
805
+ return contextualVisitor(node2, contexts.at(-1), visitChild, visitEachChild);
806
+ };
807
+ return ts.visitNode(node, visitor);
808
+ }
809
+ function isFirstParamJayEvent(eventHandler, bindingResolver) {
810
+ if (eventHandler.parameters.length > 0 && eventHandler.parameters[0].type) {
811
+ const explainedType = bindingResolver.explainType(eventHandler.parameters[0].type);
812
+ if (ts.isTypeReferenceNode(eventHandler.parameters[0].type) && eventHandler.parameters[0].type.typeArguments?.length === 2 && explainedType instanceof ImportFromModuleResolvedType && explainedType.module === "@jay-framework/runtime" && explainedType.path.length === 1 && explainedType.path[0] === "JayEvent")
813
+ return true;
814
+ }
815
+ return false;
816
+ }
817
+ function filterEventHandlersToHaveJayEventType(foundEventHandlers, bindingResolver) {
818
+ return foundEventHandlers.filter((foundEventHandler) => {
819
+ const eventHandler = foundEventHandler.eventHandler;
820
+ return isFirstParamJayEvent(eventHandler, bindingResolver);
821
+ });
822
+ }
823
+ function generateFunctionRepository(matchedReturnPatterns, matchedVariableReads, matchedConstants, safeStatements) {
824
+ const constCode = [...new Set(matchedConstants)].join("\n");
825
+ let readPatternsReturnProperties = matchedReturnPatterns.map(
826
+ ({ pattern, patternKey }) => `$${patternKey}: ${pattern.leftSidePath.join(".")}`
827
+ );
828
+ readPatternsReturnProperties = [...new Set(readPatternsReturnProperties)];
829
+ let variableReadsReturnProperties = matchedVariableReads.map(
830
+ ({ variable, patternKey }) => `$${patternKey}: ${variable.text}`
831
+ );
832
+ let returnedObjectProperties = [
833
+ ...readPatternsReturnProperties,
834
+ ...variableReadsReturnProperties
835
+ ].join(",\n");
836
+ if (safeStatements.length > 0) {
837
+ const handlerCode = `({ event }: JayEvent<any, any>) => {
838
+ ${safeStatements.map((statement) => astToCode(statement)).join("\n ")}
839
+ ${returnedObjectProperties.length > 0 ? ` return ({${returnedObjectProperties}})
840
+ ` : ""}
841
+ }`;
842
+ return { handlerCode, key: constCode };
843
+ }
844
+ if (matchedReturnPatterns.length > 0) {
845
+ let handlerCode = `({ event }: JayEvent<any, any>) => ({${returnedObjectProperties}})`;
846
+ return { handlerCode, key: constCode };
847
+ } else
848
+ return { key: void 0, handlerCode: void 0 };
849
+ }
850
+ const mkTransformEventHandlerStatementVisitor = (factory, context, bindingResolver, analyzer) => {
851
+ let sideEffects = {
852
+ matchedVariableReads: [],
853
+ matchedConstants: [],
854
+ mainContextBlocks: /* @__PURE__ */ new Map(),
855
+ matchedReturnPatterns: [],
856
+ wasEventHandlerTransformed: false
857
+ };
858
+ let patternIndexes = /* @__PURE__ */ new Map();
859
+ const getPatternIndex = (pattern) => {
860
+ if (!patternIndexes.has(pattern)) {
861
+ patternIndexes.set(pattern, patternIndexes.size);
862
+ }
863
+ return patternIndexes.get(pattern);
864
+ };
865
+ const visitor = (node, { parentStatementTargetEnv }, visitChild, visitEachChild) => {
866
+ if (ts.isStatement(node)) {
867
+ let statementAnalysis = analyzer.getStatementStatus(node);
868
+ if (statementAnalysis)
869
+ parentStatementTargetEnv = intersectJayTargetEnv(
870
+ parentStatementTargetEnv,
871
+ statementAnalysis.targetEnv
872
+ );
873
+ }
874
+ if (ts.isBlock(node) && parentStatementTargetEnv !== JayTargetEnv.sandbox) {
875
+ let sandboxStatements = [], mainStatements = [];
876
+ node.statements.forEach((statement) => {
877
+ let statementAnalysis = analyzer.getStatementStatus(statement);
878
+ switch (statementAnalysis.targetEnv) {
879
+ case JayTargetEnv.any:
880
+ sandboxStatements.push(statement);
881
+ mainStatements.push(statement);
882
+ break;
883
+ case JayTargetEnv.main:
884
+ mainStatements.push(statement);
885
+ break;
886
+ case JayTargetEnv.sandbox:
887
+ sandboxStatements.push(statement);
888
+ break;
889
+ }
890
+ });
891
+ sideEffects.mainContextBlocks.set(node, factory.createBlock(mainStatements));
892
+ if (sandboxStatements.length < node.statements.length)
893
+ sideEffects.wasEventHandlerTransformed = true;
894
+ sandboxStatements = sandboxStatements.map(
895
+ (statement) => visitChild(statement, { parentStatementTargetEnv })
896
+ );
897
+ node = factory.updateBlock(node, sandboxStatements);
898
+ return node;
899
+ } else if (ts.isExpression(node)) {
900
+ let expressionAnalysis = analyzer.getExpressionStatus(node);
901
+ if (expressionAnalysis) {
902
+ let pattern = expressionAnalysis.patterns[0];
903
+ let patternKey = getPatternIndex(pattern);
904
+ if (pattern.patternType === CompilePatternType.RETURN)
905
+ sideEffects.matchedReturnPatterns.push({ pattern, patternKey });
906
+ else if (pattern.patternType === CompilePatternType.KNOWN_VARIABLE_READ && ts.isIdentifier(node))
907
+ sideEffects.matchedVariableReads.push({ variable: node, patternKey });
908
+ else if (pattern.patternType === CompilePatternType.CONST_READ && ts.isIdentifier(node)) {
909
+ let constant = bindingResolver.explain(node);
910
+ let flattenedConstant = flattenVariable(constant);
911
+ let literal = flattenedConstant.root.literal;
912
+ if (ts.isLiteralExpression(literal)) {
913
+ let constantValue = literal.text;
914
+ sideEffects.matchedConstants.push(`const ${node.text} = ${constantValue}`);
915
+ }
916
+ return node;
917
+ } else
918
+ return node;
919
+ let replacementPattern = `event.$${patternKey}`;
920
+ sideEffects.wasEventHandlerTransformed = true;
921
+ return codeToAst(replacementPattern, context)[0].expression;
922
+ }
923
+ }
924
+ return visitEachChild(node, { parentStatementTargetEnv });
925
+ };
926
+ return { visitor, sideEffects };
927
+ };
928
+ const analyzeEventHandlerByPatternBlock = (context, bindingResolver, analyzer, factory, eventHandler, functionsRepository) => {
929
+ const scopedAnalyzer = analyzer.analyzeForScope(eventHandler);
930
+ const { sideEffects, visitor } = mkTransformEventHandlerStatementVisitor(
931
+ factory,
932
+ context,
933
+ bindingResolver,
934
+ scopedAnalyzer
935
+ );
936
+ let transformedEventHandler = visitWithContext2(
937
+ eventHandler,
938
+ { parentStatementTargetEnv: JayTargetEnv.any },
939
+ context,
940
+ visitor
941
+ );
942
+ if (sideEffects.wasEventHandlerTransformed && isFirstParamJayEvent(eventHandler, bindingResolver)) {
943
+ const originalJayEventType = eventHandler.parameters[0].type;
944
+ if (originalJayEventType.typeArguments?.length === 2) {
945
+ const transformedJayEventType = factory.createTypeReferenceNode(
946
+ originalJayEventType.typeName,
947
+ [
948
+ factory.createKeywordTypeNode(ts.SyntaxKind.AnyKeyword),
949
+ originalJayEventType.typeArguments[1]
950
+ ]
951
+ );
952
+ let visitor2 = (node) => {
953
+ if (node === originalJayEventType) {
954
+ return ts.visitEachChild(transformedJayEventType, visitor2, context);
955
+ }
956
+ return ts.visitEachChild(node, visitor2, context);
957
+ };
958
+ transformedEventHandler = ts.visitEachChild(transformedEventHandler, visitor2, context);
959
+ }
960
+ let bodyForFunctionRepository = void 0;
961
+ if (ts.isBlock(eventHandler.body) && sideEffects.mainContextBlocks.has(eventHandler.body)) {
962
+ let body = sideEffects.mainContextBlocks.get(eventHandler.body);
963
+ const replaceBodiesVisitor = (node) => {
964
+ let mainNode = ts.isBlock(node) && sideEffects.mainContextBlocks.has(node) ? sideEffects.mainContextBlocks.get(node) : node;
965
+ return ts.visitEachChild(mainNode, replaceBodiesVisitor, context);
966
+ };
967
+ bodyForFunctionRepository = ts.visitNode(body, replaceBodiesVisitor);
968
+ }
969
+ const { handlerCode, key } = generateFunctionRepository(
970
+ sideEffects.matchedReturnPatterns,
971
+ sideEffects.matchedVariableReads,
972
+ sideEffects.matchedConstants,
973
+ bodyForFunctionRepository ? [...bodyForFunctionRepository.statements] : []
974
+ );
975
+ const handlerKey = functionsRepository.addFunction(handlerCode);
976
+ functionsRepository.addConst(key);
977
+ return {
978
+ transformedEventHandler,
979
+ wasEventHandlerTransformed: sideEffects.wasEventHandlerTransformed,
980
+ handlerKey
981
+ };
982
+ } else
983
+ return {
984
+ handlerKey: "",
985
+ transformedEventHandler,
986
+ wasEventHandlerTransformed: false
987
+ };
988
+ };
989
+ const analyzeEventHandlerCall = (context, factory, handlerKey) => (node) => {
990
+ if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression)) {
991
+ return factory.createCallExpression(
992
+ factory.createPropertyAccessExpression(
993
+ factory.createCallExpression(
994
+ factory.createPropertyAccessExpression(
995
+ node.expression.expression,
996
+ node.expression.name.text + "$"
997
+ ),
998
+ void 0,
999
+ codeToAst(`handler$('${handlerKey}')`, context).map(
1000
+ (_) => _.expression
1001
+ )
1002
+ ),
1003
+ factory.createIdentifier("then")
1004
+ ),
1005
+ void 0,
1006
+ node.arguments
1007
+ );
1008
+ }
1009
+ return node;
1010
+ };
1011
+ const analyzeEventHandlerCallStatement$Block = (context, factory, handlerKey) => (node) => {
1012
+ return ts.visitEachChild(
1013
+ node,
1014
+ analyzeEventHandlerCall(context, factory, handlerKey),
1015
+ context
1016
+ );
1017
+ };
1018
+ function analyzedEventHandlersToReplaceMap(transformedEventHandlers) {
1019
+ const map = /* @__PURE__ */ new Map();
1020
+ transformedEventHandlers.forEach((_) => {
1021
+ map.set(_.eventHandlerCallStatement, _.transformedEventHandlerCallStatement);
1022
+ map.set(_.eventHandler, _.transformedEventHandler);
1023
+ });
1024
+ return map;
1025
+ }
1026
+ function analyzeEventHandlers(context, bindingResolver, analyzer, factory, foundEventHandlers, functionsRepository) {
1027
+ let handlerToTransformedHandlers = /* @__PURE__ */ new Map();
1028
+ foundEventHandlers.forEach((foundEventHandler) => {
1029
+ if (!handlerToTransformedHandlers.has(foundEventHandler.eventHandler))
1030
+ handlerToTransformedHandlers.set(
1031
+ foundEventHandler.eventHandler,
1032
+ analyzeEventHandlerByPatternBlock(
1033
+ context,
1034
+ bindingResolver,
1035
+ analyzer,
1036
+ factory,
1037
+ foundEventHandler.eventHandler,
1038
+ functionsRepository
1039
+ )
1040
+ );
1041
+ });
1042
+ return foundEventHandlers.filter(
1043
+ (foundEventHandler) => handlerToTransformedHandlers.get(foundEventHandler.eventHandler).wasEventHandlerTransformed
1044
+ ).map((foundEventHandler) => {
1045
+ const { transformedEventHandler, wasEventHandlerTransformed, handlerKey } = handlerToTransformedHandlers.get(foundEventHandler.eventHandler);
1046
+ const transformedEventHandlerCallStatement = analyzeEventHandlerCallStatement$Block(
1047
+ context,
1048
+ factory,
1049
+ handlerKey
1050
+ )(foundEventHandler.eventHandlerCallStatement);
1051
+ return {
1052
+ ...foundEventHandler,
1053
+ transformedEventHandler,
1054
+ wasEventHandlerTransformed,
1055
+ // functionRepositoryFragment,
1056
+ transformedEventHandlerCallStatement
1057
+ };
1058
+ });
1059
+ }
1060
+ class SourceFileStatementAnalyzer {
1061
+ constructor(sourceFile, bindingResolver, compiledPatterns) {
1062
+ this.sourceFile = sourceFile;
1063
+ this.bindingResolver = bindingResolver;
1064
+ this.compiledPatterns = compiledPatterns;
1065
+ }
1066
+ analyzeForScope(analysisScope) {
1067
+ return new ScopedSourceFileStatementAnalyzer(
1068
+ this.sourceFile,
1069
+ this.bindingResolver,
1070
+ this.compiledPatterns,
1071
+ analysisScope
1072
+ );
1073
+ }
1074
+ }
1075
+ class ScopedSourceFileStatementAnalyzer {
1076
+ constructor(sourceFile, bindingResolver, compiledPatterns, analysisScope) {
1077
+ __publicField(this, "analyzedStatements", /* @__PURE__ */ new Map());
1078
+ __publicField(this, "analyzedExpressions", /* @__PURE__ */ new Map());
1079
+ __publicField(this, "nextId", 0);
1080
+ this.sourceFile = sourceFile;
1081
+ this.bindingResolver = bindingResolver;
1082
+ this.compiledPatterns = compiledPatterns;
1083
+ this.analyze(analysisScope);
1084
+ }
1085
+ addPatternToStatement(statement, matchedPattern) {
1086
+ if (!this.analyzedStatements.get(statement)) {
1087
+ this.analyzedStatements.set(statement, {
1088
+ targetEnv: matchedPattern.patterns.reduce(
1089
+ (prev, curr) => intersectJayTargetEnv(prev, curr.targetEnvForStatement),
1090
+ JayTargetEnv.any
1091
+ ),
1092
+ matchedPatterns: [matchedPattern]
1093
+ });
1094
+ } else {
1095
+ let analysisResult = this.analyzedStatements.get(statement);
1096
+ analysisResult.matchedPatterns.push(matchedPattern);
1097
+ analysisResult.targetEnv = intersectJayTargetEnv(
1098
+ analysisResult.targetEnv,
1099
+ matchedPattern.patterns.reduce(
1100
+ (prev, curr) => intersectJayTargetEnv(prev, curr.targetEnvForStatement),
1101
+ JayTargetEnv.any
1102
+ )
1103
+ );
1104
+ }
1105
+ }
1106
+ markStatementSandbox(statement) {
1107
+ if (!this.analyzedStatements.get(statement)) {
1108
+ this.analyzedStatements.set(statement, {
1109
+ targetEnv: JayTargetEnv.sandbox,
1110
+ matchedPatterns: []
1111
+ });
1112
+ } else
1113
+ this.analyzedStatements.get(statement).targetEnv = JayTargetEnv.sandbox;
1114
+ }
1115
+ analyze(analysisScope) {
1116
+ let RoleInParent;
1117
+ ((RoleInParent2) => {
1118
+ RoleInParent2[RoleInParent2["none"] = 0] = "none";
1119
+ RoleInParent2[RoleInParent2["read"] = 1] = "read";
1120
+ RoleInParent2[RoleInParent2["assign"] = 2] = "assign";
1121
+ RoleInParent2[RoleInParent2["call"] = 3] = "call";
1122
+ })(RoleInParent || (RoleInParent = {}));
1123
+ const addExpressionStatus = (statement, patterns, expression, subExpressionsMatching) => {
1124
+ let matchedPattern = {
1125
+ patterns,
1126
+ expression,
1127
+ testId: this.nextId++,
1128
+ subExpressionsMatching
1129
+ };
1130
+ this.analyzedExpressions.set(expression, matchedPattern);
1131
+ this.addPatternToStatement(statement, matchedPattern);
1132
+ };
1133
+ const analyzePropertyExpression = (expression, visitChild, statement, roleInParent) => {
1134
+ let expectedPatternType = roleInParent === 2 ? CompilePatternType.ASSIGNMENT_LEFT_SIDE : CompilePatternType.RETURN;
1135
+ let { matchedPatterns, matchType } = this.matchPattern(
1136
+ expression,
1137
+ expectedPatternType,
1138
+ analysisScope
1139
+ );
1140
+ if (matchType === 0) {
1141
+ addExpressionStatus(statement, matchedPatterns, expression, true);
1142
+ } else {
1143
+ if (ts.isPropertyAccessExpression(expression))
1144
+ visitChild(expression.expression, {
1145
+ statement,
1146
+ roleInParent: 1
1147
+ /* read */
1148
+ });
1149
+ this.markStatementSandbox(statement);
1150
+ }
1151
+ };
1152
+ const analyzeCallParam = (argument, matchedPatterns, index, statement) => {
1153
+ const expressionStatus = this.getExpressionStatus(argument);
1154
+ const patternTypeMatchArgumentType = !!expressionStatus && expressionStatus.patterns.length > 0 && expressionStatus.subExpressionsMatching && areResolvedTypesCompatible(
1155
+ expressionStatus.patterns[0].returnType,
1156
+ matchedPatterns[0].callArgumentTypes[index]
1157
+ );
1158
+ const isLiteral = ts.isLiteralExpression(argument);
1159
+ let isScopedVariableAccess = false;
1160
+ if (isIdentifierOrPropertyAccessExpression(argument)) {
1161
+ const variable = this.bindingResolver.explain(argument);
1162
+ const flattened = flattenVariable(variable);
1163
+ isScopedVariableAccess = isParamVariableRoot(flattened.root) && isChildOf(flattened.root.param, analysisScope);
1164
+ }
1165
+ const paramMatching = patternTypeMatchArgumentType || isLiteral || isScopedVariableAccess;
1166
+ if (!paramMatching)
1167
+ this.markStatementSandbox(statement);
1168
+ return paramMatching;
1169
+ };
1170
+ const analyzeCallOrNewExpression = (node, visitChild, statement, roleInParent) => {
1171
+ if (isIdentifierOrPropertyAccessExpression(node.expression)) {
1172
+ let expression = node.expression;
1173
+ node.arguments.forEach(
1174
+ (argument) => visitChild(argument, {
1175
+ statement,
1176
+ roleInParent: 1
1177
+ /* read */
1178
+ })
1179
+ );
1180
+ let expectedPatternType = roleInParent === 3 ? CompilePatternType.CALL : CompilePatternType.CHAINABLE_CALL;
1181
+ let { matchedPatterns, matchType } = this.matchPattern(
1182
+ expression,
1183
+ expectedPatternType,
1184
+ analysisScope
1185
+ );
1186
+ if (matchType === 0) {
1187
+ let areArgumentsMatching = node.arguments.map((argument, index) => {
1188
+ return analyzeCallParam(argument, matchedPatterns, index, statement);
1189
+ }).reduce(byAnd(), true);
1190
+ addExpressionStatus(statement, matchedPatterns, node, areArgumentsMatching);
1191
+ } else {
1192
+ if (ts.isPropertyAccessExpression(node.expression))
1193
+ visitChild(node.expression.expression, {
1194
+ statement,
1195
+ roleInParent: 1
1196
+ /* read */
1197
+ });
1198
+ this.markStatementSandbox(statement);
1199
+ }
1200
+ } else
1201
+ this.markStatementSandbox(statement);
1202
+ };
1203
+ visitWithContext(
1204
+ this.sourceFile,
1205
+ {
1206
+ roleInParent: 0
1207
+ /* none */
1208
+ },
1209
+ (node, { statement, roleInParent }, visitChild) => {
1210
+ if (ts.isStatement(node))
1211
+ statement = node;
1212
+ if (roleInParent === 1 || roleInParent === 2) {
1213
+ if (isIdentifierOrPropertyAccessExpression(node))
1214
+ analyzePropertyExpression(node, visitChild, statement, roleInParent);
1215
+ else if (ts.isCallExpression(node) || ts.isNewExpression(node)) {
1216
+ analyzeCallOrNewExpression(node, visitChild, statement, roleInParent);
1217
+ return node;
1218
+ } else if (ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.EqualsToken)
1219
+ this.markStatementSandbox(statement);
1220
+ else if (!ts.isLiteralExpression(node) && !ts.isBinaryExpression(node))
1221
+ this.markStatementSandbox(statement);
1222
+ }
1223
+ if (ts.isCallExpression(node) && isIdentifierOrPropertyAccessExpression(node.expression) && roleInParent === 0) {
1224
+ analyzeCallOrNewExpression(
1225
+ node,
1226
+ visitChild,
1227
+ statement,
1228
+ 3
1229
+ /* call */
1230
+ );
1231
+ } else if (ts.isVariableStatement(node)) {
1232
+ node.declarationList.declarations.forEach(
1233
+ (declaration) => visitChild(declaration.initializer, {
1234
+ statement,
1235
+ roleInParent: 1
1236
+ /* read */
1237
+ })
1238
+ );
1239
+ if (this.getStatementStatus(node)?.targetEnv === JayTargetEnv.any)
1240
+ this.getStatementStatus(node).targetEnv = JayTargetEnv.main;
1241
+ } else if (ts.isArrowFunction(node) && !ts.isBlock(node.body)) {
1242
+ visitChild(node.body, {
1243
+ statement,
1244
+ roleInParent: 1
1245
+ /* read */
1246
+ });
1247
+ const bodyStatus = this.getExpressionStatus(node.body);
1248
+ if (!!bodyStatus && bodyStatus.subExpressionsMatching) {
1249
+ addExpressionStatus(
1250
+ statement,
1251
+ [
1252
+ {
1253
+ patternType: CompilePatternType.INLINE_ARROW_FUNCTION,
1254
+ returnType: new FunctionResolvedType(
1255
+ [],
1256
+ bodyStatus.patterns[0].returnType
1257
+ ),
1258
+ callArgumentTypes: [],
1259
+ targetEnvForStatement: JayTargetEnv.any,
1260
+ name: INLINE_ARROW_FUNCTION,
1261
+ leftSidePath: [],
1262
+ leftSideType: new FunctionResolvedType(
1263
+ [],
1264
+ bodyStatus.patterns[0].returnType
1265
+ )
1266
+ }
1267
+ ],
1268
+ node,
1269
+ true
1270
+ );
1271
+ }
1272
+ } else if (ts.isIfStatement(node)) {
1273
+ visitChild(node.expression, {
1274
+ statement,
1275
+ roleInParent: 1
1276
+ /* read */
1277
+ });
1278
+ visitChild(node.thenStatement, {
1279
+ statement,
1280
+ roleInParent: 0
1281
+ /* none */
1282
+ });
1283
+ if (node.elseStatement)
1284
+ visitChild(node.elseStatement, {
1285
+ statement,
1286
+ roleInParent: 0
1287
+ /* none */
1288
+ });
1289
+ } else if (ts.isForStatement(node) || ts.isForOfStatement(node) || ts.isForInStatement(node) || ts.isWhileStatement(node) || ts.isDoStatement(node)) {
1290
+ this.markStatementSandbox(statement);
1291
+ node.getChildren().forEach(
1292
+ (child) => visitChild(child, {
1293
+ statement,
1294
+ roleInParent: 0
1295
+ /* none */
1296
+ })
1297
+ );
1298
+ } else if (ts.isBinaryExpression(node)) {
1299
+ visitChild(node.right, {
1300
+ statement,
1301
+ roleInParent: 1
1302
+ /* read */
1303
+ });
1304
+ visitChild(node.left, {
1305
+ statement,
1306
+ roleInParent: node.operatorToken.kind === ts.SyntaxKind.EqualsToken ? 2 : 1
1307
+ /* read */
1308
+ });
1309
+ } else if (ts.isElementAccessExpression(node)) {
1310
+ node.getChildren().forEach(
1311
+ (child) => visitChild(child, {
1312
+ statement,
1313
+ roleInParent: 1
1314
+ /* read */
1315
+ })
1316
+ );
1317
+ } else {
1318
+ node.getChildren().forEach(
1319
+ (child) => visitChild(child, {
1320
+ statement,
1321
+ roleInParent: 0
1322
+ /* none */
1323
+ })
1324
+ );
1325
+ }
1326
+ return node;
1327
+ }
1328
+ );
1329
+ }
1330
+ matchPattern(patternTarget, expectedPatternType, analysisScope) {
1331
+ let variable = this.bindingResolver.explain(patternTarget);
1332
+ let resolvedVariable = flattenVariable(variable);
1333
+ let matchedPatterns = [];
1334
+ let currentVariableType;
1335
+ if (resolvedVariable.root) {
1336
+ if (isParamVariableRoot(resolvedVariable.root))
1337
+ currentVariableType = this.bindingResolver.explainType(
1338
+ resolvedVariable.root.param.type
1339
+ );
1340
+ else if (isGlobalVariableRoot(resolvedVariable.root)) {
1341
+ currentVariableType = this.bindingResolver.globalType(resolvedVariable.root);
1342
+ } else if (isFunctionCallVariableRoot(resolvedVariable.root)) {
1343
+ let matchedPattern = this.getExpressionStatus(resolvedVariable.root.node);
1344
+ if (matchedPattern) {
1345
+ currentVariableType = matchedPattern.patterns.at(-1).returnType;
1346
+ }
1347
+ } else if (isImportModuleVariableRoot(resolvedVariable.root)) {
1348
+ currentVariableType = this.bindingResolver.explainFlattenedVariableType(resolvedVariable);
1349
+ }
1350
+ }
1351
+ if (resolvedVariable.path.length === 0 && resolvedVariable.root && isLiteralVariableRoot(resolvedVariable.root)) {
1352
+ if (variable.letOrConst === LetOrConst.CONST)
1353
+ return {
1354
+ matchedPatterns: [
1355
+ {
1356
+ patternType: CompilePatternType.CONST_READ,
1357
+ returnType: currentVariableType,
1358
+ callArgumentTypes: [],
1359
+ targetEnvForStatement: JayTargetEnv.any,
1360
+ name: CONST_READ_NAME,
1361
+ leftSidePath: [],
1362
+ leftSideType: currentVariableType
1363
+ }
1364
+ ],
1365
+ matchType: 0
1366
+ /* FULL */
1367
+ };
1368
+ else
1369
+ return {
1370
+ matchedPatterns: [],
1371
+ matchType: 2
1372
+ /* NONE */
1373
+ };
1374
+ }
1375
+ if (currentVariableType) {
1376
+ let currentPosition = 0;
1377
+ while (currentPosition <= resolvedVariable.path.length) {
1378
+ if (resolvedVariable.path.length === 0) {
1379
+ if (variable.definingStatement && isChildOf(variable.definingStatement, analysisScope)) {
1380
+ return {
1381
+ matchedPatterns: [
1382
+ {
1383
+ patternType: CompilePatternType.KNOWN_VARIABLE_READ,
1384
+ returnType: currentVariableType,
1385
+ callArgumentTypes: [],
1386
+ targetEnvForStatement: JayTargetEnv.any,
1387
+ name: KNOWN_VARIABLE_READ_NAME,
1388
+ leftSidePath: [],
1389
+ leftSideType: currentVariableType
1390
+ }
1391
+ ],
1392
+ matchType: 0
1393
+ /* FULL */
1394
+ };
1395
+ }
1396
+ }
1397
+ let currentMatch = this.compiledPatterns.find((pattern) => {
1398
+ let leftTypeMatch = areResolvedTypesCompatible(
1399
+ currentVariableType,
1400
+ pattern.leftSideType
1401
+ );
1402
+ let pathMatch = currentPosition + pattern.leftSidePath.length <= resolvedVariable.path.length && pattern.leftSidePath.every(
1403
+ (element, index) => element === resolvedVariable.path[index + currentPosition]
1404
+ );
1405
+ let expectedTypeMatch = currentPosition + pattern.leftSidePath.length === resolvedVariable.path.length ? areCompatiblePatternTypes(pattern.patternType, expectedPatternType) : areCompatiblePatternTypes(
1406
+ pattern.patternType,
1407
+ CompilePatternType.RETURN
1408
+ );
1409
+ return leftTypeMatch && pathMatch && expectedTypeMatch;
1410
+ });
1411
+ if (currentMatch) {
1412
+ matchedPatterns.push(currentMatch);
1413
+ if (currentPosition + currentMatch.leftSidePath.length < resolvedVariable.path.length) {
1414
+ currentVariableType = currentMatch.returnType;
1415
+ currentPosition += currentMatch.leftSidePath.length;
1416
+ } else
1417
+ return {
1418
+ matchedPatterns,
1419
+ matchType: 0
1420
+ /* FULL */
1421
+ };
1422
+ } else
1423
+ return {
1424
+ matchedPatterns,
1425
+ matchType: matchedPatterns.length > 0 ? 1 : 2
1426
+ /* NONE */
1427
+ };
1428
+ }
1429
+ }
1430
+ return {
1431
+ matchedPatterns: [],
1432
+ matchType: 2
1433
+ /* NONE */
1434
+ };
1435
+ }
1436
+ getExpressionStatus(expression) {
1437
+ return this.analyzedExpressions.get(expression);
1438
+ }
1439
+ getStatementStatus(statement) {
1440
+ return this.analyzedStatements.get(statement);
1441
+ }
1442
+ getMatchedExpressions() {
1443
+ return this.analyzedExpressions.keys();
1444
+ }
1445
+ getAnalyzedStatements() {
1446
+ return this.analyzedStatements.keys();
1447
+ }
1448
+ }
1449
+ function isChildOf(node, parent) {
1450
+ if (node === parent)
1451
+ return false;
1452
+ if (!node.parent)
1453
+ return false;
1454
+ for (const sibling of node.parent.getChildren())
1455
+ if (sibling === node)
1456
+ return true;
1457
+ return isChildOf(node.parent, parent);
1458
+ }
1459
+ var FindComponentConstructorType = /* @__PURE__ */ ((FindComponentConstructorType2) => {
1460
+ FindComponentConstructorType2["makeJayComponent"] = "makeJayComponent";
1461
+ FindComponentConstructorType2["makeJayTsxComponent"] = "makeJayTsxComponent";
1462
+ return FindComponentConstructorType2;
1463
+ })(FindComponentConstructorType || {});
1464
+ function findComponentConstructorCalls(findType, bindingResolver, node) {
1465
+ const foundConstructorCalls = [];
1466
+ if (ts.isVariableStatement(node)) {
1467
+ node.declarationList.declarations.forEach((declaration) => {
1468
+ if (declaration.initializer && ts.isCallExpression(declaration.initializer) && isIdentifierOrPropertyAccessExpression(declaration.initializer.expression)) {
1469
+ const explainedInitializer = bindingResolver.explain(
1470
+ declaration.initializer.expression
1471
+ );
1472
+ const flattened = flattenVariable(explainedInitializer);
1473
+ if (flattened.path.length === 1 && flattened.path[0] === findType && flattened.root && isImportModuleVariableRoot(flattened.root) && ts.isStringLiteral(flattened.root.module) && flattened.root.module.text === compilerShared.JAY_COMPONENT) {
1474
+ let render = findType === "makeJayComponent" ? declaration.initializer.arguments[0] : void 0;
1475
+ let comp = findType === "makeJayComponent" ? declaration.initializer.arguments[1] : declaration.initializer.arguments[0];
1476
+ let foundConstructor = {
1477
+ type: findType,
1478
+ name: declaration.name,
1479
+ render,
1480
+ comp
1481
+ };
1482
+ foundConstructorCalls.push(foundConstructor);
1483
+ }
1484
+ }
1485
+ });
1486
+ }
1487
+ return foundConstructorCalls;
1488
+ }
1489
+ function findComponentConstructorCallsBlock(findType, bindingResolver, sourceFile) {
1490
+ const foundConstructorCalls = [];
1491
+ function visit(node) {
1492
+ foundConstructorCalls.push(
1493
+ ...findComponentConstructorCalls(findType, bindingResolver, node)
1494
+ );
1495
+ ts.forEachChild(node, visit);
1496
+ }
1497
+ ts.forEachChild(sourceFile, visit);
1498
+ return foundConstructorCalls;
1499
+ }
1500
+ class GeneratedFunctionRepository {
1501
+ constructor(hasFunctionRepository, functionRepository) {
1502
+ this.hasFunctionRepository = hasFunctionRepository;
1503
+ this.functionRepository = functionRepository;
1504
+ }
1505
+ map(mapper) {
1506
+ return new GeneratedFunctionRepository(
1507
+ this.hasFunctionRepository,
1508
+ mapper(this.functionRepository)
1509
+ );
1510
+ }
1511
+ }
1512
+ class FunctionRepositoryBuilder {
1513
+ constructor() {
1514
+ __publicField(this, "fragments", []);
1515
+ __publicField(this, "consts", []);
1516
+ __publicField(this, "nextIndex", 0);
1517
+ }
1518
+ addFunction(handlerCode) {
1519
+ if (!handlerCode)
1520
+ return void 0;
1521
+ const key = `${this.nextIndex++}`;
1522
+ this.fragments.push({ key, handlerCode });
1523
+ return key;
1524
+ }
1525
+ addConst(constCode) {
1526
+ if (!constCode)
1527
+ return;
1528
+ this.consts.push(constCode);
1529
+ }
1530
+ generate() {
1531
+ if (this.fragments.length > 0) {
1532
+ let fragments = [
1533
+ ...new Set(this.fragments.map((_) => `'${_.key}': ${_.handlerCode}`))
1534
+ ].join(",\n");
1535
+ let uniqueConstants = [...new Set(this.consts)];
1536
+ let constantsCodeFragment = uniqueConstants.length > 0 ? uniqueConstants.join("\n") + "\n\n" : "";
1537
+ let functionRepository = `${constantsCodeFragment}const funcRepository: FunctionsRepository = {
1538
+ ${fragments}
1539
+ };`;
1540
+ return new GeneratedFunctionRepository(true, functionRepository);
1541
+ } else
1542
+ return new GeneratedFunctionRepository(
1543
+ false,
1544
+ "const funcRepository: FunctionsRepository = {}"
1545
+ );
1546
+ }
1547
+ generateGlobalFile() {
1548
+ return this.generate().map(
1549
+ (_) => `import {FunctionsRepository} from "@jay-framework/secure";
1550
+
1551
+ export ${_}`
1552
+ );
1553
+ }
1554
+ }
1555
+ function findExec$(bindingResolver, sourceFile) {
1556
+ const foundExec$ = [];
1557
+ function visit(node) {
1558
+ if (ts.isCallExpression(node) && ts.isIdentifier(node.expression)) {
1559
+ const functionVariable = bindingResolver.explain(node.expression);
1560
+ const accessChain = flattenVariable(functionVariable);
1561
+ if (accessChain.path.length === 1 && accessChain.path[0] === "exec$" && isImportModuleVariableRoot(accessChain.root) && ts.isStringLiteral(accessChain.root.module) && accessChain.root.module.text === "@jay-framework/secure")
1562
+ foundExec$.push(node);
1563
+ }
1564
+ ts.forEachChild(node, visit);
1565
+ }
1566
+ ts.forEachChild(sourceFile, visit);
1567
+ return foundExec$;
1568
+ }
1569
+ function analyzeGlobalExec$(context, analyzer, functionRepositoryBuilder, foundExec$) {
1570
+ const scopedAnalyzer = analyzer.analyzeForScope(foundExec$);
1571
+ let foundUnsafeExpression = false;
1572
+ const visitor = (node) => {
1573
+ if (ts.isExpression(node)) {
1574
+ const matchedPattern = scopedAnalyzer.getExpressionStatus(node);
1575
+ foundUnsafeExpression = foundUnsafeExpression || !matchedPattern || !matchedPattern.subExpressionsMatching;
1576
+ } else {
1577
+ node.getChildren().forEach((child) => ts.visitNode(child, visitor));
1578
+ }
1579
+ return node;
1580
+ };
1581
+ if (ts.isArrowFunction(foundExec$.arguments[0]))
1582
+ ts.visitNode(foundExec$.arguments[0].body, visitor);
1583
+ if (foundUnsafeExpression)
1584
+ return { foundExec$, wasTransformed: false };
1585
+ else {
1586
+ const key = functionRepositoryBuilder.addFunction(astToCode(foundExec$.arguments[0]));
1587
+ const transformedExec$ = codeToAst(`exec$(funcGlobal$('${key}'))`, context).map(
1588
+ (_) => _.expression
1589
+ )[0];
1590
+ return { foundExec$, wasTransformed: true, transformedExec$ };
1591
+ }
1592
+ }
1593
+ function analyseGlobalExec$s(context, analyzer, functionRepositoryBuilder, foundExec$s) {
1594
+ return foundExec$s.map(
1595
+ (foundExec$) => analyzeGlobalExec$(context, analyzer, functionRepositoryBuilder, foundExec$)
1596
+ );
1597
+ }
1598
+ function transformedGlobalExec$toReplaceMap(transformedGlobalExec$s) {
1599
+ const map = /* @__PURE__ */ new Map();
1600
+ transformedGlobalExec$s.filter((_) => _.wasTransformed).forEach((_) => {
1601
+ map.set(_.foundExec$, _.transformedExec$);
1602
+ });
1603
+ return map;
1604
+ }
1605
+ function generateComponentConstructorCalls(context, componentConstructorCalls, hasFunctionRepository) {
1606
+ let optionsParam = hasFunctionRepository ? ", { funcRepository }" : "";
1607
+ let transformedConstructors = componentConstructorCalls.map(({ name, render }) => {
1608
+ return `${astToCode(name)} = makeJayComponentBridge(${astToCode(render)}${optionsParam})`;
1609
+ });
1610
+ if (transformedConstructors.length > 0) {
1611
+ let declarationCode = `export const ${transformedConstructors.join(", ")}`;
1612
+ return codeToAst(declarationCode, context)[0];
1613
+ } else
1614
+ return void 0;
1615
+ }
1616
+ function getRenderImportSpecifier(node) {
1617
+ const namedBindings = node.importClause?.namedBindings;
1618
+ switch (namedBindings?.kind) {
1619
+ case ts.SyntaxKind.NamedImports: {
1620
+ return namedBindings.elements.find((binding) => getImportName(binding) === "render");
1621
+ }
1622
+ default:
1623
+ return void 0;
1624
+ }
1625
+ }
1626
+ function transformImport(node, importerMode, context, hasFunctionRepository) {
1627
+ if (ts.isStringLiteral(node.moduleSpecifier)) {
1628
+ if (findMakeJayComponentImport(compilerShared.MAKE_JAY_COMPONENT, node)) {
1629
+ const code = hasFunctionRepository ? `import { makeJayComponentBridge, FunctionsRepository } from '@jay-framework/secure';` : `import { makeJayComponentBridge } from '@jay-framework/secure';`;
1630
+ return codeToAst(code, context)[0];
1631
+ }
1632
+ const renderImportSpecifier = getRenderImportSpecifier(node);
1633
+ if (Boolean(renderImportSpecifier)) {
1634
+ const importModule = `${node.moduleSpecifier.text}${compilerShared.getModeFileExtension(
1635
+ true,
1636
+ importerMode
1637
+ )}`;
1638
+ return codeToAst(
1639
+ `import { ${astToCode(renderImportSpecifier)} } from '${importModule}'`,
1640
+ context
1641
+ )[0];
1642
+ }
1643
+ if (node.moduleSpecifier.text === "@jay-framework/runtime")
1644
+ return node;
1645
+ if (node.moduleSpecifier.text.endsWith(".css") && !node.importClause)
1646
+ return node;
1647
+ return void 0;
1648
+ }
1649
+ return void 0;
1650
+ }
1651
+ function transformSourceFile(sourceFile, factory, context, importerMode, componentConstructorCalls, componentFunctionRepository) {
1652
+ let { functionRepository, hasFunctionRepository } = componentFunctionRepository.generate();
1653
+ let generatedComponentConstructorCalls = generateComponentConstructorCalls(
1654
+ context,
1655
+ componentConstructorCalls,
1656
+ hasFunctionRepository
1657
+ );
1658
+ let transformedStatements = sourceFile.statements.map((statement) => {
1659
+ if (ts.isInterfaceDeclaration(statement))
1660
+ return statement;
1661
+ else if (ts.isImportDeclaration(statement))
1662
+ return transformImport(statement, importerMode, context, hasFunctionRepository);
1663
+ else
1664
+ return void 0;
1665
+ }).filter((_) => !!_);
1666
+ const funcRepositoryStatements = hasFunctionRepository ? codeToAst(functionRepository, context) : [];
1667
+ let allStatements = [
1668
+ ...transformedStatements,
1669
+ ...funcRepositoryStatements,
1670
+ generatedComponentConstructorCalls
1671
+ ].filter((_) => !!_);
1672
+ return factory.updateSourceFile(sourceFile, allStatements);
1673
+ }
1674
+ function mkComponentBridgeTransformer({
1675
+ factory,
1676
+ sourceFile,
1677
+ context,
1678
+ importerMode,
1679
+ patterns,
1680
+ globalFunctionRepository
1681
+ }) {
1682
+ let bindingResolver = new SourceFileBindingResolver(sourceFile);
1683
+ let calls = findComponentConstructorCallsBlock(
1684
+ FindComponentConstructorType.makeJayComponent,
1685
+ bindingResolver,
1686
+ sourceFile
1687
+ );
1688
+ let constructorExpressions = calls.map(({ comp }) => comp);
1689
+ let constructorDefinitions = findComponentConstructorsBlock(constructorExpressions, sourceFile);
1690
+ let foundEventHandlers = constructorDefinitions.flatMap(
1691
+ (constructorDefinition) => findEventHandlersBlock(constructorDefinition, bindingResolver)
1692
+ );
1693
+ const elementsEventHandlers = filterEventHandlersToHaveJayEventType(
1694
+ foundEventHandlers,
1695
+ bindingResolver
1696
+ );
1697
+ let analyzer = new SourceFileStatementAnalyzer(sourceFile, bindingResolver, patterns);
1698
+ const componentFunctionRepository = new FunctionRepositoryBuilder();
1699
+ analyzeEventHandlers(
1700
+ context,
1701
+ bindingResolver,
1702
+ analyzer,
1703
+ factory,
1704
+ elementsEventHandlers,
1705
+ componentFunctionRepository
1706
+ );
1707
+ const foundExec$ = findExec$(bindingResolver, sourceFile);
1708
+ analyseGlobalExec$s(context, analyzer, globalFunctionRepository, foundExec$);
1709
+ return transformSourceFile(
1710
+ sourceFile,
1711
+ factory,
1712
+ context,
1713
+ importerMode,
1714
+ calls,
1715
+ componentFunctionRepository
1716
+ );
1717
+ }
1718
+ function transformComponentBridge(importerMode, patterns = [], globalFunctionRepository) {
1719
+ return mkTransformer(mkComponentBridgeTransformer, {
1720
+ importerMode,
1721
+ patterns,
1722
+ globalFunctionRepository
1723
+ });
1724
+ }
1725
+ function transformImportModeFileExtension(node, factory, importerMode) {
1726
+ if (!ts.isStringLiteral(node.moduleSpecifier))
1727
+ return void 0;
1728
+ const originalTarget = node.moduleSpecifier.text;
1729
+ if (!isRelativeImport(originalTarget))
1730
+ return node;
1731
+ return factory.updateImportDeclaration(
1732
+ node,
1733
+ node.modifiers,
1734
+ node.importClause,
1735
+ factory.createStringLiteral(`${originalTarget}${compilerShared.getModeFileExtension(true, importerMode)}`),
1736
+ node.attributes
1737
+ );
1738
+ }
1739
+ function findAfterImportStatementIndex(statements) {
1740
+ let lastIndex = 0;
1741
+ while (ts.isImportDeclaration(statements[lastIndex]))
1742
+ lastIndex += 1;
1743
+ return lastIndex;
1744
+ }
1745
+ function transformComponentImports(needsHandler$, needsFunc$, needsFuncGlobal$, transformedSourceFile, context, factory, sourceFile) {
1746
+ if (needsHandler$ || needsFunc$ || needsFuncGlobal$) {
1747
+ const statements = [...transformedSourceFile.statements];
1748
+ const afterImportStatementIndex = findAfterImportStatementIndex(statements);
1749
+ const importClause = [
1750
+ ...needsHandler$ ? ["handler$"] : [],
1751
+ ...needsFunc$ ? ["func$"] : [],
1752
+ ...needsFuncGlobal$ ? ["funcGlobal$"] : []
1753
+ ].join(", ");
1754
+ const allStatements = [
1755
+ ...statements.slice(0, afterImportStatementIndex),
1756
+ codeToAst(
1757
+ `import { ${importClause} } from '${compilerShared.JAY_SECURE}';`,
1758
+ context
1759
+ )[0],
1760
+ ...statements.slice(afterImportStatementIndex)
1761
+ ];
1762
+ return factory.updateSourceFile(sourceFile, allStatements);
1763
+ } else
1764
+ return transformedSourceFile;
1765
+ }
1766
+ function isCssImport(node) {
1767
+ return ts.isStringLiteral(node.moduleSpecifier) && node.moduleSpecifier.text.endsWith(".css");
1768
+ }
1769
+ function mkComponentTransformer(sftContext) {
1770
+ const { patterns, globalFunctionRepository, context, factory, sourceFile } = sftContext;
1771
+ const bindingResolver = new SourceFileBindingResolver(sourceFile);
1772
+ const calls = findComponentConstructorCallsBlock(
1773
+ FindComponentConstructorType.makeJayComponent,
1774
+ bindingResolver,
1775
+ sourceFile
1776
+ );
1777
+ const constructorExpressions = calls.map(({ comp }) => comp);
1778
+ const constructorDefinitions = findComponentConstructorsBlock(
1779
+ constructorExpressions,
1780
+ sourceFile
1781
+ );
1782
+ const foundEventHandlers = constructorDefinitions.flatMap(
1783
+ (constructorDefinition) => findEventHandlersBlock(constructorDefinition, bindingResolver)
1784
+ );
1785
+ const elementsEventHandlers = filterEventHandlersToHaveJayEventType(
1786
+ foundEventHandlers,
1787
+ bindingResolver
1788
+ );
1789
+ const analyzer = new SourceFileStatementAnalyzer(sourceFile, bindingResolver, patterns);
1790
+ const componentFunctionRepository = new FunctionRepositoryBuilder();
1791
+ const transformedEventHandlers = analyzeEventHandlers(
1792
+ context,
1793
+ bindingResolver,
1794
+ analyzer,
1795
+ factory,
1796
+ elementsEventHandlers,
1797
+ componentFunctionRepository
1798
+ );
1799
+ const eventsReplaceMap = analyzedEventHandlersToReplaceMap(transformedEventHandlers);
1800
+ const foundExec$ = findExec$(bindingResolver, sourceFile);
1801
+ const transformedGlobalExec$ = analyseGlobalExec$s(
1802
+ context,
1803
+ analyzer,
1804
+ globalFunctionRepository,
1805
+ foundExec$
1806
+ );
1807
+ const globalExec$ReplaceMap = transformedGlobalExec$toReplaceMap(transformedGlobalExec$);
1808
+ const replaceMap = new Map([...eventsReplaceMap, ...globalExec$ReplaceMap]);
1809
+ let visitor = (node) => {
1810
+ if (replaceMap.has(node)) {
1811
+ node = replaceMap.get(node);
1812
+ return ts.visitEachChild(node, visitor, context);
1813
+ }
1814
+ if (ts.isImportDeclaration(node)) {
1815
+ if (isCssImport(node))
1816
+ return void 0;
1817
+ else
1818
+ return transformImportModeFileExtension(node, factory, compilerShared.RuntimeMode.WorkerSandbox);
1819
+ }
1820
+ return ts.visitEachChild(node, visitor, context);
1821
+ };
1822
+ let transformedSourceFile = ts.visitEachChild(sftContext.sourceFile, visitor, context);
1823
+ return transformComponentImports(
1824
+ transformedEventHandlers.length > 0,
1825
+ false,
1826
+ transformedGlobalExec$.length > 0,
1827
+ transformedSourceFile,
1828
+ context,
1829
+ factory,
1830
+ sourceFile
1831
+ );
1832
+ }
1833
+ function transformComponent(patterns = [], globalFunctionRepository) {
1834
+ return mkTransformer(mkComponentTransformer, { patterns, globalFunctionRepository });
1835
+ }
1836
+ function createTsSourceFileFromSource(filePath, sourceCode, scriptKind = ts__namespace.ScriptKind.TS) {
1837
+ try {
1838
+ return ts__namespace.createSourceFile(filePath, sourceCode, ts__namespace.ScriptTarget.Latest, true, scriptKind);
1839
+ } catch (error) {
1840
+ throw compilerShared.withOriginalTrace(
1841
+ new Error(`Failed to create TypeScript source file for ${filePath}`),
1842
+ error
1843
+ );
1844
+ }
1845
+ }
1846
+ function generateImportsFileFromTsSource(filename, source) {
1847
+ const sourceFile = createTsSourceFileFromSource(filename, source);
1848
+ return fromImportModules(extractImportedModules(sourceFile));
1849
+ }
1850
+ function generateImportsFileFromJayFile(jayFile) {
1851
+ return fromImportModules(jayFile.imports.map((link) => link.module));
1852
+ }
1853
+ function fromImportModules(modules) {
1854
+ return modules.filter(isRelativeImport).map((module2) => `import '${module2}${compilerShared.JAY_QUERY_WORKER_TRUSTED}'`).join("\n");
1855
+ }
1856
+ function parseImportLinks(sourceFile) {
1857
+ const importDeclarations = extractImportDeclarations(sourceFile).filter(
1858
+ (importDeclaration) => ts__namespace.isStringLiteral(importDeclaration.moduleSpecifier)
1859
+ );
1860
+ const importLinks = importDeclarations.map((importDeclaration) => {
1861
+ const module2 = importDeclaration.moduleSpecifier.text;
1862
+ const sandbox = compilerShared.hasExtension(module2, compilerShared.JAY_QUERY_MAIN_SANDBOX) || compilerShared.hasExtension(module2, compilerShared.JAY_QUERY_WORKER_SANDBOX);
1863
+ const names = getJayImportNames(importDeclaration);
1864
+ return { module: module2, names, sandbox };
1865
+ });
1866
+ return importLinks;
1867
+ }
1868
+ function getJayImportNames(importDeclaration) {
1869
+ const importSpecifiers = getImportSpecifiers(importDeclaration);
1870
+ return importSpecifiers?.map((importSpecifier) => {
1871
+ const as = importSpecifier.propertyName?.text ? importSpecifier.name.text : void 0;
1872
+ const name = getImportName(importSpecifier);
1873
+ return {
1874
+ name,
1875
+ ...as && { as },
1876
+ type: compilerShared.JayUnknown
1877
+ };
1878
+ }) || [];
1879
+ }
1880
+ function parseGenericTypescriptFile(filePath, code) {
1881
+ const sourceFile = createTsSourceFileFromSource(filePath, code);
1882
+ const imports = parseImportLinks(sourceFile);
1883
+ const filename = path.basename(filePath);
1884
+ const baseElementName = changeCase.capitalCase(
1885
+ compilerShared.hasExtension(filename, compilerShared.JAY_EXTENSION) ? compilerShared.withoutExtension(filename, compilerShared.JAY_TS_EXTENSION) : filename.split(".").shift(),
1886
+ { delimiter: "" }
1887
+ );
1888
+ return new compilerShared.WithValidations(
1889
+ {
1890
+ format: compilerShared.SourceFileFormat.TypeScript,
1891
+ imports,
1892
+ baseElementName
1893
+ },
1894
+ []
1895
+ );
1896
+ }
1897
+ function generateElementFile(jayFile, importerMode, generateTarget = compilerShared.GenerateTarget.jay) {
1898
+ return generateTarget === compilerShared.GenerateTarget.jay ? compilerJayHtml.generateElementFile(jayFile, importerMode) : compilerJayHtml.generateElementFileReactTarget(jayFile, importerMode);
1899
+ }
1900
+ Object.defineProperty(exports, "generateElementDefinitionFile", {
1901
+ enumerable: true,
1902
+ get: () => compilerJayHtml.generateElementDefinitionFile
1903
+ });
1904
+ exports.FunctionRepositoryBuilder = FunctionRepositoryBuilder;
1905
+ exports.compileFunctionSplitPatternsBlock = compileFunctionSplitPatternsBlock;
1906
+ exports.createTsSourceFileFromSource = createTsSourceFileFromSource;
1907
+ exports.extractImportDeclarations = extractImportDeclarations;
1908
+ exports.extractImportedModules = extractImportedModules;
1909
+ exports.generateElementFile = generateElementFile;
1910
+ exports.generateImportsFileFromJayFile = generateImportsFileFromJayFile;
1911
+ exports.generateImportsFileFromTsSource = generateImportsFileFromTsSource;
1912
+ exports.getImportName = getImportName;
1913
+ exports.getImportSpecifiers = getImportSpecifiers;
1914
+ exports.isRelativeImport = isRelativeImport;
1915
+ exports.parseGenericTypescriptFile = parseGenericTypescriptFile;
1916
+ exports.transformComponent = transformComponent;
1917
+ exports.transformComponentBridge = transformComponentBridge;
1918
+ exports.transformComponentImports = transformComponentImports;