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

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.1
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,8 +1079,68 @@ 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 patternFrag = [];
1088
+ for (let i = 0; i < selectorPatterns.length; i++) {
1089
+ const { selector } = selectorPatterns[i];
1090
+ const selectorName = `_selector${id}_${i}`;
1091
+ patternFrag.push(
1092
+ NEWLINE,
1093
+ `const ${selectorName} = `,
1094
+ ...genCall(`n${id}.useSelector`, [
1095
+ `() => `,
1096
+ ...genExpression(selector, context)
1097
+ ])
1098
+ );
1099
+ }
1100
+ const blockFn = context.withId(() => {
1101
+ const frag = [];
1102
+ frag.push("(", ...args, ") => {", INDENT_START);
1103
+ if (selectorPatterns.length || keyOnlyBindingPatterns.length) {
1104
+ frag.push(
1105
+ ...genBlockContent(render, context, false, () => {
1106
+ const patternFrag2 = [];
1107
+ for (let i = 0; i < selectorPatterns.length; i++) {
1108
+ const { effect } = selectorPatterns[i];
1109
+ patternFrag2.push(
1110
+ NEWLINE,
1111
+ `_selector${id}_${i}(() => {`,
1112
+ INDENT_START
1113
+ );
1114
+ for (const oper2 of effect.operations) {
1115
+ patternFrag2.push(...genOperation(oper2, context));
1116
+ }
1117
+ patternFrag2.push(INDENT_END, NEWLINE, `})`);
1118
+ }
1119
+ for (const { effect } of keyOnlyBindingPatterns) {
1120
+ for (const oper2 of effect.operations) {
1121
+ patternFrag2.push(...genOperation(oper2, context));
1122
+ }
1123
+ }
1124
+ return patternFrag2;
1125
+ })
1126
+ );
1127
+ } else {
1128
+ frag.push(...genBlockContent(render, context));
1129
+ }
1130
+ frag.push(INDENT_END, NEWLINE, "}");
1131
+ return frag;
1132
+ }, idMap);
911
1133
  exitScope();
1134
+ let flags = 0;
1135
+ if (onlyChild) {
1136
+ flags |= 1;
1137
+ }
1138
+ if (component) {
1139
+ flags |= 2;
1140
+ }
1141
+ if (once) {
1142
+ flags |= 4;
1143
+ }
912
1144
  return [
913
1145
  NEWLINE,
914
1146
  `const n${id} = `,
@@ -917,10 +1149,10 @@ function genFor(oper, context) {
917
1149
  sourceExpr,
918
1150
  blockFn,
919
1151
  genCallback(keyProp),
920
- component && "true",
921
- once && "true"
1152
+ flags ? String(flags) : void 0
922
1153
  // todo: hydrationNode
923
- )
1154
+ ),
1155
+ ...patternFrag
924
1156
  ];
925
1157
  function parseValueDestructure() {
926
1158
  const map = /* @__PURE__ */ new Map();
@@ -1002,8 +1234,8 @@ function genFor(oper, context) {
1002
1234
  return [
1003
1235
  ...genMulti(
1004
1236
  ["(", ")", ", "],
1005
- rawValue ? rawValue : rawKey || rawIndex ? "_" : undefined,
1006
- rawKey ? rawKey : rawIndex ? "__" : undefined,
1237
+ rawValue ? rawValue : rawKey || rawIndex ? "_" : void 0,
1238
+ rawKey ? rawKey : rawIndex ? "__" : void 0,
1007
1239
  rawIndex
1008
1240
  ),
1009
1241
  " => (",
@@ -1019,6 +1251,166 @@ function genFor(oper, context) {
1019
1251
  return idMap2;
1020
1252
  }
1021
1253
  }
1254
+ function matchPatterns(render, keyProp, idMap) {
1255
+ const selectorPatterns = [];
1256
+ const keyOnlyBindingPatterns = [];
1257
+ render.effect = render.effect.filter((effect) => {
1258
+ if (keyProp !== void 0) {
1259
+ const selector = matchSelectorPattern(effect, keyProp.ast, idMap);
1260
+ if (selector) {
1261
+ selectorPatterns.push(selector);
1262
+ return false;
1263
+ }
1264
+ const keyOnly = matchKeyOnlyBindingPattern(effect, keyProp.ast);
1265
+ if (keyOnly) {
1266
+ keyOnlyBindingPatterns.push(keyOnly);
1267
+ return false;
1268
+ }
1269
+ }
1270
+ return true;
1271
+ });
1272
+ return {
1273
+ keyOnlyBindingPatterns,
1274
+ selectorPatterns
1275
+ };
1276
+ }
1277
+ function matchKeyOnlyBindingPattern(effect, keyAst) {
1278
+ if (effect.expressions.length === 1) {
1279
+ const ast = effect.expressions[0].ast;
1280
+ if (typeof ast === "object" && ast !== null) {
1281
+ if (isKeyOnlyBinding(ast, keyAst)) {
1282
+ return { effect };
1283
+ }
1284
+ }
1285
+ }
1286
+ }
1287
+ function matchSelectorPattern(effect, keyAst, idMap) {
1288
+ if (effect.expressions.length === 1) {
1289
+ const ast = effect.expressions[0].ast;
1290
+ if (typeof ast === "object" && ast) {
1291
+ const matcheds = [];
1292
+ estreeWalker.walk(ast, {
1293
+ enter(node) {
1294
+ if (typeof node === "object" && node && node.type === "BinaryExpression" && node.operator === "===" && node.left.type !== "PrivateName") {
1295
+ const { left, right } = node;
1296
+ for (const [a, b] of [
1297
+ [left, right],
1298
+ [right, left]
1299
+ ]) {
1300
+ const aIsKey = isKeyOnlyBinding(a, keyAst);
1301
+ const bIsKey = isKeyOnlyBinding(b, keyAst);
1302
+ const bVars = analyzeVariableScopes(b, idMap);
1303
+ if (aIsKey && !bIsKey && !bVars.locals.length) {
1304
+ matcheds.push([a, b]);
1305
+ }
1306
+ }
1307
+ }
1308
+ }
1309
+ });
1310
+ if (matcheds.length === 1) {
1311
+ const [key, selector] = matcheds[0];
1312
+ const content2 = effect.expressions[0].content;
1313
+ let hasExtraId = false;
1314
+ const parentStackMap = /* @__PURE__ */ new Map();
1315
+ const parentStack = [];
1316
+ compilerDom.walkIdentifiers(
1317
+ ast,
1318
+ (id) => {
1319
+ if (id.start !== key.start && id.start !== selector.start) {
1320
+ hasExtraId = true;
1321
+ }
1322
+ parentStackMap.set(id, parentStack.slice());
1323
+ },
1324
+ false,
1325
+ parentStack
1326
+ );
1327
+ if (!hasExtraId) {
1328
+ const name = content2.slice(selector.start - 1, selector.end - 1);
1329
+ return {
1330
+ effect,
1331
+ // @ts-expect-error
1332
+ selector: {
1333
+ content: name,
1334
+ ast: shared.extend({}, selector, {
1335
+ start: 1,
1336
+ end: name.length + 1
1337
+ }),
1338
+ loc: selector.loc,
1339
+ isStatic: false
1340
+ }
1341
+ };
1342
+ }
1343
+ }
1344
+ }
1345
+ const content = effect.expressions[0].content;
1346
+ 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)) {
1347
+ const left = ast.test.left;
1348
+ const right = ast.test.right;
1349
+ for (const [a, b] of [
1350
+ [left, right],
1351
+ [right, left]
1352
+ ]) {
1353
+ const aIsKey = isKeyOnlyBinding(a, keyAst);
1354
+ const bIsKey = isKeyOnlyBinding(b, keyAst);
1355
+ const bVars = analyzeVariableScopes(b, idMap);
1356
+ if (aIsKey && !bIsKey && !bVars.locals.length) {
1357
+ return {
1358
+ effect,
1359
+ // @ts-expect-error
1360
+ selector: {
1361
+ content: content.slice(b.start - 1, b.end - 1),
1362
+ ast: b,
1363
+ loc: b.loc,
1364
+ isStatic: false
1365
+ }
1366
+ };
1367
+ }
1368
+ }
1369
+ }
1370
+ }
1371
+ }
1372
+ function analyzeVariableScopes(ast, idMap) {
1373
+ let globals = [];
1374
+ let locals = [];
1375
+ const ids = [];
1376
+ const parentStackMap = /* @__PURE__ */ new Map();
1377
+ const parentStack = [];
1378
+ compilerDom.walkIdentifiers(
1379
+ ast,
1380
+ (id) => {
1381
+ ids.push(id);
1382
+ parentStackMap.set(id, parentStack.slice());
1383
+ },
1384
+ false,
1385
+ parentStack
1386
+ );
1387
+ for (const id of ids) {
1388
+ if (shared.isGloballyAllowed(id.name)) {
1389
+ continue;
1390
+ }
1391
+ if (idMap[id.name]) {
1392
+ locals.push(id.name);
1393
+ } else {
1394
+ globals.push(id.name);
1395
+ }
1396
+ }
1397
+ return { globals, locals };
1398
+ }
1399
+ function isKeyOnlyBinding(expr, keyAst) {
1400
+ let only = true;
1401
+ estreeWalker.walk(expr, {
1402
+ enter(node) {
1403
+ if (types.isNodesEquivalent(node, keyAst)) {
1404
+ this.skip();
1405
+ return;
1406
+ }
1407
+ if (node.type === "Identifier") {
1408
+ only = false;
1409
+ }
1410
+ }
1411
+ });
1412
+ return only;
1413
+ }
1022
1414
 
1023
1415
  function genSetHtml(oper, context) {
1024
1416
  const { helper } = context;
@@ -1044,478 +1436,20 @@ function genIf(oper, context, isNested = false) {
1044
1436
  if (negative.type === 1) {
1045
1437
  negativeArg = genBlock(negative, context);
1046
1438
  } else {
1047
- negativeArg = ["() => ", ...genIf(negative, context, true)];
1048
- }
1049
- }
1050
- 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;
1439
+ negativeArg = ["() => ", ...genIf(negative, context, true)];
1440
+ }
1503
1441
  }
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
- })}`;
1442
+ if (!isNested) push(NEWLINE, `const n${oper.id} = `);
1443
+ push(
1444
+ ...genCall(
1445
+ helper("createIf"),
1446
+ conditionExpr,
1447
+ positiveArg,
1448
+ negativeArg,
1449
+ once && "true"
1450
+ )
1451
+ );
1452
+ return frag;
1519
1453
  }
1520
1454
 
1521
1455
  const helpers = {
@@ -1526,9 +1460,7 @@ const helpers = {
1526
1460
  setValue: { name: "setValue" },
1527
1461
  setAttr: { name: "setAttr", needKey: true },
1528
1462
  setProp: { name: "setProp", needKey: true },
1529
- setDOMProp: { name: "setDOMProp", needKey: true },
1530
- setDynamicProps: { name: "setDynamicProps" }
1531
- };
1463
+ setDOMProp: { name: "setDOMProp", needKey: true }};
1532
1464
  function genSetProp(oper, context) {
1533
1465
  const { helper } = context;
1534
1466
  const {
@@ -1579,7 +1511,7 @@ function genPropKey({ key: node, modifier, runtimeCamelize, handler, handlerModi
1579
1511
  const keyName = (handler ? shared.toHandlerKey(node.content) : node.content) + handlerModifierPostfix;
1580
1512
  return [
1581
1513
  [
1582
- isSimpleIdentifier(keyName) ? keyName : JSON.stringify(keyName),
1514
+ compilerDom.isSimpleIdentifier(keyName) ? keyName : JSON.stringify(keyName),
1583
1515
  -2,
1584
1516
  node.loc
1585
1517
  ]
@@ -1596,7 +1528,7 @@ function genPropKey({ key: node, modifier, runtimeCamelize, handler, handlerModi
1596
1528
  "[",
1597
1529
  modifier && `${JSON.stringify(modifier)} + `,
1598
1530
  ...key,
1599
- handlerModifierPostfix ? ` + ${JSON.stringify(handlerModifierPostfix)}` : undefined,
1531
+ handlerModifierPostfix ? ` + ${JSON.stringify(handlerModifierPostfix)}` : void 0,
1600
1532
  "]"
1601
1533
  ];
1602
1534
  }
@@ -1656,8 +1588,8 @@ function genSetTemplateRef(oper, context) {
1656
1588
  setTemplateRefIdent,
1657
1589
  // will be generated in root scope
1658
1590
  `n${oper.element}`,
1659
- genExpression(oper.value, context),
1660
- oper.effect ? `r${oper.element}` : oper.refFor ? "void 0" : undefined,
1591
+ genRefValue(oper.value, context),
1592
+ oper.effect ? `r${oper.element}` : oper.refFor ? "void 0" : void 0,
1661
1593
  oper.refFor && "true"
1662
1594
  )
1663
1595
  ];
@@ -1665,26 +1597,41 @@ function genSetTemplateRef(oper, context) {
1665
1597
  function genDeclareOldRef(oper) {
1666
1598
  return [NEWLINE, `let r${oper.id}`];
1667
1599
  }
1600
+ function genRefValue(value, context) {
1601
+ if (value && context.options.inline) {
1602
+ const binding = context.options.bindingMetadata[value.content];
1603
+ if (binding === "setup-let" || binding === "setup-ref" || binding === "setup-maybe-ref") {
1604
+ return [value.content];
1605
+ }
1606
+ }
1607
+ return genExpression(value, context);
1608
+ }
1668
1609
 
1669
1610
  function genSetText(oper, context) {
1670
1611
  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)];
1612
+ const { element, values, generated, jsx } = oper;
1613
+ const texts = combineValues(values, context, jsx);
1614
+ return [
1615
+ NEWLINE,
1616
+ ...genCall(helper("setText"), `${generated ? "x" : "n"}${element}`, texts)
1617
+ ];
1674
1618
  }
1675
- function genCreateTextNode(oper, context) {
1676
- const { helper } = context;
1677
- const { id, values, effect } = oper;
1619
+ function combineValues(values, context, jsx) {
1620
+ return values.flatMap((value, i) => {
1621
+ let exp = genExpression(value, context);
1622
+ if (!jsx && getLiteralExpressionValue(value) == null) {
1623
+ exp = genCall(context.helper("toDisplayString"), exp);
1624
+ }
1625
+ if (i > 0) {
1626
+ exp.unshift(jsx ? ", " : " + ");
1627
+ }
1628
+ return exp;
1629
+ });
1630
+ }
1631
+ function genGetTextChild(oper, context) {
1678
1632
  return [
1679
1633
  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
- ])
1634
+ `const x${oper.parent} = ${context.helper("child")}(n${oper.parent})`
1688
1635
  ];
1689
1636
  }
1690
1637
 
@@ -1722,7 +1669,7 @@ function genVModel(oper, context) {
1722
1669
  // setter
1723
1670
  genModelHandler(exp, context),
1724
1671
  // modifiers
1725
- modifiers.length ? `{ ${modifiers.map((e) => e.content + ": true").join(",")} }` : undefined
1672
+ modifiers.length ? `{ ${modifiers.map((e) => e.content + ": true").join(",")} }` : void 0
1726
1673
  )
1727
1674
  ];
1728
1675
  }
@@ -1755,7 +1702,6 @@ function genCustomDirectives(opers, context) {
1755
1702
  const directives = genMulti(DELIMITERS_ARRAY, ...directiveItems);
1756
1703
  return [
1757
1704
  NEWLINE,
1758
- // @ts-expect-error
1759
1705
  ...genCall(helper("withVaporDirectives"), element, directives)
1760
1706
  ];
1761
1707
  function genDirectiveItem({
@@ -1790,7 +1736,7 @@ function genDirectiveModifiers(modifiers) {
1790
1736
  }
1791
1737
  function filterCustomDirectives(id, operations) {
1792
1738
  return operations.filter(
1793
- (oper) => oper.type === 14 && oper.element === id && !oper.builtin
1739
+ (oper) => oper.type === 13 && oper.element === id && !oper.builtin
1794
1740
  );
1795
1741
  }
1796
1742
 
@@ -1803,7 +1749,7 @@ function genCreateComponent(operation, context) {
1803
1749
  const rawProps = context.withId(() => genRawProps(props, context), ids);
1804
1750
  const inlineHandlers = handlers.reduce(
1805
1751
  (acc, { name, value }) => {
1806
- const handler = genEventHandler(context, value, undefined, false);
1752
+ const handler = genEventHandler(context, value, void 0, false);
1807
1753
  return [...acc, `const ${name} = `, ...handler, NEWLINE];
1808
1754
  },
1809
1755
  []
@@ -1833,10 +1779,10 @@ function genCreateComponent(operation, context) {
1833
1779
  return ["() => (", ...genExpression(operation.dynamic, context), ")"];
1834
1780
  }
1835
1781
  } else if (operation.asset) {
1836
- return toValidAssetId(operation.tag, "component");
1782
+ return compilerDom.toValidAssetId(operation.tag, "component");
1837
1783
  } else {
1838
1784
  return genExpression(
1839
- shared.extend(createSimpleExpression(operation.tag, false), { ast: null }),
1785
+ shared.extend(compilerDom.createSimpleExpression(operation.tag, false), { ast: null }),
1840
1786
  context
1841
1787
  );
1842
1788
  }
@@ -1857,12 +1803,12 @@ function processInlineHandlers(props, context) {
1857
1803
  const prop = staticProps[i];
1858
1804
  if (!prop.handler) continue;
1859
1805
  prop.values.forEach((value, i2) => {
1860
- const isMemberExp = isMemberExpression(value, context.options);
1806
+ const isMemberExp = compilerDom.isMemberExpression(value, context.options);
1861
1807
  if (!isMemberExp) {
1862
1808
  const name = getUniqueHandlerName(context, `_on_${prop.key.content}`);
1863
1809
  handlers.push({ name, value });
1864
1810
  ids[name] = null;
1865
- prop.values[i2] = shared.extend({ ast: null }, createSimpleExpression(name));
1811
+ prop.values[i2] = shared.extend({ ast: null }, compilerDom.createSimpleExpression(name));
1866
1812
  }
1867
1813
  });
1868
1814
  }
@@ -1923,7 +1869,12 @@ function genProp(prop, context, isStatic) {
1923
1869
  return [
1924
1870
  ...genPropKey(prop, context),
1925
1871
  ": ",
1926
- ...prop.handler ? genEventHandler(context, prop.values[0]) : isStatic ? ["() => (", ...values, ")"] : values,
1872
+ ...prop.handler ? genEventHandler(
1873
+ context,
1874
+ prop.values[0],
1875
+ void 0,
1876
+ true
1877
+ ) : isStatic ? ["() => (", ...values, ")"] : values,
1927
1878
  ...prop.model ? [...genModelEvent(prop, context), ...genModelModifiers(prop, context)] : []
1928
1879
  ];
1929
1880
  }
@@ -1946,11 +1897,11 @@ function genRawSlots(slots, context) {
1946
1897
  return genStaticSlots(
1947
1898
  staticSlots,
1948
1899
  context,
1949
- slots.length > 1 ? slots.slice(1) : undefined
1900
+ slots.length > 1 ? slots.slice(1) : void 0
1950
1901
  );
1951
1902
  } else {
1952
1903
  return genStaticSlots(
1953
- { slotType: 0, slots: {} },
1904
+ { slots: {} },
1954
1905
  context,
1955
1906
  slots
1956
1907
  );
@@ -2022,8 +1973,8 @@ function genLoopSlot(slot, context) {
2022
1973
  [
2023
1974
  ...genMulti(
2024
1975
  ["(", ")", ", "],
2025
- rawValue ? rawValue : rawKey || rawIndex ? "_" : undefined,
2026
- rawKey ? rawKey : rawIndex ? "__" : undefined,
1976
+ rawValue ? rawValue : rawKey || rawIndex ? "_" : void 0,
1977
+ rawKey ? rawKey : rawIndex ? "__" : void 0,
2027
1978
  rawIndex
2028
1979
  ),
2029
1980
  " => (",
@@ -2060,7 +2011,7 @@ function genSlotBlockWithProps(oper, context) {
2060
2011
  if (isDestructureAssignment = !!props.ast) {
2061
2012
  [depth, exitScope] = context.enterScope();
2062
2013
  propsName = `_slotProps${depth}`;
2063
- walkIdentifiers(
2014
+ compilerDom.walkIdentifiers(
2064
2015
  props.ast,
2065
2016
  (id, _, __, ___, isLocal) => {
2066
2017
  if (isLocal) idsOfProps.add(id.name);
@@ -2108,8 +2059,16 @@ function genSlotOutlet(oper, context) {
2108
2059
  function genOperations(opers, context) {
2109
2060
  const [frag, push] = buildCodeFragment();
2110
2061
  for (const operation of opers) {
2111
- push(...genOperation(operation, context));
2062
+ push(...genOperationWithInsertionState(operation, context));
2063
+ }
2064
+ return frag;
2065
+ }
2066
+ function genOperationWithInsertionState(oper, context) {
2067
+ const [frag, push] = buildCodeFragment();
2068
+ if (isBlockOperation(oper) && oper.parent) {
2069
+ push(...genInsertionState(oper, context));
2112
2070
  }
2071
+ push(...genOperation(oper, context));
2113
2072
  return frag;
2114
2073
  }
2115
2074
  function genOperation(oper, context) {
@@ -2128,24 +2087,24 @@ function genOperation(oper, context) {
2128
2087
  return genSetHtml(oper, context);
2129
2088
  case 8:
2130
2089
  return genSetTemplateRef(oper, context);
2131
- case 11:
2132
- return genCreateTextNode(oper, context);
2133
2090
  case 9:
2134
2091
  return genInsertNode(oper, context);
2135
2092
  case 10:
2136
2093
  return genPrependNode(oper, context);
2137
- case 16:
2094
+ case 15:
2138
2095
  return genIf(oper, context);
2139
- case 17:
2096
+ case 16:
2140
2097
  return genFor(oper, context);
2141
- case 12:
2098
+ case 11:
2142
2099
  return genCreateComponent(oper, context);
2143
- case 15:
2100
+ case 14:
2144
2101
  return genDeclareOldRef(oper);
2145
- case 13:
2102
+ case 12:
2146
2103
  return genSlotOutlet(oper, context);
2147
- case 14:
2104
+ case 13:
2148
2105
  return genBuiltinDirective(oper, context);
2106
+ case 17:
2107
+ return genGetTextChild(oper, context);
2149
2108
  default:
2150
2109
  const exhaustiveCheck = oper;
2151
2110
  throw new Error(
@@ -2153,17 +2112,17 @@ function genOperation(oper, context) {
2153
2112
  );
2154
2113
  }
2155
2114
  }
2156
- function genEffects(effects, context) {
2157
- const {
2158
- helper,
2159
- block: { expressions }
2160
- } = context;
2115
+ function genEffects(effects, context, genExtraFrag) {
2116
+ const { helper } = context;
2117
+ const expressions = effects.flatMap((effect) => effect.expressions);
2161
2118
  const [frag, push, unshift] = buildCodeFragment();
2119
+ const shouldDeclare = genExtraFrag === void 0;
2162
2120
  let operationsCount = 0;
2163
- const { ids, frag: declarationFrags } = processExpressions(
2164
- context,
2165
- expressions
2166
- );
2121
+ const {
2122
+ ids,
2123
+ frag: declarationFrags,
2124
+ varNames
2125
+ } = processExpressions(context, expressions, shouldDeclare);
2167
2126
  push(...declarationFrags);
2168
2127
  for (let i = 0; i < effects.length; i++) {
2169
2128
  const effect = effects[i];
@@ -2179,11 +2138,20 @@ function genEffects(effects, context) {
2179
2138
  if (newLineCount > 1 || operationsCount > 1 || declarationFrags.length > 0) {
2180
2139
  unshift(`{`, INDENT_START, NEWLINE);
2181
2140
  push(INDENT_END, NEWLINE, "}");
2141
+ if (!effects.length) {
2142
+ unshift(NEWLINE);
2143
+ }
2182
2144
  }
2183
2145
  if (effects.length) {
2184
2146
  unshift(NEWLINE, `${helper("renderEffect")}(() => `);
2185
2147
  push(`)`);
2186
2148
  }
2149
+ if (!shouldDeclare && varNames.length) {
2150
+ unshift(NEWLINE, `let `, varNames.join(", "));
2151
+ }
2152
+ if (genExtraFrag) {
2153
+ push(...context.withId(genExtraFrag, ids));
2154
+ }
2187
2155
  return frag;
2188
2156
  }
2189
2157
  function genEffect({ operations }, context) {
@@ -2197,6 +2165,16 @@ function genEffect({ operations }, context) {
2197
2165
  }
2198
2166
  return frag;
2199
2167
  }
2168
+ function genInsertionState(operation, context) {
2169
+ return [
2170
+ NEWLINE,
2171
+ ...genCall(
2172
+ context.helper("setInsertionState"),
2173
+ `n${operation.parent}`,
2174
+ operation.anchor == null ? void 0 : operation.anchor === -1 ? `0` : `n${operation.anchor}`
2175
+ )
2176
+ ];
2177
+ }
2200
2178
 
2201
2179
  function genTemplates(templates, rootIndex, { helper }) {
2202
2180
  return templates.map(
@@ -2206,52 +2184,74 @@ function genTemplates(templates, rootIndex, { helper }) {
2206
2184
  `
2207
2185
  ).join("");
2208
2186
  }
2209
- function genChildren(dynamic, context, from, paths = []) {
2210
- const { helper } = context;
2187
+ function genSelf(dynamic, context) {
2211
2188
  const [frag, push] = buildCodeFragment();
2212
- let offset = 0;
2213
- const { children, id, template } = dynamic;
2214
- if (id !== undefined && template !== undefined) {
2189
+ const { id, template, operation } = dynamic;
2190
+ if (id !== void 0 && template !== void 0) {
2215
2191
  push(NEWLINE, `const n${id} = t${template}()`);
2216
2192
  push(...genDirectivesForElement(id, context));
2217
2193
  }
2194
+ if (operation) {
2195
+ push(...genOperationWithInsertionState(operation, context));
2196
+ }
2197
+ return frag;
2198
+ }
2199
+ function genChildren(dynamic, context, pushBlock, from = `n${dynamic.id}`) {
2200
+ const { helper } = context;
2201
+ const [frag, push] = buildCodeFragment();
2202
+ const { children } = dynamic;
2203
+ let offset = 0;
2218
2204
  let prev;
2205
+ const childrenToGen = [];
2219
2206
  for (const [index, child] of children.entries()) {
2220
2207
  if (child.flags & 2) {
2221
2208
  offset--;
2222
2209
  }
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));
2210
+ const id = child.flags & 1 ? child.flags & 4 ? child.anchor : child.id : void 0;
2211
+ if (id === void 0 && !child.hasDynamicChild) {
2212
+ push(...genSelf(child, context));
2228
2213
  continue;
2229
2214
  }
2230
- push(NEWLINE, `const n${id2} = `);
2215
+ const elementIndex = Number(index) + offset;
2216
+ const variable = id === void 0 ? `p${context.block.tempId++}` : `n${id}`;
2217
+ pushBlock(NEWLINE, `const ${variable} = `);
2231
2218
  if (prev) {
2232
- const offset2 = elementIndex - prev[1];
2233
- if (offset2 === 1) {
2234
- push(`n${prev[0]}.nextSibling`);
2219
+ if (elementIndex - prev[1] === 1) {
2220
+ pushBlock(...genCall(helper("next"), prev[0]));
2235
2221
  } else {
2236
- push(...genCall(helper("next"), `n${prev[0]}`, String(offset2)));
2222
+ pushBlock(...genCall(helper("nthChild"), from, String(elementIndex)));
2237
2223
  }
2238
2224
  } else {
2239
- if (newPaths.length === 1 && newPaths[0] === 0) {
2240
- push(`n${from}.firstChild`);
2225
+ if (elementIndex === 0) {
2226
+ pushBlock(...genCall(helper("child"), from));
2241
2227
  } else {
2242
- push(
2243
- ...genCall(helper("children"), `n${from}`, ...newPaths.map(String))
2244
- );
2228
+ let init = genCall(helper("child"), from);
2229
+ if (elementIndex === 1) {
2230
+ init = genCall(helper("next"), init);
2231
+ } else if (elementIndex > 1) {
2232
+ init = genCall(helper("nthChild"), from, String(elementIndex));
2233
+ }
2234
+ pushBlock(...init);
2245
2235
  }
2246
2236
  }
2247
- push(...genDirectivesForElement(id2, context));
2248
- prev = [id2, elementIndex];
2249
- push(...genChildren(child, context, id2, []));
2237
+ if (id === child.anchor) {
2238
+ push(...genSelf(child, context));
2239
+ }
2240
+ if (id !== void 0) {
2241
+ push(...genDirectivesForElement(id, context));
2242
+ }
2243
+ prev = [variable, elementIndex];
2244
+ childrenToGen.push([child, variable]);
2245
+ }
2246
+ if (childrenToGen.length) {
2247
+ for (const [child, from2] of childrenToGen) {
2248
+ push(...genChildren(child, context, pushBlock, from2));
2249
+ }
2250
2250
  }
2251
2251
  return frag;
2252
2252
  }
2253
2253
 
2254
- function genBlock(oper, context, args = [], root, customReturns) {
2254
+ function genBlock(oper, context, args = [], root) {
2255
2255
  return [
2256
2256
  "(",
2257
2257
  ...args,
@@ -2263,19 +2263,36 @@ function genBlock(oper, context, args = [], root, customReturns) {
2263
2263
  "}"
2264
2264
  ];
2265
2265
  }
2266
- function genBlockContent(block, context, root, customReturns) {
2266
+ function genBlockContent(block, context, root, genEffectsExtraFrag) {
2267
2267
  const [frag, push] = buildCodeFragment();
2268
2268
  const { dynamic, effect, operation, returns } = block;
2269
2269
  const resetBlock = context.enterBlock(block);
2270
2270
  if (root) {
2271
- genResolveAssets("component", "resolveComponent");
2271
+ for (let name of context.ir.component) {
2272
+ const id = compilerDom.toValidAssetId(name, "component");
2273
+ const maybeSelfReference = name.endsWith("__self");
2274
+ if (maybeSelfReference) name = name.slice(0, -6);
2275
+ push(
2276
+ NEWLINE,
2277
+ `const ${id} = `,
2278
+ ...genCall(
2279
+ context.helper("resolveComponent"),
2280
+ JSON.stringify(name),
2281
+ // pass additional `maybeSelfReference` flag
2282
+ maybeSelfReference ? "true" : void 0
2283
+ )
2284
+ );
2285
+ }
2272
2286
  genResolveAssets("directive", "resolveDirective");
2273
2287
  }
2274
2288
  for (const child of dynamic.children) {
2275
- push(...genChildren(child, context, child.id));
2289
+ push(...genSelf(child, context));
2290
+ }
2291
+ for (const child of dynamic.children) {
2292
+ push(...genChildren(child, context, push, `n${child.id}`));
2276
2293
  }
2277
2294
  push(...genOperations(operation, context));
2278
- push(...genEffects(effect, context));
2295
+ push(...genEffects(effect, context, genEffectsExtraFrag));
2279
2296
  push(NEWLINE, `return `);
2280
2297
  const returnNodes = returns.map((n) => `n${n}`);
2281
2298
  const returnsCode = returnNodes.length > 1 ? genMulti(DELIMITERS_ARRAY, ...returnNodes) : [returnNodes[0] || "null"];
@@ -2413,16 +2430,20 @@ const transformChildren = (node, context) => {
2413
2430
  for (const [i, child] of node.children.entries()) {
2414
2431
  const childContext = context.create(child, i);
2415
2432
  transformNode(childContext);
2433
+ const childDynamic = childContext.dynamic;
2416
2434
  if (isFragment) {
2417
2435
  childContext.reference();
2418
2436
  childContext.registerTemplate();
2419
- if (!(childContext.dynamic.flags & 2) || childContext.dynamic.flags & 4) {
2437
+ if (!(childDynamic.flags & 2) || childDynamic.flags & 4) {
2420
2438
  context.block.returns.push(childContext.dynamic.id);
2421
2439
  }
2422
2440
  } else {
2423
2441
  context.childrenTemplate.push(childContext.template);
2424
2442
  }
2425
- context.dynamic.children[i] = childContext.dynamic;
2443
+ if (childDynamic.hasDynamicChild || childDynamic.id !== void 0 || childDynamic.flags & 2 || childDynamic.flags & 4) {
2444
+ context.dynamic.hasDynamicChild = true;
2445
+ }
2446
+ context.dynamic.children[i] = childDynamic;
2426
2447
  }
2427
2448
  if (!isFragment) {
2428
2449
  processDynamicChildren(context);
@@ -2442,18 +2463,14 @@ function processDynamicChildren(context) {
2442
2463
  context.childrenTemplate[index - prevDynamics.length] = `<!>`;
2443
2464
  prevDynamics[0].flags -= 2;
2444
2465
  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
- });
2466
+ registerInsertion(prevDynamics, context, anchor);
2451
2467
  } else {
2452
- context.registerOperation({
2453
- type: 10,
2454
- elements: prevDynamics.map((child2) => child2.id),
2455
- parent: context.reference()
2456
- });
2468
+ registerInsertion(
2469
+ prevDynamics,
2470
+ context,
2471
+ -1
2472
+ /* prepend */
2473
+ );
2457
2474
  }
2458
2475
  prevDynamics = [];
2459
2476
  }
@@ -2461,11 +2478,22 @@ function processDynamicChildren(context) {
2461
2478
  }
2462
2479
  }
2463
2480
  if (prevDynamics.length) {
2464
- context.registerOperation({
2465
- type: 9,
2466
- elements: prevDynamics.map((child) => child.id),
2467
- parent: context.reference()
2468
- });
2481
+ registerInsertion(prevDynamics, context);
2482
+ }
2483
+ }
2484
+ function registerInsertion(dynamics, context, anchor) {
2485
+ for (const child of dynamics) {
2486
+ if (child.template != null) {
2487
+ context.registerOperation({
2488
+ type: 9,
2489
+ elements: dynamics.map((child2) => child2.id),
2490
+ parent: context.reference(),
2491
+ anchor
2492
+ });
2493
+ } else if (child.operation && isBlockOperation(child.operation)) {
2494
+ child.operation.parent = context.reference();
2495
+ child.operation.anchor = anchor;
2496
+ }
2469
2497
  }
2470
2498
  }
2471
2499
 
@@ -2483,6 +2511,8 @@ const isReservedProp = /* @__PURE__ */ shared.makeMap(
2483
2511
  ",key,ref,ref_for,ref_key,"
2484
2512
  );
2485
2513
  const transformElement = (node, context) => {
2514
+ let effectIndex = context.block.effect.length;
2515
+ const getEffectIndex = () => effectIndex++;
2486
2516
  return function postTransformElement() {
2487
2517
  ({ node } = context);
2488
2518
  if (!(node.type === 1 && (node.tagType === 0 || node.tagType === 1)))
@@ -2493,24 +2523,35 @@ const transformElement = (node, context) => {
2493
2523
  node,
2494
2524
  context,
2495
2525
  isComponent,
2496
- isDynamicComponent
2526
+ isDynamicComponent,
2527
+ getEffectIndex
2497
2528
  );
2498
2529
  let { parent } = context;
2499
2530
  while (parent && parent.parent && parent.node.type === 1 && parent.node.tagType === 3) {
2500
2531
  parent = parent.parent;
2501
2532
  }
2502
2533
  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
- );
2534
+ if (isComponent) {
2535
+ transformComponentElement(
2536
+ node,
2537
+ propsResult,
2538
+ singleRoot,
2539
+ context,
2540
+ isDynamicComponent
2541
+ );
2542
+ } else {
2543
+ transformNativeElement(
2544
+ node,
2545
+ propsResult,
2546
+ singleRoot,
2547
+ context,
2548
+ getEffectIndex
2549
+ );
2550
+ }
2510
2551
  };
2511
2552
  };
2512
2553
  function transformComponentElement(node, propsResult, singleRoot, context, isDynamicComponent) {
2513
- const dynamicComponent = isDynamicComponent ? resolveDynamicComponent(node) : undefined;
2554
+ const dynamicComponent = isDynamicComponent ? resolveDynamicComponent(node) : void 0;
2514
2555
  let { tag } = node;
2515
2556
  let asset = true;
2516
2557
  if (!dynamicComponent) {
@@ -2528,21 +2569,24 @@ function transformComponentElement(node, propsResult, singleRoot, context, isDyn
2528
2569
  }
2529
2570
  }
2530
2571
  if (asset) {
2572
+ if (context.selfName && shared.capitalize(shared.camelize(tag)) === context.selfName) {
2573
+ tag += `__self`;
2574
+ }
2531
2575
  context.component.add(tag);
2532
2576
  }
2533
2577
  }
2534
2578
  context.dynamic.flags |= 2 | 4;
2535
- context.registerOperation({
2536
- type: 12,
2579
+ context.dynamic.operation = {
2580
+ type: 11,
2537
2581
  id: context.reference(),
2538
2582
  tag,
2539
2583
  props: propsResult[0] ? propsResult[1] : [propsResult[1]],
2540
2584
  asset,
2541
- root: singleRoot,
2585
+ root: singleRoot && !context.inVFor,
2542
2586
  slots: [...context.slots],
2543
2587
  once: context.inVOnce,
2544
2588
  dynamic: dynamicComponent
2545
- });
2589
+ };
2546
2590
  context.slots = [];
2547
2591
  }
2548
2592
  function resolveDynamicComponent(node) {
@@ -2570,9 +2614,9 @@ function resolveSetupReference(name, context) {
2570
2614
  }
2571
2615
  const camelName = shared.camelize(name);
2572
2616
  const PascalName = shared.capitalize(camelName);
2573
- return bindings[name] ? name : bindings[camelName] ? camelName : bindings[PascalName] ? PascalName : undefined;
2617
+ return bindings[name] ? name : bindings[camelName] ? camelName : bindings[PascalName] ? PascalName : void 0;
2574
2618
  }
2575
- function transformNativeElement(node, propsResult, singleRoot, context) {
2619
+ function transformNativeElement(node, propsResult, singleRoot, context, getEffectIndex) {
2576
2620
  const { tag } = node;
2577
2621
  const { scopeId } = context.options;
2578
2622
  let template = "";
@@ -2581,12 +2625,16 @@ function transformNativeElement(node, propsResult, singleRoot, context) {
2581
2625
  const dynamicProps = [];
2582
2626
  if (propsResult[0]) {
2583
2627
  const [, dynamicArgs, expressions] = propsResult;
2584
- context.registerEffect(expressions, {
2585
- type: 3,
2586
- element: context.reference(),
2587
- props: dynamicArgs,
2588
- root: singleRoot
2589
- });
2628
+ context.registerEffect(
2629
+ expressions,
2630
+ {
2631
+ type: 3,
2632
+ element: context.reference(),
2633
+ props: dynamicArgs,
2634
+ root: singleRoot
2635
+ },
2636
+ getEffectIndex
2637
+ );
2590
2638
  } else {
2591
2639
  for (const prop of propsResult[1]) {
2592
2640
  const { key, values } = prop;
@@ -2595,13 +2643,17 @@ function transformNativeElement(node, propsResult, singleRoot, context) {
2595
2643
  if (values[0].content) template += `="${values[0].content}"`;
2596
2644
  } else {
2597
2645
  dynamicProps.push(key.content);
2598
- context.registerEffect(values, {
2599
- type: 2,
2600
- element: context.reference(),
2601
- prop,
2602
- root: singleRoot,
2603
- tag
2604
- });
2646
+ context.registerEffect(
2647
+ values,
2648
+ {
2649
+ type: 2,
2650
+ element: context.reference(),
2651
+ prop,
2652
+ root: singleRoot,
2653
+ tag
2654
+ },
2655
+ getEffectIndex
2656
+ );
2605
2657
  }
2606
2658
  }
2607
2659
  }
@@ -2620,7 +2672,7 @@ function transformNativeElement(node, propsResult, singleRoot, context) {
2620
2672
  context.template += template;
2621
2673
  }
2622
2674
  }
2623
- function buildProps(node, context, isComponent, isDynamicComponent) {
2675
+ function buildProps(node, context, isComponent, isDynamicComponent, getEffectIndex) {
2624
2676
  const props = node.props;
2625
2677
  if (props.length === 0) return [false, []];
2626
2678
  const dynamicArgs = [];
@@ -2665,7 +2717,8 @@ function buildProps(node, context, isComponent, isDynamicComponent) {
2665
2717
  type: 6,
2666
2718
  element: context.reference(),
2667
2719
  event: prop.exp
2668
- }
2720
+ },
2721
+ getEffectIndex
2669
2722
  );
2670
2723
  }
2671
2724
  } else {
@@ -2722,7 +2775,7 @@ function transformProp(prop, node, context) {
2722
2775
  context.directive.add(name);
2723
2776
  }
2724
2777
  context.registerOperation({
2725
- type: 14,
2778
+ type: 13,
2726
2779
  element: context.reference(),
2727
2780
  dir: prop,
2728
2781
  name,
@@ -2754,7 +2807,7 @@ function dedupeProperties(results) {
2754
2807
  }
2755
2808
  function resolveDirectiveResult(prop) {
2756
2809
  return shared.extend({}, prop, {
2757
- value: undefined,
2810
+ value: void 0,
2758
2811
  values: [prop.value]
2759
2812
  });
2760
2813
  }
@@ -2787,6 +2840,17 @@ const transformVHtml = (dir, node, context) => {
2787
2840
  });
2788
2841
  };
2789
2842
 
2843
+ /*! #__NO_SIDE_EFFECTS__ */
2844
+ // @__NO_SIDE_EFFECTS__
2845
+ function makeMap(str) {
2846
+ const map = /* @__PURE__ */ Object.create(null);
2847
+ for (const key of str.split(",")) map[key] = 1;
2848
+ return (val) => val in map;
2849
+ }
2850
+
2851
+ const VOID_TAGS = "area,base,br,col,embed,hr,img,input,link,meta,param,source,track,wbr";
2852
+ const isVoidTag = /* @__PURE__ */ makeMap(VOID_TAGS);
2853
+
2790
2854
  const transformVText = (dir, node, context) => {
2791
2855
  let { exp, loc } = dir;
2792
2856
  if (!exp) {
@@ -2801,14 +2865,23 @@ const transformVText = (dir, node, context) => {
2801
2865
  );
2802
2866
  context.childrenTemplate.length = 0;
2803
2867
  }
2868
+ if (isVoidTag(context.node.tag)) {
2869
+ return;
2870
+ }
2804
2871
  const literal = getLiteralExpressionValue(exp);
2805
2872
  if (literal != null) {
2806
2873
  context.childrenTemplate = [String(literal)];
2807
2874
  } else {
2875
+ context.childrenTemplate = [" "];
2876
+ context.registerOperation({
2877
+ type: 17,
2878
+ parent: context.reference()
2879
+ });
2808
2880
  context.registerEffect([exp], {
2809
2881
  type: 4,
2810
2882
  element: context.reference(),
2811
- values: [exp]
2883
+ values: [exp],
2884
+ generated: true
2812
2885
  });
2813
2886
  }
2814
2887
  };
@@ -2856,7 +2929,7 @@ const transformVBind = (dir, node, context) => {
2856
2929
  value: exp,
2857
2930
  loc,
2858
2931
  runtimeCamelize: camel,
2859
- modifier: modifiersString.includes("prop") ? "." : modifiersString.includes("attr") ? "^" : undefined
2932
+ modifier: modifiersString.includes("prop") ? "." : modifiersString.includes("attr") ? "^" : void 0
2860
2933
  };
2861
2934
  };
2862
2935
 
@@ -2881,7 +2954,6 @@ const transformVOn = (dir, node, context) => {
2881
2954
  );
2882
2955
  let keyOverride;
2883
2956
  const isStaticClick = arg.isStatic && arg.content.toLowerCase() === "click";
2884
- const delegate = arg.isStatic && !eventOptionModifiers.length && delegatedEvents(arg.content);
2885
2957
  if (nonKeyModifiers.includes("middle")) {
2886
2958
  if (isStaticClick) {
2887
2959
  arg = shared.extend({}, arg, { content: "mouseup" });
@@ -2905,6 +2977,7 @@ const transformVOn = (dir, node, context) => {
2905
2977
  handlerModifiers: eventOptionModifiers
2906
2978
  };
2907
2979
  }
2980
+ const delegate = arg.isStatic && !eventOptionModifiers.length && delegatedEvents(arg.content);
2908
2981
  const operation = {
2909
2982
  type: 5,
2910
2983
  element: context.reference(),
@@ -2940,7 +3013,7 @@ const transformVShow = (dir, node, context) => {
2940
3013
  return;
2941
3014
  }
2942
3015
  context.registerOperation({
2943
- type: 14,
3016
+ type: 13,
2944
3017
  element: context.reference(),
2945
3018
  dir,
2946
3019
  name: "show",
@@ -2963,7 +3036,7 @@ const transformTemplateRef = (node, context) => {
2963
3036
  const id = context.reference();
2964
3037
  const effect = !isConstantExpression(value);
2965
3038
  effect && context.registerOperation({
2966
- type: 15,
3039
+ type: 14,
2967
3040
  id
2968
3041
  });
2969
3042
  context.registerEffect([value], {
@@ -2977,62 +3050,104 @@ const transformTemplateRef = (node, context) => {
2977
3050
  };
2978
3051
 
2979
3052
  const seen = /* @__PURE__ */ new WeakMap();
3053
+ function markNonTemplate(node, context) {
3054
+ seen.get(context.root).add(node);
3055
+ }
2980
3056
  const transformText = (node, context) => {
2981
3057
  if (!seen.has(context.root)) seen.set(context.root, /* @__PURE__ */ new WeakSet());
2982
3058
  if (seen.get(context.root).has(node)) {
2983
3059
  context.dynamic.flags |= 2;
2984
3060
  return;
2985
3061
  }
2986
- if (node.type === 1 && node.tagType === 0 && isAllTextLike(node.children)) {
2987
- processTextLikeContainer(
2988
- node.children,
2989
- context
2990
- );
3062
+ const isFragment = node.type === 0 || node.type === 1 && (node.tagType === 3 || node.tagType === 1);
3063
+ if ((isFragment || node.type === 1 && node.tagType === 0) && node.children.length) {
3064
+ let hasInterp = false;
3065
+ let isAllTextLike = true;
3066
+ for (const c of node.children) {
3067
+ if (c.type === 5) {
3068
+ hasInterp = true;
3069
+ } else if (c.type !== 2) {
3070
+ isAllTextLike = false;
3071
+ }
3072
+ }
3073
+ if (!isFragment && isAllTextLike && hasInterp) {
3074
+ processTextContainer(
3075
+ node.children,
3076
+ context
3077
+ );
3078
+ } else if (hasInterp) {
3079
+ for (let i = 0; i < node.children.length; i++) {
3080
+ const c = node.children[i];
3081
+ const prev = node.children[i - 1];
3082
+ if (c.type === 5 && prev && prev.type === 2) {
3083
+ markNonTemplate(prev, context);
3084
+ }
3085
+ }
3086
+ }
2991
3087
  } else if (node.type === 5) {
2992
- processTextLike(context);
3088
+ processInterpolation(context);
2993
3089
  } else if (node.type === 2) {
2994
3090
  context.template += node.content;
2995
3091
  }
2996
3092
  };
2997
- function processTextLike(context) {
2998
- const nexts = context.parent.node.children.slice(context.index);
3093
+ function processInterpolation(context) {
3094
+ const children = context.parent.node.children;
3095
+ const nexts = children.slice(context.index);
2999
3096
  const idx = nexts.findIndex((n) => !isTextLike(n));
3000
3097
  const nodes = idx > -1 ? nexts.slice(0, idx) : nexts;
3098
+ const prev = children[context.index - 1];
3099
+ if (prev && prev.type === 2) {
3100
+ nodes.unshift(prev);
3101
+ }
3102
+ context.template += " ";
3001
3103
  const id = context.reference();
3002
3104
  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
- });
3105
+ const nonConstantExps = values.filter((v) => !isConstantExpression(v));
3106
+ const isStatic = !nonConstantExps.length || nonConstantExps.every(
3107
+ (e) => isStaticExpression(e, context.options.bindingMetadata)
3108
+ ) || context.inVOnce;
3109
+ if (isStatic) {
3110
+ context.registerOperation({
3111
+ type: 4,
3112
+ element: id,
3113
+ values
3114
+ });
3115
+ } else {
3116
+ context.registerEffect(values, {
3117
+ type: 4,
3118
+ element: id,
3119
+ values
3120
+ });
3121
+ }
3010
3122
  }
3011
- function processTextLikeContainer(children, context) {
3123
+ function processTextContainer(children, context) {
3012
3124
  const values = children.map((child) => createTextLikeExpression(child, context));
3013
3125
  const literals = values.map(getLiteralExpressionValue);
3014
3126
  if (literals.every((l) => l != null)) {
3015
3127
  context.childrenTemplate = literals.map((l) => String(l));
3016
3128
  } else {
3129
+ context.childrenTemplate = [" "];
3130
+ context.registerOperation({
3131
+ type: 17,
3132
+ parent: context.reference()
3133
+ });
3017
3134
  context.registerEffect(values, {
3018
3135
  type: 4,
3019
3136
  element: context.reference(),
3020
- values
3137
+ values,
3138
+ // indicates this node is generated, so prefix should be "x" instead of "n"
3139
+ generated: true
3021
3140
  });
3022
3141
  }
3023
3142
  }
3024
3143
  function createTextLikeExpression(node, context) {
3025
- seen.get(context.root).add(node);
3144
+ markNonTemplate(node, context);
3026
3145
  if (node.type === 2) {
3027
3146
  return compilerDom.createSimpleExpression(node.content, true, node.loc);
3028
3147
  } else {
3029
3148
  return node.content;
3030
3149
  }
3031
3150
  }
3032
- function isAllTextLike(children) {
3033
- return !!children.length && children.every(isTextLike) && // at least one an interpolation
3034
- children.some((n) => n.type === 5);
3035
- }
3036
3151
  function isTextLike(node) {
3037
3152
  return node.type === 5 || node.type === 2;
3038
3153
  }
@@ -3095,7 +3210,7 @@ const transformVModel = (dir, node, context) => {
3095
3210
  modelType = "checkbox";
3096
3211
  break;
3097
3212
  case "file":
3098
- modelType = undefined;
3213
+ modelType = void 0;
3099
3214
  context.options.onError(
3100
3215
  compilerDom.createDOMCompilerError(
3101
3216
  59,
@@ -3128,7 +3243,7 @@ const transformVModel = (dir, node, context) => {
3128
3243
  }
3129
3244
  if (modelType)
3130
3245
  context.registerOperation({
3131
- type: 14,
3246
+ type: 13,
3132
3247
  element: context.reference(),
3133
3248
  dir,
3134
3249
  name: "model",
@@ -3198,29 +3313,38 @@ function processIf(node, dir, context) {
3198
3313
  const [branch, onExit] = createIfBranch(node, context);
3199
3314
  return () => {
3200
3315
  onExit();
3201
- context.registerOperation({
3202
- type: 16,
3316
+ context.dynamic.operation = {
3317
+ type: 15,
3203
3318
  id,
3204
3319
  condition: dir.exp,
3205
3320
  positive: branch,
3206
- once: context.inVOnce
3207
- });
3321
+ once: context.inVOnce || isStaticExpression(dir.exp, context.options.bindingMetadata)
3322
+ };
3208
3323
  };
3209
3324
  } else {
3210
3325
  const siblingIf = getSiblingIf(context, true);
3211
- const { operation } = context.block;
3212
- let lastIfNode = operation[operation.length - 1];
3326
+ const siblings = context.parent && context.parent.dynamic.children;
3327
+ let lastIfNode;
3328
+ if (siblings) {
3329
+ let i = siblings.length;
3330
+ while (i--) {
3331
+ if (siblings[i].operation && siblings[i].operation.type === 15) {
3332
+ lastIfNode = siblings[i].operation;
3333
+ break;
3334
+ }
3335
+ }
3336
+ }
3213
3337
  if (
3214
3338
  // check if v-if is the sibling node
3215
3339
  !siblingIf || // check if IfNode is the last operation and get the root IfNode
3216
- !lastIfNode || lastIfNode.type !== 16
3340
+ !lastIfNode || lastIfNode.type !== 15
3217
3341
  ) {
3218
3342
  context.options.onError(
3219
3343
  compilerDom.createCompilerError(30, node.loc)
3220
3344
  );
3221
3345
  return;
3222
3346
  }
3223
- while (lastIfNode.negative && lastIfNode.negative.type === 16) {
3347
+ while (lastIfNode.negative && lastIfNode.negative.type === 15) {
3224
3348
  lastIfNode = lastIfNode.negative;
3225
3349
  }
3226
3350
  if (dir.name === "else-if" && lastIfNode.negative) {
@@ -3240,7 +3364,7 @@ function processIf(node, dir, context) {
3240
3364
  lastIfNode.negative = branch;
3241
3365
  } else {
3242
3366
  lastIfNode.negative = {
3243
- type: 16,
3367
+ type: 15,
3244
3368
  id: -1,
3245
3369
  condition: dir.exp,
3246
3370
  positive: branch,
@@ -3288,8 +3412,10 @@ function processFor(node, dir, context) {
3288
3412
  context.reference();
3289
3413
  return () => {
3290
3414
  exitBlock();
3291
- context.registerOperation({
3292
- type: 17,
3415
+ const { parent } = context;
3416
+ const isOnlyChild = parent && parent.block.node !== parent.node && parent.node.children.length === 1;
3417
+ context.dynamic.operation = {
3418
+ type: 16,
3293
3419
  id,
3294
3420
  source,
3295
3421
  value,
@@ -3297,9 +3423,13 @@ function processFor(node, dir, context) {
3297
3423
  index,
3298
3424
  keyProp: keyProperty,
3299
3425
  render,
3300
- once: context.inVOnce,
3301
- component: isComponent
3302
- });
3426
+ once: context.inVOnce || isStaticExpression(
3427
+ source,
3428
+ context.options.bindingMetadata
3429
+ ),
3430
+ component: isComponent,
3431
+ onlyChild: !!isOnlyChild
3432
+ };
3303
3433
  };
3304
3434
  }
3305
3435
 
@@ -3319,16 +3449,16 @@ const transformSlotOutlet = (node, context) => {
3319
3449
  if (prop.type === 6) {
3320
3450
  if (prop.value) {
3321
3451
  if (prop.name === "name") {
3322
- slotName = createSimpleExpression(prop.value.content, true, prop.loc);
3452
+ slotName = compilerDom.createSimpleExpression(prop.value.content, true, prop.loc);
3323
3453
  } else {
3324
3454
  slotProps.push(shared.extend({}, prop, { name: shared.camelize(prop.name) }));
3325
3455
  }
3326
3456
  }
3327
- } else if (prop.name === "bind" && isStaticArgOf(prop.arg, "name")) {
3457
+ } else if (prop.name === "bind" && compilerDom.isStaticArgOf(prop.arg, "name")) {
3328
3458
  if (prop.exp) {
3329
3459
  slotName = prop.exp;
3330
3460
  } else {
3331
- slotName = createSimpleExpression(
3461
+ slotName = compilerDom.createSimpleExpression(
3332
3462
  shared.camelize(prop.arg.content),
3333
3463
  false,
3334
3464
  prop.arg.loc
@@ -3337,7 +3467,7 @@ const transformSlotOutlet = (node, context) => {
3337
3467
  }
3338
3468
  } else {
3339
3469
  let slotProp = prop;
3340
- if (slotProp.name === "bind" && slotProp.arg && isStaticExp(slotProp.arg)) {
3470
+ if (slotProp.name === "bind" && slotProp.arg && compilerDom.isStaticExp(slotProp.arg)) {
3341
3471
  slotProp = shared.extend({}, prop, {
3342
3472
  arg: shared.extend({}, slotProp.arg, {
3343
3473
  content: shared.camelize(slotProp.arg.content)
@@ -3347,7 +3477,7 @@ const transformSlotOutlet = (node, context) => {
3347
3477
  slotProps.push(slotProp);
3348
3478
  }
3349
3479
  }
3350
- slotName || (slotName = createSimpleExpression("default", true));
3480
+ slotName || (slotName = compilerDom.createSimpleExpression("default", true));
3351
3481
  let irProps = [];
3352
3482
  if (slotProps.length) {
3353
3483
  const [isDynamic, props] = buildProps(
@@ -3357,11 +3487,11 @@ const transformSlotOutlet = (node, context) => {
3357
3487
  );
3358
3488
  irProps = isDynamic ? props : [props];
3359
3489
  const runtimeDirective = context.block.operation.find(
3360
- (oper) => oper.type === 14 && oper.element === id
3490
+ (oper) => oper.type === 13 && oper.element === id
3361
3491
  );
3362
3492
  if (runtimeDirective) {
3363
3493
  context.options.onError(
3364
- createCompilerError(
3494
+ compilerDom.createCompilerError(
3365
3495
  36,
3366
3496
  runtimeDirective.dir.loc
3367
3497
  )
@@ -3370,13 +3500,13 @@ const transformSlotOutlet = (node, context) => {
3370
3500
  }
3371
3501
  return () => {
3372
3502
  exitBlock && exitBlock();
3373
- context.registerOperation({
3374
- type: 13,
3503
+ context.dynamic.operation = {
3504
+ type: 12,
3375
3505
  id,
3376
3506
  name: slotName,
3377
3507
  props: irProps,
3378
3508
  fallback
3379
- });
3509
+ };
3380
3510
  };
3381
3511
  };
3382
3512
  function createFallback(node, context) {
@@ -3402,7 +3532,7 @@ const transformVSlot = (node, context) => {
3402
3532
  const { tagType, children } = node;
3403
3533
  const { parent } = context;
3404
3534
  const isComponent = tagType === 1;
3405
- const isSlotTemplate = isTemplateNode(node) && parent && parent.node.type === 1 && parent.node.tagType === 1;
3535
+ const isSlotTemplate = compilerDom.isTemplateNode(node) && parent && parent.node.type === 1 && parent.node.tagType === 1;
3406
3536
  if (isComponent && children.length) {
3407
3537
  return transformComponentSlot(
3408
3538
  node,
@@ -3417,16 +3547,26 @@ const transformVSlot = (node, context) => {
3417
3547
  );
3418
3548
  } else if (!isComponent && dir) {
3419
3549
  context.options.onError(
3420
- createCompilerError(40, dir.loc)
3550
+ compilerDom.createCompilerError(40, dir.loc)
3421
3551
  );
3422
3552
  }
3423
3553
  };
3424
3554
  function transformComponentSlot(node, dir, context) {
3425
3555
  const { children } = node;
3426
3556
  const arg = dir && dir.arg;
3427
- const nonSlotTemplateChildren = children.filter(
3428
- (n) => isNonWhitespaceContent(node) && !(n.type === 1 && n.props.some(isVSlot))
3429
- );
3557
+ const emptyTextNodes = [];
3558
+ const nonSlotTemplateChildren = children.filter((n) => {
3559
+ if (isNonWhitespaceContent(n)) {
3560
+ return !(n.type === 1 && n.props.some(compilerDom.isVSlot));
3561
+ } else {
3562
+ emptyTextNodes.push(n);
3563
+ }
3564
+ });
3565
+ if (!nonSlotTemplateChildren.length) {
3566
+ emptyTextNodes.forEach((n) => {
3567
+ markNonTemplate(n, context);
3568
+ });
3569
+ }
3430
3570
  const [block, onExit] = createSlotBlock(node, dir, context);
3431
3571
  const { slots } = context;
3432
3572
  return () => {
@@ -3434,14 +3574,14 @@ function transformComponentSlot(node, dir, context) {
3434
3574
  const hasOtherSlots = !!slots.length;
3435
3575
  if (dir && hasOtherSlots) {
3436
3576
  context.options.onError(
3437
- createCompilerError(37, dir.loc)
3577
+ compilerDom.createCompilerError(37, dir.loc)
3438
3578
  );
3439
3579
  return;
3440
3580
  }
3441
3581
  if (nonSlotTemplateChildren.length) {
3442
3582
  if (hasStaticSlot(slots, "default")) {
3443
3583
  context.options.onError(
3444
- createCompilerError(
3584
+ compilerDom.createCompilerError(
3445
3585
  39,
3446
3586
  nonSlotTemplateChildren[0].loc
3447
3587
  )
@@ -3472,7 +3612,7 @@ function transformTemplateSlot(node, dir, context) {
3472
3612
  const slotName = arg ? arg.isStatic && arg.content : "default";
3473
3613
  if (slotName && hasStaticSlot(slots, slotName)) {
3474
3614
  context.options.onError(
3475
- createCompilerError(38, dir.loc)
3615
+ compilerDom.createCompilerError(38, dir.loc)
3476
3616
  );
3477
3617
  } else {
3478
3618
  registerSlot(slots, arg, block);
@@ -3509,7 +3649,7 @@ function transformTemplateSlot(node, dir, context) {
3509
3649
  ifNode.negative = negative;
3510
3650
  } else {
3511
3651
  context.options.onError(
3512
- createCompilerError(30, vElse.loc)
3652
+ compilerDom.createCompilerError(30, vElse.loc)
3513
3653
  );
3514
3654
  }
3515
3655
  } else if (vFor) {
@@ -3522,7 +3662,7 @@ function transformTemplateSlot(node, dir, context) {
3522
3662
  });
3523
3663
  } else {
3524
3664
  context.options.onError(
3525
- createCompilerError(32, vFor.loc)
3665
+ compilerDom.createCompilerError(32, vFor.loc)
3526
3666
  );
3527
3667
  }
3528
3668
  }
@@ -3611,8 +3751,8 @@ function getBaseTransformPreset() {
3611
3751
  transformVFor,
3612
3752
  transformSlotOutlet,
3613
3753
  transformTemplateRef,
3614
- transformText,
3615
3754
  transformElement,
3755
+ transformText,
3616
3756
  transformVSlot,
3617
3757
  transformComment,
3618
3758
  transformChildren
@@ -3628,74 +3768,6 @@ function getBaseTransformPreset() {
3628
3768
  ];
3629
3769
  }
3630
3770
 
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
3771
  function createVaporCompilerError(code, loc) {
3700
3772
  return compilerDom.createCompilerError(
3701
3773
  code,
@@ -3731,6 +3803,7 @@ exports.createVaporCompilerError = createVaporCompilerError;
3731
3803
  exports.genCall = genCall;
3732
3804
  exports.genMulti = genMulti;
3733
3805
  exports.generate = generate;
3806
+ exports.isBlockOperation = isBlockOperation;
3734
3807
  exports.transform = transform;
3735
3808
  exports.transformChildren = transformChildren;
3736
3809
  exports.transformComment = transformComment;