no-side-effects-in-computed-properties.js 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. /**
  2. * @fileoverview Don't introduce side effects in computed properties
  3. * @author Michał Sajnóg
  4. */
  5. 'use strict'
  6. const utils = require('../utils')
  7. // ------------------------------------------------------------------------------
  8. // Rule Definition
  9. // ------------------------------------------------------------------------------
  10. module.exports = {
  11. meta: {
  12. type: 'problem',
  13. docs: {
  14. description: 'disallow side effects in computed properties',
  15. category: 'essential',
  16. url: 'https://eslint.vuejs.org/rules/no-side-effects-in-computed-properties.html'
  17. },
  18. fixable: null,
  19. schema: []
  20. },
  21. create (context) {
  22. const forbiddenNodes = []
  23. return Object.assign({},
  24. {
  25. // this.xxx <=|+=|-=>
  26. 'AssignmentExpression' (node) {
  27. if (node.left.type !== 'MemberExpression') return
  28. if (utils.parseMemberExpression(node.left)[0] === 'this') {
  29. forbiddenNodes.push(node)
  30. }
  31. },
  32. // this.xxx <++|-->
  33. 'UpdateExpression > MemberExpression' (node) {
  34. if (utils.parseMemberExpression(node)[0] === 'this') {
  35. forbiddenNodes.push(node)
  36. }
  37. },
  38. // this.xxx.func()
  39. 'CallExpression' (node) {
  40. const code = utils.parseMemberOrCallExpression(node)
  41. const MUTATION_REGEX = /(this.)((?!(concat|slice|map|filter)\().)[^\)]*((push|pop|shift|unshift|reverse|splice|sort|copyWithin|fill)\()/g
  42. if (MUTATION_REGEX.test(code)) {
  43. forbiddenNodes.push(node)
  44. }
  45. }
  46. },
  47. utils.executeOnVue(context, (obj) => {
  48. const computedProperties = utils.getComputedProperties(obj)
  49. computedProperties.forEach(cp => {
  50. forbiddenNodes.forEach(node => {
  51. if (
  52. cp.value &&
  53. node.loc.start.line >= cp.value.loc.start.line &&
  54. node.loc.end.line <= cp.value.loc.end.line
  55. ) {
  56. context.report({
  57. node: node,
  58. message: 'Unexpected side effect in "{{key}}" computed property.',
  59. data: { key: cp.key }
  60. })
  61. }
  62. })
  63. })
  64. })
  65. )
  66. }
  67. }