@marko/language-tools 2.5.7 → 2.5.9

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/index.js CHANGED
@@ -2464,9 +2464,14 @@ constructor(_?: Return) {}
2464
2464
  } else {
2465
2465
  this.#writeDynamicTagName(tag);
2466
2466
  }
2467
+ this.#extractor.write("\n)),");
2468
+ const attrTagTree = this.#getAttrTagTree(tag);
2469
+ if (attrTagTree) {
2470
+ this.#writeAttrTagTree(attrTagTree, `${varShared("tags")}[${tagId}]`);
2471
+ this.#extractor.write(",");
2472
+ }
2467
2473
  this.#extractor.write(
2468
- `
2469
- )),${varShared(isDynamic ? "renderDynamicTag" : "renderTemplate")}(${varShared("tags")}[${tagId}]))`
2474
+ `${varShared(isDynamic ? "renderDynamicTag" : "renderTemplate")}(${varShared("tags")}[${tagId}]))`
2470
2475
  );
2471
2476
  }
2472
2477
  }
@@ -2659,23 +2664,23 @@ ${isMutatedVar(tag.parent, valueLiteral) ? `${varLocal("return")}.mutate.` : ""}
2659
2664
  );
2660
2665
  return hasAttrs;
2661
2666
  }
2662
- #writeAttrTags({ staticAttrTags, dynamicAttrTagParents }, inMerge) {
2667
+ #writeAttrTags({ staticAttrTags, dynamicAttrTagParents }) {
2663
2668
  let wasMerge = false;
2664
2669
  if (dynamicAttrTagParents) {
2665
2670
  if (staticAttrTags) {
2666
2671
  this.#extractor.write(`...${varShared("mergeAttrTags")}({
2667
2672
  `);
2668
- inMerge = wasMerge = true;
2673
+ wasMerge = true;
2669
2674
  } else if (dynamicAttrTagParents.length > 1) {
2670
2675
  this.#extractor.write(`...${varShared("mergeAttrTags")}(
2671
2676
  `);
2672
- inMerge = wasMerge = true;
2677
+ wasMerge = true;
2673
2678
  } else {
2674
2679
  this.#extractor.write(`...`);
2675
2680
  }
2676
2681
  }
2677
2682
  if (staticAttrTags) {
2678
- this.#writeStaticAttrTags(staticAttrTags, inMerge);
2683
+ this.#writeStaticAttrTags(staticAttrTags);
2679
2684
  if (dynamicAttrTagParents)
2680
2685
  this.#extractor.write(`}${SEP_COMMA_NEW_LINE}`);
2681
2686
  }
@@ -2684,25 +2689,7 @@ ${isMutatedVar(tag.parent, valueLiteral) ? `${varLocal("return")}.mutate.` : ""}
2684
2689
  if (wasMerge) this.#extractor.write(`)${SEP_COMMA_NEW_LINE}`);
2685
2690
  }
2686
2691
  }
2687
- #writeStaticAttrTags(staticAttrTags, wasMerge) {
2688
- if (!wasMerge) this.#extractor.write("...{");
2689
- this.#extractor.write(
2690
- `[${varShared("never")}](){
2691
- const attrTags = ${varShared(
2692
- "attrTagNames"
2693
- )}(this);
2694
- `
2695
- );
2696
- for (const nameText in staticAttrTags) {
2697
- for (const tag of staticAttrTags[nameText]) {
2698
- this.#extractor.write(`attrTags["`);
2699
- this.#extractor.copy(tag.name);
2700
- this.#extractor.write('"];\n');
2701
- }
2702
- }
2703
- this.#extractor.write("\n}");
2704
- if (!wasMerge) this.#extractor.write("}");
2705
- this.#extractor.write(SEP_COMMA_NEW_LINE);
2692
+ #writeStaticAttrTags(staticAttrTags) {
2706
2693
  for (const nameText in staticAttrTags) {
2707
2694
  const attrTag = staticAttrTags[nameText];
2708
2695
  const isRepeated = attrTag.length > 1;
@@ -2714,23 +2701,21 @@ const attrTags = ${varShared(
2714
2701
  if (isRepeated) {
2715
2702
  const tagId = this.#tagIds.get(firstAttrTag.owner);
2716
2703
  if (tagId) {
2717
- let accessor = `["${name}"]`;
2704
+ let accessor = `"${name}"`;
2718
2705
  let curTag = firstAttrTag.parent;
2719
2706
  while (curTag) {
2720
2707
  if (curTag.type === 16 /* AttrTag */) {
2721
- accessor = `["${this.#getAttrTagName(curTag)}"]${accessor}`;
2708
+ accessor = `"${this.#getAttrTagName(curTag)}",${accessor}`;
2722
2709
  } else if (!isControlFlowTag(curTag)) {
2723
2710
  break;
2724
2711
  }
2725
2712
  curTag = curTag.parent;
2726
2713
  }
2727
2714
  this.#extractor.write(
2728
- `${varShared("attrTags")}(${varShared("input")}(${varShared("tags")}[${tagId}])${accessor})([
2729
- `
2715
+ `${varShared("attrTagFor")}(${varShared("tags")}[${tagId}],${accessor})([`
2730
2716
  );
2731
2717
  } else {
2732
- this.#extractor.write(`${varShared("attrTags")}()([
2733
- `);
2718
+ this.#extractor.write(`${varShared("attrTag")}([`);
2734
2719
  }
2735
2720
  }
2736
2721
  for (const childNode of attrTag) {
@@ -2832,7 +2817,7 @@ const attrTags = ${varShared(
2832
2817
  body = this.#processBody(tag);
2833
2818
  if (body) {
2834
2819
  hasInput = true;
2835
- this.#writeAttrTags(body, false);
2820
+ this.#writeAttrTags(body);
2836
2821
  hasBodyContent = body.content !== void 0;
2837
2822
  } else if (tag.close) {
2838
2823
  hasBodyContent = true;
@@ -3092,7 +3077,7 @@ const attrTags = ${varShared(
3092
3077
  this.#extractor.write("return ");
3093
3078
  }
3094
3079
  this.#extractor.write("{\n");
3095
- this.#writeAttrTags(body, true);
3080
+ this.#writeAttrTags(body);
3096
3081
  this.#extractor.write("}");
3097
3082
  if (body.content) {
3098
3083
  this.#extractor.write(";\n})()");
@@ -3218,6 +3203,50 @@ const attrTags = ${varShared(
3218
3203
  const { nameText } = tag;
3219
3204
  return ((_a = this.#lookup.getTag(nameText)) == null ? void 0 : _a.targetProperty) || nameText.slice(nameText.lastIndexOf(":") + 1);
3220
3205
  }
3206
+ #writeAttrTagTree(tree, valueExpression, nested) {
3207
+ this.#extractor.write(
3208
+ `${varShared(nested ? "nestedAttrTagNames" : "attrTagNames")}(${valueExpression},input=>{
3209
+ `
3210
+ );
3211
+ for (const name in tree) {
3212
+ const { tags, nested: nested2 } = tree[name];
3213
+ for (const tag of tags) {
3214
+ this.#extractor.write('input["').copy(tag.name).write('"];\n');
3215
+ }
3216
+ if (nested2) {
3217
+ this.#writeAttrTagTree(nested2, `input["@${name}"]`, true);
3218
+ }
3219
+ }
3220
+ this.#extractor.write(`})`);
3221
+ }
3222
+ #getAttrTagTree(tag, attrTags) {
3223
+ if (!tag.hasAttrTags || !tag.body) return attrTags;
3224
+ const curAttrTags = attrTags || {};
3225
+ for (const child of tag.body) {
3226
+ switch (child.type) {
3227
+ case 16 /* AttrTag */: {
3228
+ const name = this.#getAttrTagName(child);
3229
+ const prev = curAttrTags[name];
3230
+ if (prev) {
3231
+ prev.tags.push(child);
3232
+ prev.nested = this.#getAttrTagTree(child, prev.nested);
3233
+ } else {
3234
+ curAttrTags[name] = {
3235
+ tags: [child],
3236
+ nested: this.#getAttrTagTree(child)
3237
+ };
3238
+ }
3239
+ break;
3240
+ }
3241
+ case 1 /* Tag */:
3242
+ if (isControlFlowTag(child)) {
3243
+ this.#getAttrTagTree(child, curAttrTags);
3244
+ }
3245
+ break;
3246
+ }
3247
+ }
3248
+ return curAttrTags;
3249
+ }
3221
3250
  #testAtIndex(reg, index) {
3222
3251
  reg.lastIndex = index;
3223
3252
  return reg.test(this.#code);
package/dist/index.mjs CHANGED
@@ -2427,9 +2427,14 @@ constructor(_?: Return) {}
2427
2427
  } else {
2428
2428
  this.#writeDynamicTagName(tag);
2429
2429
  }
2430
+ this.#extractor.write("\n)),");
2431
+ const attrTagTree = this.#getAttrTagTree(tag);
2432
+ if (attrTagTree) {
2433
+ this.#writeAttrTagTree(attrTagTree, `${varShared("tags")}[${tagId}]`);
2434
+ this.#extractor.write(",");
2435
+ }
2430
2436
  this.#extractor.write(
2431
- `
2432
- )),${varShared(isDynamic ? "renderDynamicTag" : "renderTemplate")}(${varShared("tags")}[${tagId}]))`
2437
+ `${varShared(isDynamic ? "renderDynamicTag" : "renderTemplate")}(${varShared("tags")}[${tagId}]))`
2433
2438
  );
2434
2439
  }
2435
2440
  }
@@ -2622,23 +2627,23 @@ ${isMutatedVar(tag.parent, valueLiteral) ? `${varLocal("return")}.mutate.` : ""}
2622
2627
  );
2623
2628
  return hasAttrs;
2624
2629
  }
2625
- #writeAttrTags({ staticAttrTags, dynamicAttrTagParents }, inMerge) {
2630
+ #writeAttrTags({ staticAttrTags, dynamicAttrTagParents }) {
2626
2631
  let wasMerge = false;
2627
2632
  if (dynamicAttrTagParents) {
2628
2633
  if (staticAttrTags) {
2629
2634
  this.#extractor.write(`...${varShared("mergeAttrTags")}({
2630
2635
  `);
2631
- inMerge = wasMerge = true;
2636
+ wasMerge = true;
2632
2637
  } else if (dynamicAttrTagParents.length > 1) {
2633
2638
  this.#extractor.write(`...${varShared("mergeAttrTags")}(
2634
2639
  `);
2635
- inMerge = wasMerge = true;
2640
+ wasMerge = true;
2636
2641
  } else {
2637
2642
  this.#extractor.write(`...`);
2638
2643
  }
2639
2644
  }
2640
2645
  if (staticAttrTags) {
2641
- this.#writeStaticAttrTags(staticAttrTags, inMerge);
2646
+ this.#writeStaticAttrTags(staticAttrTags);
2642
2647
  if (dynamicAttrTagParents)
2643
2648
  this.#extractor.write(`}${SEP_COMMA_NEW_LINE}`);
2644
2649
  }
@@ -2647,25 +2652,7 @@ ${isMutatedVar(tag.parent, valueLiteral) ? `${varLocal("return")}.mutate.` : ""}
2647
2652
  if (wasMerge) this.#extractor.write(`)${SEP_COMMA_NEW_LINE}`);
2648
2653
  }
2649
2654
  }
2650
- #writeStaticAttrTags(staticAttrTags, wasMerge) {
2651
- if (!wasMerge) this.#extractor.write("...{");
2652
- this.#extractor.write(
2653
- `[${varShared("never")}](){
2654
- const attrTags = ${varShared(
2655
- "attrTagNames"
2656
- )}(this);
2657
- `
2658
- );
2659
- for (const nameText in staticAttrTags) {
2660
- for (const tag of staticAttrTags[nameText]) {
2661
- this.#extractor.write(`attrTags["`);
2662
- this.#extractor.copy(tag.name);
2663
- this.#extractor.write('"];\n');
2664
- }
2665
- }
2666
- this.#extractor.write("\n}");
2667
- if (!wasMerge) this.#extractor.write("}");
2668
- this.#extractor.write(SEP_COMMA_NEW_LINE);
2655
+ #writeStaticAttrTags(staticAttrTags) {
2669
2656
  for (const nameText in staticAttrTags) {
2670
2657
  const attrTag = staticAttrTags[nameText];
2671
2658
  const isRepeated = attrTag.length > 1;
@@ -2677,23 +2664,21 @@ const attrTags = ${varShared(
2677
2664
  if (isRepeated) {
2678
2665
  const tagId = this.#tagIds.get(firstAttrTag.owner);
2679
2666
  if (tagId) {
2680
- let accessor = `["${name}"]`;
2667
+ let accessor = `"${name}"`;
2681
2668
  let curTag = firstAttrTag.parent;
2682
2669
  while (curTag) {
2683
2670
  if (curTag.type === 16 /* AttrTag */) {
2684
- accessor = `["${this.#getAttrTagName(curTag)}"]${accessor}`;
2671
+ accessor = `"${this.#getAttrTagName(curTag)}",${accessor}`;
2685
2672
  } else if (!isControlFlowTag(curTag)) {
2686
2673
  break;
2687
2674
  }
2688
2675
  curTag = curTag.parent;
2689
2676
  }
2690
2677
  this.#extractor.write(
2691
- `${varShared("attrTags")}(${varShared("input")}(${varShared("tags")}[${tagId}])${accessor})([
2692
- `
2678
+ `${varShared("attrTagFor")}(${varShared("tags")}[${tagId}],${accessor})([`
2693
2679
  );
2694
2680
  } else {
2695
- this.#extractor.write(`${varShared("attrTags")}()([
2696
- `);
2681
+ this.#extractor.write(`${varShared("attrTag")}([`);
2697
2682
  }
2698
2683
  }
2699
2684
  for (const childNode of attrTag) {
@@ -2795,7 +2780,7 @@ const attrTags = ${varShared(
2795
2780
  body = this.#processBody(tag);
2796
2781
  if (body) {
2797
2782
  hasInput = true;
2798
- this.#writeAttrTags(body, false);
2783
+ this.#writeAttrTags(body);
2799
2784
  hasBodyContent = body.content !== void 0;
2800
2785
  } else if (tag.close) {
2801
2786
  hasBodyContent = true;
@@ -3055,7 +3040,7 @@ const attrTags = ${varShared(
3055
3040
  this.#extractor.write("return ");
3056
3041
  }
3057
3042
  this.#extractor.write("{\n");
3058
- this.#writeAttrTags(body, true);
3043
+ this.#writeAttrTags(body);
3059
3044
  this.#extractor.write("}");
3060
3045
  if (body.content) {
3061
3046
  this.#extractor.write(";\n})()");
@@ -3181,6 +3166,50 @@ const attrTags = ${varShared(
3181
3166
  const { nameText } = tag;
3182
3167
  return ((_a = this.#lookup.getTag(nameText)) == null ? void 0 : _a.targetProperty) || nameText.slice(nameText.lastIndexOf(":") + 1);
3183
3168
  }
3169
+ #writeAttrTagTree(tree, valueExpression, nested) {
3170
+ this.#extractor.write(
3171
+ `${varShared(nested ? "nestedAttrTagNames" : "attrTagNames")}(${valueExpression},input=>{
3172
+ `
3173
+ );
3174
+ for (const name in tree) {
3175
+ const { tags, nested: nested2 } = tree[name];
3176
+ for (const tag of tags) {
3177
+ this.#extractor.write('input["').copy(tag.name).write('"];\n');
3178
+ }
3179
+ if (nested2) {
3180
+ this.#writeAttrTagTree(nested2, `input["@${name}"]`, true);
3181
+ }
3182
+ }
3183
+ this.#extractor.write(`})`);
3184
+ }
3185
+ #getAttrTagTree(tag, attrTags) {
3186
+ if (!tag.hasAttrTags || !tag.body) return attrTags;
3187
+ const curAttrTags = attrTags || {};
3188
+ for (const child of tag.body) {
3189
+ switch (child.type) {
3190
+ case 16 /* AttrTag */: {
3191
+ const name = this.#getAttrTagName(child);
3192
+ const prev = curAttrTags[name];
3193
+ if (prev) {
3194
+ prev.tags.push(child);
3195
+ prev.nested = this.#getAttrTagTree(child, prev.nested);
3196
+ } else {
3197
+ curAttrTags[name] = {
3198
+ tags: [child],
3199
+ nested: this.#getAttrTagTree(child)
3200
+ };
3201
+ }
3202
+ break;
3203
+ }
3204
+ case 1 /* Tag */:
3205
+ if (isControlFlowTag(child)) {
3206
+ this.#getAttrTagTree(child, curAttrTags);
3207
+ }
3208
+ break;
3209
+ }
3210
+ }
3211
+ return curAttrTags;
3212
+ }
3184
3213
  #testAtIndex(reg, index) {
3185
3214
  reg.lastIndex = index;
3186
3215
  return reg.test(this.#code);
@@ -25,15 +25,14 @@ declare global {
25
25
  override: Override,
26
26
  ): [0] extends [1 & Override] ? Marko.Global : Override;
27
27
 
28
- export function attrTagNames<Input, Keys extends keyof Input & string>(
28
+ export function attrTagNames<Tag>(
29
+ tag: Tag,
30
+ fn: (input: AttrTagNames<Marko.Input<Tag>>) => void,
31
+ ): void;
32
+ export function nestedAttrTagNames<Input>(
29
33
  input: Input,
30
- ): Record<string, never> & {
31
- [Key in Keys as `@${Input[Key] extends infer Value
32
- ? Value extends Marko.AttrTag<any>
33
- ? Key
34
- : never
35
- : never}`]: Input[Key];
36
- };
34
+ fn: (input: AttrTagNames<Input>) => void,
35
+ ): void;
37
36
 
38
37
  export const rendered: {
39
38
  scopes: Record<number, never>;
@@ -99,7 +98,8 @@ declare global {
99
98
  tags: Tags,
100
99
  index: Index,
101
100
  tag: Tag,
102
- ): asserts tags is Tags & Record<Index, Tag>;
101
+ ): asserts tags is Tags &
102
+ Record<Index, [0] extends [1 & Tag] ? any : Tag>;
103
103
 
104
104
  export function assertRendered<Index extends number, Rendered, Result>(
105
105
  rendered: Rendered,
@@ -324,16 +324,18 @@ declare global {
324
324
  export function mergeAttrTags<Attrs extends readonly any[]>(
325
325
  ...attrs: Attrs
326
326
  ): MergeAttrTags<Attrs>;
327
- export function attrTags<T>(
328
- type?: T,
327
+ export function attrTag<AttrTag>(attrTags: AttrTag[]): AttrTag;
328
+ export function attrTagFor<Tag, Path extends readonly string[]>(
329
+ tag: Tag,
330
+ ...path: Path
329
331
  ): <AttrTag>(
330
332
  attrTags: Relate<
331
333
  AttrTag,
332
- [0] extends [1 & T]
333
- ? Marko.AttrTag<unknown>
334
- : T extends Marko.AttrTag<infer Type>
335
- ? Marko.AttrTag<Type>
336
- : Marko.AttrTag<unknown>
334
+ Marko.Input<Tag> extends infer Input
335
+ ? [0] extends [1 & Input]
336
+ ? Marko.AttrTag<unknown>
337
+ : AttrTagValue<Marko.Input<Tag>, Path>
338
+ : Marko.AttrTag<unknown>
337
339
  >[],
338
340
  ) => AttrTag;
339
341
 
@@ -349,15 +351,13 @@ declare global {
349
351
  ? BodyRenderer<Name>
350
352
  : [Name] extends [
351
353
  {
352
- [BodyContentKey in DefaultBodyContentKey]?: AnyMarkoBody;
354
+ [BodyContentKey in DefaultBodyContentKey]?: infer BodyValue;
353
355
  },
354
356
  ]
355
- ? [Name[BodyContentKey]] extends [AnyMarkoBody]
356
- ? BodyRenderer<Name[BodyContentKey]>
357
+ ? [BodyValue] extends [AnyMarkoBody]
358
+ ? BodyRenderer<BodyValue>
357
359
  : BaseRenderer<
358
- BodyContentInput<
359
- BodyParameters<Exclude<Name[BodyContentKey], void>>
360
- >
360
+ BodyContentInput<BodyParameters<Exclude<BodyValue, void>>>
361
361
  >
362
362
  : DefaultRenderer;
363
363
 
@@ -548,6 +548,28 @@ type AttrTagByObjectSize<
548
548
  CheckNever<KnownKeys, Marko.AttrTag<Item>, undefined | Marko.AttrTag<Item>>
549
549
  >;
550
550
 
551
+ type AttrTagValue<Input, Path extends readonly string[]> = Path extends [
552
+ infer Prop extends keyof Input,
553
+ ...infer Rest extends readonly string[],
554
+ ]
555
+ ? Input[Prop] & Marko.AttrTag<unknown> extends infer Value
556
+ ? Rest extends readonly []
557
+ ? Value
558
+ : AttrTagValue<Value, Rest>
559
+ : Marko.AttrTag<unknown>
560
+ : Marko.AttrTag<unknown>;
561
+
562
+ type AttrTagNames<Input> = Record<string, never> &
563
+ (Input extends infer Input extends {}
564
+ ? {
565
+ [Key in keyof Input & string as `@${Input[Key] extends infer Value
566
+ ? Value extends Marko.AttrTag<any>
567
+ ? Key
568
+ : never
569
+ : never}`]: Input[Key];
570
+ }
571
+ : never);
572
+
551
573
  type RecordKeys<T> = keyof {
552
574
  [K in keyof T as CheckNever<T[K], never, K>]: 0;
553
575
  };
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.7",
4
+ "version": "2.5.9",
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"