ronantakizawa/codereview-bench huggingface dataset:
Repository: vuejs/vue-next
File: packages/runtime-core/__tests__/rendererTemplateRef.spec.ts (TypeScript)

Code before:

    refKey.value = 'bar'
    await nextTick()
    expect(refs.foo.value).toBe(null)
    expect(refs.bar.value).toBe(root.children[0])
  })

  it('render function ref unmount', async () => {
    const root = nodeOps.createElement('div')
    const el = ref(null)
    const toggle = ref(true)

    const Comp = {
      setup() {
        return () => (toggle.value ? h('div', { ref: el }) : null)
      },
    }
    render(h(Comp), root)
    expect(el.value).toBe(root.children[0])

    toggle.value = false
    await nextTick()
    expect(el.value).toBe(null)
  })

  it('render function ref unmount with conditional update', async () => {
    const root1 = nodeOps.createElement('div')
    const root2 = nodeOps.createElement('div')
    const el1 = ref(null)
    const el2 = ref(null)
    const toggle = ref(true)

    const Comp1 = {
      setup() {
        return () => (toggle.value ? h('div', { ref: el1 }) : h('div'))
      },
    }

    const Comp2 = {
      setup() {
        return () => h('div', { ref: toggle.value ? el2 : undefined })
      },
    }

    render(h(Comp1), root1)
    render(h(Comp2), root2)

    expect(el1.value).toBe(root1.children[0])
    expect(el2.value).toBe(root2.children[0])

    toggle.value = false

Review comment (suggestion):
```suggestion
  it('unset old ref when new ref is absent', async () => {
```

Code after:

    refKey.value = 'bar'
    await nextTick()
    expect(refs.foo.value).toBe(null)
    expect(refs.bar.value).toBe(root.children[0])
  })

  it('render function ref unmount', async () => {
    const root = nodeOps.createElement('div')
    const el = ref(null)
    const toggle = ref(true)

    const Comp = {
      setup() {
        return () => (toggle.value ? h('div', { ref: el }) : null)
      },
    }
    render(h(Comp), root)
    expect(el.value).toBe(root.children[0])

    toggle.value = false
    await nextTick()
    expect(el.value).toBe(null)
  })

  it('unset old ref when new ref is absent', async () => {
    const root1 = nodeOps.createElement('div')
    const root2 = nodeOps.createElement('div')
    const el1 = ref(null)
    const el2 = ref(null)
    const toggle = ref(true)

    const Comp1 = {
      setup() {
        return () => (toggle.value ? h('div', { ref: el1 }) : h('div'))
      },
    }

    const Comp2 = {
      setup() {
        return () => h('div', { ref: toggle.value ? el2 : undefined })
      },
    }

    render(h(Comp1), root1)
    render(h(Comp2), root2)

    expect(el1.value).toBe(root1.children[0])
    expect(el2.value).toBe(root2.children[0])

    toggle.value = false
Repository: vuejs/vue-next
File: packages/compiler-sfc/src/style/pluginScoped.ts (TypeScript)

Code before:
    }

    if (n.type === 'universal') {
      const prev = selector.at(selector.index(n) - 1)
      const next = selector.at(selector.index(n) + 1)
      // * ... {}
      if (!prev) {
        // * .foo {} -> .foo[xxxxxxx] {}
        if (next) {
          if (next.type === 'combinator' && next.value === ' ') {
            selector.removeChild(next)
          }
          selector.removeChild(n)
          return
        } else {
          // * {} -> [xxxxxxx] {}
          node = selectorParser.combinator({
            value: '',
          })
          selector.insertBefore(n, node)
          selector.removeChild(n)
          return false
        }
      }
      //                         v- store this
      // .foo * -> .foo[xxxxxxx] *[xxxxxxx]
      starNode = n
    }

    if (
      (n.type !== 'pseudo' &&
        n.type !== 'combinator' &&
        n.type !== 'universal') ||
      (n.type === 'pseudo' &&
        (n.value === ':is' || n.value === ':where') &&
        !node)
    ) {
      node = n
      starNode = null
    }
  })

  if (rule.nodes.some(node => node.type === 'rule')) {
    const deep = (rule as any).__deep
    if (!deep) {
      extractAndWrapNodes(rule)
      const atruleNodes = rule.nodes.filter(node => node.type === 'atrule')
      for (const atnode of atruleNodes) {
        extractAndWrapNodes(atnode)
      }
    }

Review comment (suggestion):
```suggestion
      // .foo * -> .foo[xxxxxxx] [xxxxxxx]
```

Code after:
    }

    if (n.type === 'universal') {
      const prev = selector.at(selector.index(n) - 1)
      const next = selector.at(selector.index(n) + 1)
      // * ... {}
      if (!prev) {
        // * .foo {} -> .foo[xxxxxxx] {}
        if (next) {
          if (next.type === 'combinator' && next.value === ' ') {
            selector.removeChild(next)
          }
          selector.removeChild(n)
          return
        } else {
          // * {} -> [xxxxxxx] {}
          node = selectorParser.combinator({
            value: '',
          })
          selector.insertBefore(n, node)
          selector.removeChild(n)
          return false
        }
      }
      // store the universal selector so it can be rewritten later
      // .foo * -> .foo[xxxxxxx] [xxxxxxx]
      starNode = n
    }

    if (
      (n.type !== 'pseudo' &&
        n.type !== 'combinator' &&
        n.type !== 'universal') ||
      (n.type === 'pseudo' &&
        (n.value === ':is' || n.value === ':where') &&
        !node)
    ) {
      node = n
      starNode = null
    }
  })

  if (rule.nodes.some(node => node.type === 'rule')) {
    const deep = (rule as any).__deep
    if (!deep) {
      extractAndWrapNodes(rule)
      const atruleNodes = rule.nodes.filter(node => node.type === 'atrule')
      for (const atnode of atruleNodes) {
        extractAndWrapNodes(atnode)
      }
    }
Repository: vuejs/vue-next
File: packages/compiler-sfc/src/style/pluginScoped.ts (TypeScript)

Code before:
      }
    }

    if (n.type === 'universal') {
      const prev = selector.at(selector.index(n) - 1)
      const next = selector.at(selector.index(n) + 1)
      // * ... {}
      if (!prev) {
        // * .foo {} -> .foo[xxxxxxx] {}
        if (next) {
          if (next.type === 'combinator' && next.value === ' ') {
            selector.removeChild(next)
          }
          selector.removeChild(n)
          return
        } else {
          // * {} -> [xxxxxxx] {}
          node = selectorParser.combinator({
            value: '',
          })
          selector.insertBefore(n, node)
          selector.removeChild(n)
          return false
        }
      }
      //                         v- store this
      // .foo * -> .foo[xxxxxxx] [xxxxxxx]
      starNode = n
    }

    if (
      (n.type !== 'pseudo' &&
        n.type !== 'combinator' &&
        n.type !== 'universal') ||
      (n.type === 'pseudo' &&
        (n.value === ':is' || n.value === ':where') &&
        !node)
    ) {
      node = n
      starNode = null
    }
  })

  if (rule.nodes.some(node => node.type === 'rule')) {
    const deep = (rule as any).__deep
    if (!deep) {
      extractAndWrapNodes(rule)
      const atruleNodes = rule.nodes.filter(node => node.type === 'atrule')
      for (const atnode of atruleNodes) {
        extractAndWrapNodes(atnode)
      }

Review comment (suggestion):
```suggestion
      // store the universal selector so it can be rewritten later
```

Code after:
      }
    }

    if (n.type === 'universal') {
      const prev = selector.at(selector.index(n) - 1)
      const next = selector.at(selector.index(n) + 1)
      // * ... {}
      if (!prev) {
        // * .foo {} -> .foo[xxxxxxx] {}
        if (next) {
          if (next.type === 'combinator' && next.value === ' ') {
            selector.removeChild(next)
          }
          selector.removeChild(n)
          return
        } else {
          // * {} -> [xxxxxxx] {}
          node = selectorParser.combinator({
            value: '',
          })
          selector.insertBefore(n, node)
          selector.removeChild(n)
          return false
        }
      }
      // store the universal selector so it can be rewritten later
      // .foo * -> .foo[xxxxxxx] [xxxxxxx]
      starNode = n
    }

    if (
      (n.type !== 'pseudo' &&
        n.type !== 'combinator' &&
        n.type !== 'universal') ||
      (n.type === 'pseudo' &&
        (n.value === ':is' || n.value === ':where') &&
        !node)
    ) {
      node = n
      starNode = null
    }
  })

  if (rule.nodes.some(node => node.type === 'rule')) {
    const deep = (rule as any).__deep
    if (!deep) {
      extractAndWrapNodes(rule)
      const atruleNodes = rule.nodes.filter(node => node.type === 'atrule')
      for (const atnode of atruleNodes) {
        extractAndWrapNodes(atnode)
      }
Repository: vuejs/vue-next
File: packages/vue-compat/__tests__/compiler.spec.ts (TypeScript)

Code before:
    },
  }).$mount()

  expect(vm.$el).toBeInstanceOf(HTMLButtonElement)
  expect(vm.$el.textContent).toBe(`0`)

  triggerEvent(vm.$el as Element, 'click')
  await nextTick()
  expect(vm.$el.textContent).toBe(`1`)

  expect(CompilerDeprecationTypes.COMPILER_V_BIND_SYNC).toHaveBeenWarned()
})

test('COMPILER_V_BIND_OBJECT_ORDER', () => {
  const vm = new Vue({
    template: `<div id="foo" v-bind="{ id: 'bar', class: 'baz' }" />`,
  }).$mount()
  expect(vm.$el).toBeInstanceOf(HTMLDivElement)
  expect(vm.$el.id).toBe('foo')
  expect(vm.$el.className).toBe('baz')
  expect(
    CompilerDeprecationTypes.COMPILER_V_BIND_OBJECT_ORDER,
  ).toHaveBeenWarned()
})

test('COMPILER_V_BIND_OBJECT_ORDER', () => {
  const vm = new Vue({
    template: `<div><div v-bind="{ id: 'bar', class: 'baz' }" v-for="item in 5" /></div>`,
  }).$mount()
  expect(vm.$el).toBeInstanceOf(HTMLDivElement)
  expect(
    CompilerDeprecationTypes.COMPILER_V_BIND_OBJECT_ORDER,
  ).not.toHaveBeenWarned()
})

test('COMPILER_V_ON_NATIVE', () => {
  const spy = vi.fn()
  const vm = new Vue({
    template: `<child @click="spy" @click.native="spy" />`,
    components: {
      child: {
        template: `<button />`,
      },
    },
    methods: {
      spy,
    },
  }).$mount()

  expect(vm.$el).toBeInstanceOf(HTMLButtonElement)
  triggerEvent(vm.$el as HTMLButtonElement, 'click')

Review comment (suggestion):
```suggestion
test('should not warn COMPILER_V_BIND_OBJECT_ORDER work with vFor', () => {
```

Code after:
    },
  }).$mount()

  expect(vm.$el).toBeInstanceOf(HTMLButtonElement)
  expect(vm.$el.textContent).toBe(`0`)

  triggerEvent(vm.$el as Element, 'click')
  await nextTick()
  expect(vm.$el.textContent).toBe(`1`)

  expect(CompilerDeprecationTypes.COMPILER_V_BIND_SYNC).toHaveBeenWarned()
})

test('COMPILER_V_BIND_OBJECT_ORDER', () => {
  const vm = new Vue({
    template: `<div id="foo" v-bind="{ id: 'bar', class: 'baz' }" />`,
  }).$mount()
  expect(vm.$el).toBeInstanceOf(HTMLDivElement)
  expect(vm.$el.id).toBe('foo')
  expect(vm.$el.className).toBe('baz')
  expect(
    CompilerDeprecationTypes.COMPILER_V_BIND_OBJECT_ORDER,
  ).toHaveBeenWarned()
})

test('should not warn COMPILER_V_BIND_OBJECT_ORDER work with vFor', () => {
  const vm = new Vue({
    template: `<div><div v-bind="{ id: 'bar', class: 'baz' }" v-for="item in 5" /></div>`,
  }).$mount()
  expect(vm.$el).toBeInstanceOf(HTMLDivElement)
  expect(
    CompilerDeprecationTypes.COMPILER_V_BIND_OBJECT_ORDER,
  ).not.toHaveBeenWarned()
})

test('COMPILER_V_ON_NATIVE', () => {
  const spy = vi.fn()
  const vm = new Vue({
    template: `<child @click="spy" @click.native="spy" />`,
    components: {
      child: {
        template: `<button />`,
      },
    },
    methods: {
      spy,
    },
  }).$mount()

  expect(vm.$el).toBeInstanceOf(HTMLButtonElement)
  triggerEvent(vm.$el as HTMLButtonElement, 'click')
Repository: vuejs/vue-next
File: packages/compiler-vapor/src/transforms/transformElement.ts (TypeScript)

Code before:
    const dotIndex = tag.indexOf('.')
    if (dotIndex > 0) {
      const ns = resolveSetupReference(tag.slice(0, dotIndex), context)
      if (ns) {
        tag = ns + tag.slice(dotIndex)
        asset = false
      }
    }

    if (asset) {
      context.component.add(tag)
    }
  }

  const hasVFor = node.props.some(
    p => p.type === NodeTypes.DIRECTIVE && p.name === 'for',
  )

  context.dynamic.flags |= DynamicFlag.NON_TEMPLATE | DynamicFlag.INSERT
  context.dynamic.operation = {
    type: IRNodeTypes.CREATE_COMPONENT_NODE,
    id: context.reference(),
    tag,
    props: propsResult[0] ? propsResult[1] : [propsResult[1]],
    asset,
    root: singleRoot && !hasVFor,
    slots: [...context.slots],
    once: context.inVOnce,
    dynamic: dynamicComponent,
  }
  context.slots = []
}

function resolveDynamicComponent(node: ComponentNode) {
  const isProp = findProp(node, 'is', false, true /* allow empty */)
  if (!isProp) return

  if (isProp.type === NodeTypes.ATTRIBUTE) {
    return isProp.value && createSimpleExpression(isProp.value.content, true)
  } else {
    return (
      isProp.exp ||
      // #10469 handle :is shorthand
      extend(createSimpleExpression(`is`, false, isProp.arg!.loc), {
        ast: null,
      })
    )
  }
}

function resolveSetupReference(name: string, context: TransformContext) {

Review comment (suggestion):
```suggestion
    root: singleRoot && !context.inVFor,
```

Code after:
    const dotIndex = tag.indexOf('.')
    if (dotIndex > 0) {
      const ns = resolveSetupReference(tag.slice(0, dotIndex), context)
      if (ns) {
        tag = ns + tag.slice(dotIndex)
        asset = false
      }
    }

    if (asset) {
      // self referencing component (inferred from filename)
      if (context.selfName && capitalize(camelize(tag)) === context.selfName) {
        // generators/block.ts has special check for __self postfix when generating
        // component imports, which will pass additional `maybeSelfReference` flag
        // to `resolveComponent`.
        tag += `__self`
      }
      context.component.add(tag)
    }
  }

  context.dynamic.flags |= DynamicFlag.NON_TEMPLATE | DynamicFlag.INSERT
  context.dynamic.operation = {
    type: IRNodeTypes.CREATE_COMPONENT_NODE,
    id: context.reference(),
    tag,
    props: propsResult[0] ? propsResult[1] : [propsResult[1]],
    asset,
    root: singleRoot && !context.inVFor,
    slots: [...context.slots],
    once: context.inVOnce,
    dynamic: dynamicComponent,
  }
  context.slots = []
}

function resolveDynamicComponent(node: ComponentNode) {
  const isProp = findProp(node, 'is', false, true /* allow empty */)
  if (!isProp) return

  if (isProp.type === NodeTypes.ATTRIBUTE) {
    return isProp.value && createSimpleExpression(isProp.value.content, true)
  } else {
    return (
      isProp.exp ||
      // #10469 handle :is shorthand
      extend(createSimpleExpression(`is`, false, isProp.arg!.loc), {
        ast: null,
      })
    )
  }
Repository: vuejs/vue-next
File: packages/runtime-dom/src/apiCustomElement.ts (TypeScript)

Code before:
        this._parent = parent
        break
      }
    }

    if (!this._instance) {
      if (this._resolved) {
        this._setParent()
        this._update()
      } else {
        if (parent && parent._pendingResolve) {
          this._pendingResolve = parent._pendingResolve.then(() => {
            this._pendingResolve = undefined
            this._resolveDef()
          })
        } else {
          this._resolveDef()
        }
      }
    }
  }

  private _setParent(parent = this._parent) {
    if (parent) {
      this._instance!.parent = parent._instance
      this._instance!.provides = this._instance!.appContext.provides
      this._inheritParentContext(parent)
    }
  }

  private _inheritParentContext(parent = this._parent) {
    // #13212, the provides object of the app context must inherit the provides
    // object from the parent element so we can inject values from both places
    if (parent && this._app) {
      Object.setPrototypeOf(
        this._app._context.provides,
        parent._instance!.provides,
      )
    }
  }

  disconnectedCallback(): void {
    this._connected = false
    nextTick(() => {
      if (!this._connected) {
        if (this._ob) {
          this._ob.disconnect()
          this._ob = null
        }
        // unmount
        this._app && this._app.unmount()

Review comment (suggestion):
This line is unnecessary because it's already inherit from `appContext.provides`
https://github.com/vuejs/core/blob/4f792535e25af6941d1eb267fe16e4121623a006/packages/runtime-core/src/component.ts#L633

Code after:
        this._parent = parent
        break
      }
    }

    if (!this._instance) {
      if (this._resolved) {
        this._setParent()
        this._update()
      } else {
        if (parent && parent._pendingResolve) {
          this._pendingResolve = parent._pendingResolve.then(() => {
            this._pendingResolve = undefined
            this._resolveDef()
          })
        } else {
          this._resolveDef()
        }
      }
    }
  }

  private _setParent(parent = this._parent) {
    if (parent) {
      this._instance!.parent = parent._instance
      this._inheritParentContext(parent)
    }
  }

  private _inheritParentContext(parent = this._parent) {
    // #13212, the provides object of the app context must inherit the provides
    // object from the parent element so we can inject values from both places
    if (parent && this._app) {
      Object.setPrototypeOf(
        this._app._context.provides,
        parent._instance!.provides,
      )
    }
  }

  disconnectedCallback(): void {
    this._connected = false
    nextTick(() => {
      if (!this._connected) {
        if (this._ob) {
          this._ob.disconnect()
          this._ob = null
        }
        // unmount
        this._app && this._app.unmount()
        if (this._instance) this._instance.ce = undefined
Repository: vuejs/vue-next
File: packages/runtime-core/src/hydration.ts (TypeScript)

Code before:

    // update vnode
    let parent = parentComponent
    while (parent) {
      if (parent.vnode.el === oldNode) {
        parent.vnode.el = parent.subTree.el = newNode
      }
      parent = parent.parent
    }
  }

  const isTemplateNode = (node: Node): node is HTMLTemplateElement => {
    return (
      node.nodeType === DOMNodeTypes.ELEMENT &&
      (node as Element).tagName === 'TEMPLATE'
    )
  }

  return [hydrate, hydrateNode]
}

/**
 * Dev only
 */
function propHasMismatch(
  el: Element & { $cls?: string | null },
  key: string,
  clientValue: any,
  vnode: VNode,
  instance: ComponentInternalInstance | null,
): boolean {
  let mismatchType: MismatchTypes | undefined
  let mismatchKey: string | undefined
  let actual: string | boolean | null | undefined
  let expected: string | boolean | null | undefined
  if (key === 'class') {
    // classes might be in different order, but that doesn't affect cascade
    // so we just need to check if the class lists contain the same classes.
    if (el.$cls) {
      actual = el.$cls
      delete el.$cls
    } else {
      actual = el.getAttribute('class')
    }
    expected = normalizeClass(clientValue)
    if (!isSetEqual(toClassSet(actual || ''), toClassSet(expected))) {
      mismatchType = MismatchTypes.CLASS
      mismatchKey = `class`
    }
  } else if (key === 'style') {
    // style might be in different order, but that doesn't affect cascade

Review comment (suggestion):
```suggestion
  el: Element & { $cls?: string },
```

Code after:
    }

    // update vnode
    let parent = parentComponent
    while (parent) {
      if (parent.vnode.el === oldNode) {
        parent.vnode.el = parent.subTree.el = newNode
      }
      parent = parent.parent
    }
  }

  const isTemplateNode = (node: Node): node is HTMLTemplateElement => {
    return (
      node.nodeType === DOMNodeTypes.ELEMENT &&
      (node as Element).tagName === 'TEMPLATE'
    )
  }

  return [hydrate, hydrateNode]
}

/**
 * Dev only
 */
function propHasMismatch(
  el: Element & { $cls?: string },
  key: string,
  clientValue: any,
  vnode: VNode,
  instance: ComponentInternalInstance | null,
): boolean {
  let mismatchType: MismatchTypes | undefined
  let mismatchKey: string | undefined
  let actual: string | boolean | null | undefined
  let expected: string | boolean | null | undefined
  if (key === 'class') {
    // classes might be in different order, but that doesn't affect cascade
    // so we just need to check if the class lists contain the same classes.
    if (el.$cls) {
      actual = el.$cls
      delete el.$cls
    } else {
      actual = el.getAttribute('class')
    }
    expected = normalizeClass(clientValue)
    if (!isSetEqual(toClassSet(actual || ''), toClassSet(expected))) {
      mismatchType = MismatchTypes.CLASS
      mismatchKey = `class`
    }
  } else if (key === 'style') {
Repository: vuejs/vue-next
File: packages/compiler-sfc/__tests__/compileScript.spec.ts (TypeScript)

Code before:
          })
        </script>`).content,
      )
    })

    test('should allow defineProps/Emit() referencing imported binding', () => {
      assertCode(
        compile(`<script setup>
        import { bar } from './bar'
        defineProps({
          foo: {
            default: () => bar
          }
        })
        defineEmits({
          foo: () => bar > 1
        })
        </script>`).content,
      )
    })

    test('defineModel() referencing local var', () => {
      expect(() =>
        compile(`<script setup>
        let bar = 1
        const model =defineModel({
          default: () => bar
        })
        </script>`),
      ).toThrow(`cannot reference locally declared variables`)

      // allow const
      expect(() =>
        compile(`<script setup>
        const bar = 1
        const model = defineModel({
          default: () => bar
        })
        </script>`),
      ).not.toThrow(`cannot reference locally declared variables`)

      // allow in get/set
      expect(() =>
        compile(`<script setup>
        let bar = 1
        const model = defineModel({
          get: () => bar,
          set: () => bar
        })
        </script>`),
      ).not.toThrow(`cannot reference locally declared variables`)

Review comment (suggestion):
```suggestion
        const model = defineModel({
```

Code after:
          })
        </script>`).content,
      )
    })

    test('should allow defineProps/Emit() referencing imported binding', () => {
      assertCode(
        compile(`<script setup>
        import { bar } from './bar'
        defineProps({
          foo: {
            default: () => bar
          }
        })
        defineEmits({
          foo: () => bar > 1
        })
        </script>`).content,
      )
    })

    test('defineModel() referencing local var', () => {
      expect(() =>
        compile(`<script setup>
        let bar = 1
        const model = defineModel({
          default: () => bar
        })
        </script>`),
      ).toThrow(`cannot reference locally declared variables`)

      // allow const
      expect(() =>
        compile(`<script setup>
        const bar = 1
        const model = defineModel({
          default: () => bar
        })
        </script>`),
      ).not.toThrow(`cannot reference locally declared variables`)

      // allow in get/set
      expect(() =>
        compile(`<script setup>
        let bar = 1
        const model = defineModel({
          get: () => bar,
          set: () => bar
        })
        </script>`),
      ).not.toThrow(`cannot reference locally declared variables`)