@vue/compiler-vapor 0.0.0 → 3.6.0-alpha.2

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,5 +1,5 @@
1
1
  /**
2
- * @vue/compiler-vapor v3.5.13
2
+ * @vue/compiler-vapor v3.6.0-alpha.2
3
3
  * (c) 2018-present Yuxi (Evan) You and Vue contributors
4
4
  * @license MIT
5
5
  **/
@@ -10,8 +10,9 @@ Object.defineProperty(exports, '__esModule', { value: true });
10
10
  var compilerDom = require('@vue/compiler-dom');
11
11
  var shared = require('@vue/shared');
12
12
  var sourceMapJs = require('source-map-js');
13
- var estreeWalker = require('estree-walker');
14
13
  var parser = require('@babel/parser');
14
+ var types = require('@babel/types');
15
+ var estreeWalker = require('estree-walker');
15
16
 
16
17
  const newDynamic = () => ({
17
18
  flags: 1,
@@ -24,7 +25,7 @@ const newBlock = (node) => ({
24
25
  effect: [],
25
26
  operation: [],
26
27
  returns: [],
27
- expressions: []
28
+ tempId: 0
28
29
  });
29
30
  function wrapTemplate(node, dirs) {
30
31
  if (node.tagType === 3) {
@@ -60,6 +61,15 @@ function propToExpression(prop) {
60
61
  function isConstantExpression(exp) {
61
62
  return compilerDom.isLiteralWhitelisted(exp.content) || shared.isGloballyAllowed(exp.content) || getLiteralExpressionValue(exp) !== null;
62
63
  }
64
+ function isStaticExpression(node, bindings) {
65
+ if (node.ast) {
66
+ return compilerDom.isConstantNode(node.ast, bindings);
67
+ } else if (node.ast === null) {
68
+ const type = bindings[node.content];
69
+ return type === "literal-const";
70
+ }
71
+ return false;
72
+ }
63
73
  function resolveExpression(exp) {
64
74
  if (!exp.isStatic) {
65
75
  const value = getLiteralExpressionValue(exp);
@@ -84,6 +94,7 @@ class TransformContext {
84
94
  constructor(ir, node, options = {}) {
85
95
  this.ir = ir;
86
96
  this.node = node;
97
+ this.selfName = null;
87
98
  this.parent = null;
88
99
  this.index = 0;
89
100
  this.block = this.ir.block;
@@ -100,6 +111,7 @@ class TransformContext {
100
111
  this.increaseId = () => this.globalId++;
101
112
  this.options = shared.extend({}, defaultOptions, options);
102
113
  this.root = this;
114
+ if (options.filename) this.selfName = compilerDom.getSelfName(options.filename);
103
115
  }
104
116
  enterBlock(ir, isVFor = false) {
105
117
  const { block, template, dynamic, childrenTemplate, slots } = this;
@@ -120,7 +132,7 @@ class TransformContext {
120
132
  };
121
133
  }
122
134
  reference() {
123
- if (this.dynamic.id !== undefined) return this.dynamic.id;
135
+ if (this.dynamic.id !== void 0) return this.dynamic.id;
124
136
  this.dynamic.flags |= 1;
125
137
  return this.dynamic.id = this.increaseId();
126
138
  }
@@ -137,27 +149,18 @@ class TransformContext {
137
149
  const id = this.pushTemplate(this.template);
138
150
  return this.dynamic.template = id;
139
151
  }
140
- registerEffect(expressions, ...operations) {
152
+ registerEffect(expressions, operation, getIndex = () => this.block.effect.length) {
153
+ const operations = [operation].flat();
141
154
  expressions = expressions.filter((exp) => !isConstantExpression(exp));
142
- if (this.inVOnce || expressions.length === 0 || isStaticExpression(this.root, expressions)) {
155
+ if (this.inVOnce || expressions.length === 0 || expressions.every(
156
+ (e) => isStaticExpression(e, this.root.options.bindingMetadata)
157
+ )) {
143
158
  return this.registerOperation(...operations);
144
159
  }
145
- this.block.expressions.push(...expressions);
146
- const existing = this.block.effect.find(
147
- (e) => isSameExpression(e.expressions, expressions)
148
- );
149
- if (existing) {
150
- existing.operations.push(...operations);
151
- } else {
152
- this.block.effect.push({
153
- expressions,
154
- operations
155
- });
156
- }
157
- function isSameExpression(a, b) {
158
- if (a.length !== b.length) return false;
159
- return a.every((exp, i) => exp.content === b[i].content);
160
- }
160
+ this.block.effect.splice(getIndex(), 0, {
161
+ expressions,
162
+ operations
163
+ });
161
164
  }
162
165
  registerOperation(...node) {
163
166
  this.block.operation.push(...node);
@@ -262,19 +265,6 @@ function createStructuralDirectiveTransform(name, fn) {
262
265
  }
263
266
  };
264
267
  }
265
- function isStaticExpression(context, expressions) {
266
- const {
267
- options: { bindingMetadata }
268
- } = context;
269
- const isLiteralConst = (name) => bindingMetadata[name] === "literal-const";
270
- return expressions.every((node) => {
271
- if (node.ast) {
272
- return compilerDom.isConstantNode(node.ast, isLiteralConst);
273
- } else if (node.ast === null) {
274
- return isLiteralConst(node.content);
275
- }
276
- });
277
- }
278
268
 
279
269
  const NEWLINE = Symbol(`newline` );
280
270
  const LF = Symbol(`line feed` );
@@ -395,6 +385,78 @@ ${` `.repeat(indentLevel)}`, 0];
395
385
  }
396
386
  }
397
387
 
388
+ const IRDynamicPropsKind = {
389
+ "EXPRESSION": 0,
390
+ "0": "EXPRESSION",
391
+ "ATTRIBUTE": 1,
392
+ "1": "ATTRIBUTE"
393
+ };
394
+ const IRSlotType = {
395
+ "STATIC": 0,
396
+ "0": "STATIC",
397
+ "DYNAMIC": 1,
398
+ "1": "DYNAMIC",
399
+ "LOOP": 2,
400
+ "2": "LOOP",
401
+ "CONDITIONAL": 3,
402
+ "3": "CONDITIONAL",
403
+ "EXPRESSION": 4,
404
+ "4": "EXPRESSION"
405
+ };
406
+
407
+ const IRNodeTypes = {
408
+ "ROOT": 0,
409
+ "0": "ROOT",
410
+ "BLOCK": 1,
411
+ "1": "BLOCK",
412
+ "SET_PROP": 2,
413
+ "2": "SET_PROP",
414
+ "SET_DYNAMIC_PROPS": 3,
415
+ "3": "SET_DYNAMIC_PROPS",
416
+ "SET_TEXT": 4,
417
+ "4": "SET_TEXT",
418
+ "SET_EVENT": 5,
419
+ "5": "SET_EVENT",
420
+ "SET_DYNAMIC_EVENTS": 6,
421
+ "6": "SET_DYNAMIC_EVENTS",
422
+ "SET_HTML": 7,
423
+ "7": "SET_HTML",
424
+ "SET_TEMPLATE_REF": 8,
425
+ "8": "SET_TEMPLATE_REF",
426
+ "INSERT_NODE": 9,
427
+ "9": "INSERT_NODE",
428
+ "PREPEND_NODE": 10,
429
+ "10": "PREPEND_NODE",
430
+ "CREATE_COMPONENT_NODE": 11,
431
+ "11": "CREATE_COMPONENT_NODE",
432
+ "SLOT_OUTLET_NODE": 12,
433
+ "12": "SLOT_OUTLET_NODE",
434
+ "DIRECTIVE": 13,
435
+ "13": "DIRECTIVE",
436
+ "DECLARE_OLD_REF": 14,
437
+ "14": "DECLARE_OLD_REF",
438
+ "IF": 15,
439
+ "15": "IF",
440
+ "FOR": 16,
441
+ "16": "FOR",
442
+ "GET_TEXT_CHILD": 17,
443
+ "17": "GET_TEXT_CHILD"
444
+ };
445
+ const DynamicFlag = {
446
+ "NONE": 0,
447
+ "0": "NONE",
448
+ "REFERENCED": 1,
449
+ "1": "REFERENCED",
450
+ "NON_TEMPLATE": 2,
451
+ "2": "NON_TEMPLATE",
452
+ "INSERT": 4,
453
+ "4": "INSERT"
454
+ };
455
+ function isBlockOperation(op) {
456
+ const type = op.type;
457
+ return type === 11 || type === 12 || type === 15 || type === 16;
458
+ }
459
+
398
460
  function genInsertNode({ parent, elements, anchor }, { helper }) {
399
461
  let element = elements.map((el) => `n${el}`).join(", ");
400
462
  if (elements.length > 1) element = `[${element}]`;
@@ -404,7 +466,7 @@ function genInsertNode({ parent, elements, anchor }, { helper }) {
404
466
  helper("insert"),
405
467
  element,
406
468
  `n${parent}`,
407
- anchor === undefined ? undefined : `n${anchor}`
469
+ anchor === void 0 ? void 0 : `n${anchor}`
408
470
  )
409
471
  ];
410
472
  }
@@ -446,12 +508,15 @@ function genExpression(node, context, assignment) {
446
508
  let hasMemberExpression = false;
447
509
  if (ids.length) {
448
510
  const [frag, push] = buildCodeFragment();
511
+ const isTSNode = ast && compilerDom.TS_NODE_TYPES.includes(ast.type);
449
512
  ids.sort((a, b) => a.start - b.start).forEach((id, i) => {
450
513
  const start = id.start - 1;
451
514
  const end = id.end - 1;
452
515
  const last = ids[i - 1];
453
- const leadingText = content.slice(last ? last.end - 1 : 0, start);
454
- if (leadingText.length) push([leadingText, -3]);
516
+ if (!(isTSNode && i === 0)) {
517
+ const leadingText = content.slice(last ? last.end - 1 : 0, start);
518
+ if (leadingText.length) push([leadingText, -3]);
519
+ }
455
520
  const source = content.slice(start, end);
456
521
  const parentStack2 = parentStackMap.get(id);
457
522
  const parent = parentStack2[parentStack2.length - 1];
@@ -465,13 +530,13 @@ function genExpression(node, context, assignment) {
465
530
  end: compilerDom.advancePositionWithClone(node.loc.start, source, end),
466
531
  source
467
532
  },
468
- hasMemberExpression ? undefined : assignment,
533
+ hasMemberExpression ? void 0 : assignment,
469
534
  id,
470
535
  parent,
471
536
  parentStack2
472
537
  )
473
538
  );
474
- if (i === ids.length - 1 && end < content.length) {
539
+ if (i === ids.length - 1 && end < content.length && !isTSNode) {
475
540
  push([content.slice(end), -3]);
476
541
  }
477
542
  });
@@ -491,7 +556,11 @@ function genIdentifier(raw, context, loc, assignment, id, parent, parentStack) {
491
556
  if (idMap && idMap.length) {
492
557
  const replacement = idMap[0];
493
558
  if (shared.isString(replacement)) {
494
- return [[replacement, -2, loc]];
559
+ if (parent && parent.type === "ObjectProperty" && parent.shorthand) {
560
+ return [[`${name}: ${replacement}`, -2, loc]];
561
+ } else {
562
+ return [[replacement, -2, loc]];
563
+ }
495
564
  } else {
496
565
  return genExpression(replacement, context, assignment);
497
566
  }
@@ -553,72 +622,118 @@ function canPrefix(name) {
553
622
  return false;
554
623
  return true;
555
624
  }
556
- function processExpressions(context, expressions) {
557
- const { seenVariable, variableToExpMap, expToVariableMap, seenIdentifier } = analyzeExpressions(expressions);
625
+ function processExpressions(context, expressions, shouldDeclare) {
626
+ const {
627
+ seenVariable,
628
+ variableToExpMap,
629
+ expToVariableMap,
630
+ seenIdentifier,
631
+ updatedVariable
632
+ } = analyzeExpressions(expressions);
558
633
  const varDeclarations = processRepeatedVariables(
559
634
  context,
560
635
  seenVariable,
561
636
  variableToExpMap,
562
637
  expToVariableMap,
563
- seenIdentifier
638
+ seenIdentifier,
639
+ updatedVariable
564
640
  );
565
641
  const expDeclarations = processRepeatedExpressions(
566
642
  context,
567
643
  expressions,
568
- varDeclarations
644
+ varDeclarations,
645
+ updatedVariable,
646
+ expToVariableMap
647
+ );
648
+ return genDeclarations(
649
+ [...varDeclarations, ...expDeclarations],
650
+ context,
651
+ shouldDeclare
569
652
  );
570
- return genDeclarations([...varDeclarations, ...expDeclarations], context);
571
653
  }
572
654
  function analyzeExpressions(expressions) {
573
655
  const seenVariable = /* @__PURE__ */ Object.create(null);
574
656
  const variableToExpMap = /* @__PURE__ */ new Map();
575
657
  const expToVariableMap = /* @__PURE__ */ new Map();
576
658
  const seenIdentifier = /* @__PURE__ */ new Set();
577
- const registerVariable = (name, exp, isIdentifier) => {
659
+ const updatedVariable = /* @__PURE__ */ new Set();
660
+ const registerVariable = (name, exp, isIdentifier, loc, parentStack = []) => {
578
661
  if (isIdentifier) seenIdentifier.add(name);
579
662
  seenVariable[name] = (seenVariable[name] || 0) + 1;
580
663
  variableToExpMap.set(
581
664
  name,
582
665
  (variableToExpMap.get(name) || /* @__PURE__ */ new Set()).add(exp)
583
666
  );
584
- expToVariableMap.set(exp, (expToVariableMap.get(exp) || []).concat(name));
667
+ const variables = expToVariableMap.get(exp) || [];
668
+ variables.push({ name, loc });
669
+ expToVariableMap.set(exp, variables);
670
+ if (parentStack.some(
671
+ (p) => p.type === "UpdateExpression" || p.type === "AssignmentExpression"
672
+ )) {
673
+ updatedVariable.add(name);
674
+ }
585
675
  };
586
676
  for (const exp of expressions) {
587
677
  if (!exp.ast) {
588
678
  exp.ast === null && registerVariable(exp.content, exp, true);
589
679
  continue;
590
680
  }
591
- estreeWalker.walk(exp.ast, {
592
- enter(currentNode) {
593
- if (currentNode.type === "MemberExpression") {
594
- const memberExp = extractMemberExpression(
595
- currentNode,
596
- (name) => {
597
- registerVariable(name, exp, true);
598
- }
599
- );
600
- registerVariable(memberExp, exp, false);
601
- return this.skip();
602
- }
603
- if (currentNode.type === "Identifier") {
604
- registerVariable(currentNode.name, exp, true);
605
- }
681
+ compilerDom.walkIdentifiers(exp.ast, (currentNode, parent, parentStack) => {
682
+ if (parent && isMemberExpression(parent)) {
683
+ const memberExp = extractMemberExpression(parent, (id) => {
684
+ registerVariable(id.name, exp, true, {
685
+ start: id.start,
686
+ end: id.end
687
+ });
688
+ });
689
+ registerVariable(
690
+ memberExp,
691
+ exp,
692
+ false,
693
+ { start: parent.start, end: parent.end },
694
+ parentStack
695
+ );
696
+ } else if (!parentStack.some(isMemberExpression)) {
697
+ registerVariable(
698
+ currentNode.name,
699
+ exp,
700
+ true,
701
+ { start: currentNode.start, end: currentNode.end },
702
+ parentStack
703
+ );
606
704
  }
607
705
  });
608
706
  }
609
- return { seenVariable, seenIdentifier, variableToExpMap, expToVariableMap };
707
+ return {
708
+ seenVariable,
709
+ seenIdentifier,
710
+ variableToExpMap,
711
+ expToVariableMap,
712
+ updatedVariable
713
+ };
610
714
  }
611
- function processRepeatedVariables(context, seenVariable, variableToExpMap, expToVariableMap, seenIdentifier) {
715
+ function processRepeatedVariables(context, seenVariable, variableToExpMap, expToVariableMap, seenIdentifier, updatedVariable) {
612
716
  const declarations = [];
717
+ const expToReplacementMap = /* @__PURE__ */ new Map();
613
718
  for (const [name, exps] of variableToExpMap) {
719
+ if (updatedVariable.has(name)) continue;
614
720
  if (seenVariable[name] > 1 && exps.size > 0) {
615
721
  const isIdentifier = seenIdentifier.has(name);
616
722
  const varName = isIdentifier ? name : genVarName(name);
617
- const replaceRE = new RegExp(escapeRegExp(name), "g");
618
723
  exps.forEach((node) => {
619
- if (node.ast) {
620
- node.content = node.content.replace(replaceRE, varName);
621
- node.ast = parseExp(context, node.content);
724
+ if (node.ast && varName !== name) {
725
+ const replacements = expToReplacementMap.get(node) || [];
726
+ replacements.push({
727
+ name: varName,
728
+ locs: expToVariableMap.get(node).reduce(
729
+ (locs, v) => {
730
+ if (v.name === name && v.loc) locs.push(v.loc);
731
+ return locs;
732
+ },
733
+ []
734
+ )
735
+ });
736
+ expToReplacementMap.set(node, replacements);
622
737
  }
623
738
  });
624
739
  if (!declarations.some((d) => d.name === varName) && (!isIdentifier || shouldDeclareVariable(name, expToVariableMap, exps))) {
@@ -636,10 +751,21 @@ function processRepeatedVariables(context, seenVariable, variableToExpMap, expTo
636
751
  }
637
752
  }
638
753
  }
754
+ for (const [exp, replacements] of expToReplacementMap) {
755
+ replacements.flatMap(
756
+ ({ name, locs }) => locs.map(({ start, end }) => ({ start, end, name }))
757
+ ).sort((a, b) => b.end - a.end).forEach(({ start, end, name }) => {
758
+ exp.content = exp.content.slice(0, start - 1) + name + exp.content.slice(end - 1);
759
+ });
760
+ exp.ast = parseExp(context, exp.content);
761
+ }
639
762
  return declarations;
640
763
  }
641
764
  function shouldDeclareVariable(name, expToVariableMap, exps) {
642
- const vars = Array.from(exps, (exp) => expToVariableMap.get(exp));
765
+ const vars = Array.from(
766
+ exps,
767
+ (exp) => expToVariableMap.get(exp).map((v) => v.name)
768
+ );
643
769
  if (vars.every((v) => v.length === 1)) {
644
770
  return true;
645
771
  }
@@ -660,11 +786,12 @@ function shouldDeclareVariable(name, expToVariableMap, exps) {
660
786
  }
661
787
  return true;
662
788
  }
663
- function processRepeatedExpressions(context, expressions, varDeclarations) {
789
+ function processRepeatedExpressions(context, expressions, varDeclarations, updatedVariable, expToVariableMap) {
664
790
  const declarations = [];
665
791
  const seenExp = expressions.reduce(
666
792
  (acc, exp) => {
667
- if (exp.ast && exp.ast.type !== "Identifier") {
793
+ const variables = expToVariableMap.get(exp).map((v) => v.name);
794
+ if (exp.ast && exp.ast.type !== "Identifier" && !(variables && variables.some((v) => updatedVariable.has(v)))) {
668
795
  acc[exp.content] = (acc[exp.content] || 0) + 1;
669
796
  }
670
797
  return acc;
@@ -716,26 +843,35 @@ function processRepeatedExpressions(context, expressions, varDeclarations) {
716
843
  });
717
844
  return declarations;
718
845
  }
719
- function genDeclarations(declarations, context) {
846
+ function genDeclarations(declarations, context, shouldDeclare) {
720
847
  const [frag, push] = buildCodeFragment();
721
848
  const ids = /* @__PURE__ */ Object.create(null);
849
+ const varNames = /* @__PURE__ */ new Set();
722
850
  declarations.forEach(({ name, isIdentifier, value }) => {
723
851
  if (isIdentifier) {
724
852
  const varName = ids[name] = `_${name}`;
725
- push(`const ${varName} = `, ...genExpression(value, context), NEWLINE);
853
+ varNames.add(varName);
854
+ if (shouldDeclare) {
855
+ push(`const `);
856
+ }
857
+ push(`${varName} = `, ...genExpression(value, context), NEWLINE);
726
858
  }
727
859
  });
728
860
  declarations.forEach(({ name, isIdentifier, value }) => {
729
861
  if (!isIdentifier) {
730
862
  const varName = ids[name] = `_${name}`;
863
+ varNames.add(varName);
864
+ if (shouldDeclare) {
865
+ push(`const `);
866
+ }
731
867
  push(
732
- `const ${varName} = `,
868
+ `${varName} = `,
733
869
  ...context.withId(() => genExpression(value, context), ids),
734
870
  NEWLINE
735
871
  );
736
872
  }
737
873
  });
738
- return { ids, frag };
874
+ return { ids, frag, varNames: [...varNames] };
739
875
  }
740
876
  function escapeRegExp(string) {
741
877
  return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
@@ -754,7 +890,7 @@ function extractMemberExpression(exp, onIdentifier) {
754
890
  if (!exp) return "";
755
891
  switch (exp.type) {
756
892
  case "Identifier":
757
- onIdentifier(exp.name);
893
+ onIdentifier(exp);
758
894
  return exp.name;
759
895
  case "StringLiteral":
760
896
  return exp.extra ? exp.extra.raw : exp.value;
@@ -765,6 +901,8 @@ function extractMemberExpression(exp, onIdentifier) {
765
901
  case "CallExpression":
766
902
  return `${extractMemberExpression(exp.callee, onIdentifier)}(${exp.arguments.map((arg) => extractMemberExpression(arg, onIdentifier)).join(", ")})`;
767
903
  case "MemberExpression":
904
+ // foo[bar.baz]
905
+ case "OptionalMemberExpression":
768
906
  const object = extractMemberExpression(exp.object, onIdentifier);
769
907
  const prop = exp.computed ? `[${extractMemberExpression(exp.property, onIdentifier)}]` : `.${extractMemberExpression(exp.property, shared.NOOP)}`;
770
908
  return `${object}${prop}`;
@@ -772,6 +910,9 @@ function extractMemberExpression(exp, onIdentifier) {
772
910
  return "";
773
911
  }
774
912
  }
913
+ const isMemberExpression = (node) => {
914
+ return node.type === "MemberExpression" || node.type === "OptionalMemberExpression";
915
+ };
775
916
 
776
917
  function genSetEvent(oper, context) {
777
918
  const { helper } = context;
@@ -781,6 +922,9 @@ function genSetEvent(oper, context) {
781
922
  const eventOptions = genEventOptions();
782
923
  if (delegate) {
783
924
  context.delegates.add(key.content);
925
+ if (!context.block.operation.some(isSameDelegateEvent)) {
926
+ return [NEWLINE, `n${element}.$evt${key.content} = `, ...handler];
927
+ }
784
928
  }
785
929
  return [
786
930
  NEWLINE,
@@ -812,6 +956,11 @@ function genSetEvent(oper, context) {
812
956
  ...options.map((option) => [`${option}: true`])
813
957
  );
814
958
  }
959
+ function isSameDelegateEvent(op) {
960
+ if (op.type === 5 && op !== oper && op.delegate && op.element === oper.element && op.key.content === key.content) {
961
+ return true;
962
+ }
963
+ }
815
964
  }
816
965
  function genSetDynamicEvents(oper, context) {
817
966
  const { helper } = context;
@@ -824,31 +973,35 @@ function genSetDynamicEvents(oper, context) {
824
973
  )
825
974
  ];
826
975
  }
827
- function genEventHandler(context, value, modifiers = { nonKeys: [], keys: [] }, needWrap = true) {
976
+ function genEventHandler(context, value, modifiers = { nonKeys: [], keys: [] }, extraWrap = false) {
828
977
  let handlerExp = [`() => {}`];
829
978
  if (value && value.content.trim()) {
830
- const isMemberExp = compilerDom.isMemberExpression(value, context.options);
831
- const isInlineStatement = !(isMemberExp || compilerDom.isFnExpression(value, context.options));
832
- if (isInlineStatement) {
833
- const expr = context.withId(() => genExpression(value, context), {
834
- $event: null
835
- });
979
+ if (compilerDom.isMemberExpression(value, context.options)) {
980
+ handlerExp = genExpression(value, context);
981
+ if (!isConstantBinding(value, context) && !extraWrap) {
982
+ handlerExp = [`e => `, ...handlerExp, `(e)`];
983
+ }
984
+ } else if (compilerDom.isFnExpression(value, context.options)) {
985
+ handlerExp = genExpression(value, context);
986
+ } else {
987
+ const referencesEvent = value.content.includes("$event");
836
988
  const hasMultipleStatements = value.content.includes(`;`);
989
+ const expr = referencesEvent ? context.withId(() => genExpression(value, context), {
990
+ $event: null
991
+ }) : genExpression(value, context);
837
992
  handlerExp = [
838
- "$event => ",
993
+ referencesEvent ? "$event => " : "() => ",
839
994
  hasMultipleStatements ? "{" : "(",
840
995
  ...expr,
841
996
  hasMultipleStatements ? "}" : ")"
842
997
  ];
843
- } else {
844
- handlerExp = [...genExpression(value, context)];
845
998
  }
846
999
  }
847
1000
  const { keys, nonKeys } = modifiers;
848
1001
  if (nonKeys.length)
849
1002
  handlerExp = genWithModifiers(context, handlerExp, nonKeys);
850
1003
  if (keys.length) handlerExp = genWithKeys(context, handlerExp, keys);
851
- if (needWrap) handlerExp.unshift(`() => `);
1004
+ if (extraWrap) handlerExp.unshift(`() => `);
852
1005
  return handlerExp;
853
1006
  }
854
1007
  function genWithModifiers(context, handler, nonKeys) {
@@ -861,10 +1014,29 @@ function genWithModifiers(context, handler, nonKeys) {
861
1014
  function genWithKeys(context, handler, keys) {
862
1015
  return genCall(context.helper("withKeys"), handler, JSON.stringify(keys));
863
1016
  }
1017
+ function isConstantBinding(value, context) {
1018
+ if (value.ast === null) {
1019
+ const bindingType = context.options.bindingMetadata[value.content];
1020
+ if (bindingType === "setup-const") {
1021
+ return true;
1022
+ }
1023
+ }
1024
+ }
864
1025
 
865
1026
  function genFor(oper, context) {
866
1027
  const { helper } = context;
867
- const { source, value, key, index, render, keyProp, once, id, component } = oper;
1028
+ const {
1029
+ source,
1030
+ value,
1031
+ key,
1032
+ index,
1033
+ render,
1034
+ keyProp,
1035
+ once,
1036
+ id,
1037
+ component,
1038
+ onlyChild
1039
+ } = oper;
868
1040
  let rawValue = null;
869
1041
  const rawKey = key && key.content;
870
1042
  const rawIndex = index && index.content;
@@ -907,18 +1079,87 @@ function genFor(oper, context) {
907
1079
  idMap[rawIndex] = `${indexVar}.value`;
908
1080
  idMap[indexVar] = null;
909
1081
  }
910
- const blockFn = context.withId(() => genBlock(render, context, args), idMap);
1082
+ const { selectorPatterns, keyOnlyBindingPatterns } = matchPatterns(
1083
+ render,
1084
+ keyProp,
1085
+ idMap
1086
+ );
1087
+ const selectorDeclarations = [];
1088
+ const selectorSetup = [];
1089
+ for (let i = 0; i < selectorPatterns.length; i++) {
1090
+ const { selector } = selectorPatterns[i];
1091
+ const selectorName = `_selector${id}_${i}`;
1092
+ selectorDeclarations.push(`let ${selectorName}`, NEWLINE);
1093
+ if (i === 0) {
1094
+ selectorSetup.push(`({ createSelector }) => {`, INDENT_START);
1095
+ }
1096
+ selectorSetup.push(
1097
+ NEWLINE,
1098
+ `${selectorName} = `,
1099
+ ...genCall(`createSelector`, [
1100
+ `() => `,
1101
+ ...genExpression(selector, context)
1102
+ ])
1103
+ );
1104
+ if (i === selectorPatterns.length - 1) {
1105
+ selectorSetup.push(INDENT_END, NEWLINE, "}");
1106
+ }
1107
+ }
1108
+ const blockFn = context.withId(() => {
1109
+ const frag = [];
1110
+ frag.push("(", ...args, ") => {", INDENT_START);
1111
+ if (selectorPatterns.length || keyOnlyBindingPatterns.length) {
1112
+ frag.push(
1113
+ ...genBlockContent(render, context, false, () => {
1114
+ const patternFrag = [];
1115
+ for (let i = 0; i < selectorPatterns.length; i++) {
1116
+ const { effect } = selectorPatterns[i];
1117
+ patternFrag.push(
1118
+ NEWLINE,
1119
+ `_selector${id}_${i}(() => {`,
1120
+ INDENT_START
1121
+ );
1122
+ for (const oper2 of effect.operations) {
1123
+ patternFrag.push(...genOperation(oper2, context));
1124
+ }
1125
+ patternFrag.push(INDENT_END, NEWLINE, `})`);
1126
+ }
1127
+ for (const { effect } of keyOnlyBindingPatterns) {
1128
+ for (const oper2 of effect.operations) {
1129
+ patternFrag.push(...genOperation(oper2, context));
1130
+ }
1131
+ }
1132
+ return patternFrag;
1133
+ })
1134
+ );
1135
+ } else {
1136
+ frag.push(...genBlockContent(render, context));
1137
+ }
1138
+ frag.push(INDENT_END, NEWLINE, "}");
1139
+ return frag;
1140
+ }, idMap);
911
1141
  exitScope();
1142
+ let flags = 0;
1143
+ if (onlyChild) {
1144
+ flags |= 1;
1145
+ }
1146
+ if (component) {
1147
+ flags |= 2;
1148
+ }
1149
+ if (once) {
1150
+ flags |= 4;
1151
+ }
912
1152
  return [
913
1153
  NEWLINE,
1154
+ ...selectorDeclarations,
914
1155
  `const n${id} = `,
915
1156
  ...genCall(
916
- helper("createFor"),
1157
+ [helper("createFor"), "undefined"],
917
1158
  sourceExpr,
918
1159
  blockFn,
919
1160
  genCallback(keyProp),
920
- component && "true",
921
- once && "true"
1161
+ flags ? String(flags) : void 0,
1162
+ selectorSetup.length ? selectorSetup : void 0
922
1163
  // todo: hydrationNode
923
1164
  )
924
1165
  ];
@@ -1002,8 +1243,8 @@ function genFor(oper, context) {
1002
1243
  return [
1003
1244
  ...genMulti(
1004
1245
  ["(", ")", ", "],
1005
- rawValue ? rawValue : rawKey || rawIndex ? "_" : undefined,
1006
- rawKey ? rawKey : rawIndex ? "__" : undefined,
1246
+ rawValue ? rawValue : rawKey || rawIndex ? "_" : void 0,
1247
+ rawKey ? rawKey : rawIndex ? "__" : void 0,
1007
1248
  rawIndex
1008
1249
  ),
1009
1250
  " => (",
@@ -1019,6 +1260,166 @@ function genFor(oper, context) {
1019
1260
  return idMap2;
1020
1261
  }
1021
1262
  }
1263
+ function matchPatterns(render, keyProp, idMap) {
1264
+ const selectorPatterns = [];
1265
+ const keyOnlyBindingPatterns = [];
1266
+ render.effect = render.effect.filter((effect) => {
1267
+ if (keyProp !== void 0) {
1268
+ const selector = matchSelectorPattern(effect, keyProp.ast, idMap);
1269
+ if (selector) {
1270
+ selectorPatterns.push(selector);
1271
+ return false;
1272
+ }
1273
+ const keyOnly = matchKeyOnlyBindingPattern(effect, keyProp.ast);
1274
+ if (keyOnly) {
1275
+ keyOnlyBindingPatterns.push(keyOnly);
1276
+ return false;
1277
+ }
1278
+ }
1279
+ return true;
1280
+ });
1281
+ return {
1282
+ keyOnlyBindingPatterns,
1283
+ selectorPatterns
1284
+ };
1285
+ }
1286
+ function matchKeyOnlyBindingPattern(effect, keyAst) {
1287
+ if (effect.expressions.length === 1) {
1288
+ const ast = effect.expressions[0].ast;
1289
+ if (typeof ast === "object" && ast !== null) {
1290
+ if (isKeyOnlyBinding(ast, keyAst)) {
1291
+ return { effect };
1292
+ }
1293
+ }
1294
+ }
1295
+ }
1296
+ function matchSelectorPattern(effect, keyAst, idMap) {
1297
+ if (effect.expressions.length === 1) {
1298
+ const ast = effect.expressions[0].ast;
1299
+ if (typeof ast === "object" && ast) {
1300
+ const matcheds = [];
1301
+ estreeWalker.walk(ast, {
1302
+ enter(node) {
1303
+ if (typeof node === "object" && node && node.type === "BinaryExpression" && node.operator === "===" && node.left.type !== "PrivateName") {
1304
+ const { left, right } = node;
1305
+ for (const [a, b] of [
1306
+ [left, right],
1307
+ [right, left]
1308
+ ]) {
1309
+ const aIsKey = isKeyOnlyBinding(a, keyAst);
1310
+ const bIsKey = isKeyOnlyBinding(b, keyAst);
1311
+ const bVars = analyzeVariableScopes(b, idMap);
1312
+ if (aIsKey && !bIsKey && !bVars.locals.length) {
1313
+ matcheds.push([a, b]);
1314
+ }
1315
+ }
1316
+ }
1317
+ }
1318
+ });
1319
+ if (matcheds.length === 1) {
1320
+ const [key, selector] = matcheds[0];
1321
+ const content2 = effect.expressions[0].content;
1322
+ let hasExtraId = false;
1323
+ const parentStackMap = /* @__PURE__ */ new Map();
1324
+ const parentStack = [];
1325
+ compilerDom.walkIdentifiers(
1326
+ ast,
1327
+ (id) => {
1328
+ if (id.start !== key.start && id.start !== selector.start) {
1329
+ hasExtraId = true;
1330
+ }
1331
+ parentStackMap.set(id, parentStack.slice());
1332
+ },
1333
+ false,
1334
+ parentStack
1335
+ );
1336
+ if (!hasExtraId) {
1337
+ const name = content2.slice(selector.start - 1, selector.end - 1);
1338
+ return {
1339
+ effect,
1340
+ // @ts-expect-error
1341
+ selector: {
1342
+ content: name,
1343
+ ast: shared.extend({}, selector, {
1344
+ start: 1,
1345
+ end: name.length + 1
1346
+ }),
1347
+ loc: selector.loc,
1348
+ isStatic: false
1349
+ }
1350
+ };
1351
+ }
1352
+ }
1353
+ }
1354
+ const content = effect.expressions[0].content;
1355
+ if (typeof ast === "object" && ast && ast.type === "ConditionalExpression" && ast.test.type === "BinaryExpression" && ast.test.operator === "===" && ast.test.left.type !== "PrivateName" && compilerDom.isStaticNode(ast.consequent) && compilerDom.isStaticNode(ast.alternate)) {
1356
+ const left = ast.test.left;
1357
+ const right = ast.test.right;
1358
+ for (const [a, b] of [
1359
+ [left, right],
1360
+ [right, left]
1361
+ ]) {
1362
+ const aIsKey = isKeyOnlyBinding(a, keyAst);
1363
+ const bIsKey = isKeyOnlyBinding(b, keyAst);
1364
+ const bVars = analyzeVariableScopes(b, idMap);
1365
+ if (aIsKey && !bIsKey && !bVars.locals.length) {
1366
+ return {
1367
+ effect,
1368
+ // @ts-expect-error
1369
+ selector: {
1370
+ content: content.slice(b.start - 1, b.end - 1),
1371
+ ast: b,
1372
+ loc: b.loc,
1373
+ isStatic: false
1374
+ }
1375
+ };
1376
+ }
1377
+ }
1378
+ }
1379
+ }
1380
+ }
1381
+ function analyzeVariableScopes(ast, idMap) {
1382
+ let globals = [];
1383
+ let locals = [];
1384
+ const ids = [];
1385
+ const parentStackMap = /* @__PURE__ */ new Map();
1386
+ const parentStack = [];
1387
+ compilerDom.walkIdentifiers(
1388
+ ast,
1389
+ (id) => {
1390
+ ids.push(id);
1391
+ parentStackMap.set(id, parentStack.slice());
1392
+ },
1393
+ false,
1394
+ parentStack
1395
+ );
1396
+ for (const id of ids) {
1397
+ if (shared.isGloballyAllowed(id.name)) {
1398
+ continue;
1399
+ }
1400
+ if (idMap[id.name]) {
1401
+ locals.push(id.name);
1402
+ } else {
1403
+ globals.push(id.name);
1404
+ }
1405
+ }
1406
+ return { globals, locals };
1407
+ }
1408
+ function isKeyOnlyBinding(expr, keyAst) {
1409
+ let only = true;
1410
+ estreeWalker.walk(expr, {
1411
+ enter(node) {
1412
+ if (types.isNodesEquivalent(node, keyAst)) {
1413
+ this.skip();
1414
+ return;
1415
+ }
1416
+ if (node.type === "Identifier") {
1417
+ only = false;
1418
+ }
1419
+ }
1420
+ });
1421
+ return only;
1422
+ }
1022
1423
 
1023
1424
  function genSetHtml(oper, context) {
1024
1425
  const { helper } = context;
@@ -1048,474 +1449,16 @@ function genIf(oper, context, isNested = false) {
1048
1449
  }
1049
1450
  }
1050
1451
  if (!isNested) push(NEWLINE, `const n${oper.id} = `);
1051
- push(
1052
- ...genCall(
1053
- helper("createIf"),
1054
- conditionExpr,
1055
- positiveArg,
1056
- negativeArg,
1057
- once && "true"
1058
- )
1059
- );
1060
- return frag;
1061
- }
1062
-
1063
- const locStub = {
1064
- start: { line: 1, column: 1, offset: 0 },
1065
- end: { line: 1, column: 1, offset: 0 },
1066
- source: ""
1067
- };
1068
- function createSimpleExpression(content, isStatic = false, loc = locStub, constType = 0) {
1069
- return {
1070
- type: 4,
1071
- loc,
1072
- content,
1073
- isStatic,
1074
- constType: isStatic ? 3 : constType
1075
- };
1076
- }
1077
-
1078
- function createCompilerError(code, loc, messages, additionalMessage) {
1079
- const msg = (errorMessages)[code] + (``) ;
1080
- const error = new SyntaxError(String(msg));
1081
- error.code = code;
1082
- error.loc = loc;
1083
- return error;
1084
- }
1085
- const errorMessages = {
1086
- // parse errors
1087
- [0]: "Illegal comment.",
1088
- [1]: "CDATA section is allowed only in XML context.",
1089
- [2]: "Duplicate attribute.",
1090
- [3]: "End tag cannot have attributes.",
1091
- [4]: "Illegal '/' in tags.",
1092
- [5]: "Unexpected EOF in tag.",
1093
- [6]: "Unexpected EOF in CDATA section.",
1094
- [7]: "Unexpected EOF in comment.",
1095
- [8]: "Unexpected EOF in script.",
1096
- [9]: "Unexpected EOF in tag.",
1097
- [10]: "Incorrectly closed comment.",
1098
- [11]: "Incorrectly opened comment.",
1099
- [12]: "Illegal tag name. Use '&lt;' to print '<'.",
1100
- [13]: "Attribute value was expected.",
1101
- [14]: "End tag name was expected.",
1102
- [15]: "Whitespace was expected.",
1103
- [16]: "Unexpected '<!--' in comment.",
1104
- [17]: `Attribute name cannot contain U+0022 ("), U+0027 ('), and U+003C (<).`,
1105
- [18]: "Unquoted attribute value cannot contain U+0022 (\"), U+0027 ('), U+003C (<), U+003D (=), and U+0060 (`).",
1106
- [19]: "Attribute name cannot start with '='.",
1107
- [21]: "'<?' is allowed only in XML context.",
1108
- [20]: `Unexpected null character.`,
1109
- [22]: "Illegal '/' in tags.",
1110
- // Vue-specific parse errors
1111
- [23]: "Invalid end tag.",
1112
- [24]: "Element is missing end tag.",
1113
- [25]: "Interpolation end sign was not found.",
1114
- [27]: "End bracket for dynamic directive argument was not found. Note that dynamic directive argument cannot contain spaces.",
1115
- [26]: "Legal directive name was expected.",
1116
- // transform errors
1117
- [28]: `v-if/v-else-if is missing expression.`,
1118
- [29]: `v-if/else branches must use unique keys.`,
1119
- [30]: `v-else/v-else-if has no adjacent v-if or v-else-if.`,
1120
- [31]: `v-for is missing expression.`,
1121
- [32]: `v-for has invalid expression.`,
1122
- [33]: `<template v-for> key should be placed on the <template> tag.`,
1123
- [34]: `v-bind is missing expression.`,
1124
- [52]: `v-bind with same-name shorthand only allows static argument.`,
1125
- [35]: `v-on is missing expression.`,
1126
- [36]: `Unexpected custom directive on <slot> outlet.`,
1127
- [37]: `Mixed v-slot usage on both the component and nested <template>. When there are multiple named slots, all slots should use <template> syntax to avoid scope ambiguity.`,
1128
- [38]: `Duplicate slot names found. `,
1129
- [39]: `Extraneous children found when component already has explicitly named default slot. These children will be ignored.`,
1130
- [40]: `v-slot can only be used on components or <template> tags.`,
1131
- [41]: `v-model is missing expression.`,
1132
- [42]: `v-model value must be a valid JavaScript member expression.`,
1133
- [43]: `v-model cannot be used on v-for or v-slot scope variables because they are not writable.`,
1134
- [44]: `v-model cannot be used on a prop, because local prop bindings are not writable.
1135
- Use a v-bind binding combined with a v-on listener that emits update:x event instead.`,
1136
- [45]: `Error parsing JavaScript expression: `,
1137
- [46]: `<KeepAlive> expects exactly one child component.`,
1138
- [51]: `@vnode-* hooks in templates are no longer supported. Use the vue: prefix instead. For example, @vnode-mounted should be changed to @vue:mounted. @vnode-* hooks support has been removed in 3.4.`,
1139
- // generic errors
1140
- [47]: `"prefixIdentifiers" option is not supported in this build of compiler.`,
1141
- [48]: `ES module mode is not supported in this build of compiler.`,
1142
- [49]: `"cacheHandlers" option is only supported when the "prefixIdentifiers" option is enabled.`,
1143
- [50]: `"scopeId" option is only supported in module mode.`,
1144
- // just to fulfill types
1145
- [53]: ``
1146
- };
1147
-
1148
- function walkIdentifiers(root, onIdentifier, includeAll = false, parentStack = [], knownIds = /* @__PURE__ */ Object.create(null)) {
1149
- const rootExp = root.type === "Program" ? root.body[0].type === "ExpressionStatement" && root.body[0].expression : root;
1150
- estreeWalker.walk(root, {
1151
- enter(node, parent) {
1152
- parent && parentStack.push(parent);
1153
- if (parent && parent.type.startsWith("TS") && !TS_NODE_TYPES.includes(parent.type)) {
1154
- return this.skip();
1155
- }
1156
- if (node.type === "Identifier") {
1157
- const isLocal = !!knownIds[node.name];
1158
- const isRefed = isReferencedIdentifier(node, parent, parentStack);
1159
- if (includeAll || isRefed && !isLocal) {
1160
- onIdentifier(node, parent, parentStack, isRefed, isLocal);
1161
- }
1162
- } else if (node.type === "ObjectProperty" && // eslint-disable-next-line no-restricted-syntax
1163
- (parent == null ? undefined : parent.type) === "ObjectPattern") {
1164
- node.inPattern = true;
1165
- } else if (isFunctionType(node)) {
1166
- if (node.scopeIds) {
1167
- node.scopeIds.forEach((id) => markKnownIds(id, knownIds));
1168
- } else {
1169
- walkFunctionParams(
1170
- node,
1171
- (id) => markScopeIdentifier(node, id, knownIds)
1172
- );
1173
- }
1174
- } else if (node.type === "BlockStatement") {
1175
- if (node.scopeIds) {
1176
- node.scopeIds.forEach((id) => markKnownIds(id, knownIds));
1177
- } else {
1178
- walkBlockDeclarations(
1179
- node,
1180
- (id) => markScopeIdentifier(node, id, knownIds)
1181
- );
1182
- }
1183
- } else if (node.type === "CatchClause" && node.param) {
1184
- for (const id of extractIdentifiers(node.param)) {
1185
- markScopeIdentifier(node, id, knownIds);
1186
- }
1187
- } else if (isForStatement(node)) {
1188
- walkForStatement(
1189
- node,
1190
- false,
1191
- (id) => markScopeIdentifier(node, id, knownIds)
1192
- );
1193
- }
1194
- },
1195
- leave(node, parent) {
1196
- parent && parentStack.pop();
1197
- if (node !== rootExp && node.scopeIds) {
1198
- for (const id of node.scopeIds) {
1199
- knownIds[id]--;
1200
- if (knownIds[id] === 0) {
1201
- delete knownIds[id];
1202
- }
1203
- }
1204
- }
1205
- }
1206
- });
1207
- }
1208
- function isReferencedIdentifier(id, parent, parentStack) {
1209
- if (!parent) {
1210
- return true;
1211
- }
1212
- if (id.name === "arguments") {
1213
- return false;
1214
- }
1215
- if (isReferenced(id, parent)) {
1216
- return true;
1217
- }
1218
- switch (parent.type) {
1219
- case "AssignmentExpression":
1220
- case "AssignmentPattern":
1221
- return true;
1222
- case "ObjectPattern":
1223
- case "ArrayPattern":
1224
- return isInDestructureAssignment(parent, parentStack);
1225
- }
1226
- return false;
1227
- }
1228
- function isInDestructureAssignment(parent, parentStack) {
1229
- if (parent && (parent.type === "ObjectProperty" || parent.type === "ArrayPattern")) {
1230
- let i = parentStack.length;
1231
- while (i--) {
1232
- const p = parentStack[i];
1233
- if (p.type === "AssignmentExpression") {
1234
- return true;
1235
- } else if (p.type !== "ObjectProperty" && !p.type.endsWith("Pattern")) {
1236
- break;
1237
- }
1238
- }
1239
- }
1240
- return false;
1241
- }
1242
- function walkFunctionParams(node, onIdent) {
1243
- for (const p of node.params) {
1244
- for (const id of extractIdentifiers(p)) {
1245
- onIdent(id);
1246
- }
1247
- }
1248
- }
1249
- function walkBlockDeclarations(block, onIdent) {
1250
- for (const stmt of block.body) {
1251
- if (stmt.type === "VariableDeclaration") {
1252
- if (stmt.declare) continue;
1253
- for (const decl of stmt.declarations) {
1254
- for (const id of extractIdentifiers(decl.id)) {
1255
- onIdent(id);
1256
- }
1257
- }
1258
- } else if (stmt.type === "FunctionDeclaration" || stmt.type === "ClassDeclaration") {
1259
- if (stmt.declare || !stmt.id) continue;
1260
- onIdent(stmt.id);
1261
- } else if (isForStatement(stmt)) {
1262
- walkForStatement(stmt, true, onIdent);
1263
- }
1264
- }
1265
- }
1266
- function isForStatement(stmt) {
1267
- return stmt.type === "ForOfStatement" || stmt.type === "ForInStatement" || stmt.type === "ForStatement";
1268
- }
1269
- function walkForStatement(stmt, isVar, onIdent) {
1270
- const variable = stmt.type === "ForStatement" ? stmt.init : stmt.left;
1271
- if (variable && variable.type === "VariableDeclaration" && (variable.kind === "var" ? isVar : !isVar)) {
1272
- for (const decl of variable.declarations) {
1273
- for (const id of extractIdentifiers(decl.id)) {
1274
- onIdent(id);
1275
- }
1276
- }
1277
- }
1278
- }
1279
- function extractIdentifiers(param, nodes = []) {
1280
- switch (param.type) {
1281
- case "Identifier":
1282
- nodes.push(param);
1283
- break;
1284
- case "MemberExpression":
1285
- let object = param;
1286
- while (object.type === "MemberExpression") {
1287
- object = object.object;
1288
- }
1289
- nodes.push(object);
1290
- break;
1291
- case "ObjectPattern":
1292
- for (const prop of param.properties) {
1293
- if (prop.type === "RestElement") {
1294
- extractIdentifiers(prop.argument, nodes);
1295
- } else {
1296
- extractIdentifiers(prop.value, nodes);
1297
- }
1298
- }
1299
- break;
1300
- case "ArrayPattern":
1301
- param.elements.forEach((element) => {
1302
- if (element) extractIdentifiers(element, nodes);
1303
- });
1304
- break;
1305
- case "RestElement":
1306
- extractIdentifiers(param.argument, nodes);
1307
- break;
1308
- case "AssignmentPattern":
1309
- extractIdentifiers(param.left, nodes);
1310
- break;
1311
- }
1312
- return nodes;
1313
- }
1314
- function markKnownIds(name, knownIds) {
1315
- if (name in knownIds) {
1316
- knownIds[name]++;
1317
- } else {
1318
- knownIds[name] = 1;
1319
- }
1320
- }
1321
- function markScopeIdentifier(node, child, knownIds) {
1322
- const { name } = child;
1323
- if (node.scopeIds && node.scopeIds.has(name)) {
1324
- return;
1325
- }
1326
- markKnownIds(name, knownIds);
1327
- (node.scopeIds || (node.scopeIds = /* @__PURE__ */ new Set())).add(name);
1328
- }
1329
- const isFunctionType = (node) => {
1330
- return /Function(?:Expression|Declaration)$|Method$/.test(node.type);
1331
- };
1332
- function isReferenced(node, parent, grandparent) {
1333
- switch (parent.type) {
1334
- // yes: PARENT[NODE]
1335
- // yes: NODE.child
1336
- // no: parent.NODE
1337
- case "MemberExpression":
1338
- case "OptionalMemberExpression":
1339
- if (parent.property === node) {
1340
- return !!parent.computed;
1341
- }
1342
- return parent.object === node;
1343
- case "JSXMemberExpression":
1344
- return parent.object === node;
1345
- // no: let NODE = init;
1346
- // yes: let id = NODE;
1347
- case "VariableDeclarator":
1348
- return parent.init === node;
1349
- // yes: () => NODE
1350
- // no: (NODE) => {}
1351
- case "ArrowFunctionExpression":
1352
- return parent.body === node;
1353
- // no: class { #NODE; }
1354
- // no: class { get #NODE() {} }
1355
- // no: class { #NODE() {} }
1356
- // no: class { fn() { return this.#NODE; } }
1357
- case "PrivateName":
1358
- return false;
1359
- // no: class { NODE() {} }
1360
- // yes: class { [NODE]() {} }
1361
- // no: class { foo(NODE) {} }
1362
- case "ClassMethod":
1363
- case "ClassPrivateMethod":
1364
- case "ObjectMethod":
1365
- if (parent.key === node) {
1366
- return !!parent.computed;
1367
- }
1368
- return false;
1369
- // yes: { [NODE]: "" }
1370
- // no: { NODE: "" }
1371
- // depends: { NODE }
1372
- // depends: { key: NODE }
1373
- case "ObjectProperty":
1374
- if (parent.key === node) {
1375
- return !!parent.computed;
1376
- }
1377
- return true;
1378
- // no: class { NODE = value; }
1379
- // yes: class { [NODE] = value; }
1380
- // yes: class { key = NODE; }
1381
- case "ClassProperty":
1382
- if (parent.key === node) {
1383
- return !!parent.computed;
1384
- }
1385
- return true;
1386
- case "ClassPrivateProperty":
1387
- return parent.key !== node;
1388
- // no: class NODE {}
1389
- // yes: class Foo extends NODE {}
1390
- case "ClassDeclaration":
1391
- case "ClassExpression":
1392
- return parent.superClass === node;
1393
- // yes: left = NODE;
1394
- // no: NODE = right;
1395
- case "AssignmentExpression":
1396
- return parent.right === node;
1397
- // no: [NODE = foo] = [];
1398
- // yes: [foo = NODE] = [];
1399
- case "AssignmentPattern":
1400
- return parent.right === node;
1401
- // no: NODE: for (;;) {}
1402
- case "LabeledStatement":
1403
- return false;
1404
- // no: try {} catch (NODE) {}
1405
- case "CatchClause":
1406
- return false;
1407
- // no: function foo(...NODE) {}
1408
- case "RestElement":
1409
- return false;
1410
- case "BreakStatement":
1411
- case "ContinueStatement":
1412
- return false;
1413
- // no: function NODE() {}
1414
- // no: function foo(NODE) {}
1415
- case "FunctionDeclaration":
1416
- case "FunctionExpression":
1417
- return false;
1418
- // no: export NODE from "foo";
1419
- // no: export * as NODE from "foo";
1420
- case "ExportNamespaceSpecifier":
1421
- case "ExportDefaultSpecifier":
1422
- return false;
1423
- // no: export { foo as NODE };
1424
- // yes: export { NODE as foo };
1425
- // no: export { NODE as foo } from "foo";
1426
- case "ExportSpecifier":
1427
- return parent.local === node;
1428
- // no: import NODE from "foo";
1429
- // no: import * as NODE from "foo";
1430
- // no: import { NODE as foo } from "foo";
1431
- // no: import { foo as NODE } from "foo";
1432
- // no: import NODE from "bar";
1433
- case "ImportDefaultSpecifier":
1434
- case "ImportNamespaceSpecifier":
1435
- case "ImportSpecifier":
1436
- return false;
1437
- // no: import "foo" assert { NODE: "json" }
1438
- case "ImportAttribute":
1439
- return false;
1440
- // no: <div NODE="foo" />
1441
- case "JSXAttribute":
1442
- return false;
1443
- // no: [NODE] = [];
1444
- // no: ({ NODE }) = [];
1445
- case "ObjectPattern":
1446
- case "ArrayPattern":
1447
- return false;
1448
- // no: new.NODE
1449
- // no: NODE.target
1450
- case "MetaProperty":
1451
- return false;
1452
- // yes: type X = { someProperty: NODE }
1453
- // no: type X = { NODE: OtherType }
1454
- case "ObjectTypeProperty":
1455
- return parent.key !== node;
1456
- // yes: enum X { Foo = NODE }
1457
- // no: enum X { NODE }
1458
- case "TSEnumMember":
1459
- return parent.id !== node;
1460
- // yes: { [NODE]: value }
1461
- // no: { NODE: value }
1462
- case "TSPropertySignature":
1463
- if (parent.key === node) {
1464
- return !!parent.computed;
1465
- }
1466
- return true;
1467
- }
1468
- return true;
1469
- }
1470
- const TS_NODE_TYPES = [
1471
- "TSAsExpression",
1472
- // foo as number
1473
- "TSTypeAssertion",
1474
- // (<number>foo)
1475
- "TSNonNullExpression",
1476
- // foo!
1477
- "TSInstantiationExpression",
1478
- // foo<string>
1479
- "TSSatisfiesExpression"
1480
- // foo satisfies T
1481
- ];
1482
- function unwrapTSNode(node) {
1483
- if (TS_NODE_TYPES.includes(node.type)) {
1484
- return unwrapTSNode(node.expression);
1485
- } else {
1486
- return node;
1487
- }
1488
- }
1489
-
1490
- const isStaticExp = (p) => p.type === 4 && p.isStatic;
1491
- const nonIdentifierRE = /^\d|[^\$\w\xA0-\uFFFF]/;
1492
- const isSimpleIdentifier = (name) => !nonIdentifierRE.test(name);
1493
- const getExpSource = (exp) => exp.type === 4 ? exp.content : exp.loc.source;
1494
- const isMemberExpressionNode = (exp, context) => {
1495
- try {
1496
- let ret = exp.ast || parser.parseExpression(getExpSource(exp), {
1497
- plugins: context.expressionPlugins ? [...context.expressionPlugins, "typescript"] : ["typescript"]
1498
- });
1499
- ret = unwrapTSNode(ret);
1500
- return ret.type === "MemberExpression" || ret.type === "OptionalMemberExpression" || ret.type === "Identifier" && ret.name !== "undefined";
1501
- } catch (e) {
1502
- return false;
1503
- }
1504
- };
1505
- const isMemberExpression = isMemberExpressionNode;
1506
- function isStaticArgOf(arg, name) {
1507
- return !!(arg && isStaticExp(arg) && arg.content === name);
1508
- }
1509
- function isVSlot(p) {
1510
- return p.type === 7 && p.name === "slot";
1511
- }
1512
- function isTemplateNode(node) {
1513
- return node.type === 1 && node.tagType === 3;
1514
- }
1515
- function toValidAssetId(name, type) {
1516
- return `_${type}_${name.replace(/[^\w]/g, (searchValue, replaceValue) => {
1517
- return searchValue === "-" ? "_" : name.charCodeAt(replaceValue).toString();
1518
- })}`;
1452
+ push(
1453
+ ...genCall(
1454
+ helper("createIf"),
1455
+ conditionExpr,
1456
+ positiveArg,
1457
+ negativeArg,
1458
+ once && "true"
1459
+ )
1460
+ );
1461
+ return frag;
1519
1462
  }
1520
1463
 
1521
1464
  const helpers = {
@@ -1526,9 +1469,7 @@ const helpers = {
1526
1469
  setValue: { name: "setValue" },
1527
1470
  setAttr: { name: "setAttr", needKey: true },
1528
1471
  setProp: { name: "setProp", needKey: true },
1529
- setDOMProp: { name: "setDOMProp", needKey: true },
1530
- setDynamicProps: { name: "setDynamicProps" }
1531
- };
1472
+ setDOMProp: { name: "setDOMProp", needKey: true }};
1532
1473
  function genSetProp(oper, context) {
1533
1474
  const { helper } = context;
1534
1475
  const {
@@ -1579,7 +1520,7 @@ function genPropKey({ key: node, modifier, runtimeCamelize, handler, handlerModi
1579
1520
  const keyName = (handler ? shared.toHandlerKey(node.content) : node.content) + handlerModifierPostfix;
1580
1521
  return [
1581
1522
  [
1582
- isSimpleIdentifier(keyName) ? keyName : JSON.stringify(keyName),
1523
+ compilerDom.isSimpleIdentifier(keyName) ? keyName : JSON.stringify(keyName),
1583
1524
  -2,
1584
1525
  node.loc
1585
1526
  ]
@@ -1596,7 +1537,7 @@ function genPropKey({ key: node, modifier, runtimeCamelize, handler, handlerModi
1596
1537
  "[",
1597
1538
  modifier && `${JSON.stringify(modifier)} + `,
1598
1539
  ...key,
1599
- handlerModifierPostfix ? ` + ${JSON.stringify(handlerModifierPostfix)}` : undefined,
1540
+ handlerModifierPostfix ? ` + ${JSON.stringify(handlerModifierPostfix)}` : void 0,
1600
1541
  "]"
1601
1542
  ];
1602
1543
  }
@@ -1656,8 +1597,8 @@ function genSetTemplateRef(oper, context) {
1656
1597
  setTemplateRefIdent,
1657
1598
  // will be generated in root scope
1658
1599
  `n${oper.element}`,
1659
- genExpression(oper.value, context),
1660
- oper.effect ? `r${oper.element}` : oper.refFor ? "void 0" : undefined,
1600
+ genRefValue(oper.value, context),
1601
+ oper.effect ? `r${oper.element}` : oper.refFor ? "void 0" : void 0,
1661
1602
  oper.refFor && "true"
1662
1603
  )
1663
1604
  ];
@@ -1665,26 +1606,41 @@ function genSetTemplateRef(oper, context) {
1665
1606
  function genDeclareOldRef(oper) {
1666
1607
  return [NEWLINE, `let r${oper.id}`];
1667
1608
  }
1609
+ function genRefValue(value, context) {
1610
+ if (value && context.options.inline) {
1611
+ const binding = context.options.bindingMetadata[value.content];
1612
+ if (binding === "setup-let" || binding === "setup-ref" || binding === "setup-maybe-ref") {
1613
+ return [value.content];
1614
+ }
1615
+ }
1616
+ return genExpression(value, context);
1617
+ }
1668
1618
 
1669
1619
  function genSetText(oper, context) {
1670
1620
  const { helper } = context;
1671
- const { element, values } = oper;
1672
- const texts = values.map((value) => genExpression(value, context));
1673
- return [NEWLINE, ...genCall(helper("setText"), `n${element}`, ...texts)];
1621
+ const { element, values, generated, jsx } = oper;
1622
+ const texts = combineValues(values, context, jsx);
1623
+ return [
1624
+ NEWLINE,
1625
+ ...genCall(helper("setText"), `${generated ? "x" : "n"}${element}`, texts)
1626
+ ];
1674
1627
  }
1675
- function genCreateTextNode(oper, context) {
1676
- const { helper } = context;
1677
- const { id, values, effect } = oper;
1628
+ function combineValues(values, context, jsx) {
1629
+ return values.flatMap((value, i) => {
1630
+ let exp = genExpression(value, context);
1631
+ if (!jsx && getLiteralExpressionValue(value) == null) {
1632
+ exp = genCall(context.helper("toDisplayString"), exp);
1633
+ }
1634
+ if (i > 0) {
1635
+ exp.unshift(jsx ? ", " : " + ");
1636
+ }
1637
+ return exp;
1638
+ });
1639
+ }
1640
+ function genGetTextChild(oper, context) {
1678
1641
  return [
1679
1642
  NEWLINE,
1680
- `const n${id} = `,
1681
- ...genCall(helper("createTextNode"), [
1682
- effect && "() => ",
1683
- ...genMulti(
1684
- DELIMITERS_ARRAY,
1685
- ...values.map((value) => genExpression(value, context))
1686
- )
1687
- ])
1643
+ `const x${oper.parent} = ${context.helper("child")}(n${oper.parent})`
1688
1644
  ];
1689
1645
  }
1690
1646
 
@@ -1722,7 +1678,7 @@ function genVModel(oper, context) {
1722
1678
  // setter
1723
1679
  genModelHandler(exp, context),
1724
1680
  // modifiers
1725
- modifiers.length ? `{ ${modifiers.map((e) => e.content + ": true").join(",")} }` : undefined
1681
+ modifiers.length ? `{ ${modifiers.map((e) => e.content + ": true").join(",")} }` : void 0
1726
1682
  )
1727
1683
  ];
1728
1684
  }
@@ -1755,7 +1711,6 @@ function genCustomDirectives(opers, context) {
1755
1711
  const directives = genMulti(DELIMITERS_ARRAY, ...directiveItems);
1756
1712
  return [
1757
1713
  NEWLINE,
1758
- // @ts-expect-error
1759
1714
  ...genCall(helper("withVaporDirectives"), element, directives)
1760
1715
  ];
1761
1716
  function genDirectiveItem({
@@ -1790,7 +1745,7 @@ function genDirectiveModifiers(modifiers) {
1790
1745
  }
1791
1746
  function filterCustomDirectives(id, operations) {
1792
1747
  return operations.filter(
1793
- (oper) => oper.type === 14 && oper.element === id && !oper.builtin
1748
+ (oper) => oper.type === 13 && oper.element === id && !oper.builtin
1794
1749
  );
1795
1750
  }
1796
1751
 
@@ -1803,7 +1758,7 @@ function genCreateComponent(operation, context) {
1803
1758
  const rawProps = context.withId(() => genRawProps(props, context), ids);
1804
1759
  const inlineHandlers = handlers.reduce(
1805
1760
  (acc, { name, value }) => {
1806
- const handler = genEventHandler(context, value, undefined, false);
1761
+ const handler = genEventHandler(context, value, void 0, false);
1807
1762
  return [...acc, `const ${name} = `, ...handler, NEWLINE];
1808
1763
  },
1809
1764
  []
@@ -1833,10 +1788,10 @@ function genCreateComponent(operation, context) {
1833
1788
  return ["() => (", ...genExpression(operation.dynamic, context), ")"];
1834
1789
  }
1835
1790
  } else if (operation.asset) {
1836
- return toValidAssetId(operation.tag, "component");
1791
+ return compilerDom.toValidAssetId(operation.tag, "component");
1837
1792
  } else {
1838
1793
  return genExpression(
1839
- shared.extend(createSimpleExpression(operation.tag, false), { ast: null }),
1794
+ shared.extend(compilerDom.createSimpleExpression(operation.tag, false), { ast: null }),
1840
1795
  context
1841
1796
  );
1842
1797
  }
@@ -1844,6 +1799,7 @@ function genCreateComponent(operation, context) {
1844
1799
  }
1845
1800
  function getUniqueHandlerName(context, name) {
1846
1801
  const { seenInlineHandlerNames } = context;
1802
+ name = genVarName(name);
1847
1803
  const count = seenInlineHandlerNames[name] || 0;
1848
1804
  seenInlineHandlerNames[name] = count + 1;
1849
1805
  return count === 0 ? name : `${name}${count}`;
@@ -1857,12 +1813,12 @@ function processInlineHandlers(props, context) {
1857
1813
  const prop = staticProps[i];
1858
1814
  if (!prop.handler) continue;
1859
1815
  prop.values.forEach((value, i2) => {
1860
- const isMemberExp = isMemberExpression(value, context.options);
1816
+ const isMemberExp = compilerDom.isMemberExpression(value, context.options);
1861
1817
  if (!isMemberExp) {
1862
1818
  const name = getUniqueHandlerName(context, `_on_${prop.key.content}`);
1863
1819
  handlers.push({ name, value });
1864
1820
  ids[name] = null;
1865
- prop.values[i2] = shared.extend({ ast: null }, createSimpleExpression(name));
1821
+ prop.values[i2] = shared.extend({ ast: null }, compilerDom.createSimpleExpression(name));
1866
1822
  }
1867
1823
  });
1868
1824
  }
@@ -1923,7 +1879,12 @@ function genProp(prop, context, isStatic) {
1923
1879
  return [
1924
1880
  ...genPropKey(prop, context),
1925
1881
  ": ",
1926
- ...prop.handler ? genEventHandler(context, prop.values[0]) : isStatic ? ["() => (", ...values, ")"] : values,
1882
+ ...prop.handler ? genEventHandler(
1883
+ context,
1884
+ prop.values[0],
1885
+ void 0,
1886
+ true
1887
+ ) : isStatic ? ["() => (", ...values, ")"] : values,
1927
1888
  ...prop.model ? [...genModelEvent(prop, context), ...genModelModifiers(prop, context)] : []
1928
1889
  ];
1929
1890
  }
@@ -1946,11 +1907,11 @@ function genRawSlots(slots, context) {
1946
1907
  return genStaticSlots(
1947
1908
  staticSlots,
1948
1909
  context,
1949
- slots.length > 1 ? slots.slice(1) : undefined
1910
+ slots.length > 1 ? slots.slice(1) : void 0
1950
1911
  );
1951
1912
  } else {
1952
1913
  return genStaticSlots(
1953
- { slotType: 0, slots: {} },
1914
+ { slots: {} },
1954
1915
  context,
1955
1916
  slots
1956
1917
  );
@@ -2022,8 +1983,8 @@ function genLoopSlot(slot, context) {
2022
1983
  [
2023
1984
  ...genMulti(
2024
1985
  ["(", ")", ", "],
2025
- rawValue ? rawValue : rawKey || rawIndex ? "_" : undefined,
2026
- rawKey ? rawKey : rawIndex ? "__" : undefined,
1986
+ rawValue ? rawValue : rawKey || rawIndex ? "_" : void 0,
1987
+ rawKey ? rawKey : rawIndex ? "__" : void 0,
2027
1988
  rawIndex
2028
1989
  ),
2029
1990
  " => (",
@@ -2060,7 +2021,7 @@ function genSlotBlockWithProps(oper, context) {
2060
2021
  if (isDestructureAssignment = !!props.ast) {
2061
2022
  [depth, exitScope] = context.enterScope();
2062
2023
  propsName = `_slotProps${depth}`;
2063
- walkIdentifiers(
2024
+ compilerDom.walkIdentifiers(
2064
2025
  props.ast,
2065
2026
  (id, _, __, ___, isLocal) => {
2066
2027
  if (isLocal) idsOfProps.add(id.name);
@@ -2108,8 +2069,16 @@ function genSlotOutlet(oper, context) {
2108
2069
  function genOperations(opers, context) {
2109
2070
  const [frag, push] = buildCodeFragment();
2110
2071
  for (const operation of opers) {
2111
- push(...genOperation(operation, context));
2072
+ push(...genOperationWithInsertionState(operation, context));
2073
+ }
2074
+ return frag;
2075
+ }
2076
+ function genOperationWithInsertionState(oper, context) {
2077
+ const [frag, push] = buildCodeFragment();
2078
+ if (isBlockOperation(oper) && oper.parent) {
2079
+ push(...genInsertionState(oper, context));
2112
2080
  }
2081
+ push(...genOperation(oper, context));
2113
2082
  return frag;
2114
2083
  }
2115
2084
  function genOperation(oper, context) {
@@ -2128,24 +2097,24 @@ function genOperation(oper, context) {
2128
2097
  return genSetHtml(oper, context);
2129
2098
  case 8:
2130
2099
  return genSetTemplateRef(oper, context);
2131
- case 11:
2132
- return genCreateTextNode(oper, context);
2133
2100
  case 9:
2134
2101
  return genInsertNode(oper, context);
2135
2102
  case 10:
2136
2103
  return genPrependNode(oper, context);
2137
- case 16:
2104
+ case 15:
2138
2105
  return genIf(oper, context);
2139
- case 17:
2106
+ case 16:
2140
2107
  return genFor(oper, context);
2141
- case 12:
2108
+ case 11:
2142
2109
  return genCreateComponent(oper, context);
2143
- case 15:
2110
+ case 14:
2144
2111
  return genDeclareOldRef(oper);
2145
- case 13:
2112
+ case 12:
2146
2113
  return genSlotOutlet(oper, context);
2147
- case 14:
2114
+ case 13:
2148
2115
  return genBuiltinDirective(oper, context);
2116
+ case 17:
2117
+ return genGetTextChild(oper, context);
2149
2118
  default:
2150
2119
  const exhaustiveCheck = oper;
2151
2120
  throw new Error(
@@ -2153,17 +2122,17 @@ function genOperation(oper, context) {
2153
2122
  );
2154
2123
  }
2155
2124
  }
2156
- function genEffects(effects, context) {
2157
- const {
2158
- helper,
2159
- block: { expressions }
2160
- } = context;
2125
+ function genEffects(effects, context, genExtraFrag) {
2126
+ const { helper } = context;
2127
+ const expressions = effects.flatMap((effect) => effect.expressions);
2161
2128
  const [frag, push, unshift] = buildCodeFragment();
2129
+ const shouldDeclare = genExtraFrag === void 0;
2162
2130
  let operationsCount = 0;
2163
- const { ids, frag: declarationFrags } = processExpressions(
2164
- context,
2165
- expressions
2166
- );
2131
+ const {
2132
+ ids,
2133
+ frag: declarationFrags,
2134
+ varNames
2135
+ } = processExpressions(context, expressions, shouldDeclare);
2167
2136
  push(...declarationFrags);
2168
2137
  for (let i = 0; i < effects.length; i++) {
2169
2138
  const effect = effects[i];
@@ -2179,11 +2148,20 @@ function genEffects(effects, context) {
2179
2148
  if (newLineCount > 1 || operationsCount > 1 || declarationFrags.length > 0) {
2180
2149
  unshift(`{`, INDENT_START, NEWLINE);
2181
2150
  push(INDENT_END, NEWLINE, "}");
2151
+ if (!effects.length) {
2152
+ unshift(NEWLINE);
2153
+ }
2182
2154
  }
2183
2155
  if (effects.length) {
2184
2156
  unshift(NEWLINE, `${helper("renderEffect")}(() => `);
2185
2157
  push(`)`);
2186
2158
  }
2159
+ if (!shouldDeclare && varNames.length) {
2160
+ unshift(NEWLINE, `let `, varNames.join(", "));
2161
+ }
2162
+ if (genExtraFrag) {
2163
+ push(...context.withId(genExtraFrag, ids));
2164
+ }
2187
2165
  return frag;
2188
2166
  }
2189
2167
  function genEffect({ operations }, context) {
@@ -2197,6 +2175,16 @@ function genEffect({ operations }, context) {
2197
2175
  }
2198
2176
  return frag;
2199
2177
  }
2178
+ function genInsertionState(operation, context) {
2179
+ return [
2180
+ NEWLINE,
2181
+ ...genCall(
2182
+ context.helper("setInsertionState"),
2183
+ `n${operation.parent}`,
2184
+ operation.anchor == null ? void 0 : operation.anchor === -1 ? `0` : `n${operation.anchor}`
2185
+ )
2186
+ ];
2187
+ }
2200
2188
 
2201
2189
  function genTemplates(templates, rootIndex, { helper }) {
2202
2190
  return templates.map(
@@ -2206,52 +2194,74 @@ function genTemplates(templates, rootIndex, { helper }) {
2206
2194
  `
2207
2195
  ).join("");
2208
2196
  }
2209
- function genChildren(dynamic, context, from, paths = []) {
2210
- const { helper } = context;
2197
+ function genSelf(dynamic, context) {
2211
2198
  const [frag, push] = buildCodeFragment();
2212
- let offset = 0;
2213
- const { children, id, template } = dynamic;
2214
- if (id !== undefined && template !== undefined) {
2199
+ const { id, template, operation } = dynamic;
2200
+ if (id !== void 0 && template !== void 0) {
2215
2201
  push(NEWLINE, `const n${id} = t${template}()`);
2216
2202
  push(...genDirectivesForElement(id, context));
2217
2203
  }
2204
+ if (operation) {
2205
+ push(...genOperationWithInsertionState(operation, context));
2206
+ }
2207
+ return frag;
2208
+ }
2209
+ function genChildren(dynamic, context, pushBlock, from = `n${dynamic.id}`) {
2210
+ const { helper } = context;
2211
+ const [frag, push] = buildCodeFragment();
2212
+ const { children } = dynamic;
2213
+ let offset = 0;
2218
2214
  let prev;
2215
+ const childrenToGen = [];
2219
2216
  for (const [index, child] of children.entries()) {
2220
2217
  if (child.flags & 2) {
2221
2218
  offset--;
2222
2219
  }
2223
- const id2 = child.flags & 1 ? child.flags & 4 ? child.anchor : child.id : undefined;
2224
- const elementIndex = Number(index) + offset;
2225
- const newPaths = [...paths, elementIndex];
2226
- if (id2 === undefined) {
2227
- push(...genChildren(child, context, from, newPaths));
2220
+ const id = child.flags & 1 ? child.flags & 4 ? child.anchor : child.id : void 0;
2221
+ if (id === void 0 && !child.hasDynamicChild) {
2222
+ push(...genSelf(child, context));
2228
2223
  continue;
2229
2224
  }
2230
- push(NEWLINE, `const n${id2} = `);
2225
+ const elementIndex = Number(index) + offset;
2226
+ const variable = id === void 0 ? `p${context.block.tempId++}` : `n${id}`;
2227
+ pushBlock(NEWLINE, `const ${variable} = `);
2231
2228
  if (prev) {
2232
- const offset2 = elementIndex - prev[1];
2233
- if (offset2 === 1) {
2234
- push(`n${prev[0]}.nextSibling`);
2229
+ if (elementIndex - prev[1] === 1) {
2230
+ pushBlock(...genCall(helper("next"), prev[0]));
2235
2231
  } else {
2236
- push(...genCall(helper("next"), `n${prev[0]}`, String(offset2)));
2232
+ pushBlock(...genCall(helper("nthChild"), from, String(elementIndex)));
2237
2233
  }
2238
2234
  } else {
2239
- if (newPaths.length === 1 && newPaths[0] === 0) {
2240
- push(`n${from}.firstChild`);
2235
+ if (elementIndex === 0) {
2236
+ pushBlock(...genCall(helper("child"), from));
2241
2237
  } else {
2242
- push(
2243
- ...genCall(helper("children"), `n${from}`, ...newPaths.map(String))
2244
- );
2238
+ let init = genCall(helper("child"), from);
2239
+ if (elementIndex === 1) {
2240
+ init = genCall(helper("next"), init);
2241
+ } else if (elementIndex > 1) {
2242
+ init = genCall(helper("nthChild"), from, String(elementIndex));
2243
+ }
2244
+ pushBlock(...init);
2245
2245
  }
2246
2246
  }
2247
- push(...genDirectivesForElement(id2, context));
2248
- prev = [id2, elementIndex];
2249
- push(...genChildren(child, context, id2, []));
2247
+ if (id === child.anchor) {
2248
+ push(...genSelf(child, context));
2249
+ }
2250
+ if (id !== void 0) {
2251
+ push(...genDirectivesForElement(id, context));
2252
+ }
2253
+ prev = [variable, elementIndex];
2254
+ childrenToGen.push([child, variable]);
2255
+ }
2256
+ if (childrenToGen.length) {
2257
+ for (const [child, from2] of childrenToGen) {
2258
+ push(...genChildren(child, context, pushBlock, from2));
2259
+ }
2250
2260
  }
2251
2261
  return frag;
2252
2262
  }
2253
2263
 
2254
- function genBlock(oper, context, args = [], root, customReturns) {
2264
+ function genBlock(oper, context, args = [], root) {
2255
2265
  return [
2256
2266
  "(",
2257
2267
  ...args,
@@ -2263,19 +2273,36 @@ function genBlock(oper, context, args = [], root, customReturns) {
2263
2273
  "}"
2264
2274
  ];
2265
2275
  }
2266
- function genBlockContent(block, context, root, customReturns) {
2276
+ function genBlockContent(block, context, root, genEffectsExtraFrag) {
2267
2277
  const [frag, push] = buildCodeFragment();
2268
2278
  const { dynamic, effect, operation, returns } = block;
2269
2279
  const resetBlock = context.enterBlock(block);
2270
2280
  if (root) {
2271
- genResolveAssets("component", "resolveComponent");
2281
+ for (let name of context.ir.component) {
2282
+ const id = compilerDom.toValidAssetId(name, "component");
2283
+ const maybeSelfReference = name.endsWith("__self");
2284
+ if (maybeSelfReference) name = name.slice(0, -6);
2285
+ push(
2286
+ NEWLINE,
2287
+ `const ${id} = `,
2288
+ ...genCall(
2289
+ context.helper("resolveComponent"),
2290
+ JSON.stringify(name),
2291
+ // pass additional `maybeSelfReference` flag
2292
+ maybeSelfReference ? "true" : void 0
2293
+ )
2294
+ );
2295
+ }
2272
2296
  genResolveAssets("directive", "resolveDirective");
2273
2297
  }
2274
2298
  for (const child of dynamic.children) {
2275
- push(...genChildren(child, context, child.id));
2299
+ push(...genSelf(child, context));
2300
+ }
2301
+ for (const child of dynamic.children) {
2302
+ push(...genChildren(child, context, push, `n${child.id}`));
2276
2303
  }
2277
2304
  push(...genOperations(operation, context));
2278
- push(...genEffects(effect, context));
2305
+ push(...genEffects(effect, context, genEffectsExtraFrag));
2279
2306
  push(NEWLINE, `return `);
2280
2307
  const returnNodes = returns.map((n) => `n${n}`);
2281
2308
  const returnsCode = returnNodes.length > 1 ? genMulti(DELIMITERS_ARRAY, ...returnNodes) : [returnNodes[0] || "null"];
@@ -2413,16 +2440,20 @@ const transformChildren = (node, context) => {
2413
2440
  for (const [i, child] of node.children.entries()) {
2414
2441
  const childContext = context.create(child, i);
2415
2442
  transformNode(childContext);
2443
+ const childDynamic = childContext.dynamic;
2416
2444
  if (isFragment) {
2417
2445
  childContext.reference();
2418
2446
  childContext.registerTemplate();
2419
- if (!(childContext.dynamic.flags & 2) || childContext.dynamic.flags & 4) {
2447
+ if (!(childDynamic.flags & 2) || childDynamic.flags & 4) {
2420
2448
  context.block.returns.push(childContext.dynamic.id);
2421
2449
  }
2422
2450
  } else {
2423
2451
  context.childrenTemplate.push(childContext.template);
2424
2452
  }
2425
- context.dynamic.children[i] = childContext.dynamic;
2453
+ if (childDynamic.hasDynamicChild || childDynamic.id !== void 0 || childDynamic.flags & 2 || childDynamic.flags & 4) {
2454
+ context.dynamic.hasDynamicChild = true;
2455
+ }
2456
+ context.dynamic.children[i] = childDynamic;
2426
2457
  }
2427
2458
  if (!isFragment) {
2428
2459
  processDynamicChildren(context);
@@ -2442,18 +2473,14 @@ function processDynamicChildren(context) {
2442
2473
  context.childrenTemplate[index - prevDynamics.length] = `<!>`;
2443
2474
  prevDynamics[0].flags -= 2;
2444
2475
  const anchor = prevDynamics[0].anchor = context.increaseId();
2445
- context.registerOperation({
2446
- type: 9,
2447
- elements: prevDynamics.map((child2) => child2.id),
2448
- parent: context.reference(),
2449
- anchor
2450
- });
2476
+ registerInsertion(prevDynamics, context, anchor);
2451
2477
  } else {
2452
- context.registerOperation({
2453
- type: 10,
2454
- elements: prevDynamics.map((child2) => child2.id),
2455
- parent: context.reference()
2456
- });
2478
+ registerInsertion(
2479
+ prevDynamics,
2480
+ context,
2481
+ -1
2482
+ /* prepend */
2483
+ );
2457
2484
  }
2458
2485
  prevDynamics = [];
2459
2486
  }
@@ -2461,11 +2488,22 @@ function processDynamicChildren(context) {
2461
2488
  }
2462
2489
  }
2463
2490
  if (prevDynamics.length) {
2464
- context.registerOperation({
2465
- type: 9,
2466
- elements: prevDynamics.map((child) => child.id),
2467
- parent: context.reference()
2468
- });
2491
+ registerInsertion(prevDynamics, context);
2492
+ }
2493
+ }
2494
+ function registerInsertion(dynamics, context, anchor) {
2495
+ for (const child of dynamics) {
2496
+ if (child.template != null) {
2497
+ context.registerOperation({
2498
+ type: 9,
2499
+ elements: dynamics.map((child2) => child2.id),
2500
+ parent: context.reference(),
2501
+ anchor
2502
+ });
2503
+ } else if (child.operation && isBlockOperation(child.operation)) {
2504
+ child.operation.parent = context.reference();
2505
+ child.operation.anchor = anchor;
2506
+ }
2469
2507
  }
2470
2508
  }
2471
2509
 
@@ -2483,6 +2521,8 @@ const isReservedProp = /* @__PURE__ */ shared.makeMap(
2483
2521
  ",key,ref,ref_for,ref_key,"
2484
2522
  );
2485
2523
  const transformElement = (node, context) => {
2524
+ let effectIndex = context.block.effect.length;
2525
+ const getEffectIndex = () => effectIndex++;
2486
2526
  return function postTransformElement() {
2487
2527
  ({ node } = context);
2488
2528
  if (!(node.type === 1 && (node.tagType === 0 || node.tagType === 1)))
@@ -2493,24 +2533,35 @@ const transformElement = (node, context) => {
2493
2533
  node,
2494
2534
  context,
2495
2535
  isComponent,
2496
- isDynamicComponent
2536
+ isDynamicComponent,
2537
+ getEffectIndex
2497
2538
  );
2498
2539
  let { parent } = context;
2499
2540
  while (parent && parent.parent && parent.node.type === 1 && parent.node.tagType === 3) {
2500
2541
  parent = parent.parent;
2501
2542
  }
2502
2543
  const singleRoot = context.root === parent && parent.node.children.filter((child) => child.type !== 3).length === 1;
2503
- (isComponent ? transformComponentElement : transformNativeElement)(
2504
- node,
2505
- propsResult,
2506
- singleRoot,
2507
- context,
2508
- isDynamicComponent
2509
- );
2544
+ if (isComponent) {
2545
+ transformComponentElement(
2546
+ node,
2547
+ propsResult,
2548
+ singleRoot,
2549
+ context,
2550
+ isDynamicComponent
2551
+ );
2552
+ } else {
2553
+ transformNativeElement(
2554
+ node,
2555
+ propsResult,
2556
+ singleRoot,
2557
+ context,
2558
+ getEffectIndex
2559
+ );
2560
+ }
2510
2561
  };
2511
2562
  };
2512
2563
  function transformComponentElement(node, propsResult, singleRoot, context, isDynamicComponent) {
2513
- const dynamicComponent = isDynamicComponent ? resolveDynamicComponent(node) : undefined;
2564
+ const dynamicComponent = isDynamicComponent ? resolveDynamicComponent(node) : void 0;
2514
2565
  let { tag } = node;
2515
2566
  let asset = true;
2516
2567
  if (!dynamicComponent) {
@@ -2528,21 +2579,24 @@ function transformComponentElement(node, propsResult, singleRoot, context, isDyn
2528
2579
  }
2529
2580
  }
2530
2581
  if (asset) {
2582
+ if (context.selfName && shared.capitalize(shared.camelize(tag)) === context.selfName) {
2583
+ tag += `__self`;
2584
+ }
2531
2585
  context.component.add(tag);
2532
2586
  }
2533
2587
  }
2534
2588
  context.dynamic.flags |= 2 | 4;
2535
- context.registerOperation({
2536
- type: 12,
2589
+ context.dynamic.operation = {
2590
+ type: 11,
2537
2591
  id: context.reference(),
2538
2592
  tag,
2539
2593
  props: propsResult[0] ? propsResult[1] : [propsResult[1]],
2540
2594
  asset,
2541
- root: singleRoot,
2595
+ root: singleRoot && !context.inVFor,
2542
2596
  slots: [...context.slots],
2543
2597
  once: context.inVOnce,
2544
2598
  dynamic: dynamicComponent
2545
- });
2599
+ };
2546
2600
  context.slots = [];
2547
2601
  }
2548
2602
  function resolveDynamicComponent(node) {
@@ -2570,9 +2624,9 @@ function resolveSetupReference(name, context) {
2570
2624
  }
2571
2625
  const camelName = shared.camelize(name);
2572
2626
  const PascalName = shared.capitalize(camelName);
2573
- return bindings[name] ? name : bindings[camelName] ? camelName : bindings[PascalName] ? PascalName : undefined;
2627
+ return bindings[name] ? name : bindings[camelName] ? camelName : bindings[PascalName] ? PascalName : void 0;
2574
2628
  }
2575
- function transformNativeElement(node, propsResult, singleRoot, context) {
2629
+ function transformNativeElement(node, propsResult, singleRoot, context, getEffectIndex) {
2576
2630
  const { tag } = node;
2577
2631
  const { scopeId } = context.options;
2578
2632
  let template = "";
@@ -2581,12 +2635,16 @@ function transformNativeElement(node, propsResult, singleRoot, context) {
2581
2635
  const dynamicProps = [];
2582
2636
  if (propsResult[0]) {
2583
2637
  const [, dynamicArgs, expressions] = propsResult;
2584
- context.registerEffect(expressions, {
2585
- type: 3,
2586
- element: context.reference(),
2587
- props: dynamicArgs,
2588
- root: singleRoot
2589
- });
2638
+ context.registerEffect(
2639
+ expressions,
2640
+ {
2641
+ type: 3,
2642
+ element: context.reference(),
2643
+ props: dynamicArgs,
2644
+ root: singleRoot
2645
+ },
2646
+ getEffectIndex
2647
+ );
2590
2648
  } else {
2591
2649
  for (const prop of propsResult[1]) {
2592
2650
  const { key, values } = prop;
@@ -2595,13 +2653,17 @@ function transformNativeElement(node, propsResult, singleRoot, context) {
2595
2653
  if (values[0].content) template += `="${values[0].content}"`;
2596
2654
  } else {
2597
2655
  dynamicProps.push(key.content);
2598
- context.registerEffect(values, {
2599
- type: 2,
2600
- element: context.reference(),
2601
- prop,
2602
- root: singleRoot,
2603
- tag
2604
- });
2656
+ context.registerEffect(
2657
+ values,
2658
+ {
2659
+ type: 2,
2660
+ element: context.reference(),
2661
+ prop,
2662
+ root: singleRoot,
2663
+ tag
2664
+ },
2665
+ getEffectIndex
2666
+ );
2605
2667
  }
2606
2668
  }
2607
2669
  }
@@ -2620,7 +2682,7 @@ function transformNativeElement(node, propsResult, singleRoot, context) {
2620
2682
  context.template += template;
2621
2683
  }
2622
2684
  }
2623
- function buildProps(node, context, isComponent, isDynamicComponent) {
2685
+ function buildProps(node, context, isComponent, isDynamicComponent, getEffectIndex) {
2624
2686
  const props = node.props;
2625
2687
  if (props.length === 0) return [false, []];
2626
2688
  const dynamicArgs = [];
@@ -2665,7 +2727,8 @@ function buildProps(node, context, isComponent, isDynamicComponent) {
2665
2727
  type: 6,
2666
2728
  element: context.reference(),
2667
2729
  event: prop.exp
2668
- }
2730
+ },
2731
+ getEffectIndex
2669
2732
  );
2670
2733
  }
2671
2734
  } else {
@@ -2722,7 +2785,7 @@ function transformProp(prop, node, context) {
2722
2785
  context.directive.add(name);
2723
2786
  }
2724
2787
  context.registerOperation({
2725
- type: 14,
2788
+ type: 13,
2726
2789
  element: context.reference(),
2727
2790
  dir: prop,
2728
2791
  name,
@@ -2754,7 +2817,7 @@ function dedupeProperties(results) {
2754
2817
  }
2755
2818
  function resolveDirectiveResult(prop) {
2756
2819
  return shared.extend({}, prop, {
2757
- value: undefined,
2820
+ value: void 0,
2758
2821
  values: [prop.value]
2759
2822
  });
2760
2823
  }
@@ -2787,6 +2850,17 @@ const transformVHtml = (dir, node, context) => {
2787
2850
  });
2788
2851
  };
2789
2852
 
2853
+ /*! #__NO_SIDE_EFFECTS__ */
2854
+ // @__NO_SIDE_EFFECTS__
2855
+ function makeMap(str) {
2856
+ const map = /* @__PURE__ */ Object.create(null);
2857
+ for (const key of str.split(",")) map[key] = 1;
2858
+ return (val) => val in map;
2859
+ }
2860
+
2861
+ const VOID_TAGS = "area,base,br,col,embed,hr,img,input,link,meta,param,source,track,wbr";
2862
+ const isVoidTag = /* @__PURE__ */ makeMap(VOID_TAGS);
2863
+
2790
2864
  const transformVText = (dir, node, context) => {
2791
2865
  let { exp, loc } = dir;
2792
2866
  if (!exp) {
@@ -2801,14 +2875,23 @@ const transformVText = (dir, node, context) => {
2801
2875
  );
2802
2876
  context.childrenTemplate.length = 0;
2803
2877
  }
2878
+ if (isVoidTag(context.node.tag)) {
2879
+ return;
2880
+ }
2804
2881
  const literal = getLiteralExpressionValue(exp);
2805
2882
  if (literal != null) {
2806
2883
  context.childrenTemplate = [String(literal)];
2807
2884
  } else {
2885
+ context.childrenTemplate = [" "];
2886
+ context.registerOperation({
2887
+ type: 17,
2888
+ parent: context.reference()
2889
+ });
2808
2890
  context.registerEffect([exp], {
2809
2891
  type: 4,
2810
2892
  element: context.reference(),
2811
- values: [exp]
2893
+ values: [exp],
2894
+ generated: true
2812
2895
  });
2813
2896
  }
2814
2897
  };
@@ -2856,7 +2939,7 @@ const transformVBind = (dir, node, context) => {
2856
2939
  value: exp,
2857
2940
  loc,
2858
2941
  runtimeCamelize: camel,
2859
- modifier: modifiersString.includes("prop") ? "." : modifiersString.includes("attr") ? "^" : undefined
2942
+ modifier: modifiersString.includes("prop") ? "." : modifiersString.includes("attr") ? "^" : void 0
2860
2943
  };
2861
2944
  };
2862
2945
 
@@ -2881,7 +2964,6 @@ const transformVOn = (dir, node, context) => {
2881
2964
  );
2882
2965
  let keyOverride;
2883
2966
  const isStaticClick = arg.isStatic && arg.content.toLowerCase() === "click";
2884
- const delegate = arg.isStatic && !eventOptionModifiers.length && delegatedEvents(arg.content);
2885
2967
  if (nonKeyModifiers.includes("middle")) {
2886
2968
  if (isStaticClick) {
2887
2969
  arg = shared.extend({}, arg, { content: "mouseup" });
@@ -2905,6 +2987,7 @@ const transformVOn = (dir, node, context) => {
2905
2987
  handlerModifiers: eventOptionModifiers
2906
2988
  };
2907
2989
  }
2990
+ const delegate = arg.isStatic && !eventOptionModifiers.length && delegatedEvents(arg.content);
2908
2991
  const operation = {
2909
2992
  type: 5,
2910
2993
  element: context.reference(),
@@ -2940,7 +3023,7 @@ const transformVShow = (dir, node, context) => {
2940
3023
  return;
2941
3024
  }
2942
3025
  context.registerOperation({
2943
- type: 14,
3026
+ type: 13,
2944
3027
  element: context.reference(),
2945
3028
  dir,
2946
3029
  name: "show",
@@ -2963,7 +3046,7 @@ const transformTemplateRef = (node, context) => {
2963
3046
  const id = context.reference();
2964
3047
  const effect = !isConstantExpression(value);
2965
3048
  effect && context.registerOperation({
2966
- type: 15,
3049
+ type: 14,
2967
3050
  id
2968
3051
  });
2969
3052
  context.registerEffect([value], {
@@ -2977,61 +3060,116 @@ const transformTemplateRef = (node, context) => {
2977
3060
  };
2978
3061
 
2979
3062
  const seen = /* @__PURE__ */ new WeakMap();
3063
+ function markNonTemplate(node, context) {
3064
+ seen.get(context.root).add(node);
3065
+ }
2980
3066
  const transformText = (node, context) => {
2981
3067
  if (!seen.has(context.root)) seen.set(context.root, /* @__PURE__ */ new WeakSet());
2982
3068
  if (seen.get(context.root).has(node)) {
2983
3069
  context.dynamic.flags |= 2;
2984
3070
  return;
2985
3071
  }
2986
- if (node.type === 1 && node.tagType === 0 && isAllTextLike(node.children)) {
2987
- processTextLikeContainer(
2988
- node.children,
2989
- context
2990
- );
3072
+ const isFragment = node.type === 0 || node.type === 1 && (node.tagType === 3 || node.tagType === 1);
3073
+ if ((isFragment || node.type === 1 && node.tagType === 0) && node.children.length) {
3074
+ let hasInterp = false;
3075
+ let isAllTextLike = true;
3076
+ for (const c of node.children) {
3077
+ if (c.type === 5) {
3078
+ hasInterp = true;
3079
+ } else if (c.type !== 2) {
3080
+ isAllTextLike = false;
3081
+ }
3082
+ }
3083
+ if (!isFragment && isAllTextLike && hasInterp) {
3084
+ processTextContainer(
3085
+ node.children,
3086
+ context
3087
+ );
3088
+ } else if (hasInterp) {
3089
+ for (let i = 0; i < node.children.length; i++) {
3090
+ const c = node.children[i];
3091
+ const prev = node.children[i - 1];
3092
+ if (c.type === 5 && prev && prev.type === 2) {
3093
+ markNonTemplate(prev, context);
3094
+ }
3095
+ }
3096
+ }
2991
3097
  } else if (node.type === 5) {
2992
- processTextLike(context);
3098
+ processInterpolation(context);
2993
3099
  } else if (node.type === 2) {
2994
3100
  context.template += node.content;
2995
3101
  }
2996
3102
  };
2997
- function processTextLike(context) {
2998
- const nexts = context.parent.node.children.slice(context.index);
3103
+ function processInterpolation(context) {
3104
+ const parentNode = context.parent.node;
3105
+ const children = parentNode.children;
3106
+ const nexts = children.slice(context.index);
2999
3107
  const idx = nexts.findIndex((n) => !isTextLike(n));
3000
3108
  const nodes = idx > -1 ? nexts.slice(0, idx) : nexts;
3109
+ const prev = children[context.index - 1];
3110
+ if (prev && prev.type === 2) {
3111
+ nodes.unshift(prev);
3112
+ }
3113
+ const values = processTextLikeChildren(nodes, context);
3114
+ if (values.length === 0 && parentNode.type !== 0) {
3115
+ return;
3116
+ }
3117
+ context.template += " ";
3001
3118
  const id = context.reference();
3002
- const values = nodes.map((node) => createTextLikeExpression(node, context));
3003
- context.dynamic.flags |= 4 | 2;
3004
- context.registerOperation({
3005
- type: 11,
3006
- id,
3007
- values,
3008
- effect: !values.every(isConstantExpression) && !context.inVOnce
3009
- });
3119
+ if (values.length === 0) {
3120
+ return;
3121
+ }
3122
+ const nonConstantExps = values.filter((v) => !isConstantExpression(v));
3123
+ const isStatic = !nonConstantExps.length || nonConstantExps.every(
3124
+ (e) => isStaticExpression(e, context.options.bindingMetadata)
3125
+ ) || context.inVOnce;
3126
+ if (isStatic) {
3127
+ context.registerOperation({
3128
+ type: 4,
3129
+ element: id,
3130
+ values
3131
+ });
3132
+ } else {
3133
+ context.registerEffect(values, {
3134
+ type: 4,
3135
+ element: id,
3136
+ values
3137
+ });
3138
+ }
3010
3139
  }
3011
- function processTextLikeContainer(children, context) {
3012
- const values = children.map((child) => createTextLikeExpression(child, context));
3140
+ function processTextContainer(children, context) {
3141
+ const values = processTextLikeChildren(children, context);
3013
3142
  const literals = values.map(getLiteralExpressionValue);
3014
3143
  if (literals.every((l) => l != null)) {
3015
3144
  context.childrenTemplate = literals.map((l) => String(l));
3016
3145
  } else {
3146
+ context.childrenTemplate = [" "];
3147
+ context.registerOperation({
3148
+ type: 17,
3149
+ parent: context.reference()
3150
+ });
3017
3151
  context.registerEffect(values, {
3018
3152
  type: 4,
3019
3153
  element: context.reference(),
3020
- values
3154
+ values,
3155
+ // indicates this node is generated, so prefix should be "x" instead of "n"
3156
+ generated: true
3021
3157
  });
3022
3158
  }
3023
3159
  }
3024
- function createTextLikeExpression(node, context) {
3025
- seen.get(context.root).add(node);
3026
- if (node.type === 2) {
3027
- return compilerDom.createSimpleExpression(node.content, true, node.loc);
3028
- } else {
3029
- return node.content;
3160
+ function processTextLikeChildren(nodes, context) {
3161
+ const exps = [];
3162
+ for (const node of nodes) {
3163
+ let exp;
3164
+ markNonTemplate(node, context);
3165
+ if (node.type === 2) {
3166
+ exp = compilerDom.createSimpleExpression(node.content, true, node.loc);
3167
+ } else {
3168
+ exp = node.content;
3169
+ }
3170
+ if (exp.content) exps.push(exp);
3030
3171
  }
3031
- }
3032
- function isAllTextLike(children) {
3033
- return !!children.length && children.every(isTextLike) && // at least one an interpolation
3034
- children.some((n) => n.type === 5);
3172
+ return exps;
3035
3173
  }
3036
3174
  function isTextLike(node) {
3037
3175
  return node.type === 5 || node.type === 2;
@@ -3095,7 +3233,7 @@ const transformVModel = (dir, node, context) => {
3095
3233
  modelType = "checkbox";
3096
3234
  break;
3097
3235
  case "file":
3098
- modelType = undefined;
3236
+ modelType = void 0;
3099
3237
  context.options.onError(
3100
3238
  compilerDom.createDOMCompilerError(
3101
3239
  59,
@@ -3128,7 +3266,7 @@ const transformVModel = (dir, node, context) => {
3128
3266
  }
3129
3267
  if (modelType)
3130
3268
  context.registerOperation({
3131
- type: 14,
3269
+ type: 13,
3132
3270
  element: context.reference(),
3133
3271
  dir,
3134
3272
  name: "model",
@@ -3198,29 +3336,38 @@ function processIf(node, dir, context) {
3198
3336
  const [branch, onExit] = createIfBranch(node, context);
3199
3337
  return () => {
3200
3338
  onExit();
3201
- context.registerOperation({
3202
- type: 16,
3339
+ context.dynamic.operation = {
3340
+ type: 15,
3203
3341
  id,
3204
3342
  condition: dir.exp,
3205
3343
  positive: branch,
3206
- once: context.inVOnce
3207
- });
3344
+ once: context.inVOnce || isStaticExpression(dir.exp, context.options.bindingMetadata)
3345
+ };
3208
3346
  };
3209
3347
  } else {
3210
3348
  const siblingIf = getSiblingIf(context, true);
3211
- const { operation } = context.block;
3212
- let lastIfNode = operation[operation.length - 1];
3349
+ const siblings = context.parent && context.parent.dynamic.children;
3350
+ let lastIfNode;
3351
+ if (siblings) {
3352
+ let i = siblings.length;
3353
+ while (i--) {
3354
+ if (siblings[i].operation && siblings[i].operation.type === 15) {
3355
+ lastIfNode = siblings[i].operation;
3356
+ break;
3357
+ }
3358
+ }
3359
+ }
3213
3360
  if (
3214
3361
  // check if v-if is the sibling node
3215
3362
  !siblingIf || // check if IfNode is the last operation and get the root IfNode
3216
- !lastIfNode || lastIfNode.type !== 16
3363
+ !lastIfNode || lastIfNode.type !== 15
3217
3364
  ) {
3218
3365
  context.options.onError(
3219
3366
  compilerDom.createCompilerError(30, node.loc)
3220
3367
  );
3221
3368
  return;
3222
3369
  }
3223
- while (lastIfNode.negative && lastIfNode.negative.type === 16) {
3370
+ while (lastIfNode.negative && lastIfNode.negative.type === 15) {
3224
3371
  lastIfNode = lastIfNode.negative;
3225
3372
  }
3226
3373
  if (dir.name === "else-if" && lastIfNode.negative) {
@@ -3240,7 +3387,7 @@ function processIf(node, dir, context) {
3240
3387
  lastIfNode.negative = branch;
3241
3388
  } else {
3242
3389
  lastIfNode.negative = {
3243
- type: 16,
3390
+ type: 15,
3244
3391
  id: -1,
3245
3392
  condition: dir.exp,
3246
3393
  positive: branch,
@@ -3288,8 +3435,10 @@ function processFor(node, dir, context) {
3288
3435
  context.reference();
3289
3436
  return () => {
3290
3437
  exitBlock();
3291
- context.registerOperation({
3292
- type: 17,
3438
+ const { parent } = context;
3439
+ const isOnlyChild = parent && parent.block.node !== parent.node && parent.node.children.length === 1;
3440
+ context.dynamic.operation = {
3441
+ type: 16,
3293
3442
  id,
3294
3443
  source,
3295
3444
  value,
@@ -3297,9 +3446,13 @@ function processFor(node, dir, context) {
3297
3446
  index,
3298
3447
  keyProp: keyProperty,
3299
3448
  render,
3300
- once: context.inVOnce,
3301
- component: isComponent
3302
- });
3449
+ once: context.inVOnce || isStaticExpression(
3450
+ source,
3451
+ context.options.bindingMetadata
3452
+ ),
3453
+ component: isComponent,
3454
+ onlyChild: !!isOnlyChild
3455
+ };
3303
3456
  };
3304
3457
  }
3305
3458
 
@@ -3319,16 +3472,16 @@ const transformSlotOutlet = (node, context) => {
3319
3472
  if (prop.type === 6) {
3320
3473
  if (prop.value) {
3321
3474
  if (prop.name === "name") {
3322
- slotName = createSimpleExpression(prop.value.content, true, prop.loc);
3475
+ slotName = compilerDom.createSimpleExpression(prop.value.content, true, prop.loc);
3323
3476
  } else {
3324
3477
  slotProps.push(shared.extend({}, prop, { name: shared.camelize(prop.name) }));
3325
3478
  }
3326
3479
  }
3327
- } else if (prop.name === "bind" && isStaticArgOf(prop.arg, "name")) {
3480
+ } else if (prop.name === "bind" && compilerDom.isStaticArgOf(prop.arg, "name")) {
3328
3481
  if (prop.exp) {
3329
3482
  slotName = prop.exp;
3330
3483
  } else {
3331
- slotName = createSimpleExpression(
3484
+ slotName = compilerDom.createSimpleExpression(
3332
3485
  shared.camelize(prop.arg.content),
3333
3486
  false,
3334
3487
  prop.arg.loc
@@ -3337,7 +3490,7 @@ const transformSlotOutlet = (node, context) => {
3337
3490
  }
3338
3491
  } else {
3339
3492
  let slotProp = prop;
3340
- if (slotProp.name === "bind" && slotProp.arg && isStaticExp(slotProp.arg)) {
3493
+ if (slotProp.name === "bind" && slotProp.arg && compilerDom.isStaticExp(slotProp.arg)) {
3341
3494
  slotProp = shared.extend({}, prop, {
3342
3495
  arg: shared.extend({}, slotProp.arg, {
3343
3496
  content: shared.camelize(slotProp.arg.content)
@@ -3347,7 +3500,7 @@ const transformSlotOutlet = (node, context) => {
3347
3500
  slotProps.push(slotProp);
3348
3501
  }
3349
3502
  }
3350
- slotName || (slotName = createSimpleExpression("default", true));
3503
+ slotName || (slotName = compilerDom.createSimpleExpression("default", true));
3351
3504
  let irProps = [];
3352
3505
  if (slotProps.length) {
3353
3506
  const [isDynamic, props] = buildProps(
@@ -3357,11 +3510,11 @@ const transformSlotOutlet = (node, context) => {
3357
3510
  );
3358
3511
  irProps = isDynamic ? props : [props];
3359
3512
  const runtimeDirective = context.block.operation.find(
3360
- (oper) => oper.type === 14 && oper.element === id
3513
+ (oper) => oper.type === 13 && oper.element === id
3361
3514
  );
3362
3515
  if (runtimeDirective) {
3363
3516
  context.options.onError(
3364
- createCompilerError(
3517
+ compilerDom.createCompilerError(
3365
3518
  36,
3366
3519
  runtimeDirective.dir.loc
3367
3520
  )
@@ -3370,13 +3523,13 @@ const transformSlotOutlet = (node, context) => {
3370
3523
  }
3371
3524
  return () => {
3372
3525
  exitBlock && exitBlock();
3373
- context.registerOperation({
3374
- type: 13,
3526
+ context.dynamic.operation = {
3527
+ type: 12,
3375
3528
  id,
3376
3529
  name: slotName,
3377
3530
  props: irProps,
3378
3531
  fallback
3379
- });
3532
+ };
3380
3533
  };
3381
3534
  };
3382
3535
  function createFallback(node, context) {
@@ -3402,7 +3555,7 @@ const transformVSlot = (node, context) => {
3402
3555
  const { tagType, children } = node;
3403
3556
  const { parent } = context;
3404
3557
  const isComponent = tagType === 1;
3405
- const isSlotTemplate = isTemplateNode(node) && parent && parent.node.type === 1 && parent.node.tagType === 1;
3558
+ const isSlotTemplate = compilerDom.isTemplateNode(node) && parent && parent.node.type === 1 && parent.node.tagType === 1;
3406
3559
  if (isComponent && children.length) {
3407
3560
  return transformComponentSlot(
3408
3561
  node,
@@ -3417,16 +3570,26 @@ const transformVSlot = (node, context) => {
3417
3570
  );
3418
3571
  } else if (!isComponent && dir) {
3419
3572
  context.options.onError(
3420
- createCompilerError(40, dir.loc)
3573
+ compilerDom.createCompilerError(40, dir.loc)
3421
3574
  );
3422
3575
  }
3423
3576
  };
3424
3577
  function transformComponentSlot(node, dir, context) {
3425
3578
  const { children } = node;
3426
3579
  const arg = dir && dir.arg;
3427
- const nonSlotTemplateChildren = children.filter(
3428
- (n) => isNonWhitespaceContent(node) && !(n.type === 1 && n.props.some(isVSlot))
3429
- );
3580
+ const emptyTextNodes = [];
3581
+ const nonSlotTemplateChildren = children.filter((n) => {
3582
+ if (isNonWhitespaceContent(n)) {
3583
+ return !(n.type === 1 && n.props.some(compilerDom.isVSlot));
3584
+ } else {
3585
+ emptyTextNodes.push(n);
3586
+ }
3587
+ });
3588
+ if (!nonSlotTemplateChildren.length) {
3589
+ emptyTextNodes.forEach((n) => {
3590
+ markNonTemplate(n, context);
3591
+ });
3592
+ }
3430
3593
  const [block, onExit] = createSlotBlock(node, dir, context);
3431
3594
  const { slots } = context;
3432
3595
  return () => {
@@ -3434,14 +3597,14 @@ function transformComponentSlot(node, dir, context) {
3434
3597
  const hasOtherSlots = !!slots.length;
3435
3598
  if (dir && hasOtherSlots) {
3436
3599
  context.options.onError(
3437
- createCompilerError(37, dir.loc)
3600
+ compilerDom.createCompilerError(37, dir.loc)
3438
3601
  );
3439
3602
  return;
3440
3603
  }
3441
3604
  if (nonSlotTemplateChildren.length) {
3442
3605
  if (hasStaticSlot(slots, "default")) {
3443
3606
  context.options.onError(
3444
- createCompilerError(
3607
+ compilerDom.createCompilerError(
3445
3608
  39,
3446
3609
  nonSlotTemplateChildren[0].loc
3447
3610
  )
@@ -3472,7 +3635,7 @@ function transformTemplateSlot(node, dir, context) {
3472
3635
  const slotName = arg ? arg.isStatic && arg.content : "default";
3473
3636
  if (slotName && hasStaticSlot(slots, slotName)) {
3474
3637
  context.options.onError(
3475
- createCompilerError(38, dir.loc)
3638
+ compilerDom.createCompilerError(38, dir.loc)
3476
3639
  );
3477
3640
  } else {
3478
3641
  registerSlot(slots, arg, block);
@@ -3509,7 +3672,7 @@ function transformTemplateSlot(node, dir, context) {
3509
3672
  ifNode.negative = negative;
3510
3673
  } else {
3511
3674
  context.options.onError(
3512
- createCompilerError(30, vElse.loc)
3675
+ compilerDom.createCompilerError(30, vElse.loc)
3513
3676
  );
3514
3677
  }
3515
3678
  } else if (vFor) {
@@ -3522,7 +3685,7 @@ function transformTemplateSlot(node, dir, context) {
3522
3685
  });
3523
3686
  } else {
3524
3687
  context.options.onError(
3525
- createCompilerError(32, vFor.loc)
3688
+ compilerDom.createCompilerError(32, vFor.loc)
3526
3689
  );
3527
3690
  }
3528
3691
  }
@@ -3611,8 +3774,8 @@ function getBaseTransformPreset() {
3611
3774
  transformVFor,
3612
3775
  transformSlotOutlet,
3613
3776
  transformTemplateRef,
3614
- transformText,
3615
3777
  transformElement,
3778
+ transformText,
3616
3779
  transformVSlot,
3617
3780
  transformComment,
3618
3781
  transformChildren
@@ -3628,74 +3791,6 @@ function getBaseTransformPreset() {
3628
3791
  ];
3629
3792
  }
3630
3793
 
3631
- const IRDynamicPropsKind = {
3632
- "EXPRESSION": 0,
3633
- "0": "EXPRESSION",
3634
- "ATTRIBUTE": 1,
3635
- "1": "ATTRIBUTE"
3636
- };
3637
- const IRSlotType = {
3638
- "STATIC": 0,
3639
- "0": "STATIC",
3640
- "DYNAMIC": 1,
3641
- "1": "DYNAMIC",
3642
- "LOOP": 2,
3643
- "2": "LOOP",
3644
- "CONDITIONAL": 3,
3645
- "3": "CONDITIONAL",
3646
- "EXPRESSION": 4,
3647
- "4": "EXPRESSION"
3648
- };
3649
-
3650
- const IRNodeTypes = {
3651
- "ROOT": 0,
3652
- "0": "ROOT",
3653
- "BLOCK": 1,
3654
- "1": "BLOCK",
3655
- "SET_PROP": 2,
3656
- "2": "SET_PROP",
3657
- "SET_DYNAMIC_PROPS": 3,
3658
- "3": "SET_DYNAMIC_PROPS",
3659
- "SET_TEXT": 4,
3660
- "4": "SET_TEXT",
3661
- "SET_EVENT": 5,
3662
- "5": "SET_EVENT",
3663
- "SET_DYNAMIC_EVENTS": 6,
3664
- "6": "SET_DYNAMIC_EVENTS",
3665
- "SET_HTML": 7,
3666
- "7": "SET_HTML",
3667
- "SET_TEMPLATE_REF": 8,
3668
- "8": "SET_TEMPLATE_REF",
3669
- "INSERT_NODE": 9,
3670
- "9": "INSERT_NODE",
3671
- "PREPEND_NODE": 10,
3672
- "10": "PREPEND_NODE",
3673
- "CREATE_TEXT_NODE": 11,
3674
- "11": "CREATE_TEXT_NODE",
3675
- "CREATE_COMPONENT_NODE": 12,
3676
- "12": "CREATE_COMPONENT_NODE",
3677
- "SLOT_OUTLET_NODE": 13,
3678
- "13": "SLOT_OUTLET_NODE",
3679
- "DIRECTIVE": 14,
3680
- "14": "DIRECTIVE",
3681
- "DECLARE_OLD_REF": 15,
3682
- "15": "DECLARE_OLD_REF",
3683
- "IF": 16,
3684
- "16": "IF",
3685
- "FOR": 17,
3686
- "17": "FOR"
3687
- };
3688
- const DynamicFlag = {
3689
- "NONE": 0,
3690
- "0": "NONE",
3691
- "REFERENCED": 1,
3692
- "1": "REFERENCED",
3693
- "NON_TEMPLATE": 2,
3694
- "2": "NON_TEMPLATE",
3695
- "INSERT": 4,
3696
- "4": "INSERT"
3697
- };
3698
-
3699
3794
  function createVaporCompilerError(code, loc) {
3700
3795
  return compilerDom.createCompilerError(
3701
3796
  code,
@@ -3731,6 +3826,7 @@ exports.createVaporCompilerError = createVaporCompilerError;
3731
3826
  exports.genCall = genCall;
3732
3827
  exports.genMulti = genMulti;
3733
3828
  exports.generate = generate;
3829
+ exports.isBlockOperation = isBlockOperation;
3734
3830
  exports.transform = transform;
3735
3831
  exports.transformChildren = transformChildren;
3736
3832
  exports.transformComment = transformComment;