@@ -18614,6 +18614,12 @@ function makeTemporaryIdentifier(id, loc) {
18614
18614
function forkTemporaryIdentifier(id, source) {
18615
18615
return Object.assign(Object.assign({}, source), { mutableRange: { start: makeInstructionId(0), end: makeInstructionId(0) }, id });
18616
18616
}
18617
+ function validateIdentifierName(name) {
18618
+ if (isReservedWord(name) || !libExports$1.isValidIdentifier(name)) {
18619
+ return Err(null);
18620
+ }
18621
+ return Ok(makeIdentifierName(name).value);
18622
+ }
18617
18623
function makeIdentifierName(name) {
18618
18624
if (isReservedWord(name)) {
18619
18625
CompilerError.throwInvalidJS({
@@ -25842,13 +25848,16 @@ function trimJsxText(original) {
25842
25848
}
25843
25849
}
25844
25850
function lowerFunctionToValue(builder, expr) {
25845
- var _a, _b, _c, _d;
25851
+ var _a, _b, _c, _d, _e, _f, _g ;
25846
25852
const exprNode = expr.node;
25847
25853
const exprLoc = (_a = exprNode.loc) !== null && _a !== void 0 ? _a : GeneratedSource;
25848
25854
let name = null;
25849
25855
if (expr.isFunctionExpression()) {
25850
25856
name = (_d = (_c = (_b = expr.get('id')) === null || _b === void 0 ? void 0 : _b.node) === null || _c === void 0 ? void 0 : _c.name) !== null && _d !== void 0 ? _d : null;
25851
25857
}
25858
+ else if (expr.isFunctionDeclaration()) {
25859
+ name = (_g = (_f = (_e = expr.get('id')) === null || _e === void 0 ? void 0 : _e.node) === null || _f === void 0 ? void 0 : _f.name) !== null && _g !== void 0 ? _g : null;
25860
+ }
25852
25861
const loweredFunc = lowerFunction(builder, expr);
25853
25862
if (!loweredFunc) {
25854
25863
return { kind: 'UnsupportedNode', node: exprNode, loc: exprLoc };
@@ -32084,6 +32093,7 @@ const EnvironmentConfigSchema = zod.z.object({
32084
32093
flowTypeProvider: zod.z.nullable(zod.z.function().args(zod.z.string())).default(null),
32085
32094
enableOptionalDependencies: zod.z.boolean().default(true),
32086
32095
enableFire: zod.z.boolean().default(false),
32096
+ enableNameAnonymousFunctions: zod.z.boolean().default(false),
32087
32097
inferEffectDependencies: zod.z
32088
32098
.nullable(zod.z.array(zod.z.object({
32089
32099
function: ExternalFunctionSchema,
@@ -38457,7 +38467,7 @@ function codegenInstructionValueToExpression(cx, instrValue) {
38457
38467
return convertValueToExpression(value);
38458
38468
}
38459
38469
function codegenInstructionValue(cx, instrValue) {
38460
- var _a, _b, _c, _d, _e, _f, _g, _h ;
38470
+ var _a, _b, _c, _d, _e, _f, _g;
38461
38471
let value;
38462
38472
switch (instrValue.kind) {
38463
38473
case 'ArrayExpression': {
@@ -38775,6 +38785,9 @@ function codegenInstructionValue(cx, instrValue) {
38775
38785
pruneUnusedLValues(reactiveFunction);
38776
38786
pruneHoistedContexts(reactiveFunction);
38777
38787
const fn = codegenReactiveFunction(new Context$2(cx.env, (_g = reactiveFunction.id) !== null && _g !== void 0 ? _g : '[[ anonymous ]]', cx.uniqueIdentifiers, cx.fbtOperands, cx.temp), reactiveFunction).unwrap();
38788
+ const validatedName = instrValue.name != null
38789
+ ? validateIdentifierName(instrValue.name)
38790
+ : Err(null);
38778
38791
if (instrValue.type === 'ArrowFunctionExpression') {
38779
38792
let body = fn.body;
38780
38793
if (body.body.length === 1 && loweredFunc.directives.length == 0) {
@@ -38786,7 +38799,15 @@ function codegenInstructionValue(cx, instrValue) {
38786
38799
value = libExports$1.arrowFunctionExpression(fn.params, body, fn.async);
38787
38800
}
38788
38801
else {
38789
- value = libExports$1.functionExpression((_h = fn.id) !== null && _h !== void 0 ? _h : (instrValue.name != null ? libExports$1.identifier(instrValue.name) : null), fn.params, fn.body, fn.generator, fn.async);
38802
+ value = libExports$1.functionExpression(validatedName
38803
+ .map(name => libExports$1.identifier(name))
38804
+ .unwrapOr(null), fn.params, fn.body, fn.generator, fn.async);
38805
+ }
38806
+ if (cx.env.config.enableNameAnonymousFunctions &&
38807
+ validatedName.isErr() &&
38808
+ instrValue.name != null) {
38809
+ const name = instrValue.name;
38810
+ value = libExports$1.memberExpression(libExports$1.objectExpression([libExports$1.objectProperty(libExports$1.stringLiteral(name), value)]), libExports$1.stringLiteral(name), true, false);
38790
38811
}
38791
38812
break;
38792
38813
}
@@ -51841,6 +51862,136 @@ function validateEffect(effectFunction, effectDeps, errors) {
51841
51862
}
51842
51863
}
51843
51864
51865
+ function nameAnonymousFunctions(fn) {
51866
+ if (fn.id == null) {
51867
+ return;
51868
+ }
51869
+ const parentName = fn.id;
51870
+ const functions = nameAnonymousFunctionsImpl(fn);
51871
+ function visit(node, prefix) {
51872
+ var _a, _b;
51873
+ if (node.generatedName != null) {
51874
+ const name = `${prefix}${node.generatedName}]`;
51875
+ node.fn.name = name;
51876
+ }
51877
+ const nextPrefix = `${prefix}${(_b = (_a = node.generatedName) !== null && _a !== void 0 ? _a : node.fn.name) !== null && _b !== void 0 ? _b : '<anonymous>'} > `;
51878
+ for (const inner of node.inner) {
51879
+ visit(inner, nextPrefix);
51880
+ }
51881
+ }
51882
+ for (const node of functions) {
51883
+ visit(node, `${parentName}[`);
51884
+ }
51885
+ }
51886
+ function nameAnonymousFunctionsImpl(fn) {
51887
+ var _a, _b;
51888
+ const functions = new Map();
51889
+ const names = new Map();
51890
+ const nodes = [];
51891
+ for (const block of fn.body.blocks.values()) {
51892
+ for (const instr of block.instructions) {
51893
+ const { lvalue, value } = instr;
51894
+ switch (value.kind) {
51895
+ case 'LoadGlobal': {
51896
+ names.set(lvalue.identifier.id, value.binding.name);
51897
+ break;
51898
+ }
51899
+ case 'LoadContext':
51900
+ case 'LoadLocal': {
51901
+ const name = value.place.identifier.name;
51902
+ if (name != null && name.kind === 'named') {
51903
+ names.set(lvalue.identifier.id, name.value);
51904
+ }
51905
+ break;
51906
+ }
51907
+ case 'PropertyLoad': {
51908
+ const objectName = names.get(value.object.identifier.id);
51909
+ if (objectName != null) {
51910
+ names.set(lvalue.identifier.id, `${objectName}.${String(value.property)}`);
51911
+ }
51912
+ break;
51913
+ }
51914
+ case 'FunctionExpression': {
51915
+ const inner = nameAnonymousFunctionsImpl(value.loweredFunc.func);
51916
+ const node = {
51917
+ fn: value,
51918
+ generatedName: null,
51919
+ inner,
51920
+ };
51921
+ nodes.push(node);
51922
+ if (value.name == null) {
51923
+ functions.set(lvalue.identifier.id, node);
51924
+ }
51925
+ break;
51926
+ }
51927
+ case 'StoreContext':
51928
+ case 'StoreLocal': {
51929
+ const node = functions.get(value.value.identifier.id);
51930
+ const variableName = value.lvalue.place.identifier.name;
51931
+ if (node != null &&
51932
+ variableName != null &&
51933
+ variableName.kind === 'named') {
51934
+ node.generatedName = variableName.value;
51935
+ functions.delete(value.value.identifier.id);
51936
+ }
51937
+ break;
51938
+ }
51939
+ case 'CallExpression':
51940
+ case 'MethodCall': {
51941
+ const callee = value.kind === 'MethodCall' ? value.property : value.callee;
51942
+ const hookKind = getHookKind(fn.env, callee.identifier);
51943
+ let calleeName = null;
51944
+ if (hookKind != null && hookKind !== 'Custom') {
51945
+ calleeName = hookKind;
51946
+ }
51947
+ else {
51948
+ calleeName = (_a = names.get(callee.identifier.id)) !== null && _a !== void 0 ? _a : '(anonymous)';
51949
+ }
51950
+ let fnArgCount = 0;
51951
+ for (const arg of value.args) {
51952
+ if (arg.kind === 'Identifier' && functions.has(arg.identifier.id)) {
51953
+ fnArgCount++;
51954
+ }
51955
+ }
51956
+ for (let i = 0; i < value.args.length; i++) {
51957
+ const arg = value.args[i];
51958
+ if (arg.kind === 'Spread') {
51959
+ continue;
51960
+ }
51961
+ const node = functions.get(arg.identifier.id);
51962
+ if (node != null) {
51963
+ const generatedName = fnArgCount > 1 ? `${calleeName}(arg${i})` : `${calleeName}()`;
51964
+ node.generatedName = generatedName;
51965
+ functions.delete(arg.identifier.id);
51966
+ }
51967
+ }
51968
+ break;
51969
+ }
51970
+ case 'JsxExpression': {
51971
+ for (const attr of value.props) {
51972
+ if (attr.kind === 'JsxSpreadAttribute') {
51973
+ continue;
51974
+ }
51975
+ const node = functions.get(attr.place.identifier.id);
51976
+ if (node != null) {
51977
+ const elementName = value.tag.kind === 'BuiltinTag'
51978
+ ? value.tag.name
51979
+ : ((_b = names.get(value.tag.identifier.id)) !== null && _b !== void 0 ? _b : null);
51980
+ const propName = elementName == null
51981
+ ? attr.name
51982
+ : `<${elementName}>.${attr.name}`;
51983
+ node.generatedName = `${propName}`;
51984
+ functions.delete(attr.place.identifier.id);
51985
+ }
51986
+ }
51987
+ break;
51988
+ }
51989
+ }
51990
+ }
51991
+ }
51992
+ return nodes;
51993
+ }
51994
+
51844
51995
function run(func, config, fnType, mode, programContext, logger, filename, code) {
51845
51996
var _a, _b;
51846
51997
const contextIdentifiers = findContextIdentifiers(func);
@@ -52059,6 +52210,14 @@ function runWithEnvironment(func, env) {
52059
52210
value: hir,
52060
52211
});
52061
52212
}
52213
+ if (env.config.enableNameAnonymousFunctions) {
52214
+ nameAnonymousFunctions(hir);
52215
+ log({
52216
+ kind: 'hir',
52217
+ name: 'NameAnonymougFunctions',
52218
+ value: hir,
52219
+ });
52220
+ }
52062
52221
const reactiveFunction = buildReactiveFunction(hir);
52063
52222
log({
52064
52223
kind: 'reactive',
0 commit comments