@barefootjs/jsx 0.23.0 → 0.24.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/analyzer.d.ts.map +1 -1
- package/dist/errors.d.ts +1 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/format-date-lowering.d.ts +6 -3
- package/dist/format-date-lowering.d.ts.map +1 -1
- package/dist/index.js +475 -57
- package/dist/ir-to-client-js/emit-reactive.d.ts.map +1 -1
- package/dist/jsx-to-ir.d.ts.map +1 -1
- package/dist/to-locale-date-lowering.d.ts +62 -23
- package/dist/to-locale-date-lowering.d.ts.map +1 -1
- package/dist/types.d.ts +27 -3
- package/dist/types.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/__tests__/format-date-lowering.test.ts +22 -6
- package/src/__tests__/reactive-factory-cross-file.test.ts +263 -0
- package/src/__tests__/to-locale-date-lowering.test.ts +203 -2
- package/src/analyzer.ts +350 -52
- package/src/errors.ts +6 -0
- package/src/format-date-lowering.ts +9 -5
- package/src/ir-to-client-js/emit-reactive.ts +14 -4
- package/src/jsx-to-ir.ts +15 -4
- package/src/to-locale-date-lowering.ts +437 -49
- package/src/types.ts +28 -3
package/dist/index.js
CHANGED
|
@@ -5243,7 +5243,8 @@ var ErrorCodes = {
|
|
|
5243
5243
|
INLINE_JSX_CALLBACK_CAPTURE: "BF080",
|
|
5244
5244
|
UNRECOGNIZED_REACTIVE_FACTORY: "BF110",
|
|
5245
5245
|
REACTIVE_FACTORY_RENAME_UNSUPPORTED: "BF111",
|
|
5246
|
-
REACTIVE_FACTORY_MODULE_CAPTURE: "BF112"
|
|
5246
|
+
REACTIVE_FACTORY_MODULE_CAPTURE: "BF112",
|
|
5247
|
+
REACTIVE_FACTORY_IMPORT_COLLISION: "BF113"
|
|
5247
5248
|
};
|
|
5248
5249
|
var errorMessages = {
|
|
5249
5250
|
[ErrorCodes.MISSING_USE_CLIENT]: "'use client' directive required for components with createSignal or event handlers",
|
|
@@ -5269,7 +5270,8 @@ var errorMessages = {
|
|
|
5269
5270
|
[ErrorCodes.INLINE_JSX_CALLBACK_CAPTURE]: "Inline JSX-returning arrow function captures a non-module identifier. Extract the callback into a top-level 'use client' component (e.g. `function MyNode(n) { return <div/> }` then `renderNode={MyNode}`) or pass captured values via component props.",
|
|
5270
5271
|
[ErrorCodes.UNRECOGNIZED_REACTIVE_FACTORY]: "Tuple destructuring of a non-reactive factory call. The compiler only recognizes createSignal / createMemo calls and same-file helpers that wrap them with a single `return [a, b]` exit.",
|
|
5271
5272
|
[ErrorCodes.REACTIVE_FACTORY_RENAME_UNSUPPORTED]: "Reactive factory object return/destructure must use shorthand properties only. " + "Property renames (`{ lists: myLists }`), defaults, and rest elements are not " + "supported — destructure with the factory's own property names.",
|
|
5272
|
-
[ErrorCodes.REACTIVE_FACTORY_MODULE_CAPTURE]: "Imported reactive factory references bindings from its own module scope, so its " + "body cannot be inlined into the component file. Move those helpers into the " + "component file, pass them to the factory as parameters, or define the factory " + "in the component file."
|
|
5273
|
+
[ErrorCodes.REACTIVE_FACTORY_MODULE_CAPTURE]: "Imported reactive factory references bindings from its own module scope, so its " + "body cannot be inlined into the component file. Move those helpers into the " + "component file, pass them to the factory as parameters, or define the factory " + "in the component file.",
|
|
5274
|
+
[ErrorCodes.REACTIVE_FACTORY_IMPORT_COLLISION]: "Inlining an imported reactive factory requires re-importing one of its helper " + "imports into this file, but that name is already bound here to something else. " + "Rename the conflicting binding in this file, or alias the import in the factory's own file."
|
|
5273
5275
|
};
|
|
5274
5276
|
function createError(code, loc, options) {
|
|
5275
5277
|
if (code === undefined || !(code in errorMessages)) {
|
|
@@ -7780,6 +7782,74 @@ function prescanReactiveFactoriesInSource(source, filePath) {
|
|
|
7780
7782
|
prescanImportedReactiveFactories(sourceFile, filePath, result);
|
|
7781
7783
|
return result;
|
|
7782
7784
|
}
|
|
7785
|
+
function toComponentRelativeSpecifier(resolvedAbs, componentFilePath) {
|
|
7786
|
+
let rel = path_default.relative(path_default.dirname(componentFilePath), resolvedAbs).split(path_default.sep).join("/");
|
|
7787
|
+
rel = rel.replace(/\.(tsx|ts|jsx|js)$/, "");
|
|
7788
|
+
if (rel === "")
|
|
7789
|
+
rel = ".";
|
|
7790
|
+
if (!rel.startsWith("."))
|
|
7791
|
+
rel = "./" + rel;
|
|
7792
|
+
return rel;
|
|
7793
|
+
}
|
|
7794
|
+
function buildEntryImportIndex(sf, filePath) {
|
|
7795
|
+
const index = new Map;
|
|
7796
|
+
for (const stmt of sf.statements) {
|
|
7797
|
+
if (!ts8.isImportDeclaration(stmt))
|
|
7798
|
+
continue;
|
|
7799
|
+
if (!ts8.isStringLiteral(stmt.moduleSpecifier))
|
|
7800
|
+
continue;
|
|
7801
|
+
if (stmt.importClause?.isTypeOnly)
|
|
7802
|
+
continue;
|
|
7803
|
+
const src = stmt.moduleSpecifier.text;
|
|
7804
|
+
const targetKey = src.startsWith("./") || src.startsWith("../") ? resolveRelativeImportToFile(src, filePath) ?? "unresolved:" + src : src;
|
|
7805
|
+
const namedBindings = stmt.importClause?.namedBindings;
|
|
7806
|
+
if (namedBindings && ts8.isNamedImports(namedBindings)) {
|
|
7807
|
+
for (const el of namedBindings.elements) {
|
|
7808
|
+
if (el.isTypeOnly)
|
|
7809
|
+
continue;
|
|
7810
|
+
index.set(el.name.text, { targetKey, exportedName: (el.propertyName ?? el.name).text });
|
|
7811
|
+
}
|
|
7812
|
+
}
|
|
7813
|
+
}
|
|
7814
|
+
return index;
|
|
7815
|
+
}
|
|
7816
|
+
function collectEntryBindingNames(sf) {
|
|
7817
|
+
const names = new Set;
|
|
7818
|
+
function visit2(node) {
|
|
7819
|
+
if (ts8.isImportDeclaration(node) && node.importClause) {
|
|
7820
|
+
if (node.importClause.name)
|
|
7821
|
+
names.add(node.importClause.name.text);
|
|
7822
|
+
const namedBindings = node.importClause.namedBindings;
|
|
7823
|
+
if (namedBindings && ts8.isNamedImports(namedBindings)) {
|
|
7824
|
+
for (const el of namedBindings.elements)
|
|
7825
|
+
names.add(el.name.text);
|
|
7826
|
+
}
|
|
7827
|
+
if (namedBindings && ts8.isNamespaceImport(namedBindings)) {
|
|
7828
|
+
names.add(namedBindings.name.text);
|
|
7829
|
+
}
|
|
7830
|
+
}
|
|
7831
|
+
if (ts8.isVariableDeclaration(node)) {
|
|
7832
|
+
const out = [];
|
|
7833
|
+
addBindingNames(node.name, out);
|
|
7834
|
+
for (const n of out)
|
|
7835
|
+
names.add(n);
|
|
7836
|
+
}
|
|
7837
|
+
if ((ts8.isFunctionDeclaration(node) || ts8.isClassDeclaration(node) || ts8.isEnumDeclaration(node)) && node.name) {
|
|
7838
|
+
names.add(node.name.text);
|
|
7839
|
+
}
|
|
7840
|
+
if (ts8.isFunctionLike(node)) {
|
|
7841
|
+
for (const p of node.parameters) {
|
|
7842
|
+
const out = [];
|
|
7843
|
+
addBindingNames(p.name, out);
|
|
7844
|
+
for (const n of out)
|
|
7845
|
+
names.add(n);
|
|
7846
|
+
}
|
|
7847
|
+
}
|
|
7848
|
+
ts8.forEachChild(node, visit2);
|
|
7849
|
+
}
|
|
7850
|
+
visit2(sf);
|
|
7851
|
+
return names;
|
|
7852
|
+
}
|
|
7783
7853
|
function prescanImportedReactiveFactories(entrySourceFile, filePath, result) {
|
|
7784
7854
|
const candidateCallees = new Set;
|
|
7785
7855
|
function collectCandidates(node) {
|
|
@@ -7820,6 +7890,9 @@ function prescanImportedReactiveFactories(entrySourceFile, filePath, result) {
|
|
|
7820
7890
|
}
|
|
7821
7891
|
if (importsToCheck.length === 0)
|
|
7822
7892
|
return;
|
|
7893
|
+
const entryBindingNames = collectEntryBindingNames(entrySourceFile);
|
|
7894
|
+
const entryImportIndex = buildEntryImportIndex(entrySourceFile, filePath);
|
|
7895
|
+
const plannedInjections = new Map;
|
|
7823
7896
|
for (const { src, specs } of importsToCheck) {
|
|
7824
7897
|
const resolved = resolveRelativeImportToFile(src, filePath);
|
|
7825
7898
|
if (!resolved)
|
|
@@ -7885,17 +7958,64 @@ function prescanImportedReactiveFactories(entrySourceFile, filePath, result) {
|
|
|
7885
7958
|
result.declined.set(spec.local, det.declined);
|
|
7886
7959
|
break;
|
|
7887
7960
|
case "factory": {
|
|
7888
|
-
const
|
|
7889
|
-
if (
|
|
7961
|
+
const capture = moduleCaptureCheck(fn, det.info, moduleBindings, fn.name.text);
|
|
7962
|
+
if (capture.captured.length > 0) {
|
|
7890
7963
|
result.declined.set(spec.local, {
|
|
7891
7964
|
code: "BF112",
|
|
7892
|
-
detail: `'${
|
|
7965
|
+
detail: `'${capture.captured.join("', '")}'`,
|
|
7893
7966
|
loc: det.info.loc
|
|
7894
7967
|
});
|
|
7895
|
-
|
|
7896
|
-
|
|
7897
|
-
|
|
7968
|
+
break;
|
|
7969
|
+
}
|
|
7970
|
+
const required = [];
|
|
7971
|
+
const pending = [];
|
|
7972
|
+
let declinedEntry = null;
|
|
7973
|
+
for (const ref of capture.importedRefs) {
|
|
7974
|
+
let specifier;
|
|
7975
|
+
let targetKey;
|
|
7976
|
+
if (ref.source.startsWith("./") || ref.source.startsWith("../")) {
|
|
7977
|
+
const abs = resolveRelativeImportToFile(ref.source, resolved);
|
|
7978
|
+
if (!abs) {
|
|
7979
|
+
declinedEntry = {
|
|
7980
|
+
code: "BF112",
|
|
7981
|
+
detail: `'${ref.localName}' (import '${ref.source}' did not resolve from the helper file)`,
|
|
7982
|
+
loc: det.info.loc
|
|
7983
|
+
};
|
|
7984
|
+
break;
|
|
7985
|
+
}
|
|
7986
|
+
specifier = toComponentRelativeSpecifier(abs, filePath);
|
|
7987
|
+
targetKey = abs;
|
|
7988
|
+
} else {
|
|
7989
|
+
specifier = ref.source;
|
|
7990
|
+
targetKey = ref.source;
|
|
7991
|
+
}
|
|
7992
|
+
const existing = entryImportIndex.get(ref.localName);
|
|
7993
|
+
if (existing && existing.targetKey === targetKey && existing.exportedName === ref.exportedName) {
|
|
7994
|
+
continue;
|
|
7995
|
+
}
|
|
7996
|
+
const planned = plannedInjections.get(ref.localName);
|
|
7997
|
+
const collides = existing !== undefined || planned !== undefined && (planned.targetKey !== targetKey || planned.exportedName !== ref.exportedName) || planned === undefined && entryBindingNames.has(ref.localName);
|
|
7998
|
+
if (collides) {
|
|
7999
|
+
declinedEntry = {
|
|
8000
|
+
code: "BF113",
|
|
8001
|
+
detail: `'${ref.localName}' from '${specifier}'`,
|
|
8002
|
+
loc: det.info.loc
|
|
8003
|
+
};
|
|
8004
|
+
break;
|
|
8005
|
+
}
|
|
8006
|
+
pending.push([ref.localName, { targetKey, exportedName: ref.exportedName }]);
|
|
8007
|
+
required.push({ localName: ref.localName, exportedName: ref.exportedName, specifier });
|
|
7898
8008
|
}
|
|
8009
|
+
if (declinedEntry) {
|
|
8010
|
+
result.declined.set(spec.local, declinedEntry);
|
|
8011
|
+
break;
|
|
8012
|
+
}
|
|
8013
|
+
for (const [name, id] of pending)
|
|
8014
|
+
plannedInjections.set(name, id);
|
|
8015
|
+
det.info.sourceFilePath = resolved;
|
|
8016
|
+
if (required.length > 0)
|
|
8017
|
+
det.info.requiredImports = required;
|
|
8018
|
+
result.factories.set(spec.local, det.info);
|
|
7899
8019
|
break;
|
|
7900
8020
|
}
|
|
7901
8021
|
}
|
|
@@ -7903,7 +8023,8 @@ function prescanImportedReactiveFactories(entrySourceFile, filePath, result) {
|
|
|
7903
8023
|
}
|
|
7904
8024
|
}
|
|
7905
8025
|
function collectHelperModuleValueBindings(sf) {
|
|
7906
|
-
const
|
|
8026
|
+
const local = new Set;
|
|
8027
|
+
const imported = new Map;
|
|
7907
8028
|
for (const stmt of sf.statements) {
|
|
7908
8029
|
if (ts8.isVariableStatement(stmt)) {
|
|
7909
8030
|
const out = [];
|
|
@@ -7911,11 +8032,11 @@ function collectHelperModuleValueBindings(sf) {
|
|
|
7911
8032
|
addBindingNames(decl.name, out);
|
|
7912
8033
|
}
|
|
7913
8034
|
for (const n of out)
|
|
7914
|
-
|
|
8035
|
+
local.add(n);
|
|
7915
8036
|
continue;
|
|
7916
8037
|
}
|
|
7917
8038
|
if ((ts8.isFunctionDeclaration(stmt) || ts8.isClassDeclaration(stmt) || ts8.isEnumDeclaration(stmt)) && stmt.name) {
|
|
7918
|
-
|
|
8039
|
+
local.add(stmt.name.text);
|
|
7919
8040
|
continue;
|
|
7920
8041
|
}
|
|
7921
8042
|
if (ts8.isImportDeclaration(stmt)) {
|
|
@@ -7927,25 +8048,25 @@ function collectHelperModuleValueBindings(sf) {
|
|
|
7927
8048
|
if (src === "@barefootjs/client" || src === "@barefootjs/client/runtime")
|
|
7928
8049
|
continue;
|
|
7929
8050
|
if (stmt.importClause?.name)
|
|
7930
|
-
|
|
8051
|
+
local.add(stmt.importClause.name.text);
|
|
7931
8052
|
const namedBindings = stmt.importClause?.namedBindings;
|
|
7932
8053
|
if (namedBindings && ts8.isNamedImports(namedBindings)) {
|
|
7933
8054
|
for (const el of namedBindings.elements) {
|
|
7934
8055
|
if (el.isTypeOnly)
|
|
7935
8056
|
continue;
|
|
7936
|
-
|
|
8057
|
+
imported.set(el.name.text, { source: src, exportedName: (el.propertyName ?? el.name).text });
|
|
7937
8058
|
}
|
|
7938
8059
|
}
|
|
7939
8060
|
if (namedBindings && ts8.isNamespaceImport(namedBindings)) {
|
|
7940
|
-
|
|
8061
|
+
local.add(namedBindings.name.text);
|
|
7941
8062
|
}
|
|
7942
8063
|
}
|
|
7943
8064
|
}
|
|
7944
|
-
return
|
|
8065
|
+
return { local, imported };
|
|
7945
8066
|
}
|
|
7946
8067
|
function moduleCaptureCheck(fn, info, moduleBindings, selfName) {
|
|
7947
8068
|
if (!fn.body)
|
|
7948
|
-
return [];
|
|
8069
|
+
return { captured: [], importedRefs: [] };
|
|
7949
8070
|
const free = extractFreeIdentifiersFromNode(fn.body);
|
|
7950
8071
|
const exclude = new Set(info.params);
|
|
7951
8072
|
for (const b of info.localBindings)
|
|
@@ -7955,14 +8076,22 @@ function moduleCaptureCheck(fn, info, moduleBindings, selfName) {
|
|
|
7955
8076
|
for (const p of REACTIVE_PRIMITIVES)
|
|
7956
8077
|
exclude.add(p);
|
|
7957
8078
|
exclude.add(selfName);
|
|
7958
|
-
const
|
|
8079
|
+
const captured = [];
|
|
8080
|
+
const importedRefs = [];
|
|
7959
8081
|
for (const id of free) {
|
|
7960
8082
|
if (exclude.has(id))
|
|
7961
8083
|
continue;
|
|
7962
|
-
if (moduleBindings.has(id))
|
|
7963
|
-
|
|
8084
|
+
if (moduleBindings.local.has(id)) {
|
|
8085
|
+
captured.push(id);
|
|
8086
|
+
continue;
|
|
8087
|
+
}
|
|
8088
|
+
const imp = moduleBindings.imported.get(id);
|
|
8089
|
+
if (imp)
|
|
8090
|
+
importedRefs.push({ localName: id, source: imp.source, exportedName: imp.exportedName });
|
|
7964
8091
|
}
|
|
7965
|
-
|
|
8092
|
+
captured.sort();
|
|
8093
|
+
importedRefs.sort((a, b) => a.localName < b.localName ? -1 : 1);
|
|
8094
|
+
return { captured, importedRefs };
|
|
7966
8095
|
}
|
|
7967
8096
|
function detectReactiveFactory(node, sourceFile, filePath) {
|
|
7968
8097
|
if (!node.body || !node.name)
|
|
@@ -8086,6 +8215,7 @@ function rewriteFactoryCallsInSource(source, prescan) {
|
|
|
8086
8215
|
const { factories, sourceFile } = prescan;
|
|
8087
8216
|
const edits = [];
|
|
8088
8217
|
let callSiteIndex = 0;
|
|
8218
|
+
const inlinedFactories = new Set;
|
|
8089
8219
|
function visitStmt(node, inComponent) {
|
|
8090
8220
|
if (ts8.isVariableStatement(node) && inComponent) {
|
|
8091
8221
|
for (const decl of node.declarationList.declarations) {
|
|
@@ -8187,10 +8317,34 @@ function rewriteFactoryCallsInSource(source, prescan) {
|
|
|
8187
8317
|
end: stmt.getEnd(),
|
|
8188
8318
|
replacement: body
|
|
8189
8319
|
});
|
|
8320
|
+
inlinedFactories.add(factory);
|
|
8190
8321
|
}
|
|
8191
8322
|
visitStmt(sourceFile, false);
|
|
8192
8323
|
if (edits.length === 0)
|
|
8193
8324
|
return source;
|
|
8325
|
+
const importsBySpecifier = new Map;
|
|
8326
|
+
for (const f of inlinedFactories) {
|
|
8327
|
+
for (const r of f.requiredImports ?? []) {
|
|
8328
|
+
let names = importsBySpecifier.get(r.specifier);
|
|
8329
|
+
if (!names) {
|
|
8330
|
+
names = new Map;
|
|
8331
|
+
importsBySpecifier.set(r.specifier, names);
|
|
8332
|
+
}
|
|
8333
|
+
names.set(r.localName, r.exportedName);
|
|
8334
|
+
}
|
|
8335
|
+
}
|
|
8336
|
+
if (importsBySpecifier.size > 0) {
|
|
8337
|
+
const lines = [...importsBySpecifier].sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([spec, names]) => {
|
|
8338
|
+
const specifiers = [...names].sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0).map(([local, exported]) => exported === local ? local : `${exported} as ${local}`);
|
|
8339
|
+
return `import { ${specifiers.join(", ")} } from '${spec}'`;
|
|
8340
|
+
});
|
|
8341
|
+
const at = factoryImportInsertionOffset(sourceFile);
|
|
8342
|
+
edits.push({ start: at, end: at, replacement: at === 0 ? lines.join(`
|
|
8343
|
+
`) + `
|
|
8344
|
+
` : `
|
|
8345
|
+
` + lines.join(`
|
|
8346
|
+
`) });
|
|
8347
|
+
}
|
|
8194
8348
|
edits.sort((a, b) => b.start - a.start);
|
|
8195
8349
|
let out = source;
|
|
8196
8350
|
for (const e of edits) {
|
|
@@ -8198,6 +8352,20 @@ function rewriteFactoryCallsInSource(source, prescan) {
|
|
|
8198
8352
|
}
|
|
8199
8353
|
return out;
|
|
8200
8354
|
}
|
|
8355
|
+
function factoryImportInsertionOffset(sf) {
|
|
8356
|
+
let lastImportEnd = -1;
|
|
8357
|
+
let directiveEnd = -1;
|
|
8358
|
+
for (const stmt of sf.statements) {
|
|
8359
|
+
if (ts8.isImportDeclaration(stmt)) {
|
|
8360
|
+
lastImportEnd = stmt.getEnd();
|
|
8361
|
+
continue;
|
|
8362
|
+
}
|
|
8363
|
+
if (directiveEnd === -1 && ts8.isExpressionStatement(stmt) && ts8.isStringLiteral(stmt.expression) && stmt.expression.text === "use client") {
|
|
8364
|
+
directiveEnd = stmt.getEnd();
|
|
8365
|
+
}
|
|
8366
|
+
}
|
|
8367
|
+
return lastImportEnd >= 0 ? lastImportEnd : directiveEnd >= 0 ? directiveEnd : 0;
|
|
8368
|
+
}
|
|
8201
8369
|
function isPascalCaseComponentFn(node) {
|
|
8202
8370
|
if (ts8.isFunctionDeclaration(node) && node.name) {
|
|
8203
8371
|
return /^[A-Z]/.test(node.name.text);
|
|
@@ -8214,8 +8382,21 @@ function declinedFactoryMessage(callee, d) {
|
|
|
8214
8382
|
if (d.code === "BF112") {
|
|
8215
8383
|
return `Reactive factory '${callee}' references ${d.detail} from its own module ` + `scope and cannot be inlined. Move the referenced helper(s) into this file, ` + `pass them as factory arguments, or inline the factory here.`;
|
|
8216
8384
|
}
|
|
8385
|
+
if (d.code === "BF113") {
|
|
8386
|
+
return `Reactive factory '${callee}' cannot be inlined: it needs ${d.detail} ` + `imported into this file, but that name is already bound here to something ` + `else. Rename the conflicting binding in this file, or alias the import in ` + `the factory's own file (import { x as y }).`;
|
|
8387
|
+
}
|
|
8217
8388
|
return `Reactive factory '${callee}' cannot be inlined: ${d.detail}.`;
|
|
8218
8389
|
}
|
|
8390
|
+
function declinedFactoryErrorCode(code) {
|
|
8391
|
+
switch (code) {
|
|
8392
|
+
case "BF112":
|
|
8393
|
+
return ErrorCodes.REACTIVE_FACTORY_MODULE_CAPTURE;
|
|
8394
|
+
case "BF113":
|
|
8395
|
+
return ErrorCodes.REACTIVE_FACTORY_IMPORT_COLLISION;
|
|
8396
|
+
default:
|
|
8397
|
+
return ErrorCodes.REACTIVE_FACTORY_RENAME_UNSUPPORTED;
|
|
8398
|
+
}
|
|
8399
|
+
}
|
|
8219
8400
|
function validateReactiveFactoryCalls(ctx) {
|
|
8220
8401
|
if (!ctx.componentNode)
|
|
8221
8402
|
return;
|
|
@@ -8239,7 +8420,7 @@ function validateReactiveFactoryCalls(ctx) {
|
|
|
8239
8420
|
continue;
|
|
8240
8421
|
const declinedEntry = ctx.declinedReactiveFactories.get(callee);
|
|
8241
8422
|
if (declinedEntry) {
|
|
8242
|
-
ctx.errors.push(createError(declinedEntry.code
|
|
8423
|
+
ctx.errors.push(createError(declinedFactoryErrorCode(declinedEntry.code), loc, { severity: "error", message: declinedFactoryMessage(callee, declinedEntry) }));
|
|
8243
8424
|
continue;
|
|
8244
8425
|
}
|
|
8245
8426
|
const objectFactory = ctx.reactiveFactories.get(callee);
|
|
@@ -8296,7 +8477,7 @@ function validateObjectFactoryDestructure(ctx, pattern, callee, loc) {
|
|
|
8296
8477
|
}
|
|
8297
8478
|
const declinedEntry = ctx.declinedReactiveFactories.get(callee);
|
|
8298
8479
|
if (declinedEntry) {
|
|
8299
|
-
ctx.errors.push(createError(declinedEntry.code
|
|
8480
|
+
ctx.errors.push(createError(declinedFactoryErrorCode(declinedEntry.code), loc, { severity: "error", message: declinedFactoryMessage(callee, declinedEntry) }));
|
|
8300
8481
|
return;
|
|
8301
8482
|
}
|
|
8302
8483
|
if (ctx.reactiveShapedHelpers.has(callee)) {
|
|
@@ -8848,19 +9029,83 @@ function resolveFreeRefs(node, env) {
|
|
|
8848
9029
|
// src/to-locale-date-lowering.ts
|
|
8849
9030
|
var TO_LOCALE_TZ_RE = /^(?:UTC|[+-](?:[01]\d|2[0-3]):[0-5]\d)$/;
|
|
8850
9031
|
var PROBE_UTC = new Date(Date.UTC(2001, 1, 3));
|
|
8851
|
-
var
|
|
8852
|
-
|
|
8853
|
-
|
|
9032
|
+
var formatCache = new Map;
|
|
9033
|
+
var namesCache = new Map;
|
|
9034
|
+
function deriveMonthNames(locale, ctx) {
|
|
9035
|
+
return deriveNamesCached(`${locale}|m|${ctx}`, () => {
|
|
9036
|
+
const months = (width) => Array.from({ length: 12 }, (_, m) => probePart(locale, ctx === "formatting" ? { month: width, day: "numeric" } : { month: width }, Date.UTC(2001, m, 15), "month"));
|
|
9037
|
+
return [...months("long"), ...months("short")];
|
|
9038
|
+
});
|
|
9039
|
+
}
|
|
9040
|
+
function deriveWeekdayNames(locale, ctx) {
|
|
9041
|
+
return deriveNamesCached(`${locale}|w|${ctx}`, () => {
|
|
9042
|
+
const weekdays = (width) => Array.from({ length: 7 }, (_, d) => probePart(locale, ctx === "formatting" ? { weekday: width, month: "numeric", day: "numeric" } : { weekday: width }, Date.UTC(2023, 0, 1 + d), "weekday"));
|
|
9043
|
+
return [...weekdays("long"), ...weekdays("short")];
|
|
9044
|
+
});
|
|
9045
|
+
}
|
|
9046
|
+
function probePart(locale, options, utc, type) {
|
|
9047
|
+
const parts = new Intl.DateTimeFormat(locale, { ...options, timeZone: "UTC" }).formatToParts(new Date(utc));
|
|
9048
|
+
const found = parts.find((p) => p.type === type);
|
|
9049
|
+
if (!found || !found.value)
|
|
9050
|
+
throw new Error("missing part");
|
|
9051
|
+
return found.value;
|
|
9052
|
+
}
|
|
9053
|
+
function deriveNamesCached(key, derive) {
|
|
9054
|
+
const cached = namesCache.get(key);
|
|
9055
|
+
if (cached !== undefined)
|
|
9056
|
+
return cached;
|
|
9057
|
+
let derived;
|
|
9058
|
+
try {
|
|
9059
|
+
derived = derive();
|
|
9060
|
+
} catch {
|
|
9061
|
+
derived = null;
|
|
9062
|
+
}
|
|
9063
|
+
namesCache.set(key, derived);
|
|
9064
|
+
return derived;
|
|
9065
|
+
}
|
|
9066
|
+
function resolveLocaleDateFormat(locale, probeOptions) {
|
|
9067
|
+
const key = `${locale}|${JSON.stringify(probeOptions, Object.keys(probeOptions).sort())}`;
|
|
9068
|
+
const cached = formatCache.get(key);
|
|
8854
9069
|
if (cached !== undefined)
|
|
8855
9070
|
return cached;
|
|
8856
|
-
const derived =
|
|
8857
|
-
|
|
9071
|
+
const derived = deriveFormat(locale, probeOptions);
|
|
9072
|
+
formatCache.set(key, derived);
|
|
8858
9073
|
return derived;
|
|
8859
9074
|
}
|
|
8860
|
-
|
|
9075
|
+
var VERIFY_UTC = new Date(Date.UTC(2001, 4, 13));
|
|
9076
|
+
function renderPatternAt(pattern, names, y, m, d, wd) {
|
|
9077
|
+
const pad2 = (n) => String(n).padStart(2, "0");
|
|
9078
|
+
return pattern.replace(/YYYY|MMMM|MMM|MM|DD|dddd|ddd|M|D/g, (token) => {
|
|
9079
|
+
switch (token) {
|
|
9080
|
+
case "YYYY":
|
|
9081
|
+
return String(y).padStart(4, "0");
|
|
9082
|
+
case "MMMM":
|
|
9083
|
+
return names[m - 1] ?? "";
|
|
9084
|
+
case "MMM":
|
|
9085
|
+
return names[12 + m - 1] ?? "";
|
|
9086
|
+
case "MM":
|
|
9087
|
+
return pad2(m);
|
|
9088
|
+
case "M":
|
|
9089
|
+
return String(m);
|
|
9090
|
+
case "DD":
|
|
9091
|
+
return pad2(d);
|
|
9092
|
+
case "D":
|
|
9093
|
+
return String(d);
|
|
9094
|
+
case "dddd":
|
|
9095
|
+
return names[24 + wd] ?? "";
|
|
9096
|
+
default:
|
|
9097
|
+
return names[31 + wd] ?? "";
|
|
9098
|
+
}
|
|
9099
|
+
});
|
|
9100
|
+
}
|
|
9101
|
+
function deriveFormat(locale, probeOptions) {
|
|
9102
|
+
let dtf;
|
|
8861
9103
|
let parts;
|
|
8862
9104
|
try {
|
|
8863
|
-
|
|
9105
|
+
dtf = new Intl.DateTimeFormat(locale, {
|
|
9106
|
+
...probeOptions,
|
|
9107
|
+
timeZone: "UTC"
|
|
9108
|
+
});
|
|
8864
9109
|
const resolved = dtf.resolvedOptions();
|
|
8865
9110
|
if (resolved.calendar !== "gregory" || resolved.numberingSystem !== "latn")
|
|
8866
9111
|
return null;
|
|
@@ -8868,7 +9113,18 @@ function derivePattern(locale) {
|
|
|
8868
9113
|
} catch {
|
|
8869
9114
|
return null;
|
|
8870
9115
|
}
|
|
9116
|
+
const monthTables = [
|
|
9117
|
+
deriveMonthNames(locale, "formatting"),
|
|
9118
|
+
deriveMonthNames(locale, "standalone")
|
|
9119
|
+
];
|
|
9120
|
+
const weekdayTables = [
|
|
9121
|
+
deriveWeekdayNames(locale, "formatting"),
|
|
9122
|
+
deriveWeekdayNames(locale, "standalone")
|
|
9123
|
+
];
|
|
9124
|
+
let monthTable = null;
|
|
9125
|
+
let weekdayTable = null;
|
|
8871
9126
|
let pattern = "";
|
|
9127
|
+
let usesNames = false;
|
|
8872
9128
|
for (const part of parts) {
|
|
8873
9129
|
switch (part.type) {
|
|
8874
9130
|
case "year":
|
|
@@ -8876,14 +9132,27 @@ function derivePattern(locale) {
|
|
|
8876
9132
|
return null;
|
|
8877
9133
|
pattern += "YYYY";
|
|
8878
9134
|
break;
|
|
8879
|
-
case "month":
|
|
8880
|
-
if (part.value === "2")
|
|
9135
|
+
case "month": {
|
|
9136
|
+
if (part.value === "2") {
|
|
8881
9137
|
pattern += "M";
|
|
8882
|
-
|
|
9138
|
+
break;
|
|
9139
|
+
}
|
|
9140
|
+
if (part.value === "02") {
|
|
8883
9141
|
pattern += "MM";
|
|
9142
|
+
break;
|
|
9143
|
+
}
|
|
9144
|
+
const wide = monthTables.find((t) => t && part.value === t[1]) ?? null;
|
|
9145
|
+
const abbr = wide ? null : monthTables.find((t) => t && part.value === t[12 + 1]) ?? null;
|
|
9146
|
+
if (wide)
|
|
9147
|
+
pattern += "MMMM";
|
|
9148
|
+
else if (abbr)
|
|
9149
|
+
pattern += "MMM";
|
|
8884
9150
|
else
|
|
8885
9151
|
return null;
|
|
9152
|
+
monthTable = wide ?? abbr;
|
|
9153
|
+
usesNames = true;
|
|
8886
9154
|
break;
|
|
9155
|
+
}
|
|
8887
9156
|
case "day":
|
|
8888
9157
|
if (part.value === "3")
|
|
8889
9158
|
pattern += "D";
|
|
@@ -8892,8 +9161,21 @@ function derivePattern(locale) {
|
|
|
8892
9161
|
else
|
|
8893
9162
|
return null;
|
|
8894
9163
|
break;
|
|
9164
|
+
case "weekday": {
|
|
9165
|
+
const wide = weekdayTables.find((t) => t && part.value === t[6]) ?? null;
|
|
9166
|
+
const abbr = wide ? null : weekdayTables.find((t) => t && part.value === t[7 + 6]) ?? null;
|
|
9167
|
+
if (wide)
|
|
9168
|
+
pattern += "dddd";
|
|
9169
|
+
else if (abbr)
|
|
9170
|
+
pattern += "ddd";
|
|
9171
|
+
else
|
|
9172
|
+
return null;
|
|
9173
|
+
weekdayTable = wide ?? abbr;
|
|
9174
|
+
usesNames = true;
|
|
9175
|
+
break;
|
|
9176
|
+
}
|
|
8895
9177
|
case "literal":
|
|
8896
|
-
if (/[YMD]/.test(part.value))
|
|
9178
|
+
if (/[YMD]/.test(part.value) || /ddd/.test(part.value))
|
|
8897
9179
|
return null;
|
|
8898
9180
|
pattern += part.value;
|
|
8899
9181
|
break;
|
|
@@ -8901,9 +9183,73 @@ function derivePattern(locale) {
|
|
|
8901
9183
|
return null;
|
|
8902
9184
|
}
|
|
8903
9185
|
}
|
|
8904
|
-
if (
|
|
9186
|
+
if (!/YYYY|MMMM|MMM|MM|M/.test(pattern) && !/DD|D/.test(pattern))
|
|
8905
9187
|
return null;
|
|
8906
|
-
|
|
9188
|
+
if (!usesNames)
|
|
9189
|
+
return { pattern, names: null };
|
|
9190
|
+
const names = [
|
|
9191
|
+
...monthTable ?? monthTables[0] ?? monthTables[1] ?? Array(24).fill(""),
|
|
9192
|
+
...weekdayTable ?? weekdayTables[0] ?? weekdayTables[1] ?? Array(14).fill("")
|
|
9193
|
+
];
|
|
9194
|
+
if (renderPatternAt(pattern, names, 2001, 5, 13, 0) !== dtf.format(VERIFY_UTC))
|
|
9195
|
+
return null;
|
|
9196
|
+
return { pattern, names };
|
|
9197
|
+
}
|
|
9198
|
+
function unionMemberLiteral(member) {
|
|
9199
|
+
const m = /^'([^'\\]*)'$|^"([^"\\]*)"$/.exec(member.raw.trim());
|
|
9200
|
+
return m ? m[1] ?? m[2] : null;
|
|
9201
|
+
}
|
|
9202
|
+
function resolveLocaleUnionMembers(locale, metadata) {
|
|
9203
|
+
let sourcePropName = null;
|
|
9204
|
+
if (metadata.propsObjectName) {
|
|
9205
|
+
if (locale.kind === "member" && !locale.computed && locale.object.kind === "identifier" && locale.object.name === metadata.propsObjectName) {
|
|
9206
|
+
sourcePropName = locale.property;
|
|
9207
|
+
}
|
|
9208
|
+
} else if (locale.kind === "identifier") {
|
|
9209
|
+
const name = locale.name;
|
|
9210
|
+
const param = metadata.propsParams?.find((pp) => pp.name === name);
|
|
9211
|
+
if (param)
|
|
9212
|
+
sourcePropName = param.sourceName ?? param.name;
|
|
9213
|
+
}
|
|
9214
|
+
if (!sourcePropName)
|
|
9215
|
+
return null;
|
|
9216
|
+
const target = sourcePropName;
|
|
9217
|
+
const prop = metadata.propsType?.properties?.find((p) => p.name === target);
|
|
9218
|
+
if (!prop || prop.optional)
|
|
9219
|
+
return null;
|
|
9220
|
+
const type = prop.type;
|
|
9221
|
+
if (type.kind !== "union" || !type.unionTypes || type.unionTypes.length === 0)
|
|
9222
|
+
return null;
|
|
9223
|
+
const members = [];
|
|
9224
|
+
for (const member of type.unionTypes) {
|
|
9225
|
+
const value = unionMemberLiteral(member);
|
|
9226
|
+
if (value === null)
|
|
9227
|
+
return null;
|
|
9228
|
+
members.push(value);
|
|
9229
|
+
}
|
|
9230
|
+
return members;
|
|
9231
|
+
}
|
|
9232
|
+
var strLit = (value) => ({ kind: "literal", value, literalType: "string" });
|
|
9233
|
+
function strArr(values) {
|
|
9234
|
+
return {
|
|
9235
|
+
kind: "array-literal",
|
|
9236
|
+
elements: values.map((v) => strLit(v)),
|
|
9237
|
+
raw: JSON.stringify(values)
|
|
9238
|
+
};
|
|
9239
|
+
}
|
|
9240
|
+
function foldMembers(locale, members, leaves, allEqual) {
|
|
9241
|
+
let expr = leaves[leaves.length - 1];
|
|
9242
|
+
if (allEqual)
|
|
9243
|
+
return expr;
|
|
9244
|
+
for (let i = leaves.length - 2;i >= 0; i--) {
|
|
9245
|
+
expr = {
|
|
9246
|
+
kind: "conditional",
|
|
9247
|
+
test: { kind: "binary", op: "===", left: locale, right: strLit(members[i]) },
|
|
9248
|
+
consequent: leaves[i],
|
|
9249
|
+
alternate: expr
|
|
9250
|
+
};
|
|
9251
|
+
}
|
|
9252
|
+
return expr;
|
|
8907
9253
|
}
|
|
8908
9254
|
function matchToLocaleDateStringCall(callee, args, metadata) {
|
|
8909
9255
|
if (callee.kind !== "member" || callee.computed)
|
|
@@ -8911,17 +9257,23 @@ function matchToLocaleDateStringCall(callee, args, metadata) {
|
|
|
8911
9257
|
if (callee.property !== "toLocaleDateString" || args.length !== 2)
|
|
8912
9258
|
return null;
|
|
8913
9259
|
const [locale, options] = args;
|
|
8914
|
-
if (
|
|
8915
|
-
return null;
|
|
8916
|
-
if (options.kind !== "object-literal" || options.properties.length !== 1)
|
|
9260
|
+
if (options.kind !== "object-literal")
|
|
8917
9261
|
return null;
|
|
8918
|
-
|
|
8919
|
-
|
|
8920
|
-
|
|
8921
|
-
|
|
8922
|
-
|
|
8923
|
-
|
|
8924
|
-
|
|
9262
|
+
let tz = null;
|
|
9263
|
+
const probeOptions = {};
|
|
9264
|
+
for (const prop of options.properties) {
|
|
9265
|
+
if (prop.value.kind !== "literal" || prop.value.literalType !== "string")
|
|
9266
|
+
return null;
|
|
9267
|
+
const value = String(prop.value.value);
|
|
9268
|
+
if (prop.key === "timeZone") {
|
|
9269
|
+
if (!TO_LOCALE_TZ_RE.test(value))
|
|
9270
|
+
return null;
|
|
9271
|
+
tz = value;
|
|
9272
|
+
} else {
|
|
9273
|
+
probeOptions[prop.key] = value;
|
|
9274
|
+
}
|
|
9275
|
+
}
|
|
9276
|
+
if (tz === null)
|
|
8925
9277
|
return null;
|
|
8926
9278
|
const receiverType = resolveReceiverType(callee.object, metadata, new Map);
|
|
8927
9279
|
if (!receiverType || receiverType.kind !== "interface")
|
|
@@ -8931,19 +9283,64 @@ function matchToLocaleDateStringCall(callee, args, metadata) {
|
|
|
8931
9283
|
return null;
|
|
8932
9284
|
if (metadata.typeDefinitions.some((d) => d.name === typeName))
|
|
8933
9285
|
return null;
|
|
8934
|
-
|
|
8935
|
-
|
|
9286
|
+
if (locale.kind === "literal" && locale.literalType === "string") {
|
|
9287
|
+
const format2 = resolveLocaleDateFormat(String(locale.value), probeOptions);
|
|
9288
|
+
if (format2 === null)
|
|
9289
|
+
return null;
|
|
9290
|
+
return {
|
|
9291
|
+
kind: "helper-call",
|
|
9292
|
+
helper: "format_date",
|
|
9293
|
+
args: [callee.object, strLit(format2.pattern), strLit(tz), strArr(format2.names ?? [])]
|
|
9294
|
+
};
|
|
9295
|
+
}
|
|
9296
|
+
const members = resolveLocaleUnionMembers(locale, metadata);
|
|
9297
|
+
if (!members)
|
|
8936
9298
|
return null;
|
|
9299
|
+
const formats = [];
|
|
9300
|
+
for (const member of members) {
|
|
9301
|
+
const format2 = resolveLocaleDateFormat(member, probeOptions);
|
|
9302
|
+
if (format2 === null)
|
|
9303
|
+
return null;
|
|
9304
|
+
formats.push(format2);
|
|
9305
|
+
}
|
|
9306
|
+
const patterns = formats.map((f) => f.pattern);
|
|
9307
|
+
const nameTables = formats.map((f) => JSON.stringify(f.names ?? []));
|
|
8937
9308
|
return {
|
|
8938
9309
|
kind: "helper-call",
|
|
8939
9310
|
helper: "format_date",
|
|
8940
9311
|
args: [
|
|
8941
9312
|
callee.object,
|
|
8942
|
-
|
|
8943
|
-
|
|
9313
|
+
foldMembers(locale, members, patterns.map(strLit), new Set(patterns).size === 1),
|
|
9314
|
+
strLit(tz),
|
|
9315
|
+
foldMembers(locale, members, formats.map((f) => strArr(f.names ?? [])), new Set(nameTables).size === 1)
|
|
8944
9316
|
]
|
|
8945
9317
|
};
|
|
8946
9318
|
}
|
|
9319
|
+
function foldedArgToClientJs(arg, localeText) {
|
|
9320
|
+
if (arg.kind === "literal")
|
|
9321
|
+
return JSON.stringify(arg.value);
|
|
9322
|
+
if (arg.kind === "array-literal") {
|
|
9323
|
+
const values = [];
|
|
9324
|
+
for (const el of arg.elements) {
|
|
9325
|
+
if (el.kind !== "literal")
|
|
9326
|
+
return null;
|
|
9327
|
+
values.push(String(el.value));
|
|
9328
|
+
}
|
|
9329
|
+
return JSON.stringify(values);
|
|
9330
|
+
}
|
|
9331
|
+
if (arg.kind !== "conditional")
|
|
9332
|
+
return null;
|
|
9333
|
+
const t = arg.test;
|
|
9334
|
+
if (t.kind !== "binary" || t.op !== "===" || t.right.kind !== "literal")
|
|
9335
|
+
return null;
|
|
9336
|
+
if (arg.consequent.kind !== "literal" && arg.consequent.kind !== "array-literal")
|
|
9337
|
+
return null;
|
|
9338
|
+
const cons = foldedArgToClientJs(arg.consequent, localeText);
|
|
9339
|
+
const rest = foldedArgToClientJs(arg.alternate, localeText);
|
|
9340
|
+
if (cons === null || rest === null)
|
|
9341
|
+
return null;
|
|
9342
|
+
return `${localeText} === ${JSON.stringify(t.right.value)} ? ${cons} : ${rest}`;
|
|
9343
|
+
}
|
|
8947
9344
|
var toLocaleDatePlugin = {
|
|
8948
9345
|
name: "toLocaleDateString",
|
|
8949
9346
|
prepare(metadata) {
|
|
@@ -9110,12 +9507,22 @@ function lowerToLocaleDateCalls(text, expr, ctx) {
|
|
|
9110
9507
|
const node = matcher(tsNodeToParsedExpr(propAccess), call.arguments.map((a) => tsNodeToParsedExpr(a)));
|
|
9111
9508
|
if (!node || node.kind !== "helper-call" || node.helper !== "format_date")
|
|
9112
9509
|
continue;
|
|
9113
|
-
const [, patternArg, tzArg] = node.args;
|
|
9114
|
-
if (patternArg
|
|
9510
|
+
const [, patternArg, tzArg, namesArg] = node.args;
|
|
9511
|
+
if (!patternArg || tzArg?.kind !== "literal")
|
|
9115
9512
|
continue;
|
|
9513
|
+
const localeText = ctx.getJS(call.arguments[0]);
|
|
9514
|
+
const patternJs = foldedArgToClientJs(patternArg, localeText);
|
|
9515
|
+
if (patternJs === null)
|
|
9516
|
+
continue;
|
|
9517
|
+
let namesJs = null;
|
|
9518
|
+
if (namesArg && !(namesArg.kind === "array-literal" && namesArg.elements.length === 0)) {
|
|
9519
|
+
namesJs = foldedArgToClientJs(namesArg, localeText);
|
|
9520
|
+
if (namesJs === null)
|
|
9521
|
+
continue;
|
|
9522
|
+
}
|
|
9116
9523
|
const receiverText = ctx.getJS(propAccess.expression);
|
|
9117
9524
|
const matchText = ctx.getJS(call);
|
|
9118
|
-
result = replaceProtectedCall(result, matchText, () => `formatDate(${receiverText}, ${
|
|
9525
|
+
result = replaceProtectedCall(result, matchText, () => `formatDate(${receiverText}, ${patternJs}, ${JSON.stringify(tzArg.value)}${namesJs !== null ? `, ${namesJs}` : ""})`);
|
|
9119
9526
|
}
|
|
9120
9527
|
return restore(result);
|
|
9121
9528
|
}
|
|
@@ -17194,12 +17601,22 @@ function lowerToLocaleCallsInReactiveExpr(expr, matcher) {
|
|
|
17194
17601
|
const node = matcher(tsNodeToParsedExpr(propAccess), call.arguments.map((a) => tsNodeToParsedExpr(a)));
|
|
17195
17602
|
if (!node || node.kind !== "helper-call" || node.helper !== "format_date")
|
|
17196
17603
|
continue;
|
|
17197
|
-
const [, patternArg, tzArg] = node.args;
|
|
17198
|
-
if (patternArg
|
|
17604
|
+
const [, patternArg, tzArg, namesArg] = node.args;
|
|
17605
|
+
if (!patternArg || tzArg?.kind !== "literal")
|
|
17606
|
+
continue;
|
|
17607
|
+
const localeText = call.arguments[0].getText(sourceFile);
|
|
17608
|
+
const patternJs = foldedArgToClientJs(patternArg, localeText);
|
|
17609
|
+
if (patternJs === null)
|
|
17199
17610
|
continue;
|
|
17611
|
+
let namesJs = null;
|
|
17612
|
+
if (namesArg && !(namesArg.kind === "array-literal" && namesArg.elements.length === 0)) {
|
|
17613
|
+
namesJs = foldedArgToClientJs(namesArg, localeText);
|
|
17614
|
+
if (namesJs === null)
|
|
17615
|
+
continue;
|
|
17616
|
+
}
|
|
17200
17617
|
const receiverText = propAccess.expression.getText(sourceFile);
|
|
17201
17618
|
const matchText = call.getText(sourceFile);
|
|
17202
|
-
result = replaceProtectedCall(result, matchText, () => `formatDate(${receiverText}, ${
|
|
17619
|
+
result = replaceProtectedCall(result, matchText, () => `formatDate(${receiverText}, ${patternJs}, ${JSON.stringify(tzArg.value)}${namesJs !== null ? `, ${namesJs}` : ""})`);
|
|
17203
17620
|
}
|
|
17204
17621
|
return restore(result);
|
|
17205
17622
|
}
|
|
@@ -22002,15 +22419,16 @@ function isOmitBranch(node) {
|
|
|
22002
22419
|
}
|
|
22003
22420
|
// src/format-date-lowering.ts
|
|
22004
22421
|
var UTC_LITERAL = { kind: "literal", value: "UTC", literalType: "string" };
|
|
22422
|
+
var EMPTY_NAMES = { kind: "array-literal", elements: [], raw: "[]" };
|
|
22005
22423
|
function matchFormatDateCall(callee, args, locals) {
|
|
22006
22424
|
if (callee.kind !== "identifier" || !locals.has(callee.name))
|
|
22007
22425
|
return null;
|
|
22008
|
-
if (args.length < 2 || args.length >
|
|
22426
|
+
if (args.length < 2 || args.length > 4)
|
|
22009
22427
|
return null;
|
|
22010
22428
|
return {
|
|
22011
22429
|
kind: "helper-call",
|
|
22012
22430
|
helper: "format_date",
|
|
22013
|
-
args: [args[0], args[1], args[2] ?? UTC_LITERAL]
|
|
22431
|
+
args: [args[0], args[1], args[2] ?? UTC_LITERAL, args[3] ?? EMPTY_NAMES]
|
|
22014
22432
|
};
|
|
22015
22433
|
}
|
|
22016
22434
|
var formatDatePlugin = {
|