@marko/language-tools 2.5.5 → 2.5.7

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.
@@ -1,6 +1,7 @@
1
1
  import type { TaglibLookup } from "@marko/babel-utils";
2
2
  import type TS from "typescript/lib/tsserverlibrary";
3
3
  import { type Parsed } from "../../parser";
4
+ import type { Meta } from "../../util/project";
4
5
  /**
5
6
  * Iterate over the Marko CST and extract all the script content.
6
7
  */
@@ -14,5 +15,6 @@ export interface ExtractScriptOptions {
14
15
  lookup: TaglibLookup;
15
16
  scriptLang: ScriptLang;
16
17
  runtimeTypesCode?: string;
18
+ translator: Meta["config"]["translator"];
17
19
  }
18
20
  export declare function extractScript(opts: ExtractScriptOptions): import("../../util/extractor").Extracted;
@@ -0,0 +1,9 @@
1
+ import { Parsed } from "../../../parser";
2
+ export type RuntimeAPI = (typeof RuntimeAPI)[keyof typeof RuntimeAPI] | void;
3
+ export declare const RuntimeAPI: {
4
+ readonly tags: "tags";
5
+ readonly class: "class";
6
+ };
7
+ export declare function getRuntimeAPI(translator: {
8
+ preferAPI?: string;
9
+ } | undefined, parsed: Parsed): RuntimeAPI;
package/dist/index.js CHANGED
@@ -42,6 +42,7 @@ __export(src_exports, {
42
42
  getLines: () => import_htmljs_parser2.getLines,
43
43
  getLocation: () => import_htmljs_parser2.getLocation,
44
44
  getPosition: () => import_htmljs_parser2.getPosition,
45
+ isControlFlowTag: () => isControlFlowTag,
45
46
  isDefinitionFile: () => isDefinitionFile,
46
47
  parse: () => parse
47
48
  });
@@ -1653,6 +1654,120 @@ function tryReaddirSync(dir) {
1653
1654
  }
1654
1655
  }
1655
1656
 
1657
+ // src/extractors/script/util/get-runtime-api.ts
1658
+ var RuntimeAPI = {
1659
+ tags: "tags",
1660
+ class: "class"
1661
+ };
1662
+ function getRuntimeAPI(translator, parsed) {
1663
+ return detectAPIFromTranslator(translator) || detectAPIFromFileName(parsed.filename) || detectAPIFromProgram(parsed, parsed.program);
1664
+ }
1665
+ function detectAPIFromTranslator(translator) {
1666
+ switch (translator == null ? void 0 : translator.preferAPI) {
1667
+ case "class":
1668
+ return RuntimeAPI.class;
1669
+ case "tags":
1670
+ return RuntimeAPI.tags;
1671
+ }
1672
+ }
1673
+ function detectAPIFromFileName(filename) {
1674
+ for (let end = filename.length, i = end; --i; ) {
1675
+ switch (filename[i]) {
1676
+ case "/":
1677
+ case "\\":
1678
+ if (filename.startsWith("tags", i + 1)) {
1679
+ return RuntimeAPI.tags;
1680
+ } else if (filename.startsWith("components", i + 1)) {
1681
+ return;
1682
+ }
1683
+ end = i;
1684
+ break;
1685
+ }
1686
+ }
1687
+ }
1688
+ function detectAPIFromProgram(parsed, program) {
1689
+ if (program.comments) {
1690
+ switch (parsed.read(program.comments[0].value).trim()) {
1691
+ case "use tags":
1692
+ return RuntimeAPI.tags;
1693
+ case "use class":
1694
+ return RuntimeAPI.class;
1695
+ }
1696
+ }
1697
+ if (program.static) {
1698
+ for (const stmt of program.static) {
1699
+ switch (stmt.type) {
1700
+ case 26 /* Class */:
1701
+ case 27 /* Style */:
1702
+ return RuntimeAPI.class;
1703
+ }
1704
+ }
1705
+ }
1706
+ return detectAPIFromBody(parsed, program.body);
1707
+ }
1708
+ function detectAPIFromBody(parsed, body) {
1709
+ if (body) {
1710
+ for (const child of body) {
1711
+ const api = detectAPIFromChild(parsed, child);
1712
+ if (api) return api;
1713
+ }
1714
+ }
1715
+ }
1716
+ function detectAPIFromChild(parsed, child) {
1717
+ switch (child.type) {
1718
+ case 23 /* Scriptlet */:
1719
+ return RuntimeAPI.class;
1720
+ case 1 /* Tag */:
1721
+ case 16 /* AttrTag */:
1722
+ return detectAPIFromTag(parsed, child);
1723
+ }
1724
+ }
1725
+ function detectAPIFromTag(parsed, tag) {
1726
+ var _a;
1727
+ switch (tag.nameText) {
1728
+ case "macro":
1729
+ case "include-text":
1730
+ case "include-html":
1731
+ case "init-components":
1732
+ case "await-reorderer":
1733
+ case "while":
1734
+ case "module-code":
1735
+ return RuntimeAPI.class;
1736
+ case "const":
1737
+ case "debug":
1738
+ case "define":
1739
+ case "html-script":
1740
+ case "html-style":
1741
+ case "id":
1742
+ case "let":
1743
+ case "lifecycle":
1744
+ case "log":
1745
+ case "return":
1746
+ return RuntimeAPI.tags;
1747
+ }
1748
+ if (tag.var) {
1749
+ return RuntimeAPI.tags;
1750
+ }
1751
+ if (tag.attrs) {
1752
+ for (const attr of tag.attrs) {
1753
+ if (attr.type !== 15 /* AttrSpread */) {
1754
+ if (((_a = attr.value) == null ? void 0 : _a.type) === 13 /* AttrValue */ && attr.value.bound) {
1755
+ return RuntimeAPI.tags;
1756
+ }
1757
+ if (attr.args) {
1758
+ return RuntimeAPI.class;
1759
+ }
1760
+ if (/^(?:key|no-update(?:-body)?(?:-if)?)$|:(scoped:no-update)$/.test(
1761
+ parsed.read(attr.name)
1762
+ )) {
1763
+ return RuntimeAPI.class;
1764
+ }
1765
+ }
1766
+ }
1767
+ }
1768
+ return detectAPIFromBody(parsed, tag.body);
1769
+ }
1770
+
1656
1771
  // src/extractors/script/util/jsdoc-input-type.ts
1657
1772
  var MaybeInputTypedefReg = /@typedef\b[\s\S]*\bInput\b/;
1658
1773
  function getJSDocInputType(comment, ts) {
@@ -1758,7 +1873,7 @@ function getRuntimeOverrides(runtimeTypes, generics, applyGenerics) {
1758
1873
  }
1759
1874
 
1760
1875
  // src/extractors/script/util/script-parser.ts
1761
- var import_parser6 = require("@babel/parser");
1876
+ var import_parser7 = require("@babel/parser");
1762
1877
  var plugins = [
1763
1878
  "exportDefaultFrom",
1764
1879
  "importAssertions",
@@ -1772,7 +1887,7 @@ var ScriptParser = class {
1772
1887
  statementAt(startIndex, src) {
1773
1888
  const pos = this.#parsed.positionAt(startIndex);
1774
1889
  try {
1775
- return (0, import_parser6.parse)(src, {
1890
+ return (0, import_parser7.parse)(src, {
1776
1891
  plugins,
1777
1892
  startIndex,
1778
1893
  startLine: pos.line + 1,
@@ -1793,7 +1908,7 @@ var ScriptParser = class {
1793
1908
  expressionAt(startIndex, src) {
1794
1909
  const pos = this.#parsed.positionAt(startIndex);
1795
1910
  try {
1796
- return (0, import_parser6.parseExpression)(src, {
1911
+ return (0, import_parser7.parseExpression)(src, {
1797
1912
  plugins,
1798
1913
  startIndex,
1799
1914
  startLine: pos.line + 1,
@@ -1829,7 +1944,7 @@ var REG_TAG_IMPORT = /(?<=(['"]))<([^'">]+)>(?=\1)/;
1829
1944
  var REG_INPUT_TYPE = /\s*(interface|type)\s+Input\b/y;
1830
1945
  var REG_OBJECT_PROPERTY = /^[_$a-z][_$a-z0-9]*$/i;
1831
1946
  var REG_COMMENT_PRAGMA = /\/\/(?:\s*@ts-|\/\s*<)/y;
1832
- var REG_TAG_NAME_IDENTIFIER = /^[A-Z][a-zA-Z_$]+$/;
1947
+ var REG_TAG_NAME_IDENTIFIER = /^[A-Z][a-zA-Z0-9_$]+$/;
1833
1948
  var IF_TAG_ALTERNATES = /* @__PURE__ */ new WeakMap();
1834
1949
  var WROTE_COMMENT = /* @__PURE__ */ new WeakSet();
1835
1950
  var START_OF_FILE = { start: 0, end: 0 };
@@ -1849,11 +1964,14 @@ var ScriptExtractor = class {
1849
1964
  #scriptParser;
1850
1965
  #read;
1851
1966
  #lookup;
1967
+ #tagIds = /* @__PURE__ */ new Map();
1852
1968
  #renderIds = /* @__PURE__ */ new Map();
1853
1969
  #scriptLang;
1854
1970
  #ts;
1855
1971
  #runtimeTypes;
1972
+ #api;
1856
1973
  #mutationOffsets;
1974
+ #tagId = 1;
1857
1975
  #renderId = 1;
1858
1976
  constructor(opts) {
1859
1977
  const { parsed, lookup, scriptLang } = opts;
@@ -1867,6 +1985,7 @@ var ScriptExtractor = class {
1867
1985
  this.#extractor = new Extractor(parsed);
1868
1986
  this.#scriptParser = new ScriptParser(parsed);
1869
1987
  this.#read = parsed.read.bind(parsed);
1988
+ this.#api = getRuntimeAPI(opts.translator, parsed);
1870
1989
  this.#mutationOffsets = crawlProgramScope(this.#parsed, this.#scriptParser);
1871
1990
  this.#writeProgram(parsed.program);
1872
1991
  }
@@ -2025,8 +2144,8 @@ function ${templateName}() {
2025
2144
  ${varShared("noop")}({ input, component, state, out, $global, $signal });
2026
2145
  `);
2027
2146
  const body = this.#processBody(program);
2028
- if (body == null ? void 0 : body.renderBody) {
2029
- this.#writeChildren(program, body.renderBody);
2147
+ if (body == null ? void 0 : body.content) {
2148
+ this.#writeChildren(program, body.content);
2030
2149
  }
2031
2150
  const hoists = getHoists(program);
2032
2151
  if (hoists) {
@@ -2057,6 +2176,7 @@ function ${templateName}() {
2057
2176
  "ReturnWithScope"
2058
2177
  )}<${internalInput}, ${didReturn ? `typeof ${templateName + typeArgsStr} extends () => infer Return ? Return : never` : "void"}>)`;
2059
2178
  const templateOverrideClass = `${templateBaseClass}<{${this.#runtimeTypes ? getRuntimeOverrides(this.#runtimeTypes, typeParamsStr, typeArgsStr) : ""}
2179
+ ${this.#api ? `api: "${this.#api}",` : ""}
2060
2180
  _${typeParamsStr ? `<${internalApply} = 1>(): ${internalApply} extends 0
2061
2181
  ? ${typeParamsStr}() => <${internalInputWithExtends}>${renderAndReturn}
2062
2182
  : () => <${internalInputWithExtends}, ${typeParamsStr.slice(
@@ -2163,9 +2283,9 @@ constructor(_?: Return) {}
2163
2283
  this.#getRangeWithoutTrailingComma((_a = child.args) == null ? void 0 : _a.value) || this.#getAttrValue(child, ATTR_UNAMED2) || "undefined"
2164
2284
  ).write(") {\n");
2165
2285
  const ifBody = this.#processBody(child);
2166
- if (ifBody == null ? void 0 : ifBody.renderBody) {
2286
+ if (ifBody == null ? void 0 : ifBody.content) {
2167
2287
  const localBindings = getHoistSources(child);
2168
- this.#writeChildren(child, ifBody.renderBody, true);
2288
+ this.#writeChildren(child, ifBody.content, true);
2169
2289
  if (localBindings) {
2170
2290
  this.#extractor.write("return {\nscope:");
2171
2291
  this.#writeObjectKeys(localBindings);
@@ -2185,9 +2305,9 @@ constructor(_?: Return) {}
2185
2305
  this.#extractor.write("\n} else if (undefined) {\n");
2186
2306
  }
2187
2307
  const alternateBody = this.#processBody(node);
2188
- if (alternateBody == null ? void 0 : alternateBody.renderBody) {
2308
+ if (alternateBody == null ? void 0 : alternateBody.content) {
2189
2309
  const localBindings = getHoistSources(node);
2190
- this.#writeChildren(node, alternateBody.renderBody, true);
2310
+ this.#writeChildren(node, alternateBody.content, true);
2191
2311
  if (localBindings) {
2192
2312
  this.#extractor.write("return {\nscope:");
2193
2313
  this.#writeObjectKeys(localBindings);
@@ -2228,12 +2348,12 @@ constructor(_?: Return) {}
2228
2348
  }
2229
2349
  this.#extractor.write("\n) => {\n");
2230
2350
  const body = this.#processBody(child);
2231
- if (body == null ? void 0 : body.renderBody) {
2232
- this.#writeChildren(child, body.renderBody);
2351
+ if (body == null ? void 0 : body.content) {
2352
+ this.#writeChildren(child, body.content);
2233
2353
  }
2234
2354
  this.#writeReturn(
2235
2355
  void 0,
2236
- (body == null ? void 0 : body.renderBody) ? getHoistSources(child) : void 0
2356
+ (body == null ? void 0 : body.content) ? getHoistSources(child) : void 0
2237
2357
  );
2238
2358
  if (renderId) {
2239
2359
  this.#extractor.write("\n}));\n");
@@ -2248,8 +2368,8 @@ constructor(_?: Return) {}
2248
2368
  this.#getRangeWithoutTrailingComma((_b = child.args) == null ? void 0 : _b.value) || "undefined"
2249
2369
  ).write("\n) {\n");
2250
2370
  const body = this.#processBody(child);
2251
- if (body == null ? void 0 : body.renderBody) {
2252
- this.#writeChildren(child, body.renderBody);
2371
+ if (body == null ? void 0 : body.content) {
2372
+ this.#writeChildren(child, body.content);
2253
2373
  }
2254
2374
  this.#extractor.write("\n}\n");
2255
2375
  break;
@@ -2309,51 +2429,53 @@ constructor(_?: Return) {}
2309
2429
  #writeTag(tag) {
2310
2430
  const tagName = tag.nameText;
2311
2431
  const renderId = this.#getRenderId(tag);
2312
- let nestedTagType;
2432
+ const def = tagName ? this.#lookup.getTag(tagName) : void 0;
2313
2433
  if (renderId) {
2314
2434
  this.#extractor.write(
2315
- `${varShared("assertRendered")}(${varShared(
2316
- "rendered"
2317
- )}, ${renderId}, `
2435
+ `${varShared("assertRendered")}(${varShared("rendered")},${renderId},`
2318
2436
  );
2319
2437
  }
2320
- if (tagName) {
2321
- const def = this.#lookup.getTag(tagName);
2322
- if (def) {
2323
- const importPath = resolveTagImport(this.#filename, def);
2324
- const isMarkoFile = importPath == null ? void 0 : importPath.endsWith(".marko");
2325
- if (isMarkoFile) {
2326
- nestedTagType = `import("${importPath}").Input`;
2327
- }
2328
- const renderer = (importPath == null ? void 0 : importPath.endsWith(".marko")) ? `renderTemplate(import("${importPath}"))` : def.html ? `renderNativeTag("${def.name}")` : "missingTag";
2329
- if (!def.html && REG_TAG_NAME_IDENTIFIER.test(tagName)) {
2438
+ if (def == null ? void 0 : def.html) {
2439
+ this.#extractor.write(`${varShared("renderNativeTag")}("`).copy(tag.name).write('")');
2440
+ } else {
2441
+ const importPath = def && resolveTagImport(this.#filename, def);
2442
+ if (def && !importPath) {
2443
+ this.#extractor.write(varShared("missingTag"));
2444
+ } else {
2445
+ const tagId = this.#ensureTagId(tag);
2446
+ let isDynamic = true;
2447
+ this.#extractor.write(
2448
+ `(${varShared("assertTag")}(${varShared("tags")},${tagId},(
2449
+ `
2450
+ );
2451
+ if (tagName && REG_TAG_NAME_IDENTIFIER.test(tagName)) {
2452
+ if (importPath) {
2453
+ this.#extractor.write(
2454
+ `${varShared("fallbackTemplate")}(${tagName},import("${importPath}"))`
2455
+ );
2456
+ } else {
2457
+ this.#extractor.copy(tag.name);
2458
+ }
2459
+ } else if (importPath) {
2460
+ isDynamic = !importPath.endsWith(".marko");
2330
2461
  this.#extractor.write(
2331
- `${varShared("renderPreferLocal")}(
2332
- // @ts-expect-error We expect the compiler to error because we are checking if the tag is defined.
2333
- (${varShared("error")}, `
2334
- ).copy(tag.name).write(`),
2335
- ${varShared(renderer)})`);
2462
+ `${varShared("resolveTemplate")}(import("${importPath}"))`
2463
+ );
2336
2464
  } else {
2337
- this.#extractor.write(varShared(renderer));
2465
+ this.#writeDynamicTagName(tag);
2338
2466
  }
2339
- } else if (REG_TAG_NAME_IDENTIFIER.test(tagName)) {
2340
- nestedTagType = `Marko.Input<typeof ${this.#read(tag.name)}>`;
2341
- this.#extractor.write(`${varShared("renderDynamicTag")}(
2342
- `).copy(tag.name).write("\n)");
2343
- } else {
2344
- this.#extractor.write(`${varShared("missingTag")}`);
2467
+ this.#extractor.write(
2468
+ `
2469
+ )),${varShared(isDynamic ? "renderDynamicTag" : "renderTemplate")}(${varShared("tags")}[${tagId}]))`
2470
+ );
2345
2471
  }
2346
- } else {
2347
- this.#extractor.write(`${varShared("renderDynamicTag")}(`);
2348
- this.#writeDynamicTagName(tag);
2349
- this.#extractor.write(")");
2350
2472
  }
2351
2473
  if (tag.typeArgs) {
2352
2474
  this.#extractor.write(`<0>()`).copy(tag.typeArgs).write("()(");
2353
2475
  } else {
2354
2476
  this.#extractor.write("()()(");
2355
2477
  }
2356
- this.#writeTagInputObject(tag, nestedTagType);
2478
+ this.#writeTagInputObject(tag);
2357
2479
  if (renderId) {
2358
2480
  this.#extractor.write(`)`);
2359
2481
  }
@@ -2537,7 +2659,7 @@ ${isMutatedVar(tag.parent, valueLiteral) ? `${varLocal("return")}.mutate.` : ""}
2537
2659
  );
2538
2660
  return hasAttrs;
2539
2661
  }
2540
- #writeAttrTags({ staticAttrTags, dynamicAttrTagParents }, inMerge, nestedTagType) {
2662
+ #writeAttrTags({ staticAttrTags, dynamicAttrTagParents }, inMerge) {
2541
2663
  let wasMerge = false;
2542
2664
  if (dynamicAttrTagParents) {
2543
2665
  if (staticAttrTags) {
@@ -2553,7 +2675,7 @@ ${isMutatedVar(tag.parent, valueLiteral) ? `${varLocal("return")}.mutate.` : ""}
2553
2675
  }
2554
2676
  }
2555
2677
  if (staticAttrTags) {
2556
- this.#writeStaticAttrTags(staticAttrTags, inMerge, nestedTagType);
2678
+ this.#writeStaticAttrTags(staticAttrTags, inMerge);
2557
2679
  if (dynamicAttrTagParents)
2558
2680
  this.#extractor.write(`}${SEP_COMMA_NEW_LINE}`);
2559
2681
  }
@@ -2562,7 +2684,7 @@ ${isMutatedVar(tag.parent, valueLiteral) ? `${varLocal("return")}.mutate.` : ""}
2562
2684
  if (wasMerge) this.#extractor.write(`)${SEP_COMMA_NEW_LINE}`);
2563
2685
  }
2564
2686
  }
2565
- #writeStaticAttrTags(staticAttrTags, wasMerge, nestedTagType) {
2687
+ #writeStaticAttrTags(staticAttrTags, wasMerge) {
2566
2688
  if (!wasMerge) this.#extractor.write("...{");
2567
2689
  this.#extractor.write(
2568
2690
  `[${varShared("never")}](){
@@ -2583,36 +2705,40 @@ const attrTags = ${varShared(
2583
2705
  this.#extractor.write(SEP_COMMA_NEW_LINE);
2584
2706
  for (const nameText in staticAttrTags) {
2585
2707
  const attrTag = staticAttrTags[nameText];
2586
- const attrTagDef = this.#lookup.getTag(nameText);
2587
2708
  const isRepeated = attrTag.length > 1;
2588
2709
  const [firstAttrTag] = attrTag;
2589
- const name = (attrTagDef == null ? void 0 : attrTagDef.targetProperty) || nameText.slice(nameText.lastIndexOf(":") + 1);
2710
+ const name = this.#getAttrTagName(firstAttrTag);
2590
2711
  this.#extractor.write(`["${name}"`);
2591
2712
  this.#writeTagNameComment(firstAttrTag);
2592
2713
  this.#extractor.write("]: ");
2593
2714
  if (isRepeated) {
2594
- this.#extractor.write(`${varShared("repeatedAttrTag")}(
2595
- ...
2596
- `);
2597
- if (nestedTagType && this.#scriptLang === "js" /* js */) {
2715
+ const tagId = this.#tagIds.get(firstAttrTag.owner);
2716
+ if (tagId) {
2717
+ let accessor = `["${name}"]`;
2718
+ let curTag = firstAttrTag.parent;
2719
+ while (curTag) {
2720
+ if (curTag.type === 16 /* AttrTag */) {
2721
+ accessor = `["${this.#getAttrTagName(curTag)}"]${accessor}`;
2722
+ } else if (!isControlFlowTag(curTag)) {
2723
+ break;
2724
+ }
2725
+ curTag = curTag.parent;
2726
+ }
2598
2727
  this.#extractor.write(
2599
- `/** @satisfies {${nestedTagType}["${name}"][]} */
2728
+ `${varShared("attrTags")}(${varShared("input")}(${varShared("tags")}[${tagId}])${accessor})([
2600
2729
  `
2601
2730
  );
2602
- }
2603
- this.#extractor.write(`([
2731
+ } else {
2732
+ this.#extractor.write(`${varShared("attrTags")}()([
2604
2733
  `);
2734
+ }
2605
2735
  }
2606
2736
  for (const childNode of attrTag) {
2607
2737
  this.#writeTagInputObject(childNode);
2608
2738
  this.#extractor.write(SEP_COMMA_NEW_LINE);
2609
2739
  }
2610
2740
  if (isRepeated) {
2611
- this.#extractor.write("])");
2612
- if (nestedTagType && this.#scriptLang === "ts" /* ts */) {
2613
- this.#extractor.write(` satisfies ${nestedTagType}["${name}"][]`);
2614
- }
2615
- this.#extractor.write(`)${SEP_COMMA_NEW_LINE}`);
2741
+ this.#extractor.write(`])${SEP_COMMA_NEW_LINE}`);
2616
2742
  }
2617
2743
  }
2618
2744
  }
@@ -2675,7 +2801,7 @@ const attrTags = ${varShared(
2675
2801
  this.#extractor.write(SEP_COMMA_NEW_LINE);
2676
2802
  }
2677
2803
  }
2678
- #writeTagInputObject(tag, nestedTagType) {
2804
+ #writeTagInputObject(tag) {
2679
2805
  if (!tag.params) this.#writeComments(tag);
2680
2806
  let hasInput = false;
2681
2807
  this.#extractor.write("{\n");
@@ -2693,7 +2819,7 @@ const attrTags = ${varShared(
2693
2819
  hasInput = true;
2694
2820
  }
2695
2821
  const isScript = isTextOnlyScript(tag);
2696
- let hasRenderBody = false;
2822
+ let hasBodyContent = false;
2697
2823
  let body;
2698
2824
  if (isScript) {
2699
2825
  this.#extractor.write("async value(){");
@@ -2706,14 +2832,35 @@ const attrTags = ${varShared(
2706
2832
  body = this.#processBody(tag);
2707
2833
  if (body) {
2708
2834
  hasInput = true;
2709
- this.#writeAttrTags(body, false, nestedTagType);
2710
- hasRenderBody = body.renderBody !== void 0;
2835
+ this.#writeAttrTags(body, false);
2836
+ hasBodyContent = body.content !== void 0;
2711
2837
  } else if (tag.close) {
2712
- hasRenderBody = true;
2838
+ hasBodyContent = true;
2713
2839
  }
2714
2840
  }
2715
- if (tag.params || hasRenderBody) {
2716
- this.#extractor.write('["renderBody"');
2841
+ if (tag.params || hasBodyContent) {
2842
+ this.#extractor.write("[");
2843
+ switch (this.#api) {
2844
+ case RuntimeAPI.tags:
2845
+ this.#extractor.write('"content"');
2846
+ break;
2847
+ case RuntimeAPI.class:
2848
+ this.#extractor.write('"renderBody"');
2849
+ break;
2850
+ default: {
2851
+ const tagId = this.#tagIds.get(
2852
+ tag.type === 16 /* AttrTag */ ? tag.owner : tag
2853
+ );
2854
+ if (tagId) {
2855
+ this.#extractor.write(
2856
+ `${varShared("contentFor")}(${varShared("tags")}[${tagId}])`
2857
+ );
2858
+ } else {
2859
+ this.#extractor.write(varShared("content"));
2860
+ }
2861
+ break;
2862
+ }
2863
+ }
2717
2864
  this.#writeTagNameComment(tag);
2718
2865
  this.#extractor.write("]: ");
2719
2866
  if (tag.params) {
@@ -2727,8 +2874,8 @@ const attrTags = ${varShared(
2727
2874
  `);
2728
2875
  }
2729
2876
  let didReturn = false;
2730
- if (body == null ? void 0 : body.renderBody) {
2731
- didReturn = this.#writeChildren(tag, body.renderBody);
2877
+ if (body == null ? void 0 : body.content) {
2878
+ didReturn = this.#writeChildren(tag, body.content);
2732
2879
  }
2733
2880
  if (!tag.params) {
2734
2881
  this.#extractor.write(`return () => {
@@ -2817,7 +2964,7 @@ const attrTags = ${varShared(
2817
2964
  const { body } = parent;
2818
2965
  if (!body) return;
2819
2966
  const last = body.length - 1;
2820
- let renderBody;
2967
+ let content;
2821
2968
  let staticAttrTags;
2822
2969
  let dynamicAttrTagParents;
2823
2970
  let i = 0;
@@ -2906,48 +3053,48 @@ const attrTags = ${varShared(
2906
3053
  } else {
2907
3054
  dynamicAttrTagParents = [child];
2908
3055
  }
2909
- } else if (renderBody) {
2910
- renderBody.push(child);
3056
+ } else if (content) {
3057
+ content.push(child);
2911
3058
  } else {
2912
- renderBody = [child];
3059
+ content = [child];
2913
3060
  }
2914
3061
  break;
2915
3062
  }
2916
3063
  case 17 /* Text */: {
2917
3064
  if (!this.#isEmptyText(child)) {
2918
- if (renderBody) {
2919
- renderBody.push(child);
3065
+ if (content) {
3066
+ content.push(child);
2920
3067
  } else {
2921
- renderBody = [child];
3068
+ content = [child];
2922
3069
  }
2923
3070
  }
2924
3071
  break;
2925
3072
  }
2926
3073
  default:
2927
- if (renderBody) {
2928
- renderBody.push(child);
3074
+ if (content) {
3075
+ content.push(child);
2929
3076
  } else {
2930
- renderBody = [child];
3077
+ content = [child];
2931
3078
  }
2932
3079
  break;
2933
3080
  }
2934
3081
  }
2935
- if (renderBody || staticAttrTags || dynamicAttrTagParents) {
2936
- return { renderBody, staticAttrTags, dynamicAttrTagParents };
3082
+ if (content || staticAttrTags || dynamicAttrTagParents) {
3083
+ return { content, staticAttrTags, dynamicAttrTagParents };
2937
3084
  }
2938
3085
  }
2939
3086
  #writeDynamicAttrTagBody(tag) {
2940
3087
  const body = this.#processBody(tag);
2941
3088
  if (body) {
2942
- if (body.renderBody) {
3089
+ if (body.content) {
2943
3090
  this.#extractor.write("(() => {\n");
2944
- this.#writeChildren(tag, body.renderBody);
3091
+ this.#writeChildren(tag, body.content);
2945
3092
  this.#extractor.write("return ");
2946
3093
  }
2947
3094
  this.#extractor.write("{\n");
2948
3095
  this.#writeAttrTags(body, true);
2949
3096
  this.#extractor.write("}");
2950
- if (body.renderBody) {
3097
+ if (body.content) {
2951
3098
  this.#extractor.write(";\n})()");
2952
3099
  }
2953
3100
  } else {
@@ -3050,6 +3197,14 @@ const attrTags = ${varShared(
3050
3197
  }
3051
3198
  return renderId;
3052
3199
  }
3200
+ #ensureTagId(tag) {
3201
+ let tagId = this.#tagIds.get(tag);
3202
+ if (!tagId) {
3203
+ tagId = this.#tagId++;
3204
+ this.#tagIds.set(tag, tagId);
3205
+ }
3206
+ return tagId;
3207
+ }
3053
3208
  #getNamedAttrModifierIndex(attr) {
3054
3209
  const start = attr.name.start + 1;
3055
3210
  const end = attr.name.end - 1;
@@ -3058,6 +3213,11 @@ const attrTags = ${varShared(
3058
3213
  }
3059
3214
  return false;
3060
3215
  }
3216
+ #getAttrTagName(tag) {
3217
+ var _a;
3218
+ const { nameText } = tag;
3219
+ return ((_a = this.#lookup.getTag(nameText)) == null ? void 0 : _a.targetProperty) || nameText.slice(nameText.lastIndexOf(":") + 1);
3220
+ }
3061
3221
  #testAtIndex(reg, index) {
3062
3222
  reg.lastIndex = index;
3063
3223
  return reg.test(this.#code);
@@ -3547,6 +3707,7 @@ var marko_default = {
3547
3707
  return extractScript({
3548
3708
  ts,
3549
3709
  parsed,
3710
+ translator: getConfig(dir).translator,
3550
3711
  lookup: getTagLookup(dir),
3551
3712
  scriptLang: getScriptLang(
3552
3713
  fileName,
@@ -3697,6 +3858,7 @@ function isDefinitionFile(fileName) {
3697
3858
  getLines,
3698
3859
  getLocation,
3699
3860
  getPosition,
3861
+ isControlFlowTag,
3700
3862
  isDefinitionFile,
3701
3863
  parse
3702
3864
  });