@generaltranslation/vue-extractor 0.1.0-iris.0 → 0.1.0-iris.1
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/internal/script/analyze.js +76 -28
- package/dist/internal/script/analyze.js.map +1 -1
- package/dist/internal/script/knownValues.js +4 -0
- package/dist/internal/script/knownValues.js.map +1 -1
- package/dist/internal/script/localModules.js +2 -0
- package/dist/internal/script/localModules.js.map +1 -1
- package/dist/internal/script/model.d.ts +1 -1
- package/dist/internal/script/runtimeModules.d.ts +1 -1
- package/dist/internal/script/runtimeModules.js +1 -1
- package/dist/internal/script/runtimeModules.js.map +1 -1
- package/dist/internal/stringCalls.js +8 -2
- package/dist/internal/stringCalls.js.map +1 -1
- package/dist/internal/template.js +1 -1
- package/dist/internal/template.js.map +1 -1
- package/dist/internal/types.d.ts +1 -1
- package/package.json +1 -1
|
@@ -138,7 +138,7 @@ function parseVueScript(source, language, context, templateBindings, exposeToTem
|
|
|
138
138
|
const localCallable = resolveCalledFunction(path.node.callee, path.scope, state, /* @__PURE__ */ new Set());
|
|
139
139
|
const calleePath = readResolvedMemberPath(path.node.callee, path.scope, state);
|
|
140
140
|
const uncertainTranslationHelper = Boolean(calleePath && pathMayReferenceUncertainTranslationHelper(path.node.callee, calleePath, path.scope, state) && callArgumentsMayProvideTranslationFunction(path.node, path.scope, state));
|
|
141
|
-
if (!callTarget.definitelyOrdinary && !localCallable && calleePath && (callTarget.possibleStringFunction || uncertainTranslationHelper || templateBindings.uncertainStringFunctions.has(calleePath) || state.analysis.uncertainStringFunctions.has(calleePath) || calleePath.endsWith(".value") && templateBindings.uncertainStringFunctions.has(calleePath.slice(0, -6)))) addVueError(context, consumerLocation, `Could not statically resolve possible gt-vue string function alias "${calleePath}"`, "Use a direct, immutable alias of useGT(), useMessages(), or
|
|
141
|
+
if (!callTarget.definitelyOrdinary && !localCallable && calleePath && (callTarget.possibleStringFunction || uncertainTranslationHelper || templateBindings.uncertainStringFunctions.has(calleePath) || state.analysis.uncertainStringFunctions.has(calleePath) || calleePath.endsWith(".value") && templateBindings.uncertainStringFunctions.has(calleePath.slice(0, -6)))) addVueError(context, consumerLocation, `Could not statically resolve possible gt-vue string function alias "${calleePath}"`, "Use a direct, immutable alias of useGT(), useMessages(), msg(), or t()");
|
|
142
142
|
processForwardedTranslationCalls(path, consumerLocation);
|
|
143
143
|
return;
|
|
144
144
|
}
|
|
@@ -374,6 +374,7 @@ function recordRuntimeReexport(source, exportNames, importerFile, state) {
|
|
|
374
374
|
if ((exportNames.includes("*") ? [
|
|
375
375
|
...COMPONENT_IMPORTS,
|
|
376
376
|
"msg",
|
|
377
|
+
"t",
|
|
377
378
|
"useGT",
|
|
378
379
|
"useMessages"
|
|
379
380
|
] : exportNames).some((name) => resolver.hasGTExportReference(modulePath, name))) state.analysis.hasGTSourceReference = true;
|
|
@@ -447,6 +448,7 @@ function recordDynamicImportPattern(pattern, source, scope, importerFile, state)
|
|
|
447
448
|
for (const exportName of [
|
|
448
449
|
...COMPONENT_IMPORTS,
|
|
449
450
|
"msg",
|
|
451
|
+
"t",
|
|
450
452
|
"useGT",
|
|
451
453
|
"useMessages"
|
|
452
454
|
]) recordDynamicImportBinding(appendTemplatePath(pattern.name, exportName), exportName, modulePath, state, bindingReferencesNamespaceMember(binding, exportName, state));
|
|
@@ -456,11 +458,13 @@ function recordDynamicImportPattern(pattern, source, scope, importerFile, state)
|
|
|
456
458
|
state.analysis.uncertainComponents.add(path);
|
|
457
459
|
state.analysis.uncertainGTComponents.add(path);
|
|
458
460
|
}
|
|
459
|
-
|
|
461
|
+
const stringFunctions = [
|
|
460
462
|
"msg",
|
|
461
463
|
"useGT",
|
|
462
464
|
"useMessages"
|
|
463
|
-
]
|
|
465
|
+
];
|
|
466
|
+
if (source === "gt-vue") stringFunctions.push("t");
|
|
467
|
+
for (const name of stringFunctions) state.analysis.uncertainStringFunctions.add(appendTemplatePath(pattern.name, name));
|
|
464
468
|
}
|
|
465
469
|
return;
|
|
466
470
|
}
|
|
@@ -470,14 +474,14 @@ function recordDynamicImportPattern(pattern, source, scope, importerFile, state)
|
|
|
470
474
|
const exportedName = readPropertyKey(property);
|
|
471
475
|
const localName = readPatternIdentifier(property.value);
|
|
472
476
|
if (exportedName && localName) if (modulePath) recordDynamicImportBinding(localName, exportedName, modulePath, state, importerFile === state.analysis.entryFile);
|
|
473
|
-
else recordUnresolvedGTShapedBinding(localName, exportedName, state);
|
|
477
|
+
else recordUnresolvedGTShapedBinding(localName, exportedName, state, source === "gt-vue");
|
|
474
478
|
}
|
|
475
479
|
for (const property of pattern.properties) {
|
|
476
480
|
if (property.type !== "ObjectProperty" || !property.computed) continue;
|
|
477
481
|
const exportedName = readResolvedPropertyKey(property, scope, state);
|
|
478
482
|
const localName = readPatternIdentifier(property.value);
|
|
479
483
|
if (exportedName && localName) if (modulePath) recordDynamicImportBinding(localName, exportedName, modulePath, state, importerFile === state.analysis.entryFile);
|
|
480
|
-
else recordUnresolvedGTShapedBinding(localName, exportedName, state);
|
|
484
|
+
else recordUnresolvedGTShapedBinding(localName, exportedName, state, source === "gt-vue");
|
|
481
485
|
}
|
|
482
486
|
}
|
|
483
487
|
/** Returns whether one namespace binding is used through a static member. */
|
|
@@ -678,6 +682,7 @@ function recordLocalNamespaceMembers(localName, modulePath, state, binding) {
|
|
|
678
682
|
...resolver.listExportNames(modulePath),
|
|
679
683
|
...COMPONENT_IMPORTS,
|
|
680
684
|
"msg",
|
|
685
|
+
"t",
|
|
681
686
|
"useGT",
|
|
682
687
|
"useMessages"
|
|
683
688
|
]);
|
|
@@ -705,27 +710,29 @@ function recordLocalNamespaceMembers(localName, modulePath, state, binding) {
|
|
|
705
710
|
/** Retains the original gt-vue role hidden by a malformed re-export alias. */
|
|
706
711
|
function recordInvalidGTResolution(localName, resolution, state) {
|
|
707
712
|
if (resolution.gtExportName === "*") {
|
|
708
|
-
recordUnresolvedGTNamespace(localName, state);
|
|
713
|
+
recordUnresolvedGTNamespace(localName, state, true);
|
|
709
714
|
return;
|
|
710
715
|
}
|
|
711
716
|
if (resolution.gtExportName) {
|
|
712
|
-
recordUnresolvedGTShapedBinding(localName, resolution.gtExportName, state);
|
|
717
|
+
recordUnresolvedGTShapedBinding(localName, resolution.gtExportName, state, true);
|
|
713
718
|
return;
|
|
714
719
|
}
|
|
715
720
|
state.analysis.uncertainTranslationHelpers.add(localName);
|
|
716
721
|
}
|
|
717
722
|
/** Marks the GT-shaped members of one unresolved namespace path. */
|
|
718
|
-
function recordUnresolvedGTNamespace(localName, state) {
|
|
723
|
+
function recordUnresolvedGTNamespace(localName, state, includeImmediateTranslation = false) {
|
|
719
724
|
for (const component of COMPONENT_IMPORTS) {
|
|
720
725
|
const componentPath = appendTemplatePath(localName, component);
|
|
721
726
|
state.analysis.uncertainComponents.add(componentPath);
|
|
722
727
|
state.analysis.uncertainGTComponents.add(componentPath);
|
|
723
728
|
}
|
|
724
|
-
|
|
729
|
+
const stringFunctions = [
|
|
725
730
|
"msg",
|
|
726
731
|
"useGT",
|
|
727
732
|
"useMessages"
|
|
728
|
-
]
|
|
733
|
+
];
|
|
734
|
+
if (includeImmediateTranslation) stringFunctions.push("t");
|
|
735
|
+
for (const name of stringFunctions) state.analysis.uncertainStringFunctions.add(appendTemplatePath(localName, name));
|
|
729
736
|
}
|
|
730
737
|
/** Records unresolved roles only when a local export can actually be GT. */
|
|
731
738
|
function recordMaterializedLocalUncertainty(localName, materialized, state, forceKnownValues = false) {
|
|
@@ -768,12 +775,12 @@ function recordUncertainTranslationHelperBinding(localName, scope, state) {
|
|
|
768
775
|
if (binding) state.uncertainTranslationHelperBindings.add(binding);
|
|
769
776
|
}
|
|
770
777
|
/** Records the conservative GT roles implied by an unresolved export name. */
|
|
771
|
-
function recordUnresolvedGTShapedBinding(localName, exportName, state) {
|
|
778
|
+
function recordUnresolvedGTShapedBinding(localName, exportName, state, includeImmediateTranslation = false) {
|
|
772
779
|
if (COMPONENT_IMPORTS.has(exportName)) {
|
|
773
780
|
state.analysis.uncertainComponents.add(localName);
|
|
774
781
|
state.analysis.uncertainGTComponents.add(localName);
|
|
775
782
|
}
|
|
776
|
-
if (exportName === "msg" || exportName === "useGT" || exportName === "useMessages") state.analysis.uncertainStringFunctions.add(localName);
|
|
783
|
+
if (exportName === "msg" || includeImmediateTranslation && exportName === "t" || exportName === "useGT" || exportName === "useMessages") state.analysis.uncertainStringFunctions.add(localName);
|
|
777
784
|
}
|
|
778
785
|
/** Fails closed when a resolved local export is ambiguous or mutable. */
|
|
779
786
|
function recordAmbiguousLocalBinding(localName, state) {
|
|
@@ -1060,6 +1067,7 @@ function exposeKnownValue(localName, value, templateBindings, analysis) {
|
|
|
1060
1067
|
else if (value.type === "namespace" && value.source === "gt-vue") {
|
|
1061
1068
|
for (const component of COMPONENT_IMPORTS) templateBindings.components.set(appendTemplatePath(localName, component), component);
|
|
1062
1069
|
templateBindings.stringFunctions.set(appendTemplatePath(localName, "msg"), "msg");
|
|
1070
|
+
templateBindings.stringFunctions.set(appendTemplatePath(localName, "t"), "t");
|
|
1063
1071
|
} else if (value.type === "namespace" && value.source === "vue") {
|
|
1064
1072
|
for (const builtin of VUE_BUILTIN_IMPORTS) templateBindings.vueBuiltins.set(appendTemplatePath(localName, builtin), builtin);
|
|
1065
1073
|
templateBindings.identityFunctions.add(appendTemplatePath(localName, "markRaw"));
|
|
@@ -1104,6 +1112,7 @@ function exposeUncertainKnownValue(localName, value, uncertainComponents, uncert
|
|
|
1104
1112
|
uncertainGTComponents.add(appendTemplatePath(localName, component));
|
|
1105
1113
|
}
|
|
1106
1114
|
uncertainStringFunctions.add(appendTemplatePath(localName, "msg"));
|
|
1115
|
+
uncertainStringFunctions.add(appendTemplatePath(localName, "t"));
|
|
1107
1116
|
} else if (value.type === "namespace" && value.source === "vue") for (const builtin of VUE_BUILTIN_IMPORTS) uncertainComponents.add(appendTemplatePath(localName, builtin));
|
|
1108
1117
|
}
|
|
1109
1118
|
/** Exposes a callable whose return can affect template component identity. */
|
|
@@ -1324,21 +1333,28 @@ function collectNamespaceRestMemberCandidates(localName, binding, pattern, value
|
|
|
1324
1333
|
return key !== void 0 ? [key] : [];
|
|
1325
1334
|
}));
|
|
1326
1335
|
const certain = isSafelyReadContainerBinding(binding, binding.identifier, Number.POSITIVE_INFINITY, true, state);
|
|
1327
|
-
return (namespace.source === "gt-vue" ? [
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1336
|
+
return (namespace.source === "gt-vue" ? [
|
|
1337
|
+
...[...COMPONENT_IMPORTS].map((name) => ({
|
|
1338
|
+
type: "component",
|
|
1339
|
+
name
|
|
1340
|
+
})),
|
|
1341
|
+
{
|
|
1342
|
+
type: "string",
|
|
1343
|
+
kind: "msg"
|
|
1344
|
+
},
|
|
1345
|
+
{
|
|
1346
|
+
type: "string",
|
|
1347
|
+
kind: "t"
|
|
1348
|
+
}
|
|
1349
|
+
] : [...VUE_BUILTIN_IMPORTS].map((name) => ({
|
|
1334
1350
|
type: "vue-builtin",
|
|
1335
1351
|
name
|
|
1336
1352
|
}))).filter((entry) => {
|
|
1337
|
-
const name = entry.type === "component" ? entry.name : entry.type === "string" ?
|
|
1353
|
+
const name = entry.type === "component" ? entry.name : entry.type === "string" ? entry.kind : entry.name;
|
|
1338
1354
|
return !excluded.has(name);
|
|
1339
1355
|
}).map((entry) => ({
|
|
1340
1356
|
certain,
|
|
1341
|
-
name: appendTemplatePath(localName, entry.type === "component" ? entry.name : entry.type === "string" ?
|
|
1357
|
+
name: appendTemplatePath(localName, entry.type === "component" ? entry.name : entry.type === "string" ? entry.kind : entry.name),
|
|
1342
1358
|
value: entry
|
|
1343
1359
|
}));
|
|
1344
1360
|
}
|
|
@@ -2171,13 +2187,12 @@ function resolveKnownExpression(node, scope, state, seen) {
|
|
|
2171
2187
|
if (expression.type === "LogicalExpression") {
|
|
2172
2188
|
const left = resolveKnownExpression(expression.left, scope, state, new Set(seen));
|
|
2173
2189
|
if (left) return expression.operator === "&&" ? resolveKnownExpression(expression.right, scope, state, new Set(seen)) : left;
|
|
2174
|
-
const
|
|
2175
|
-
|
|
2176
|
-
return (expression.operator === "??" ? staticLeft.value == null : expression.operator === "||" ? !staticLeft.value : Boolean(staticLeft.value)) ? resolveKnownExpression(expression.right, scope, state, new Set(seen)) : void 0;
|
|
2190
|
+
const selection = readStaticLogicalSelection(expression, scope, state, new Set(seen));
|
|
2191
|
+
return selection ? resolveKnownExpression(expression[selection], scope, state, new Set(seen)) : void 0;
|
|
2177
2192
|
}
|
|
2178
2193
|
if (expression.type === "ConditionalExpression") {
|
|
2179
|
-
const condition =
|
|
2180
|
-
if (condition
|
|
2194
|
+
const condition = readStaticTruthiness(expression.test, scope, state, new Set(seen));
|
|
2195
|
+
if (condition) return resolveKnownExpression(condition === "truthy" ? expression.consequent : expression.alternate, scope, state, new Set(seen));
|
|
2181
2196
|
const consequent = resolveKnownExpression(expression.consequent, scope, state, new Set(seen));
|
|
2182
2197
|
const alternate = resolveKnownExpression(expression.alternate, scope, state, new Set(seen));
|
|
2183
2198
|
return consequent && alternate && knownValueKey(consequent) === knownValueKey(alternate) ? consequent : void 0;
|
|
@@ -3629,6 +3644,31 @@ function bindingMayReferenceStringFunction(binding, state) {
|
|
|
3629
3644
|
if (declaration.type === "VariableDeclarator" && declaration.init && patternMayProduceStringFunction(declaration.id, declaration.init, binding.identifier.name, binding.path.scope, state, new Set([binding]))) return true;
|
|
3630
3645
|
return binding.constantViolations.some((violation) => violation.isAssignmentExpression() && patternContains(violation.node.left, binding.identifier.name) && expressionMayProduceStringFunction(violation.node.right, violation.scope, state, new Set([binding])));
|
|
3631
3646
|
}
|
|
3647
|
+
/** Evaluates only side-effect-free truthiness needed for static branch choice. */
|
|
3648
|
+
function readStaticTruthiness(node, scope, state, seen) {
|
|
3649
|
+
const expression = unwrapExpression(node);
|
|
3650
|
+
if (!expression) return void 0;
|
|
3651
|
+
const primitive = readStaticFromScope(expression, scope, new Set(seen), expression.end ?? Number.POSITIVE_INFINITY, state.analysis);
|
|
3652
|
+
if (primitive.ok) {
|
|
3653
|
+
if (primitive.value == null) return "nullish";
|
|
3654
|
+
return primitive.value ? "truthy" : "falsy";
|
|
3655
|
+
}
|
|
3656
|
+
if (expression.type === "ConditionalExpression" || expression.type === "LogicalExpression") return;
|
|
3657
|
+
if (resolveKnownExpression(expression, scope, state, new Set(seen))) return "truthy";
|
|
3658
|
+
if (expression.type === "ArrayExpression" || expression.type === "ArrowFunctionExpression" || expression.type === "ClassExpression" || expression.type === "FunctionExpression" || expression.type === "ObjectExpression" || expression.type === "RegExpLiteral") return "truthy";
|
|
3659
|
+
if (expression.type === "Identifier") {
|
|
3660
|
+
const binding = scope.getBinding(expression.name);
|
|
3661
|
+
if (!binding) return expression.name !== "undefined" && ORDINARY_GLOBAL_VALUES.has(expression.name) ? "truthy" : void 0;
|
|
3662
|
+
if (!binding.constant || seen.has(binding)) return void 0;
|
|
3663
|
+
if (binding.path.isClassDeclaration() || binding.path.isFunctionDeclaration()) return "truthy";
|
|
3664
|
+
}
|
|
3665
|
+
}
|
|
3666
|
+
/** Selects a logical branch when the left value's truthiness is static. */
|
|
3667
|
+
function readStaticLogicalSelection(expression, scope, state, seen = /* @__PURE__ */ new Set()) {
|
|
3668
|
+
const value = readStaticTruthiness(expression.left, scope, state, seen);
|
|
3669
|
+
if (!value) return void 0;
|
|
3670
|
+
return (expression.operator === "??" ? value === "nullish" : expression.operator === "||" ? value !== "truthy" : value === "truthy") ? "right" : "left";
|
|
3671
|
+
}
|
|
3632
3672
|
/** Tracks expressions whose resulting value can be a gt-vue string function. */
|
|
3633
3673
|
function expressionMayProduceStringFunction(node, scope, state, seen) {
|
|
3634
3674
|
if (state.analysis.stats) state.analysis.stats.stringFunctionVisits += 1;
|
|
@@ -3667,8 +3707,16 @@ function expressionMayProduceStringFunction(node, scope, state, seen) {
|
|
|
3667
3707
|
}
|
|
3668
3708
|
return expression.arguments.some((argument) => argument.type !== "ArgumentPlaceholder" && (expressionMayProduceStringFunction(argument.type === "SpreadElement" ? argument.argument : argument, scope, state, seen) || containerMayContainStringFunction(argument.type === "SpreadElement" ? argument.argument : argument, scope, state, /* @__PURE__ */ new Set())));
|
|
3669
3709
|
}
|
|
3670
|
-
if (expression.type === "ConditionalExpression")
|
|
3671
|
-
|
|
3710
|
+
if (expression.type === "ConditionalExpression") {
|
|
3711
|
+
const condition = readStaticTruthiness(expression.test, scope, state, seen);
|
|
3712
|
+
if (condition) return expressionMayProduceStringFunction(condition === "truthy" ? expression.consequent : expression.alternate, scope, state, seen);
|
|
3713
|
+
return expressionMayProduceStringFunction(expression.consequent, scope, state, seen) || expressionMayProduceStringFunction(expression.alternate, scope, state, seen);
|
|
3714
|
+
}
|
|
3715
|
+
if (expression.type === "LogicalExpression") {
|
|
3716
|
+
const selection = readStaticLogicalSelection(expression, scope, state);
|
|
3717
|
+
if (selection) return expressionMayProduceStringFunction(expression[selection], scope, state, seen);
|
|
3718
|
+
return expressionMayProduceStringFunction(expression.left, scope, state, seen) || expressionMayProduceStringFunction(expression.right, scope, state, seen);
|
|
3719
|
+
}
|
|
3672
3720
|
if (expression.type === "SequenceExpression") return expressionMayProduceStringFunction(expression.expressions.at(-1), scope, state, seen);
|
|
3673
3721
|
if (expression.type === "AssignmentExpression") return expressionMayProduceStringFunction(expression.right, scope, state, seen);
|
|
3674
3722
|
if (expression.type === "AwaitExpression" || expression.type === "YieldExpression") return expressionMayProduceStringFunction(expression.argument, scope, state, seen);
|