@marko/language-tools 2.5.42 → 2.5.44

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.
@@ -32,7 +32,7 @@ export interface ParamBinding {
32
32
  type: BindingType.param;
33
33
  name: string;
34
34
  node: Node.ParentNode;
35
- scope: TagScope;
35
+ scope: Scope;
36
36
  hoisted: false;
37
37
  }
38
38
  export interface HoistedBinding {
@@ -53,7 +53,11 @@ type Bindings = {
53
53
  * Traverses the Marko tree and analyzes the bindings.
54
54
  */
55
55
  export declare function crawlProgramScope(parsed: Parsed, scriptParser: ScriptParser): [number, ...number[]] | [...number[], number] | undefined;
56
- export declare function getHoists(node: Node.Program): Repeatable<string>;
56
+ export declare function getProgramBindings(node: Node.Program): {
57
+ all: Repeated<string>;
58
+ vars: Repeatable<string>;
59
+ hoists: Repeatable<string>;
60
+ } | undefined;
57
61
  export declare function getHoistSources(body: Node.ParentNode["body"]): Repeatable<string>;
58
62
  export declare function getMutatedVars(node: Node.ParentNode): Set<VarBinding> | undefined;
59
63
  export declare function isMutatedVar(node: Node.ParentNode, name: string): boolean;
package/dist/index.js CHANGED
@@ -1093,21 +1093,17 @@ function crawlProgramScope(parsed, scriptParser) {
1093
1093
  mutatedBindings: void 0
1094
1094
  };
1095
1095
  programScope.bindings.input = {
1096
- type: 0 /* var */,
1096
+ type: 1 /* param */,
1097
1097
  name: "input",
1098
1098
  node: program,
1099
1099
  scope: programScope,
1100
- hoisted: false,
1101
- mutated: false,
1102
- sourceName: void 0,
1103
- objectPath: void 0
1100
+ hoisted: false
1104
1101
  };
1105
1102
  visit(program.body, programScope);
1106
1103
  Scopes.set(program.body, programScope);
1107
1104
  for (const binding of potentialHoists) {
1108
1105
  const { scope, name } = binding;
1109
- const parentScope = scope.parent;
1110
- let curParent = parentScope;
1106
+ let curParent = scope.parent;
1111
1107
  while (curParent) {
1112
1108
  const parentBinding = (_a = curParent.bindings) == null ? void 0 : _a[name];
1113
1109
  if (parentBinding) {
@@ -1117,7 +1113,6 @@ function crawlProgramScope(parsed, scriptParser) {
1117
1113
  }
1118
1114
  break;
1119
1115
  }
1120
- curParent.hoists = true;
1121
1116
  if (curParent === programScope) {
1122
1117
  binding.hoisted = true;
1123
1118
  programScope.bindings[name] = {
@@ -1132,6 +1127,11 @@ function crawlProgramScope(parsed, scriptParser) {
1132
1127
  }
1133
1128
  if (binding.hoisted) {
1134
1129
  scope.hoists = true;
1130
+ curParent = scope.parent;
1131
+ while (curParent && !curParent.hoists && curParent !== programScope) {
1132
+ curParent.hoists = true;
1133
+ curParent = curParent.parent;
1134
+ }
1135
1135
  }
1136
1136
  }
1137
1137
  for (const [scope, nodes] of nodesToCheckForMutations) {
@@ -1328,19 +1328,35 @@ ${read({
1328
1328
  }
1329
1329
  }
1330
1330
  }
1331
- function getHoists(node) {
1331
+ function getProgramBindings(node) {
1332
1332
  const { bindings } = Scopes.get(node.body);
1333
- let result;
1333
+ let hoists;
1334
+ let vars;
1334
1335
  for (const key in bindings) {
1335
- if (bindings[key].type === 2 /* hoisted */) {
1336
- if (result) {
1337
- result.push(key);
1338
- } else {
1339
- result = [key];
1340
- }
1336
+ switch (bindings[key].type) {
1337
+ case 2 /* hoisted */:
1338
+ if (hoists) {
1339
+ hoists.push(key);
1340
+ } else {
1341
+ hoists = [key];
1342
+ }
1343
+ break;
1344
+ case 0 /* var */:
1345
+ if (vars) {
1346
+ vars.push(key);
1347
+ } else {
1348
+ vars = [key];
1349
+ }
1350
+ break;
1341
1351
  }
1342
1352
  }
1343
- return result;
1353
+ if (hoists || vars) {
1354
+ return {
1355
+ all: vars ? hoists ? [...vars, ...hoists] : vars : hoists,
1356
+ vars,
1357
+ hoists
1358
+ };
1359
+ }
1344
1360
  }
1345
1361
  function getHoistSources(body) {
1346
1362
  let result;
@@ -2014,6 +2030,7 @@ var ScriptExtractor = class {
2014
2030
  #mutationOffsets;
2015
2031
  #tagId = 1;
2016
2032
  #renderId = 1;
2033
+ #closeBrackets = [0];
2017
2034
  constructor(opts) {
2018
2035
  const { parsed, lookup, scriptLang } = opts;
2019
2036
  const { api, interop } = getRuntimeAPI(
@@ -2196,7 +2213,7 @@ function ${templateName}() {
2196
2213
  this.#extractor.write(` const input = ${this.#getCastedType(`Input${typeArgsStr}`)};${this.#api === RuntimeAPI.class ? `
2197
2214
  const component = ${this.#getCastedType(`Component${typeArgsStr}`)};
2198
2215
  const state = ${varShared("state")}(component);
2199
- const out = ${varShared("out")};` : ""}
2216
+ const out = ${this.#getCastedType("Marko.Out")};` : ""}
2200
2217
  const $signal = ${this.#getCastedType("AbortSignal")};
2201
2218
  const $global = ${varShared("getGlobal")}(
2202
2219
  // @ts-expect-error We expect the compiler to error because we are checking if the MarkoRun.Context is defined.
@@ -2204,18 +2221,37 @@ function ${templateName}() {
2204
2221
  );
2205
2222
  `);
2206
2223
  const body = this.#processBody(program);
2224
+ const bindings = getProgramBindings(program);
2225
+ if (bindings) {
2226
+ for (const name of bindings.all) {
2227
+ this.#extractor.write(
2228
+ `const ${name} = ${varShared("hoist")}(() => ${varLocal(`hoist__${name}`)});
2229
+ `
2230
+ );
2231
+ }
2232
+ }
2207
2233
  if (body == null ? void 0 : body.content) {
2208
2234
  this.#writeChildren(program, body.content);
2209
- }
2210
- const hoists = getHoists(program);
2211
- if (hoists) {
2212
- this.#extractor.write(
2213
- `const { ${hoists.join(SEP_COMMA_SPACE)} } = ${this.#getBodyHoistScopeExpression(program.body)};
2235
+ if (bindings) {
2236
+ if (bindings.vars) {
2237
+ for (const name of bindings.vars) {
2238
+ this.#extractor.write(
2239
+ `var ${varLocal(`hoist__${name}`)} = ${name};
2214
2240
  `
2215
- );
2241
+ );
2242
+ }
2243
+ }
2244
+ if (bindings.hoists) {
2245
+ this.#extractor.write(
2246
+ `var {${bindings.hoists.map((name) => `${name}: ${varLocal(`hoist__${name}`)}`).join(SEP_COMMA_SPACE)}} = ${this.#getBodyHoistScopeExpression(program.body)};
2247
+ `
2248
+ );
2249
+ }
2250
+ }
2251
+ this.#endChildren();
2216
2252
  }
2217
2253
  this.#extractor.write(
2218
- `${varShared("noop")}({ ${hoists ? hoists.join(SEP_COMMA_SPACE) + SEP_COMMA_SPACE : ""}${this.#api === RuntimeAPI.class ? "component, state, out, " : ""}input, $global, $signal });
2254
+ `${varShared("noop")}({ ${bindings ? bindings.all.join(SEP_COMMA_SPACE) + SEP_COMMA_SPACE : ""}${this.#api === RuntimeAPI.class ? "component, state, out, " : ""}input, $global, $signal });
2219
2255
  `
2220
2256
  );
2221
2257
  if (didReturn) {
@@ -2314,7 +2350,7 @@ function ${templateName}() {
2314
2350
  this.#extractor.write(`return new (class MarkoReturn<Return = void> {
2315
2351
  `);
2316
2352
  if (scopeExpr) {
2317
- this.#extractor.write(`[Marko._.scope] = ${scopeExpr};
2353
+ this.#extractor.write(`[${varShared("scope")}] = ${scopeExpr};
2318
2354
  `);
2319
2355
  }
2320
2356
  this.#extractor.write(`declare return: Return;
@@ -2329,6 +2365,7 @@ constructor(_?: Return) {}
2329
2365
  const last = children.length - 1;
2330
2366
  let returnTag;
2331
2367
  let i = 0;
2368
+ this.#closeBrackets.push(0);
2332
2369
  while (i <= last) {
2333
2370
  const child = children[i++];
2334
2371
  switch (child.type) {
@@ -2372,6 +2409,7 @@ scope: ${scopeExpr}
2372
2409
  };
2373
2410
  `);
2374
2411
  }
2412
+ this.#endChildren();
2375
2413
  }
2376
2414
  let needsAlternate = true;
2377
2415
  if (alternates) {
@@ -2397,6 +2435,7 @@ scope: ${scopeExpr}
2397
2435
  `
2398
2436
  );
2399
2437
  }
2438
+ this.#endChildren();
2400
2439
  }
2401
2440
  }
2402
2441
  }
@@ -2434,6 +2473,9 @@ scope: ${scopeExpr}
2434
2473
  this.#writeChildren(child, body.content);
2435
2474
  }
2436
2475
  this.#writeReturn(void 0, (body == null ? void 0 : body.content) && child.body);
2476
+ if (body == null ? void 0 : body.content) {
2477
+ this.#endChildren();
2478
+ }
2437
2479
  this.#extractor.write("\n});\n");
2438
2480
  break;
2439
2481
  }
@@ -2445,6 +2487,7 @@ scope: ${scopeExpr}
2445
2487
  const body = this.#processBody(child);
2446
2488
  if (body == null ? void 0 : body.content) {
2447
2489
  this.#writeChildren(child, body.content);
2490
+ this.#endChildren();
2448
2491
  }
2449
2492
  this.#extractor.write("\n}\n");
2450
2493
  break;
@@ -2464,7 +2507,7 @@ scope: ${scopeExpr}
2464
2507
  }
2465
2508
  const mutatedVars = getMutatedVars(parent);
2466
2509
  if (returnTag || mutatedVars) {
2467
- this.#extractor.write(`const ${varLocal("return")} = {
2510
+ this.#extractor.write(`var ${varLocal("return")} = {
2468
2511
  `);
2469
2512
  if (returnTag) {
2470
2513
  this.#extractor.write(`return: ${varShared("returnTag")}(`);
@@ -2562,7 +2605,8 @@ scope: ${scopeExpr}
2562
2605
  this.#writeTagInputObject(tag);
2563
2606
  this.#extractor.write(");\n");
2564
2607
  if (renderId && tag.var) {
2565
- this.#extractor.write(`const `);
2608
+ this.#extractor.write(`{const `);
2609
+ this.#closeBrackets[this.#closeBrackets.length - 1]++;
2566
2610
  this.#copyWithMutationsReplaced(tag.var.value);
2567
2611
  this.#extractor.write(
2568
2612
  ` = ${varLocal("rendered_" + renderId)}.return.${ATTR_UNAMED2};
@@ -2570,6 +2614,12 @@ scope: ${scopeExpr}
2570
2614
  );
2571
2615
  }
2572
2616
  }
2617
+ #endChildren() {
2618
+ const pendingBrackets = this.#closeBrackets.pop();
2619
+ if (pendingBrackets) {
2620
+ this.#extractor.write("}".repeat(pendingBrackets));
2621
+ }
2622
+ }
2573
2623
  #writeDynamicTagName(tag) {
2574
2624
  const dynamicTagNameExpression = this.#getDynamicTagExpression(tag);
2575
2625
  if (dynamicTagNameExpression) {
@@ -2657,7 +2707,9 @@ scope: ${scopeExpr}
2657
2707
  const valueLiteral = this.#read(boundRange.value);
2658
2708
  this.#extractor.copy(boundRange.value).copy(boundRange.types).write(`
2659
2709
  )${SEP_COMMA_NEW_LINE}"`).copy(defaultMapPosition).copy(name).write(
2660
- `Change"(_${valueLiteral}) {
2710
+ `Change"(
2711
+ // @ts-ignore
2712
+ _${valueLiteral}) {
2661
2713
  ${isMutatedVar(tag.parent, valueLiteral) ? `${varLocal("return")}.mutate.` : ""}`
2662
2714
  ).copy(boundRange.value).write(`= _${valueLiteral};
2663
2715
  }`);
@@ -2948,6 +3000,9 @@ ${isMutatedVar(tag.parent, valueLiteral) ? `${varLocal("return")}.mutate.` : ""}
2948
3000
  didReturn ? `${varLocal("return")}.return` : void 0,
2949
3001
  tag.body
2950
3002
  );
3003
+ if (body == null ? void 0 : body.content) {
3004
+ this.#endChildren();
3005
+ }
2951
3006
  if (tag.params) {
2952
3007
  this.#extractor.write("})");
2953
3008
  } else {
@@ -3153,6 +3208,7 @@ ${isMutatedVar(tag.parent, valueLiteral) ? `${varLocal("return")}.mutate.` : ""}
3153
3208
  this.#writeAttrTags(body);
3154
3209
  this.#extractor.write("}");
3155
3210
  if (body.content) {
3211
+ this.#endChildren();
3156
3212
  this.#extractor.write(";\n})()");
3157
3213
  }
3158
3214
  } else {
package/dist/index.mjs CHANGED
@@ -1053,21 +1053,17 @@ function crawlProgramScope(parsed, scriptParser) {
1053
1053
  mutatedBindings: void 0
1054
1054
  };
1055
1055
  programScope.bindings.input = {
1056
- type: 0 /* var */,
1056
+ type: 1 /* param */,
1057
1057
  name: "input",
1058
1058
  node: program,
1059
1059
  scope: programScope,
1060
- hoisted: false,
1061
- mutated: false,
1062
- sourceName: void 0,
1063
- objectPath: void 0
1060
+ hoisted: false
1064
1061
  };
1065
1062
  visit(program.body, programScope);
1066
1063
  Scopes.set(program.body, programScope);
1067
1064
  for (const binding of potentialHoists) {
1068
1065
  const { scope, name } = binding;
1069
- const parentScope = scope.parent;
1070
- let curParent = parentScope;
1066
+ let curParent = scope.parent;
1071
1067
  while (curParent) {
1072
1068
  const parentBinding = (_a = curParent.bindings) == null ? void 0 : _a[name];
1073
1069
  if (parentBinding) {
@@ -1077,7 +1073,6 @@ function crawlProgramScope(parsed, scriptParser) {
1077
1073
  }
1078
1074
  break;
1079
1075
  }
1080
- curParent.hoists = true;
1081
1076
  if (curParent === programScope) {
1082
1077
  binding.hoisted = true;
1083
1078
  programScope.bindings[name] = {
@@ -1092,6 +1087,11 @@ function crawlProgramScope(parsed, scriptParser) {
1092
1087
  }
1093
1088
  if (binding.hoisted) {
1094
1089
  scope.hoists = true;
1090
+ curParent = scope.parent;
1091
+ while (curParent && !curParent.hoists && curParent !== programScope) {
1092
+ curParent.hoists = true;
1093
+ curParent = curParent.parent;
1094
+ }
1095
1095
  }
1096
1096
  }
1097
1097
  for (const [scope, nodes] of nodesToCheckForMutations) {
@@ -1288,19 +1288,35 @@ ${read({
1288
1288
  }
1289
1289
  }
1290
1290
  }
1291
- function getHoists(node) {
1291
+ function getProgramBindings(node) {
1292
1292
  const { bindings } = Scopes.get(node.body);
1293
- let result;
1293
+ let hoists;
1294
+ let vars;
1294
1295
  for (const key in bindings) {
1295
- if (bindings[key].type === 2 /* hoisted */) {
1296
- if (result) {
1297
- result.push(key);
1298
- } else {
1299
- result = [key];
1300
- }
1296
+ switch (bindings[key].type) {
1297
+ case 2 /* hoisted */:
1298
+ if (hoists) {
1299
+ hoists.push(key);
1300
+ } else {
1301
+ hoists = [key];
1302
+ }
1303
+ break;
1304
+ case 0 /* var */:
1305
+ if (vars) {
1306
+ vars.push(key);
1307
+ } else {
1308
+ vars = [key];
1309
+ }
1310
+ break;
1301
1311
  }
1302
1312
  }
1303
- return result;
1313
+ if (hoists || vars) {
1314
+ return {
1315
+ all: vars ? hoists ? [...vars, ...hoists] : vars : hoists,
1316
+ vars,
1317
+ hoists
1318
+ };
1319
+ }
1304
1320
  }
1305
1321
  function getHoistSources(body) {
1306
1322
  let result;
@@ -1977,6 +1993,7 @@ var ScriptExtractor = class {
1977
1993
  #mutationOffsets;
1978
1994
  #tagId = 1;
1979
1995
  #renderId = 1;
1996
+ #closeBrackets = [0];
1980
1997
  constructor(opts) {
1981
1998
  const { parsed, lookup, scriptLang } = opts;
1982
1999
  const { api, interop } = getRuntimeAPI(
@@ -2159,7 +2176,7 @@ function ${templateName}() {
2159
2176
  this.#extractor.write(` const input = ${this.#getCastedType(`Input${typeArgsStr}`)};${this.#api === RuntimeAPI.class ? `
2160
2177
  const component = ${this.#getCastedType(`Component${typeArgsStr}`)};
2161
2178
  const state = ${varShared("state")}(component);
2162
- const out = ${varShared("out")};` : ""}
2179
+ const out = ${this.#getCastedType("Marko.Out")};` : ""}
2163
2180
  const $signal = ${this.#getCastedType("AbortSignal")};
2164
2181
  const $global = ${varShared("getGlobal")}(
2165
2182
  // @ts-expect-error We expect the compiler to error because we are checking if the MarkoRun.Context is defined.
@@ -2167,18 +2184,37 @@ function ${templateName}() {
2167
2184
  );
2168
2185
  `);
2169
2186
  const body = this.#processBody(program);
2187
+ const bindings = getProgramBindings(program);
2188
+ if (bindings) {
2189
+ for (const name of bindings.all) {
2190
+ this.#extractor.write(
2191
+ `const ${name} = ${varShared("hoist")}(() => ${varLocal(`hoist__${name}`)});
2192
+ `
2193
+ );
2194
+ }
2195
+ }
2170
2196
  if (body == null ? void 0 : body.content) {
2171
2197
  this.#writeChildren(program, body.content);
2172
- }
2173
- const hoists = getHoists(program);
2174
- if (hoists) {
2175
- this.#extractor.write(
2176
- `const { ${hoists.join(SEP_COMMA_SPACE)} } = ${this.#getBodyHoistScopeExpression(program.body)};
2198
+ if (bindings) {
2199
+ if (bindings.vars) {
2200
+ for (const name of bindings.vars) {
2201
+ this.#extractor.write(
2202
+ `var ${varLocal(`hoist__${name}`)} = ${name};
2177
2203
  `
2178
- );
2204
+ );
2205
+ }
2206
+ }
2207
+ if (bindings.hoists) {
2208
+ this.#extractor.write(
2209
+ `var {${bindings.hoists.map((name) => `${name}: ${varLocal(`hoist__${name}`)}`).join(SEP_COMMA_SPACE)}} = ${this.#getBodyHoistScopeExpression(program.body)};
2210
+ `
2211
+ );
2212
+ }
2213
+ }
2214
+ this.#endChildren();
2179
2215
  }
2180
2216
  this.#extractor.write(
2181
- `${varShared("noop")}({ ${hoists ? hoists.join(SEP_COMMA_SPACE) + SEP_COMMA_SPACE : ""}${this.#api === RuntimeAPI.class ? "component, state, out, " : ""}input, $global, $signal });
2217
+ `${varShared("noop")}({ ${bindings ? bindings.all.join(SEP_COMMA_SPACE) + SEP_COMMA_SPACE : ""}${this.#api === RuntimeAPI.class ? "component, state, out, " : ""}input, $global, $signal });
2182
2218
  `
2183
2219
  );
2184
2220
  if (didReturn) {
@@ -2277,7 +2313,7 @@ function ${templateName}() {
2277
2313
  this.#extractor.write(`return new (class MarkoReturn<Return = void> {
2278
2314
  `);
2279
2315
  if (scopeExpr) {
2280
- this.#extractor.write(`[Marko._.scope] = ${scopeExpr};
2316
+ this.#extractor.write(`[${varShared("scope")}] = ${scopeExpr};
2281
2317
  `);
2282
2318
  }
2283
2319
  this.#extractor.write(`declare return: Return;
@@ -2292,6 +2328,7 @@ constructor(_?: Return) {}
2292
2328
  const last = children.length - 1;
2293
2329
  let returnTag;
2294
2330
  let i = 0;
2331
+ this.#closeBrackets.push(0);
2295
2332
  while (i <= last) {
2296
2333
  const child = children[i++];
2297
2334
  switch (child.type) {
@@ -2335,6 +2372,7 @@ scope: ${scopeExpr}
2335
2372
  };
2336
2373
  `);
2337
2374
  }
2375
+ this.#endChildren();
2338
2376
  }
2339
2377
  let needsAlternate = true;
2340
2378
  if (alternates) {
@@ -2360,6 +2398,7 @@ scope: ${scopeExpr}
2360
2398
  `
2361
2399
  );
2362
2400
  }
2401
+ this.#endChildren();
2363
2402
  }
2364
2403
  }
2365
2404
  }
@@ -2397,6 +2436,9 @@ scope: ${scopeExpr}
2397
2436
  this.#writeChildren(child, body.content);
2398
2437
  }
2399
2438
  this.#writeReturn(void 0, (body == null ? void 0 : body.content) && child.body);
2439
+ if (body == null ? void 0 : body.content) {
2440
+ this.#endChildren();
2441
+ }
2400
2442
  this.#extractor.write("\n});\n");
2401
2443
  break;
2402
2444
  }
@@ -2408,6 +2450,7 @@ scope: ${scopeExpr}
2408
2450
  const body = this.#processBody(child);
2409
2451
  if (body == null ? void 0 : body.content) {
2410
2452
  this.#writeChildren(child, body.content);
2453
+ this.#endChildren();
2411
2454
  }
2412
2455
  this.#extractor.write("\n}\n");
2413
2456
  break;
@@ -2427,7 +2470,7 @@ scope: ${scopeExpr}
2427
2470
  }
2428
2471
  const mutatedVars = getMutatedVars(parent);
2429
2472
  if (returnTag || mutatedVars) {
2430
- this.#extractor.write(`const ${varLocal("return")} = {
2473
+ this.#extractor.write(`var ${varLocal("return")} = {
2431
2474
  `);
2432
2475
  if (returnTag) {
2433
2476
  this.#extractor.write(`return: ${varShared("returnTag")}(`);
@@ -2525,7 +2568,8 @@ scope: ${scopeExpr}
2525
2568
  this.#writeTagInputObject(tag);
2526
2569
  this.#extractor.write(");\n");
2527
2570
  if (renderId && tag.var) {
2528
- this.#extractor.write(`const `);
2571
+ this.#extractor.write(`{const `);
2572
+ this.#closeBrackets[this.#closeBrackets.length - 1]++;
2529
2573
  this.#copyWithMutationsReplaced(tag.var.value);
2530
2574
  this.#extractor.write(
2531
2575
  ` = ${varLocal("rendered_" + renderId)}.return.${ATTR_UNAMED2};
@@ -2533,6 +2577,12 @@ scope: ${scopeExpr}
2533
2577
  );
2534
2578
  }
2535
2579
  }
2580
+ #endChildren() {
2581
+ const pendingBrackets = this.#closeBrackets.pop();
2582
+ if (pendingBrackets) {
2583
+ this.#extractor.write("}".repeat(pendingBrackets));
2584
+ }
2585
+ }
2536
2586
  #writeDynamicTagName(tag) {
2537
2587
  const dynamicTagNameExpression = this.#getDynamicTagExpression(tag);
2538
2588
  if (dynamicTagNameExpression) {
@@ -2620,7 +2670,9 @@ scope: ${scopeExpr}
2620
2670
  const valueLiteral = this.#read(boundRange.value);
2621
2671
  this.#extractor.copy(boundRange.value).copy(boundRange.types).write(`
2622
2672
  )${SEP_COMMA_NEW_LINE}"`).copy(defaultMapPosition).copy(name).write(
2623
- `Change"(_${valueLiteral}) {
2673
+ `Change"(
2674
+ // @ts-ignore
2675
+ _${valueLiteral}) {
2624
2676
  ${isMutatedVar(tag.parent, valueLiteral) ? `${varLocal("return")}.mutate.` : ""}`
2625
2677
  ).copy(boundRange.value).write(`= _${valueLiteral};
2626
2678
  }`);
@@ -2911,6 +2963,9 @@ ${isMutatedVar(tag.parent, valueLiteral) ? `${varLocal("return")}.mutate.` : ""}
2911
2963
  didReturn ? `${varLocal("return")}.return` : void 0,
2912
2964
  tag.body
2913
2965
  );
2966
+ if (body == null ? void 0 : body.content) {
2967
+ this.#endChildren();
2968
+ }
2914
2969
  if (tag.params) {
2915
2970
  this.#extractor.write("})");
2916
2971
  } else {
@@ -3116,6 +3171,7 @@ ${isMutatedVar(tag.parent, valueLiteral) ? `${varLocal("return")}.mutate.` : ""}
3116
3171
  this.#writeAttrTags(body);
3117
3172
  this.#extractor.write("}");
3118
3173
  if (body.content) {
3174
+ this.#endChildren();
3119
3175
  this.#extractor.write(";\n})()");
3120
3176
  }
3121
3177
  } else {
@@ -17,7 +17,6 @@ declare global {
17
17
  namespace _ {
18
18
  export const voidReturn: MarkoReturn<void>;
19
19
  export const scope: unique symbol;
20
- export const out: Marko.Out;
21
20
  export const never: never;
22
21
  export const any: any;
23
22
 
@@ -25,6 +24,12 @@ declare global {
25
24
  override: Override,
26
25
  ): [0] extends [1 & Override] ? Marko.Global : Override;
27
26
 
27
+ export function hoist<T, U = T>(
28
+ value: () => T,
29
+ ): T extends (...args: any[]) => any
30
+ ? (T | (U extends undefined ? () => undefined : never)) & Iterable<T>
31
+ : never;
32
+
28
33
  export function attrTagNames<Tag>(
29
34
  tag: Tag,
30
35
  fn: (input: AttrTagNames<Marko.Input<Tag>>) => void,
@@ -99,8 +104,7 @@ declare global {
99
104
  : never
100
105
  : never;
101
106
  }[keyof Rendered]
102
- > &
103
- Record<any, never>;
107
+ >;
104
108
 
105
109
  export function readScope<Value>(
106
110
  value: Value,
@@ -116,8 +120,7 @@ declare global {
116
120
  ? never
117
121
  : Scope
118
122
  : never
119
- > &
120
- Record<any, never>;
123
+ >;
121
124
 
122
125
  export function mutable<Lookup>(lookup: Lookup): UnionToIntersection<
123
126
  Lookup extends readonly (infer Item)[]
@@ -507,10 +510,6 @@ type BodyParamsWithDefault<Body extends AnyMarkoBody> =
507
510
  : Params
508
511
  : never;
509
512
 
510
- type Scopes<Input> = [0] extends [1 & Input]
511
- ? never
512
- : MergeScopes<FlatScopes<Input>>;
513
-
514
513
  type ComponentEventHandlers<Component extends Marko.Component> = {
515
514
  [K in Exclude<
516
515
  keyof Component,
@@ -521,7 +520,7 @@ type ComponentEventHandlers<Component extends Marko.Component> = {
521
520
  >]: Component[K] extends (...args: any) => any ? Component[K] : never;
522
521
  };
523
522
 
524
- type FlatScopes<Input> = [0] extends [1 & Input]
523
+ type Scopes<Input> = [0] extends [1 & Input]
525
524
  ? never
526
525
  :
527
526
  | (Input[("content" | "renderBody") & keyof Input] extends infer Prop
@@ -533,7 +532,7 @@ type FlatScopes<Input> = [0] extends [1 & Input]
533
532
  ? Prop extends { [Symbol.iterator]: any }
534
533
  ? Prop extends readonly any[]
535
534
  ? never
536
- : FlatScopes<Prop>
535
+ : Scopes<Prop>
537
536
  : never
538
537
  : never);
539
538
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@marko/language-tools",
3
3
  "description": "Marko Language Tools",
4
- "version": "2.5.42",
4
+ "version": "2.5.44",
5
5
  "bugs": "https://github.com/marko-js/language-server/issues/new?template=Bug_report.md",
6
6
  "peerDependencies": {
7
7
  "@marko/compiler": "^5.28.4"