1. /* @flow */
    2. import config from '../config'
    3. import { noop } from 'shared/util'
    4. export let warn = noop
    5. export let tip = noop
    6. export let generateComponentTrace = (noop: any) // work around flow check
    7. export let formatComponentName = (noop: any)
    8. if (process.env.NODE_ENV !== 'production') {
    9. const hasConsole = typeof console !== 'undefined'
    10. const classifyRE = /(?:^|[-_])(\w)/g
    11. const classify = str => str
    12. .replace(classifyRE, c => c.toUpperCase())
    13. .replace(/[-_]/g, '')
    14. warn = (msg, vm) => {
    15. const trace = vm ? generateComponentTrace(vm) : ''
    16. if (config.warnHandler) {
    17. config.warnHandler.call(null, msg, vm, trace)
    18. } else if (hasConsole && (!config.silent)) {
    19. console.error(`[Vue warn]: ${msg}${trace}`)
    20. }
    21. }
    22. tip = (msg, vm) => {
    23. if (hasConsole && (!config.silent)) {
    24. console.warn(`[Vue tip]: ${msg}` + (
    25. vm ? generateComponentTrace(vm) : ''
    26. ))
    27. }
    28. }
    29. formatComponentName = (vm, includeFile) => {
    30. if (vm.$root === vm) {
    31. return '<Root>'
    32. }
    33. const options = typeof vm === 'function' && vm.cid != null
    34. ? vm.options
    35. : vm._isVue
    36. ? vm.$options || vm.constructor.options
    37. : vm
    38. let name = options.name || options._componentTag
    39. const file = options.__file
    40. if (!name && file) {
    41. const match = file.match(/([^/\\]+)\.vue$/)
    42. name = match && match[1]
    43. }
    44. return (
    45. (name ? `<${classify(name)}>` : `<Anonymous>`) +
    46. (file && includeFile !== false ? ` at ${file}` : '')
    47. )
    48. }
    49. const repeat = (str, n) => {
    50. let res = ''
    51. while (n) {
    52. if (n % 2 === 1) res += str
    53. if (n > 1) str += str
    54. n >>= 1
    55. }
    56. return res
    57. }
    58. generateComponentTrace = vm => {
    59. if (vm._isVue && vm.$parent) {
    60. const tree = []
    61. let currentRecursiveSequence = 0
    62. while (vm) {
    63. if (tree.length > 0) {
    64. const last = tree[tree.length - 1]
    65. if (last.constructor === vm.constructor) {
    66. currentRecursiveSequence++
    67. vm = vm.$parent
    68. continue
    69. } else if (currentRecursiveSequence > 0) {
    70. tree[tree.length - 1] = [last, currentRecursiveSequence]
    71. currentRecursiveSequence = 0
    72. }
    73. }
    74. tree.push(vm)
    75. vm = vm.$parent
    76. }
    77. return '\n\nfound in\n\n' + tree
    78. .map((vm, i) => `${
    79. i === 0 ? '---> ' : repeat(' ', 5 + i * 2)
    80. }${
    81. Array.isArray(vm)
    82. ? `${formatComponentName(vm[0])}... (${vm[1]} recursive calls)`
    83. : formatComponentName(vm)
    84. }`)
    85. .join('\n')
    86. } else {
    87. return `\n\n(found in ${formatComponentName(vm)})`
    88. }
    89. }
    90. }