@vobs/compiler 1.2.1 → 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 +349 -254
- package/dist/compile.cjs.map +1 -1
- package/dist/compile.js +90 -23
- package/dist/compile.js.map +1 -1
- package/dist/i18n-extractor.cjs +45 -16
- package/dist/i18n-extractor.cjs.map +1 -1
- package/dist/i18n-extractor.js +6 -5
- package/dist/i18n-extractor.js.map +1 -1
- package/dist/index.cjs +361 -260
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +99 -28
- package/dist/index.js.map +1 -1
- package/dist/plugin.cjs +18 -2
- package/dist/plugin.cjs.map +1 -1
- package/dist/plugin.d.cts +6 -0
- package/dist/plugin.d.ts +6 -0
- package/dist/plugin.js +0 -2
- package/dist/plugin.js.map +1 -1
- 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/compile.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import ts from 'typescript';
|
|
2
|
-
import { VobsError } from '@vobs/runtime/error';
|
|
3
|
-
|
|
4
1
|
var __defProp = Object.defineProperty;
|
|
5
2
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
|
+
|
|
4
|
+
// packages/compiler/src/compile.ts
|
|
5
|
+
import ts from "typescript";
|
|
6
|
+
import { VobsError } from "@vobs/runtime/error";
|
|
6
7
|
function createCompiler(options = {}) {
|
|
7
8
|
const basePlugins = options.plugins ?? [];
|
|
8
9
|
return {
|
|
@@ -57,7 +58,8 @@ function compileWithSourceMap(code, options = {}) {
|
|
|
57
58
|
sourceLocation: options.sourceLocation ?? true,
|
|
58
59
|
stateAliases: collectStateAliases(sourceFile),
|
|
59
60
|
localBindings: collectLocallyDeclaredNames(sourceFile),
|
|
60
|
-
diagnostics: []
|
|
61
|
+
diagnostics: [],
|
|
62
|
+
hmrModuleId: options.hmrModuleId ?? null
|
|
61
63
|
};
|
|
62
64
|
const cleanFilename = filename.split(/[?#]/u, 1)[0] || filename;
|
|
63
65
|
const diagnostics = ts.transpileModule(code, {
|
|
@@ -83,14 +85,15 @@ function compileWithSourceMap(code, options = {}) {
|
|
|
83
85
|
}
|
|
84
86
|
for (const plugin of plugins) sourceFile = transformPluginNodes(sourceFile, plugin, context);
|
|
85
87
|
const statements = sourceFile.statements.map(
|
|
86
|
-
(statement) => ts.isImportDeclaration(statement) ? rebuildImport(state, statement) : transformStatement(state, statement)
|
|
88
|
+
(statement) => ts.isImportDeclaration(statement) ? rebuildImport(state, statement) : transformStatement(state, statement, true)
|
|
87
89
|
);
|
|
88
90
|
const templateDeclarations = createTemplateDeclarations(state);
|
|
89
|
-
|
|
91
|
+
let resultFile = ts.factory.updateSourceFile(sourceFile, [
|
|
90
92
|
...createRuntimeImports(state),
|
|
91
93
|
...templateDeclarations,
|
|
92
94
|
...statements
|
|
93
95
|
]);
|
|
96
|
+
resultFile = transformResidualJsx(state, resultFile);
|
|
94
97
|
const generated = ts.createPrinter().printFile(resultFile);
|
|
95
98
|
return {
|
|
96
99
|
code: generated,
|
|
@@ -372,7 +375,7 @@ function rebuildImport(state, node) {
|
|
|
372
375
|
), node);
|
|
373
376
|
}
|
|
374
377
|
__name(rebuildImport, "rebuildImport");
|
|
375
|
-
function transformStatement(state, node) {
|
|
378
|
+
function transformStatement(state, node, moduleScope = false) {
|
|
376
379
|
if (ts.isFunctionDeclaration(node) && node.body) {
|
|
377
380
|
return tagStatement(state, ts.factory.updateFunctionDeclaration(
|
|
378
381
|
node,
|
|
@@ -385,7 +388,7 @@ function transformStatement(state, node) {
|
|
|
385
388
|
transformBlock(state, node.body)
|
|
386
389
|
), node);
|
|
387
390
|
}
|
|
388
|
-
if (ts.isVariableStatement(node)) return transformVariableStatement(state, node);
|
|
391
|
+
if (ts.isVariableStatement(node)) return transformVariableStatement(state, node, moduleScope);
|
|
389
392
|
if (ts.isExportAssignment(node) && containsJsx(node.expression)) {
|
|
390
393
|
return tagStatement(state, ts.factory.updateExportAssignment(node, node.modifiers, transformEmbeddedExpression(state, node.expression)), node);
|
|
391
394
|
}
|
|
@@ -398,7 +401,7 @@ function transformStatement(state, node) {
|
|
|
398
401
|
return node;
|
|
399
402
|
}
|
|
400
403
|
__name(transformStatement, "transformStatement");
|
|
401
|
-
function transformVariableStatement(state, node) {
|
|
404
|
+
function transformVariableStatement(state, node, moduleScope = false) {
|
|
402
405
|
let changed = false;
|
|
403
406
|
const declarations = node.declarationList.declarations.map((declaration) => {
|
|
404
407
|
const initializer = declaration.initializer;
|
|
@@ -406,6 +409,8 @@ function transformVariableStatement(state, node) {
|
|
|
406
409
|
let nextInitializer = inferStateDebugName(state, declaration, initializer) ?? initializer;
|
|
407
410
|
if (containsJsx(nextInitializer)) {
|
|
408
411
|
nextInitializer = transformEmbeddedExpression(state, nextInitializer);
|
|
412
|
+
} else if (moduleScope && state.hmrModuleId !== null) {
|
|
413
|
+
nextInitializer = wrapStateWithHmrRef(state, declaration, nextInitializer) ?? nextInitializer;
|
|
409
414
|
}
|
|
410
415
|
if (nextInitializer === initializer) return declaration;
|
|
411
416
|
changed = true;
|
|
@@ -443,6 +448,29 @@ function inferStateDebugName(state, declaration, initializer) {
|
|
|
443
448
|
]);
|
|
444
449
|
}
|
|
445
450
|
__name(inferStateDebugName, "inferStateDebugName");
|
|
451
|
+
function wrapStateWithHmrRef(state, declaration, initializer) {
|
|
452
|
+
let call = initializer;
|
|
453
|
+
while (ts.isParenthesizedExpression(call) || ts.isAsExpression(call) || ts.isTypeAssertionExpression(call) || ts.isSatisfiesExpression(call)) {
|
|
454
|
+
call = call.expression;
|
|
455
|
+
}
|
|
456
|
+
if (!ts.isCallExpression(call)) return void 0;
|
|
457
|
+
const callee = call.expression;
|
|
458
|
+
if (!ts.isIdentifier(callee) || !state.stateAliases.has(callee.text)) return void 0;
|
|
459
|
+
if (state.localBindings.has(callee.text)) return void 0;
|
|
460
|
+
if (!ts.isIdentifier(declaration.name)) return void 0;
|
|
461
|
+
return ts.factory.createCallExpression(helperRef(state, "hmrStateRef"), void 0, [
|
|
462
|
+
ts.factory.createStringLiteral(`${state.hmrModuleId}#${declaration.name.text}`),
|
|
463
|
+
ts.factory.createArrowFunction(
|
|
464
|
+
void 0,
|
|
465
|
+
void 0,
|
|
466
|
+
[],
|
|
467
|
+
void 0,
|
|
468
|
+
ts.factory.createToken(ts.SyntaxKind.EqualsGreaterThanToken),
|
|
469
|
+
initializer
|
|
470
|
+
)
|
|
471
|
+
]);
|
|
472
|
+
}
|
|
473
|
+
__name(wrapStateWithHmrRef, "wrapStateWithHmrRef");
|
|
446
474
|
function containsJsx(expression) {
|
|
447
475
|
let found = false;
|
|
448
476
|
const visit = /* @__PURE__ */ __name((node) => {
|
|
@@ -703,6 +731,27 @@ function transformEmbeddedExpression(state, expression) {
|
|
|
703
731
|
}
|
|
704
732
|
}
|
|
705
733
|
__name(transformEmbeddedExpression, "transformEmbeddedExpression");
|
|
734
|
+
function transformResidualJsx(state, sourceFile) {
|
|
735
|
+
if (!containsJsx(sourceFile)) return sourceFile;
|
|
736
|
+
const result = ts.transform(sourceFile, [(context) => (root) => {
|
|
737
|
+
const visit = /* @__PURE__ */ __name((node) => {
|
|
738
|
+
if (ts.isReturnStatement(node) && node.expression && containsJsx(node.expression)) {
|
|
739
|
+
return ts.factory.updateReturnStatement(node, transformEmbeddedExpression(state, node.expression));
|
|
740
|
+
}
|
|
741
|
+
if (isJsxExpression(node)) {
|
|
742
|
+
return transformJsxExpression(state, node);
|
|
743
|
+
}
|
|
744
|
+
return ts.visitEachChild(node, visit, context);
|
|
745
|
+
}, "visit");
|
|
746
|
+
return ts.visitNode(root, visit);
|
|
747
|
+
}]);
|
|
748
|
+
try {
|
|
749
|
+
return result.transformed[0];
|
|
750
|
+
} finally {
|
|
751
|
+
result.dispose();
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
__name(transformResidualJsx, "transformResidualJsx");
|
|
706
755
|
function isStaticElement(tagName, attributes, children) {
|
|
707
756
|
if (!ts.isIdentifier(tagName) || !/^[a-z]/.test(tagName.text)) return false;
|
|
708
757
|
for (const attribute of attributes.properties) {
|
|
@@ -955,36 +1004,52 @@ function createSourceLocation(node) {
|
|
|
955
1004
|
}
|
|
956
1005
|
__name(createSourceLocation, "createSourceLocation");
|
|
957
1006
|
function transformDynamicExpression(state, expression) {
|
|
1007
|
+
const converted = convertDynamicNodeExpression(state, expression);
|
|
1008
|
+
return converted ? createGetter(converted) : null;
|
|
1009
|
+
}
|
|
1010
|
+
__name(transformDynamicExpression, "transformDynamicExpression");
|
|
1011
|
+
function convertDynamicNodeExpression(state, expression) {
|
|
958
1012
|
if (ts.isBinaryExpression(expression) && expression.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken) {
|
|
959
1013
|
const right = unwrapExpression(expression.right);
|
|
960
|
-
if (
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
ts.factory.createNull()
|
|
967
|
-
));
|
|
1014
|
+
if (isJsxExpression(right)) {
|
|
1015
|
+
return createNodeConditional(expression.left, transformJsxExpression(state, right), null);
|
|
1016
|
+
}
|
|
1017
|
+
const convertedRight = convertDynamicNodeExpression(state, right);
|
|
1018
|
+
if (convertedRight) return createNodeConditional(expression.left, convertedRight, null);
|
|
1019
|
+
return null;
|
|
968
1020
|
}
|
|
969
1021
|
if (ts.isConditionalExpression(expression)) {
|
|
970
1022
|
const whenTrue = transformDynamicBranch(state, expression.whenTrue);
|
|
971
1023
|
const whenFalse = transformDynamicBranch(state, expression.whenFalse);
|
|
972
1024
|
if (!whenTrue && !whenFalse) return null;
|
|
973
|
-
return
|
|
1025
|
+
return ts.factory.createConditionalExpression(
|
|
974
1026
|
expression.condition,
|
|
975
1027
|
ts.factory.createToken(ts.SyntaxKind.QuestionToken),
|
|
976
1028
|
whenTrue ?? ts.factory.createNull(),
|
|
977
1029
|
ts.factory.createToken(ts.SyntaxKind.ColonToken),
|
|
978
1030
|
whenFalse ?? ts.factory.createNull()
|
|
979
|
-
)
|
|
1031
|
+
);
|
|
980
1032
|
}
|
|
981
1033
|
return null;
|
|
982
1034
|
}
|
|
983
|
-
__name(
|
|
1035
|
+
__name(convertDynamicNodeExpression, "convertDynamicNodeExpression");
|
|
1036
|
+
function createNodeConditional(condition, whenTrue, whenFalse) {
|
|
1037
|
+
return ts.factory.createConditionalExpression(
|
|
1038
|
+
condition,
|
|
1039
|
+
ts.factory.createToken(ts.SyntaxKind.QuestionToken),
|
|
1040
|
+
whenTrue,
|
|
1041
|
+
ts.factory.createToken(ts.SyntaxKind.ColonToken),
|
|
1042
|
+
whenFalse ?? ts.factory.createNull()
|
|
1043
|
+
);
|
|
1044
|
+
}
|
|
1045
|
+
__name(createNodeConditional, "createNodeConditional");
|
|
984
1046
|
function transformDynamicBranch(state, expression) {
|
|
985
1047
|
const branch = unwrapExpression(expression);
|
|
986
1048
|
if (isJsxExpression(branch)) return transformJsxExpression(state, branch);
|
|
987
1049
|
if (branch.kind === ts.SyntaxKind.NullKeyword || branch.kind === ts.SyntaxKind.FalseKeyword) return branch;
|
|
1050
|
+
if (ts.isConditionalExpression(branch) || ts.isBinaryExpression(branch) && branch.operatorToken.kind === ts.SyntaxKind.AmpersandAmpersandToken) {
|
|
1051
|
+
return convertDynamicNodeExpression(state, branch);
|
|
1052
|
+
}
|
|
988
1053
|
return null;
|
|
989
1054
|
}
|
|
990
1055
|
__name(transformDynamicBranch, "transformDynamicBranch");
|
|
@@ -1135,7 +1200,9 @@ function nextIdentifier(state, prefix) {
|
|
|
1135
1200
|
return ts.factory.createIdentifier(name);
|
|
1136
1201
|
}
|
|
1137
1202
|
__name(nextIdentifier, "nextIdentifier");
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1203
|
+
export {
|
|
1204
|
+
compile,
|
|
1205
|
+
compileWithSourceMap,
|
|
1206
|
+
createCompiler
|
|
1207
|
+
};
|
|
1141
1208
|
//# sourceMappingURL=compile.js.map
|