]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
wip: save
authordaiwei <daiwei521@126.com>
Sat, 26 Jul 2025 08:32:03 +0000 (16:32 +0800)
committerdaiwei <daiwei521@126.com>
Sat, 26 Jul 2025 08:32:03 +0000 (16:32 +0800)
13 files changed:
packages/compiler-vapor/__tests__/transforms/transformElement.spec.ts
packages/compiler-vapor/__tests__/transforms/transformSlotOutlet.spec.ts
packages/compiler-vapor/__tests__/transforms/transformTemplateRef.spec.ts
packages/compiler-vapor/__tests__/transforms/vBind.spec.ts
packages/compiler-vapor/__tests__/transforms/vFor.spec.ts
packages/compiler-vapor/__tests__/transforms/vHtml.spec.ts
packages/compiler-vapor/__tests__/transforms/vIf.spec.ts
packages/compiler-vapor/__tests__/transforms/vSlot.spec.ts
packages/compiler-vapor/__tests__/transforms/vText.spec.ts
packages/compiler-vapor/src/generators/template.ts
packages/compiler-vapor/src/ir/index.ts
packages/compiler-vapor/src/transform.ts
packages/compiler-vapor/src/transforms/transformElement.ts

index 4c9e5c5c2e9dde8848c444dc4338ba364c3087d9..43280f6061aa32480e5909f254f61900ce626577 100644 (file)
@@ -579,7 +579,7 @@ describe('compiler: element transform', () => {
     const template = '<div id="foo" class="bar"></div>'
     expect(code).toMatchSnapshot()
     expect(code).contains(JSON.stringify(template))
-    expect(ir.template).toMatchObject([template])
+    expect([...ir.template.keys()]).toMatchObject([template])
     expect(ir.block.effect).lengthOf(0)
   })
 
@@ -591,7 +591,7 @@ describe('compiler: element transform', () => {
     const template = '<div id="foo"><span></span></div>'
     expect(code).toMatchSnapshot()
     expect(code).contains(JSON.stringify(template))
-    expect(ir.template).toMatchObject([template])
+    expect([...ir.template.keys()]).toMatchObject([template])
     expect(ir.block.effect).lengthOf(0)
   })
 
@@ -937,7 +937,11 @@ describe('compiler: element transform', () => {
       <form><form/></form>`,
     )
     expect(code).toMatchSnapshot()
-    expect(ir.template).toEqual(['<div>123</div>', '<p></p>', '<form></form>'])
+    expect([...ir.template.keys()]).toEqual([
+      '<div>123</div>',
+      '<p></p>',
+      '<form></form>',
+    ])
     expect(ir.block.dynamic).toMatchObject({
       children: [
         { id: 1, template: 1, children: [{ id: 0, template: 0 }] },
@@ -964,8 +968,8 @@ describe('compiler: element transform', () => {
     expect(code).contains(
       '_template("<svg><circle r=\\"40\\"></circle></svg>", true, 1)',
     )
-    expect(ir.template).toMatchObject([t])
-    expect(ir.templateNS.get(t)).toBe(1)
+    expect([...ir.template.keys()]).toMatchObject([t])
+    expect(ir.template.get(t)).toBe(1)
   })
 
   test('MathML', () => {
@@ -975,7 +979,7 @@ describe('compiler: element transform', () => {
     expect(code).contains(
       '_template("<math><mrow><mi>x</mi></mrow></math>", true, 2)',
     )
-    expect(ir.template).toMatchObject([t])
-    expect(ir.templateNS.get(t)).toBe(2)
+    expect([...ir.template.keys()]).toMatchObject([t])
+    expect(ir.template.get(t)).toBe(2)
   })
 })
index 389c665a12fc4d464f50ea1ef8209eb7ba3d248d..99daa571f60d3768d4381e2790f6ab51c49a18c8 100644 (file)
@@ -155,7 +155,7 @@ describe('compiler: transform <slot> outlets', () => {
   test('default slot outlet with fallback', () => {
     const { ir, code } = compileWithSlotsOutlet(`<slot><div/></slot>`)
     expect(code).toMatchSnapshot()
-    expect(ir.template[0]).toBe('<div></div>')
+    expect([...ir.template.keys()][0]).toBe('<div></div>')
     expect(ir.block.dynamic.children[0].operation).toMatchObject({
       type: IRNodeTypes.SLOT_OUTLET_NODE,
       id: 0,
@@ -175,7 +175,7 @@ describe('compiler: transform <slot> outlets', () => {
       `<slot name="foo"><div/></slot>`,
     )
     expect(code).toMatchSnapshot()
-    expect(ir.template[0]).toBe('<div></div>')
+    expect([...ir.template.keys()][0]).toBe('<div></div>')
     expect(ir.block.dynamic.children[0].operation).toMatchObject({
       type: IRNodeTypes.SLOT_OUTLET_NODE,
       id: 0,
@@ -195,7 +195,7 @@ describe('compiler: transform <slot> outlets', () => {
       `<slot :foo="bar"><div/></slot>`,
     )
     expect(code).toMatchSnapshot()
-    expect(ir.template[0]).toBe('<div></div>')
+    expect([...ir.template.keys()][0]).toBe('<div></div>')
     expect(ir.block.dynamic.children[0].operation).toMatchObject({
       type: IRNodeTypes.SLOT_OUTLET_NODE,
       id: 0,
@@ -216,7 +216,7 @@ describe('compiler: transform <slot> outlets', () => {
       `<slot name="foo" :foo="bar"><div/></slot>`,
     )
     expect(code).toMatchSnapshot()
-    expect(ir.template[0]).toBe('<div></div>')
+    expect([...ir.template.keys()][0]).toBe('<div></div>')
     expect(ir.block.dynamic.children[0].operation).toMatchObject({
       type: IRNodeTypes.SLOT_OUTLET_NODE,
       id: 0,
index 2c883d10cc6cd16e822b321ac50c6c91feba7320..82d07ce0ab6a38e5193b10463e537c00c6d06ad5 100644 (file)
@@ -30,7 +30,7 @@ describe('compiler: template ref transform', () => {
       id: 0,
       flags: DynamicFlag.REFERENCED,
     })
-    expect(ir.template).toEqual(['<div></div>'])
+    expect([...ir.template.keys()]).toEqual(['<div></div>'])
     expect(ir.block.operation).lengthOf(1)
     expect(ir.block.operation[0]).toMatchObject({
       type: IRNodeTypes.SET_TEMPLATE_REF,
@@ -66,7 +66,7 @@ describe('compiler: template ref transform', () => {
       id: 0,
       flags: DynamicFlag.REFERENCED,
     })
-    expect(ir.template).toEqual(['<div></div>'])
+    expect([...ir.template.keys()]).toEqual(['<div></div>'])
     expect(ir.block.operation).toMatchObject([
       {
         type: IRNodeTypes.DECLARE_OLD_REF,
@@ -104,7 +104,7 @@ describe('compiler: template ref transform', () => {
       id: 0,
       flags: DynamicFlag.REFERENCED,
     })
-    expect(ir.template).toEqual(['<div></div>'])
+    expect([...ir.template.keys()]).toEqual(['<div></div>'])
     expect(ir.block.operation).toMatchObject([
       {
         type: IRNodeTypes.DECLARE_OLD_REF,
index a36a76d8385b9294ddeccdb4c33508e5948dc1fc..60cd9d986edf0a4396dafa90a6cc56a50c58e19f 100644 (file)
@@ -23,7 +23,7 @@ describe('compiler v-bind', () => {
       id: 0,
       flags: DynamicFlag.REFERENCED,
     })
-    expect(ir.template).toEqual(['<div></div>'])
+    expect([...ir.template.keys()]).toEqual(['<div></div>'])
     expect(ir.block.effect).lengthOf(1)
     expect(ir.block.effect[0].expressions).lengthOf(1)
     expect(ir.block.effect[0].operations).lengthOf(1)
@@ -241,7 +241,7 @@ describe('compiler v-bind', () => {
         end: { line: 1, column: 19 },
       },
     })
-    expect(ir.template).toEqual(['<div arg></div>'])
+    expect([...ir.template.keys()]).toEqual(['<div arg></div>'])
 
     expect(code).matchSnapshot()
     expect(code).contains(JSON.stringify('<div arg></div>'))
index 7357ad84fefafef4805bfbeb57054f4724d9b6db..011eb0ca92c6955a5328465062ef6b5fa8500eb5 100644 (file)
@@ -32,7 +32,7 @@ describe('compiler: v-for', () => {
 
     expect(code).matchSnapshot()
     expect(helpers).contains('createFor')
-    expect(ir.template).toEqual(['<div> </div>'])
+    expect([...ir.template.keys()]).toEqual(['<div> </div>'])
     expect(ir.block.dynamic.children[0].operation).toMatchObject({
       type: IRNodeTypes.FOR,
       id: 0,
@@ -156,7 +156,7 @@ describe('compiler: v-for', () => {
       `_createFor(() => (_for_item0.value), (_for_item1) => {`,
     )
     expect(code).contains(`_for_item1.value+_for_item0.value`)
-    expect(ir.template).toEqual(['<span> </span>', '<div></div>'])
+    expect([...ir.template.keys()]).toEqual(['<span> </span>', '<div></div>'])
     const parentOp = ir.block.dynamic.children[0].operation
     expect(parentOp).toMatchObject({
       type: IRNodeTypes.FOR,
index 0de0b6abca6a055ae1f9d4249148906107a108d2..f297362b2cb681d9395d98c919c68ea8f0b1edcb 100644 (file)
@@ -66,7 +66,7 @@ describe('v-html', () => {
     expect(helpers).contains('setHtml')
 
     // children should have been removed
-    expect(ir.template).toEqual(['<div></div>'])
+    expect([...ir.template.keys()]).toEqual(['<div></div>'])
 
     expect(ir.block.operation).toMatchObject([])
     expect(ir.block.effect).toMatchObject([
index e5fd61add2e6fb86bba3a35d1255ce787c03822a..76a1bde6123c779a213f76e0d0a45757f122fb52 100644 (file)
@@ -32,7 +32,7 @@ describe('compiler: v-if', () => {
 
     expect(helpers).contains('createIf')
 
-    expect(ir.template).toEqual(['<div> </div>'])
+    expect([...ir.template.keys()]).toEqual(['<div> </div>'])
 
     const op = ir.block.dynamic.children[0].operation
     expect(op).toMatchObject({
@@ -68,7 +68,11 @@ describe('compiler: v-if', () => {
     )
     expect(code).matchSnapshot()
 
-    expect(ir.template).toEqual(['<div></div>', 'hello', '<p> </p>'])
+    expect([...ir.template.keys()]).toEqual([
+      '<div></div>',
+      'hello',
+      '<p> </p>',
+    ])
     expect(ir.block.effect).toEqual([])
     const op = ir.block.dynamic.children[0].operation as IfIRNode
     expect(op.positive.effect).toMatchObject([
@@ -103,7 +107,7 @@ describe('compiler: v-if', () => {
       `<div v-if="ok">hello</div><div v-if="ok">hello</div>`,
     )
     expect(code).matchSnapshot()
-    expect(ir.template).toEqual(['<div>hello</div>'])
+    expect([...ir.template.keys()]).toEqual(['<div>hello</div>'])
     expect(ir.block.returns).toEqual([0, 3])
   })
 
@@ -113,7 +117,7 @@ describe('compiler: v-if', () => {
   test('v-if + v-else', () => {
     const { code, ir, helpers } = compileWithVIf(`<div v-if="ok"/><p v-else/>`)
     expect(code).matchSnapshot()
-    expect(ir.template).toEqual(['<div></div>', '<p></p>'])
+    expect([...ir.template.keys()]).toEqual(['<div></div>', '<p></p>'])
 
     expect(helpers).contains('createIf')
     expect(ir.block.effect).lengthOf(0)
@@ -146,7 +150,7 @@ describe('compiler: v-if', () => {
       `<div v-if="ok"/><p v-else-if="orNot"/>`,
     )
     expect(code).matchSnapshot()
-    expect(ir.template).toEqual(['<div></div>', '<p></p>'])
+    expect([...ir.template.keys()]).toEqual(['<div></div>', '<p></p>'])
 
     expect(ir.block.dynamic.children[0].operation).toMatchObject({
       type: IRNodeTypes.IF,
@@ -185,7 +189,7 @@ describe('compiler: v-if', () => {
       `<div v-if="ok"/><p v-else-if="orNot"/><template v-else>fine</template>`,
     )
     expect(code).matchSnapshot()
-    expect(ir.template).toEqual(['<div></div>', '<p></p>', 'fine'])
+    expect([...ir.template.keys()]).toEqual(['<div></div>', '<p></p>', 'fine'])
 
     expect(ir.block.returns).toEqual([0])
     expect(ir.block.dynamic.children[0].operation).toMatchObject({
@@ -236,7 +240,7 @@ describe('compiler: v-if', () => {
       <div v-text="text" />
     `)
     expect(code).matchSnapshot()
-    expect(ir.template).toEqual([
+    expect([...ir.template.keys()]).toEqual([
       '<div></div>',
       '<!--foo-->',
       '<p></p>',
index 909162fe3ca027e5716c6cb7f1b67672105f48f1..2a462479c3e32ba0fdc0dc4c9f5522e18aea8f98 100644 (file)
@@ -35,7 +35,7 @@ describe('compiler: transform slot', () => {
     const { ir, code } = compileWithSlots(`<Comp><div/></Comp>`)
     expect(code).toMatchSnapshot()
 
-    expect(ir.template).toEqual(['<div></div>'])
+    expect([...ir.template.keys()]).toEqual(['<div></div>'])
     expect(ir.block.dynamic.children[0].operation).toMatchObject({
       type: IRNodeTypes.CREATE_COMPONENT_NODE,
       id: 1,
@@ -163,7 +163,7 @@ describe('compiler: transform slot', () => {
     )
     expect(code).toMatchSnapshot()
 
-    expect(ir.template).toEqual(['foo', 'bar', '<span></span>'])
+    expect([...ir.template.keys()]).toEqual(['foo', 'bar', '<span></span>'])
     expect(ir.block.dynamic.children[0].operation).toMatchObject({
       type: IRNodeTypes.CREATE_COMPONENT_NODE,
       id: 4,
index 4f074fee87e16b8a2b1d15e468028d7893125dcd..7ebac8554a87613397056d6a6e3f5257fc2b9db7 100644 (file)
@@ -68,7 +68,7 @@ describe('v-text', () => {
     ])
 
     // children should have been removed
-    expect(ir.template).toEqual(['<div> </div>'])
+    expect([...ir.template.keys()]).toEqual(['<div> </div>'])
 
     expect(ir.block.effect).toMatchObject([
       {
index 3b8886d8b926aba209a530d022a7a4fcabf668ae..e3cca1b48b046adcab0752879a97dd90702d032a 100644 (file)
@@ -5,18 +5,21 @@ import { genOperationWithInsertionState } from './operation'
 import { type CodeFragment, NEWLINE, buildCodeFragment, genCall } from './utils'
 
 export function genTemplates(
-  templates: string[],
+  templates: Map<string, number>,
   rootIndex: number | undefined,
-  { helper, ir: { templateNS } }: CodegenContext,
+  { helper }: CodegenContext,
 ): string {
-  return templates
-    .map((template, i) => {
-      const ns = templateNS.get(template)
-      return `const t${i} = ${helper('template')}(${JSON.stringify(
+  const result: string[] = []
+  let i = 0
+  templates.forEach((ns, template) => {
+    result.push(
+      `const t${i} = ${helper('template')}(${JSON.stringify(
         template,
-      )}${i === rootIndex ? ', true' : ns ? ', false' : ''}${ns ? `, ${ns}` : ''})\n`
-    })
-    .join('')
+      )}${i === rootIndex ? ', true' : ns ? ', false' : ''}${ns ? `, ${ns}` : ''})\n`,
+    )
+    i++
+  })
+  return result.join('')
 }
 
 export function genSelf(
index b53c2ae6adba2299cf8cb48ca92ca73cb30d31cb..b7c67eac9233b6511bee335f8e78cf44c0c1d336 100644 (file)
@@ -59,8 +59,8 @@ export interface RootIRNode {
   type: IRNodeTypes.ROOT
   node: RootNode
   source: string
-  template: string[]
-  templateNS: Map<string, number>
+  template: Map<string, number>
+  templateIndexMap: Map<string, number>
   rootTemplateIndex?: number
   component: Set<string>
   directive: Set<string>
index bce40a46c398ed65644c826e6c21e764a94914c8..e993daf4b0cecd8e6ea154faf684800e1bc140b5 100644 (file)
@@ -74,7 +74,6 @@ export class TransformContext<T extends AllNode = AllNode> {
   >
 
   template: string = ''
-  templateNS: Map<string, number> = new Map<string, number>()
   childrenTemplate: (string | null)[] = []
   dynamic: IRDynamicInfo = this.ir.block.dynamic
 
@@ -100,12 +99,10 @@ export class TransformContext<T extends AllNode = AllNode> {
   }
 
   enterBlock(ir: BlockIRNode, isVFor: boolean = false): () => void {
-    const { block, template, templateNS, dynamic, childrenTemplate, slots } =
-      this
+    const { block, template, dynamic, childrenTemplate, slots } = this
     this.block = ir
     this.dynamic = ir.dynamic
     this.template = ''
-    this.templateNS = new Map<string, number>()
     this.childrenTemplate = []
     this.slots = []
     isVFor && this.inVFor++
@@ -114,7 +111,6 @@ export class TransformContext<T extends AllNode = AllNode> {
       this.registerTemplate()
       this.block = block
       this.template = template
-      this.templateNS = templateNS
       this.dynamic = dynamic
       this.childrenTemplate = childrenTemplate
       this.slots = slots
@@ -130,13 +126,15 @@ export class TransformContext<T extends AllNode = AllNode> {
   }
 
   pushTemplate(content: string): number {
-    const existing = this.ir.template.findIndex(
-      template => template === content,
-    )
-    if (existing !== -1) return existing
-    this.ir.template.push(content)
-    this.ir.templateNS.set(content, (this.node as PlainElementNode).ns)
-    return this.ir.template.length - 1
+    const existingIndex = this.ir.templateIndexMap.get(content)
+    if (existingIndex !== undefined) {
+      return existingIndex
+    }
+
+    const newIndex = this.ir.template.size
+    this.ir.template.set(content, (this.node as PlainElementNode).ns)
+    this.ir.templateIndexMap.set(content, newIndex)
+    return newIndex
   }
   registerTemplate(): number {
     if (!this.template) return -1
@@ -220,8 +218,8 @@ export function transform(
     type: IRNodeTypes.ROOT,
     node,
     source: node.source,
-    template: [],
-    templateNS: new Map<string, number>(),
+    template: new Map<string, number>(),
+    templateIndexMap: new Map<string, number>(),
     component: new Set(),
     directive: new Set(),
     block: newBlock(node),
index 05153e729aff475dd609bc8bb5bedfe3f1cde0d3..1919ccd2a2bd018068d9ea0ba0cdb578b03d82e8 100644 (file)
@@ -250,7 +250,7 @@ function transformNativeElement(
   }
 
   if (singleRoot) {
-    context.ir.rootTemplateIndex = context.ir.template.length
+    context.ir.rootTemplateIndex = context.ir.template.size
   }
 
   if (