no-deprecated-props-default-this.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. /**
  2. * @author Yosuke Ota
  3. * See LICENSE file in root directory for full license.
  4. */
  5. 'use strict'
  6. // ------------------------------------------------------------------------------
  7. // Requirements
  8. // ------------------------------------------------------------------------------
  9. const utils = require('../utils')
  10. // ------------------------------------------------------------------------------
  11. // Rule Definition
  12. // ------------------------------------------------------------------------------
  13. module.exports = {
  14. meta: {
  15. type: 'problem',
  16. docs: {
  17. description: 'disallow props default function `this` access',
  18. categories: ['vue3-essential'],
  19. url:
  20. 'https://eslint.vuejs.org/rules/no-deprecated-props-default-this.html'
  21. },
  22. fixable: null,
  23. schema: [],
  24. messages: {
  25. deprecated:
  26. 'Props default value factory functions no longer have access to `this`.'
  27. }
  28. },
  29. /** @param {RuleContext} context */
  30. create(context) {
  31. /**
  32. * @typedef {object} ScopeStack
  33. * @property {ScopeStack | null} upper
  34. * @property {FunctionExpression | FunctionDeclaration} node
  35. * @property {boolean} propDefault
  36. */
  37. /** @type {Set<FunctionExpression>} */
  38. const propsDefault = new Set()
  39. /** @type {ScopeStack | null} */
  40. let scopeStack = null
  41. /**
  42. * @param {FunctionExpression | FunctionDeclaration | ArrowFunctionExpression} node
  43. */
  44. function onFunctionEnter(node) {
  45. if (node.type === 'ArrowFunctionExpression') {
  46. return
  47. }
  48. if (scopeStack) {
  49. scopeStack = {
  50. upper: scopeStack,
  51. node,
  52. propDefault: false
  53. }
  54. } else if (node.type === 'FunctionExpression' && propsDefault.has(node)) {
  55. scopeStack = {
  56. upper: scopeStack,
  57. node,
  58. propDefault: true
  59. }
  60. }
  61. }
  62. /**
  63. * @param {FunctionExpression | FunctionDeclaration | ArrowFunctionExpression} node
  64. */
  65. function onFunctionExit(node) {
  66. if (scopeStack && scopeStack.node === node) {
  67. scopeStack = scopeStack.upper
  68. }
  69. }
  70. return utils.defineVueVisitor(context, {
  71. onVueObjectEnter(node) {
  72. for (const prop of utils.getComponentProps(node)) {
  73. if (prop.type !== 'object') {
  74. continue
  75. }
  76. if (prop.value.type !== 'ObjectExpression') {
  77. continue
  78. }
  79. const def = utils.findProperty(prop.value, 'default')
  80. if (!def) {
  81. continue
  82. }
  83. if (def.value.type !== 'FunctionExpression') {
  84. continue
  85. }
  86. propsDefault.add(def.value)
  87. }
  88. },
  89. ':function': onFunctionEnter,
  90. ':function:exit': onFunctionExit,
  91. ThisExpression(node) {
  92. if (scopeStack && scopeStack.propDefault) {
  93. context.report({
  94. node,
  95. messageId: 'deprecated'
  96. })
  97. }
  98. }
  99. })
  100. }
  101. }