@vobs/compiler 1.2.2 → 1.3.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/compile.cjs +81 -17
- package/dist/compile.cjs.map +1 -1
- package/dist/compile.js +81 -17
- package/dist/compile.js.map +1 -1
- package/dist/index.cjs +81 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +81 -17
- package/dist/index.js.map +1 -1
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.d.cts +6 -0
- package/dist/plugin.d.ts +6 -0
- package/package.json +2 -2
- package/src/compile.test.ts +74 -0
- package/src/compile.ts +113 -17
- package/src/plugin.ts +6 -0
package/dist/index.cjs
CHANGED
|
@@ -96,7 +96,8 @@ function compileWithSourceMap(code, options = {}) {
|
|
|
96
96
|
sourceLocation: options.sourceLocation ?? true,
|
|
97
97
|
stateAliases: collectStateAliases(sourceFile),
|
|
98
98
|
localBindings: collectLocallyDeclaredNames(sourceFile),
|
|
99
|
-
diagnostics: []
|
|
99
|
+
diagnostics: [],
|
|
100
|
+
hmrModuleId: options.hmrModuleId ?? null
|
|
100
101
|
};
|
|
101
102
|
const cleanFilename = filename.split(/[?#]/u, 1)[0] || filename;
|
|
102
103
|
const diagnostics = import_typescript.default.transpileModule(code, {
|
|
@@ -122,14 +123,15 @@ function compileWithSourceMap(code, options = {}) {
|
|
|
122
123
|
}
|
|
123
124
|
for (const plugin of plugins) sourceFile = transformPluginNodes(sourceFile, plugin, context);
|
|
124
125
|
const statements = sourceFile.statements.map(
|
|
125
|
-
(statement) => import_typescript.default.isImportDeclaration(statement) ? rebuildImport(state, statement) : transformStatement(state, statement)
|
|
126
|
+
(statement) => import_typescript.default.isImportDeclaration(statement) ? rebuildImport(state, statement) : transformStatement(state, statement, true)
|
|
126
127
|
);
|
|
127
128
|
const templateDeclarations = createTemplateDeclarations(state);
|
|
128
|
-
|
|
129
|
+
let resultFile = import_typescript.default.factory.updateSourceFile(sourceFile, [
|
|
129
130
|
...createRuntimeImports(state),
|
|
130
131
|
...templateDeclarations,
|
|
131
132
|
...statements
|
|
132
133
|
]);
|
|
134
|
+
resultFile = transformResidualJsx(state, resultFile);
|
|
133
135
|
const generated = import_typescript.default.createPrinter().printFile(resultFile);
|
|
134
136
|
return {
|
|
135
137
|
code: generated,
|
|
@@ -411,7 +413,7 @@ function rebuildImport(state, node) {
|
|
|
411
413
|
), node);
|
|
412
414
|
}
|
|
413
415
|
__name(rebuildImport, "rebuildImport");
|
|
414
|
-
function transformStatement(state, node) {
|
|
416
|
+
function transformStatement(state, node, moduleScope = false) {
|
|
415
417
|
if (import_typescript.default.isFunctionDeclaration(node) && node.body) {
|
|
416
418
|
return tagStatement(state, import_typescript.default.factory.updateFunctionDeclaration(
|
|
417
419
|
node,
|
|
@@ -424,7 +426,7 @@ function transformStatement(state, node) {
|
|
|
424
426
|
transformBlock(state, node.body)
|
|
425
427
|
), node);
|
|
426
428
|
}
|
|
427
|
-
if (import_typescript.default.isVariableStatement(node)) return transformVariableStatement(state, node);
|
|
429
|
+
if (import_typescript.default.isVariableStatement(node)) return transformVariableStatement(state, node, moduleScope);
|
|
428
430
|
if (import_typescript.default.isExportAssignment(node) && containsJsx(node.expression)) {
|
|
429
431
|
return tagStatement(state, import_typescript.default.factory.updateExportAssignment(node, node.modifiers, transformEmbeddedExpression(state, node.expression)), node);
|
|
430
432
|
}
|
|
@@ -437,7 +439,7 @@ function transformStatement(state, node) {
|
|
|
437
439
|
return node;
|
|
438
440
|
}
|
|
439
441
|
__name(transformStatement, "transformStatement");
|
|
440
|
-
function transformVariableStatement(state, node) {
|
|
442
|
+
function transformVariableStatement(state, node, moduleScope = false) {
|
|
441
443
|
let changed = false;
|
|
442
444
|
const declarations = node.declarationList.declarations.map((declaration) => {
|
|
443
445
|
const initializer = declaration.initializer;
|
|
@@ -445,6 +447,8 @@ function transformVariableStatement(state, node) {
|
|
|
445
447
|
let nextInitializer = inferStateDebugName(state, declaration, initializer) ?? initializer;
|
|
446
448
|
if (containsJsx(nextInitializer)) {
|
|
447
449
|
nextInitializer = transformEmbeddedExpression(state, nextInitializer);
|
|
450
|
+
} else if (moduleScope && state.hmrModuleId !== null) {
|
|
451
|
+
nextInitializer = wrapStateWithHmrRef(state, declaration, nextInitializer) ?? nextInitializer;
|
|
448
452
|
}
|
|
449
453
|
if (nextInitializer === initializer) return declaration;
|
|
450
454
|
changed = true;
|
|
@@ -482,6 +486,29 @@ function inferStateDebugName(state, declaration, initializer) {
|
|
|
482
486
|
]);
|
|
483
487
|
}
|
|
484
488
|
__name(inferStateDebugName, "inferStateDebugName");
|
|
489
|
+
function wrapStateWithHmrRef(state, declaration, initializer) {
|
|
490
|
+
let call = initializer;
|
|
491
|
+
while (import_typescript.default.isParenthesizedExpression(call) || import_typescript.default.isAsExpression(call) || import_typescript.default.isTypeAssertionExpression(call) || import_typescript.default.isSatisfiesExpression(call)) {
|
|
492
|
+
call = call.expression;
|
|
493
|
+
}
|
|
494
|
+
if (!import_typescript.default.isCallExpression(call)) return void 0;
|
|
495
|
+
const callee = call.expression;
|
|
496
|
+
if (!import_typescript.default.isIdentifier(callee) || !state.stateAliases.has(callee.text)) return void 0;
|
|
497
|
+
if (state.localBindings.has(callee.text)) return void 0;
|
|
498
|
+
if (!import_typescript.default.isIdentifier(declaration.name)) return void 0;
|
|
499
|
+
return import_typescript.default.factory.createCallExpression(helperRef(state, "hmrStateRef"), void 0, [
|
|
500
|
+
import_typescript.default.factory.createStringLiteral(`${state.hmrModuleId}#${declaration.name.text}`),
|
|
501
|
+
import_typescript.default.factory.createArrowFunction(
|
|
502
|
+
void 0,
|
|
503
|
+
void 0,
|
|
504
|
+
[],
|
|
505
|
+
void 0,
|
|
506
|
+
import_typescript.default.factory.createToken(import_typescript.default.SyntaxKind.EqualsGreaterThanToken),
|
|
507
|
+
initializer
|
|
508
|
+
)
|
|
509
|
+
]);
|
|
510
|
+
}
|
|
511
|
+
__name(wrapStateWithHmrRef, "wrapStateWithHmrRef");
|
|
485
512
|
function containsJsx(expression) {
|
|
486
513
|
let found = false;
|
|
487
514
|
const visit = /* @__PURE__ */ __name((node) => {
|
|
@@ -742,6 +769,27 @@ function transformEmbeddedExpression(state, expression) {
|
|
|
742
769
|
}
|
|
743
770
|
}
|
|
744
771
|
__name(transformEmbeddedExpression, "transformEmbeddedExpression");
|
|
772
|
+
function transformResidualJsx(state, sourceFile) {
|
|
773
|
+
if (!containsJsx(sourceFile)) return sourceFile;
|
|
774
|
+
const result = import_typescript.default.transform(sourceFile, [(context) => (root) => {
|
|
775
|
+
const visit = /* @__PURE__ */ __name((node) => {
|
|
776
|
+
if (import_typescript.default.isReturnStatement(node) && node.expression && containsJsx(node.expression)) {
|
|
777
|
+
return import_typescript.default.factory.updateReturnStatement(node, transformEmbeddedExpression(state, node.expression));
|
|
778
|
+
}
|
|
779
|
+
if (isJsxExpression(node)) {
|
|
780
|
+
return transformJsxExpression(state, node);
|
|
781
|
+
}
|
|
782
|
+
return import_typescript.default.visitEachChild(node, visit, context);
|
|
783
|
+
}, "visit");
|
|
784
|
+
return import_typescript.default.visitNode(root, visit);
|
|
785
|
+
}]);
|
|
786
|
+
try {
|
|
787
|
+
return result.transformed[0];
|
|
788
|
+
} finally {
|
|
789
|
+
result.dispose();
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
__name(transformResidualJsx, "transformResidualJsx");
|
|
745
793
|
function isStaticElement(tagName, attributes, children) {
|
|
746
794
|
if (!import_typescript.default.isIdentifier(tagName) || !/^[a-z]/.test(tagName.text)) return false;
|
|
747
795
|
for (const attribute of attributes.properties) {
|
|
@@ -994,36 +1042,52 @@ function createSourceLocation(node) {
|
|
|
994
1042
|
}
|
|
995
1043
|
__name(createSourceLocation, "createSourceLocation");
|
|
996
1044
|
function transformDynamicExpression(state, expression) {
|
|
1045
|
+
const converted = convertDynamicNodeExpression(state, expression);
|
|
1046
|
+
return converted ? createGetter(converted) : null;
|
|
1047
|
+
}
|
|
1048
|
+
__name(transformDynamicExpression, "transformDynamicExpression");
|
|
1049
|
+
function convertDynamicNodeExpression(state, expression) {
|
|
997
1050
|
if (import_typescript.default.isBinaryExpression(expression) && expression.operatorToken.kind === import_typescript.default.SyntaxKind.AmpersandAmpersandToken) {
|
|
998
1051
|
const right = unwrapExpression(expression.right);
|
|
999
|
-
if (
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
import_typescript.default.factory.createNull()
|
|
1006
|
-
));
|
|
1052
|
+
if (isJsxExpression(right)) {
|
|
1053
|
+
return createNodeConditional(expression.left, transformJsxExpression(state, right), null);
|
|
1054
|
+
}
|
|
1055
|
+
const convertedRight = convertDynamicNodeExpression(state, right);
|
|
1056
|
+
if (convertedRight) return createNodeConditional(expression.left, convertedRight, null);
|
|
1057
|
+
return null;
|
|
1007
1058
|
}
|
|
1008
1059
|
if (import_typescript.default.isConditionalExpression(expression)) {
|
|
1009
1060
|
const whenTrue = transformDynamicBranch(state, expression.whenTrue);
|
|
1010
1061
|
const whenFalse = transformDynamicBranch(state, expression.whenFalse);
|
|
1011
1062
|
if (!whenTrue && !whenFalse) return null;
|
|
1012
|
-
return
|
|
1063
|
+
return import_typescript.default.factory.createConditionalExpression(
|
|
1013
1064
|
expression.condition,
|
|
1014
1065
|
import_typescript.default.factory.createToken(import_typescript.default.SyntaxKind.QuestionToken),
|
|
1015
1066
|
whenTrue ?? import_typescript.default.factory.createNull(),
|
|
1016
1067
|
import_typescript.default.factory.createToken(import_typescript.default.SyntaxKind.ColonToken),
|
|
1017
1068
|
whenFalse ?? import_typescript.default.factory.createNull()
|
|
1018
|
-
)
|
|
1069
|
+
);
|
|
1019
1070
|
}
|
|
1020
1071
|
return null;
|
|
1021
1072
|
}
|
|
1022
|
-
__name(
|
|
1073
|
+
__name(convertDynamicNodeExpression, "convertDynamicNodeExpression");
|
|
1074
|
+
function createNodeConditional(condition, whenTrue, whenFalse) {
|
|
1075
|
+
return import_typescript.default.factory.createConditionalExpression(
|
|
1076
|
+
condition,
|
|
1077
|
+
import_typescript.default.factory.createToken(import_typescript.default.SyntaxKind.QuestionToken),
|
|
1078
|
+
whenTrue,
|
|
1079
|
+
import_typescript.default.factory.createToken(import_typescript.default.SyntaxKind.ColonToken),
|
|
1080
|
+
whenFalse ?? import_typescript.default.factory.createNull()
|
|
1081
|
+
);
|
|
1082
|
+
}
|
|
1083
|
+
__name(createNodeConditional, "createNodeConditional");
|
|
1023
1084
|
function transformDynamicBranch(state, expression) {
|
|
1024
1085
|
const branch = unwrapExpression(expression);
|
|
1025
1086
|
if (isJsxExpression(branch)) return transformJsxExpression(state, branch);
|
|
1026
1087
|
if (branch.kind === import_typescript.default.SyntaxKind.NullKeyword || branch.kind === import_typescript.default.SyntaxKind.FalseKeyword) return branch;
|
|
1088
|
+
if (import_typescript.default.isConditionalExpression(branch) || import_typescript.default.isBinaryExpression(branch) && branch.operatorToken.kind === import_typescript.default.SyntaxKind.AmpersandAmpersandToken) {
|
|
1089
|
+
return convertDynamicNodeExpression(state, branch);
|
|
1090
|
+
}
|
|
1027
1091
|
return null;
|
|
1028
1092
|
}
|
|
1029
1093
|
__name(transformDynamicBranch, "transformDynamicBranch");
|