Repository: vuejs/vue-next
File: packages/compiler-core/src/transforms/transformElement.ts (TypeScript)

Code before:
      // skip v-on in SSR compilation
      if (isVOn && ssr) {
        continue
      }

      if (
        // #938: elements with dynamic keys should be forced into blocks
        (isVBind && isStaticArgOf(arg, 'key')) ||
        // inline before-update hooks need to force block so that it is invoked
        // before children
        (isVOn && hasChildren && isStaticArgOf(arg, 'vue:before-update'))
      ) {
        shouldUseBlock = true
      }

      if (isVBind && isStaticArgOf(arg, 'ref')) {
        pushRefVForMarker()
      }

      // special case for v-bind and v-on with no argument
      if (!arg && (isVBind || isVOn)) {
        hasDynamicKeys = true
        if (exp) {
          if (isVBind) {
            // have to merge early for compat build check
            pushMergeArg()
            if (__COMPAT__) {
              // 2.x v-bind object order compat
              if (__DEV__) {
                const hasOverridableKeys = mergeArgs.some(arg => {
                  if (arg.type === NodeTypes.JS_OBJECT_EXPRESSION) {
                    return arg.properties.some(({ key }) => {
                      if (
                        key.type !== NodeTypes.SIMPLE_EXPRESSION ||
                        !key.isStatic
                      ) {
                        return true
                      }
                      return (
                        key.content !== 'class' &&
                        key.content !== 'style' &&
                        !isOn(key.content)
                      )
                    })
                  } else {
                    // dynamic expression
                    return true
                  }
                })
                if (hasOverridableKeys) {
                  checkCompatEnabled(

Review comment (suggestion):
Given the new call to `pushMergeArg()` that's been added just before `mergeArgs.push(exp)`, I'm wondering whether this earlier call can now be moved inside the `if (__COMPAT__) {` check?

For non-compat builds I think that'd be equivalent to what we have currently, with just a single call to `pushMergeArg()`, so we'd only have the double push in the compat build.

Code after:
      // skip v-on in SSR compilation
      if (isVOn && ssr) {
        continue
      }

      if (
        // #938: elements with dynamic keys should be forced into blocks
        (isVBind && isStaticArgOf(arg, 'key')) ||
        // inline before-update hooks need to force block so that it is invoked
        // before children
        (isVOn && hasChildren && isStaticArgOf(arg, 'vue:before-update'))
      ) {
        shouldUseBlock = true
      }

      if (isVBind && isStaticArgOf(arg, 'ref')) {
        pushRefVForMarker()
      }

      // special case for v-bind and v-on with no argument
      if (!arg && (isVBind || isVOn)) {
        hasDynamicKeys = true
        if (exp) {
          if (isVBind) {
            if (__COMPAT__) {
              // have to merge early for compat build check
              pushMergeArg()
              // 2.x v-bind object order compat
              if (__DEV__) {
                const hasOverridableKeys = mergeArgs.some(arg => {
                  if (arg.type === NodeTypes.JS_OBJECT_EXPRESSION) {
                    return arg.properties.some(({ key }) => {
                      if (
                        key.type !== NodeTypes.SIMPLE_EXPRESSION ||
                        !key.isStatic
                      ) {
                        return true
                      }
                      return (
                        key.content !== 'class' &&
                        key.content !== 'style' &&
                        !isOn(key.content)
                      )
                    })
                  } else {
                    // dynamic expression
                    return true
                  }
                })
                if (hasOverridableKeys) {
                  checkCompatEnabled(