{
  //             let a = '' + lett
  //             v = a
  //          }"/>
  //          
 {
  //             // nested scopes
  //             (()=>{
  //               let x = a
  //               (()=>{
  //                 let z = x
  //                 let z2 = z
  //               })
  //               let lz = z
  //             })
  //             v = a
  //          }"/>
  //       
  //       `,
  //       { inlineTemplate: true }
  //     )
  //     // known const ref: set value
  //     expect(content).toMatch(`count.value = 1`)
  //     // const but maybe ref: only assign after check
  //     expect(content).toMatch(`maybe.value = count.value`)
  //     // let: handle both cases
  //     expect(content).toMatch(
  //       `_isRef(lett) ? lett.value = count.value : lett = count.value`
  //     )
  //     expect(content).toMatch(`_isRef(v) ? v.value += 1 : v += 1`)
  //     expect(content).toMatch(`_isRef(v) ? v.value -= 1 : v -= 1`)
  //     expect(content).toMatch(`_isRef(v) ? v.value = a : v = a`)
  //     expect(content).toMatch(`_isRef(v) ? v.value = _ctx.a : v = _ctx.a`)
  //     assertCode(content)
  //   })
  //   test('template update expression codegen', () => {
  //     const { content } = compile(
  //       `
  //       
  //         
  //         
  //         
  //         
  //         
  //         
  //       
  //       `,
  //       { inlineTemplate: true }
  //     )
  //     // known const ref: set value
  //     expect(content).toMatch(`count.value++`)
  //     expect(content).toMatch(`--count.value`)
  //     // const but maybe ref (non-ref case ignored)
  //     expect(content).toMatch(`maybe.value++`)
  //     expect(content).toMatch(`--maybe.value`)
  //     // let: handle both cases
  //     expect(content).toMatch(`_isRef(lett) ? lett.value++ : lett++`)
  //     expect(content).toMatch(`_isRef(lett) ? --lett.value : --lett`)
  //     assertCode(content)
  //   })
  //   test('template destructure assignment codegen', () => {
  //     const { content } = compile(
  //       `
  //       
  //         
  //         
  //         
  //       
  //       `,
  //       { inlineTemplate: true }
  //     )
  //     // known const ref: set value
  //     expect(content).toMatch(`({ count: count.value } = val)`)
  //     // const but maybe ref (non-ref case ignored)
  //     expect(content).toMatch(`[maybe.value] = val`)
  //     // let: assumes non-ref
  //     expect(content).toMatch(`{ lett: lett } = val`)
  //     assertCode(content)
  //   })
  //   test('ssr codegen', () => {
  //     const { content } = compile(
  //       `
  //       
  //       
  //         {{ count }}
  //         static
  //       
  //       
  //       `,
  //       {
  //         inlineTemplate: true,
  //         templateOptions: {
  //           ssr: true
  //         }
  //       }
  //     )
  //     expect(content).toMatch(`\n  __ssrInlineRender: true,\n`)
  //     expect(content).toMatch(`return (_ctx, _push`)
  //     expect(content).toMatch(`ssrInterpolate`)
  //     expect(content).not.toMatch(`useCssVars`)
  //     expect(content).toMatch(`"--${mockId}-count": (count.value)`)
  //     assertCode(content)
  //   })
  // })
  describe('with TypeScript', () => {
    test('hoist type declarations', () => {
      const { content } = compile(`
      `)
      assertCode(content)
    })
    test('defineProps/Emit w/ runtime options', () => {
      const { content } = compile(`
      `)
      assertCode(content)
      expect(content).toMatch(`export default /*#__PURE__*/_defineComponent({
  props: { foo: String },
  emits: ['a', 'b'],
  setup(__props, { emit }) {`)
    })
    test('defineProps w/ type', () => {
      const { content, bindings } = compile(`
      `)
      assertCode(content)
      expect(content).toMatch(`string: { type: String, required: true }`)
      expect(content).toMatch(`number: { type: Number, required: true }`)
      expect(content).toMatch(`boolean: { type: Boolean, required: true }`)
      expect(content).toMatch(`object: { type: Object, required: true }`)
      expect(content).toMatch(`objectLiteral: { type: Object, required: true }`)
      expect(content).toMatch(`fn: { type: Function, required: true }`)
      expect(content).toMatch(`functionRef: { type: Function, required: true }`)
      expect(content).toMatch(`objectRef: { type: Object, required: true }`)
      expect(content).toMatch(`dateTime: { type: Date, required: true }`)
      expect(content).toMatch(`array: { type: Array, required: true }`)
      expect(content).toMatch(`arrayRef: { type: Array, required: true }`)
      expect(content).toMatch(`tuple: { type: Array, required: true }`)
      expect(content).toMatch(`set: { type: Set, required: true }`)
      expect(content).toMatch(`literal: { type: String, required: true }`)
      expect(content).toMatch(`optional: { type: null, required: false }`)
      expect(content).toMatch(`recordRef: { type: Object, required: true }`)
      expect(content).toMatch(`interface: { type: Object, required: true }`)
      expect(content).toMatch(`alias: { type: Array, required: true }`)
      expect(content).toMatch(`method: { type: Function, required: true }`)
      expect(content).toMatch(`symbol: { type: Symbol, required: true }`)
      expect(content).toMatch(
        `union: { type: [String, Number], required: true }`
      )
      expect(content).toMatch(`literalUnion: { type: String, required: true }`)
      expect(content).toMatch(
        `literalUnionNumber: { type: Number, required: true }`
      )
      expect(content).toMatch(
        `literalUnionMixed: { type: [String, Number, Boolean], required: true }`
      )
      expect(content).toMatch(`intersection: { type: Object, required: true }`)
      expect(content).toMatch(`foo: { type: [Function, null], required: true }`)
      expect(bindings).toStrictEqual({
        string: BindingTypes.PROPS,
        number: BindingTypes.PROPS,
        boolean: BindingTypes.PROPS,
        object: BindingTypes.PROPS,
        objectLiteral: BindingTypes.PROPS,
        fn: BindingTypes.PROPS,
        functionRef: BindingTypes.PROPS,
        objectRef: BindingTypes.PROPS,
        dateTime: BindingTypes.PROPS,
        array: BindingTypes.PROPS,
        arrayRef: BindingTypes.PROPS,
        tuple: BindingTypes.PROPS,
        set: BindingTypes.PROPS,
        literal: BindingTypes.PROPS,
        optional: BindingTypes.PROPS,
        recordRef: BindingTypes.PROPS,
        interface: BindingTypes.PROPS,
        alias: BindingTypes.PROPS,
        method: BindingTypes.PROPS,
        symbol: BindingTypes.PROPS,
        union: BindingTypes.PROPS,
        literalUnion: BindingTypes.PROPS,
        literalUnionNumber: BindingTypes.PROPS,
        literalUnionMixed: BindingTypes.PROPS,
        intersection: BindingTypes.PROPS,
        foo: BindingTypes.PROPS
      })
    })
    test('defineProps w/ interface', () => {
      const { content, bindings } = compile(`
      
      `)
      assertCode(content)
      expect(content).toMatch(`x: { type: Number, required: false }`)
      expect(bindings).toStrictEqual({
        x: BindingTypes.PROPS
      })
    })
    test('defineProps w/ exported interface', () => {
      const { content, bindings } = compile(`
      
      `)
      assertCode(content)
      expect(content).toMatch(`x: { type: Number, required: false }`)
      expect(bindings).toStrictEqual({
        x: BindingTypes.PROPS
      })
    })
    test('defineProps w/ exported interface in normal script', () => {
      const { content, bindings } = compile(`
      
      
      `)
      assertCode(content)
      expect(content).toMatch(`x: { type: Number, required: false }`)
      expect(bindings).toStrictEqual({
        x: BindingTypes.PROPS
      })
    })
    test('defineProps w/ type alias', () => {
      const { content, bindings } = compile(`
      
      `)
      assertCode(content)
      expect(content).toMatch(`x: { type: Number, required: false }`)
      expect(bindings).toStrictEqual({
        x: BindingTypes.PROPS
      })
    })
    test('defineProps w/ exported type alias', () => {
      const { content, bindings } = compile(`
      
      `)
      assertCode(content)
      expect(content).toMatch(`x: { type: Number, required: false }`)
      expect(bindings).toStrictEqual({
        x: BindingTypes.PROPS
      })
    })
    test('withDefaults (static)', () => {
      const { content, bindings } = compile(`
      
      `)
      assertCode(content)
      expect(content).toMatch(
        `foo: { type: String, required: false, default: 'hi' }`
      )
      expect(content).toMatch(`bar: { type: Number, required: false }`)
      expect(content).toMatch(`baz: { type: Boolean, required: true }`)
      expect(content).toMatch(
        `qux: { type: Function, required: false, default() { return 1 } }`
      )
      expect(content).toMatch(
        `{ foo: string, bar?: number, baz: boolean, qux(): number }`
      )
      expect(content).toMatch(`const props = __props`)
      expect(bindings).toStrictEqual({
        foo: BindingTypes.PROPS,
        bar: BindingTypes.PROPS,
        baz: BindingTypes.PROPS,
        qux: BindingTypes.PROPS,
        props: BindingTypes.SETUP_CONST
      })
    })
    test('withDefaults (dynamic)', () => {
      const { content } = compile(`
      
      `)
      assertCode(content)
      expect(content).toMatch(`import { mergeDefaults as _mergeDefaults`)
      expect(content).toMatch(
        `
  _mergeDefaults({
    foo: { type: String, required: false },
    bar: { type: Number, required: false },
    baz: { type: Boolean, required: true }
  }, { ...defaults })`.trim()
      )
    })
    test('defineEmits w/ type', () => {
      const { content } = compile(`
      
      `)
      assertCode(content)
      expect(content).toMatch(`emit: ((e: 'foo' | 'bar') => void),`)
      expect(content).toMatch(`emits: ["foo", "bar"]`)
    })
    test('defineEmits w/ type (union)', () => {
      const type = `((e: 'foo' | 'bar') => void) | ((e: 'baz', id: number) => void)`
      expect(() =>
        compile(`
      
      `)
      ).toThrow()
    })
    test('defineEmits w/ type (type literal w/ call signatures)', () => {
      const type = `{(e: 'foo' | 'bar'): void; (e: 'baz', id: number): void;}`
      const { content } = compile(`
      
      `)
      assertCode(content)
      expect(content).toMatch(`emit: (${type}),`)
      expect(content).toMatch(`emits: ["foo", "bar", "baz"]`)
    })
    test('defineEmits w/ type (interface)', () => {
      const { content } = compile(`
      
      `)
      assertCode(content)
      expect(content).toMatch(`emit: ({ (e: 'foo' | 'bar'): void }),`)
      expect(content).toMatch(`emits: ["foo", "bar"]`)
    })
    test('defineEmits w/ type (exported interface)', () => {
      const { content } = compile(`
      
      `)
      assertCode(content)
      expect(content).toMatch(`emit: ({ (e: 'foo' | 'bar'): void }),`)
      expect(content).toMatch(`emits: ["foo", "bar"]`)
    })
    test('defineEmits w/ type (type alias)', () => {
      const { content } = compile(`
      
      `)
      assertCode(content)
      expect(content).toMatch(`emit: ({ (e: 'foo' | 'bar'): void }),`)
      expect(content).toMatch(`emits: ["foo", "bar"]`)
    })
    test('defineEmits w/ type (exported type alias)', () => {
      const { content } = compile(`
      
      `)
      assertCode(content)
      expect(content).toMatch(`emit: ({ (e: 'foo' | 'bar'): void }),`)
      expect(content).toMatch(`emits: ["foo", "bar"]`)
    })
    test('defineEmits w/ type (referenced function type)', () => {
      const { content } = compile(`
      
      `)
      assertCode(content)
      expect(content).toMatch(`emit: ((e: 'foo' | 'bar') => void),`)
      expect(content).toMatch(`emits: ["foo", "bar"]`)
    })
    test('defineEmits w/ type (referenced exported function type)', () => {
      const { content } = compile(`
      
      `)
      assertCode(content)
      expect(content).toMatch(`emit: ((e: 'foo' | 'bar') => void),`)
      expect(content).toMatch(`emits: ["foo", "bar"]`)
    })
    // https://github.com/vuejs/core/issues/5393
    test('defineEmits w/ type (interface ts type)', () => {
      const { content } = compile(`
      
      `)
      assertCode(content)
      expect(content).toMatch(`setup(__props, { emit }) {`)
      expect(content).toMatch(`emits: ['foo']`)
    })
    test('runtime Enum', () => {
      const { content, bindings } = compile(
        ``
      )
      assertCode(content)
      expect(bindings).toStrictEqual({
        Foo: BindingTypes.SETUP_CONST
      })
    })
    test('runtime Enum in normal script', () => {
      const { content, bindings } = compile(
        `
        `
      )
      assertCode(content)
      expect(bindings).toStrictEqual({
        D: BindingTypes.SETUP_CONST,
        C: BindingTypes.SETUP_CONST,
        B: BindingTypes.SETUP_CONST,
        Foo: BindingTypes.SETUP_CONST
      })
    })
    test('const Enum', () => {
      const { content, bindings } = compile(
        ``
      )
      assertCode(content)
      expect(bindings).toStrictEqual({
        Foo: BindingTypes.SETUP_CONST
      })
    })
    test('import type', () => {
      const { content } = compile(
        ``
      )
      expect(content).toMatch(`return { Baz }`)
      assertCode(content)
    })
  })
  describe('errors', () => {
    test('`)
      ).toThrow(``)
      ).toThrow(moduleErrorMsg)
      expect(() =>
        compile(``)
      ).toThrow(moduleErrorMsg)
      expect(() =>
        compile(``)
      ).toThrow(moduleErrorMsg)
    })
    test('defineProps/Emit() w/ both type and non-type args', () => {
      expect(() => {
        compile(``)
      }).toThrow(`cannot accept both type and non-type arguments`)
      expect(() => {
        compile(``)
      }).toThrow(`cannot accept both type and non-type arguments`)
    })
    test('defineProps/Emit() referencing local var', () => {
      expect(() =>
        compile(``)
      ).toThrow(`cannot reference locally declared variables`)
      expect(() =>
        compile(``)
      ).toThrow(`cannot reference locally declared variables`)
      // #4644
      expect(() =>
        compile(`
        
        `)
      ).not.toThrow(`cannot reference locally declared variables`)
    })
    test('should allow defineProps/Emit() referencing scope var', () => {
      assertCode(
        compile(``).content
      )
    })
    test('should allow defineProps/Emit() referencing imported binding', () => {
      assertCode(
        compile(``).content
      )
    })
  })
})
describe('SFC analyze 
    `)
    expect(scriptAst).toBeDefined()
  })
  it('recognizes props array declaration', () => {
    const { bindings } = compile(`
      
    `)
    expect(bindings).toStrictEqual({
      foo: BindingTypes.PROPS,
      bar: BindingTypes.PROPS
    })
    expect(bindings!.__isScriptSetup).toBe(false)
  })
  it('recognizes props object declaration', () => {
    const { bindings } = compile(`
      
    `)
    expect(bindings).toStrictEqual({
      foo: BindingTypes.PROPS,
      bar: BindingTypes.PROPS,
      baz: BindingTypes.PROPS,
      qux: BindingTypes.PROPS
    })
    expect(bindings!.__isScriptSetup).toBe(false)
  })
  it('recognizes setup return', () => {
    const { bindings } = compile(`
      
    `)
    expect(bindings).toStrictEqual({
      foo: BindingTypes.SETUP_MAYBE_REF,
      bar: BindingTypes.SETUP_MAYBE_REF
    })
    expect(bindings!.__isScriptSetup).toBe(false)
  })
  it('recognizes exported vars', () => {
    const { bindings } = compile(`
      
      
    `)
    expect(bindings).toStrictEqual({
      foo: BindingTypes.SETUP_CONST
    })
  })
  it('recognizes async setup return', () => {
    const { bindings } = compile(`
      
    `)
    expect(bindings).toStrictEqual({
      foo: BindingTypes.SETUP_MAYBE_REF,
      bar: BindingTypes.SETUP_MAYBE_REF
    })
    expect(bindings!.__isScriptSetup).toBe(false)
  })
  it('recognizes data return', () => {
    const { bindings } = compile(`
      
    `)
    expect(bindings).toStrictEqual({
      foo: BindingTypes.DATA,
      bar: BindingTypes.DATA
    })
  })
  it('recognizes methods', () => {
    const { bindings } = compile(`
      
    `)
    expect(bindings).toStrictEqual({ foo: BindingTypes.OPTIONS })
  })
  it('recognizes computeds', () => {
    const { bindings } = compile(`
      
    `)
    expect(bindings).toStrictEqual({
      foo: BindingTypes.OPTIONS,
      bar: BindingTypes.OPTIONS
    })
  })
  it('recognizes injections array declaration', () => {
    const { bindings } = compile(`
      
    `)
    expect(bindings).toStrictEqual({
      foo: BindingTypes.OPTIONS,
      bar: BindingTypes.OPTIONS
    })
  })
  it('recognizes injections object declaration', () => {
    const { bindings } = compile(`
      
    `)
    expect(bindings).toStrictEqual({
      foo: BindingTypes.OPTIONS,
      bar: BindingTypes.OPTIONS
    })
  })
  it('works for mixed bindings', () => {
    const { bindings } = compile(`
      
    `)
    expect(bindings).toStrictEqual({
      foo: BindingTypes.OPTIONS,
      bar: BindingTypes.PROPS,
      baz: BindingTypes.SETUP_MAYBE_REF,
      qux: BindingTypes.DATA,
      quux: BindingTypes.OPTIONS,
      quuz: BindingTypes.OPTIONS
    })
  })
  it('works for script setup', () => {
    const { bindings } = compile(`
      
    `)
    expect(bindings).toStrictEqual({
      r: BindingTypes.SETUP_CONST,
      a: BindingTypes.SETUP_REF,
      b: BindingTypes.SETUP_LET,
      c: BindingTypes.SETUP_CONST,
      d: BindingTypes.SETUP_MAYBE_REF,
      e: BindingTypes.SETUP_LET,
      foo: BindingTypes.PROPS
    })
  })
  describe('auto name inference', () => {
    test('basic', () => {
      const { content } = compile(
        `
        
{{ a }}`,
        undefined,
        {
          filename: 'FooBar.vue'
        }
      )
      expect(content).toMatch(`export default {
  __name: 'FooBar'`)
      assertCode(content)
    })
    test('do not overwrite manual name (object)', () => {
      const { content } = compile(
        `
        
        
{{ a }}`,
        undefined,
        {
          filename: 'FooBar.vue'
        }
      )
      expect(content).not.toMatch(`name: 'FooBar'`)
      expect(content).toMatch(`name: 'Baz'`)
      assertCode(content)
    })
    test('do not overwrite manual name (call)', () => {
      const { content } = compile(
        `
        
        
{{ a }}`,
        undefined,
        {
          filename: 'FooBar.vue'
        }
      )
      expect(content).not.toMatch(`name: 'FooBar'`)
      expect(content).toMatch(`name: 'Baz'`)
      assertCode(content)
    })
    // #12591
    test('should not error when performing ts expression check for v-on inline statement', () => {
      compile(`
      
      
        
      
      `)
    })
    // #12841
    test('should not error when performing ts expression check for v-slot destructured default value', () => {
      compile(`
      
      
        
          
            {{ bar.baz }}
          
        
      
      `)
    })
  })
})