Skip to content

False negative with vue/no-unused-properties #1462

Closed
@dsl101

Description

@dsl101

Checklist

  • I have tried restarting my IDE and the issue persists.
  • I have read the FAQ and my problem is not listed.

Tell us about your environment

  • ESLint version: v7.16.0
  • eslint-plugin-vue version: 7.7.0
  • Node version: v14.16.0
  • Operating System: Windows 10 Pro

Please show your full configuration:

module.exports = {
  root: true,

  parserOptions: {
    parser: 'babel-eslint',
    ecmaVersion: 2018, // Allows for the parsing of modern ECMAScript features
    sourceType: 'module'
  },

  env: {
    browser: true
  },

  extends: [
    // https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention
    // consider switching to `plugin:vue/strongly-recommended` or `plugin:vue/recommended` for stricter rules.
    'eslint:recommended',
    'plugin:vue/recommended',
    'plugin:quasar/standard',
    'plugin:import/errors',
    'plugin:import/warnings',
    // '@vue/standard'
  ],

  // required to lint *.vue files
  plugins: [
    // 'vue',
    // 'quasar',
    // 'import',
  ],
  // "settings": {
  //   "import/resolver": {
  //     "webpack": {
  //       "config": "webpack.config-base.js"
  //     }
  //   }
  // },

  'settings': {
    'import/resolver': 'webpack'
    // 'import/resolver': {
    //   'webpack': {
    //     'config': 'build/webpack.base.conf.js'
    //   }
    // }
  },

  globals: {
    // '_': false,
    'APP_VERSION': 'readonly',
    '__dirname': 'readonly',
    'module': 'writable',
    // 'ga': true, // Google Analytics
    // 'cordova': true,
    // '__statics': true,
    'process': 'readonly',
    'require': 'readonly'
  },

  // add your custom rules here
  rules: {
    // Quasar
    'vue/order-in-components': 'off',
    'no-shadow': ['error', { 'builtinGlobals': true, 'hoist': 'functions', 'allow': [] }],
    // allow async-await
    'generator-star-spacing': 'off',
    // allow paren-less arrow functions
    'arrow-parens': 'off',
    'one-var': 'off',

    // 'import/first': 'off',
    // 'import/named': 'error',
    // 'import/namespace': 'error',
    // 'import/default': 'error',
    // 'import/export': 'error',
    // 'import/extensions': 'off',
    // 'import/no-unresolved': 'off',
    // 'import/no-extraneous-dependencies': 'off',
    'prefer-promise-reject-errors': 'off',

    // Allow v-for and v-if when not trivial to replace
    'vue/no-use-v-if-with-v-for': ['error', {
      'allowUsingIterationVar': true
    }],

    'vue/no-parsing-error': ['error', {
      // For {{ a < b ? 'thing1' : 'thing2' }}
      // See https://github.com/vuejs/eslint-plugin-vue/issues/370
      "invalid-first-character-of-tag-name": false
    }],
    'vue/mustache-interpolation-spacing': 'off',
    'vue/attributes-order': ['error', { order: [
      'DEFINITION',  // is
      'LIST_RENDERING',  // v-for
      'CONDITIONALS',  // v-if
      'RENDER_MODIFIERS',  // v-once
      'UNIQUE',  // ref
      'GLOBAL',  // id
      'SLOT',  // slot / v-slot
      'TWO_WAY_BINDING',  // v-model
      'OTHER_DIRECTIVES',  // v-close-overlay
      'OTHER_ATTR',  // class="xyz" / :prop
      'EVENTS',  // @event
      'CONTENT',  // v-html
    ]}],
    'vue/max-attributes-per-line': ['error', {
      'singleline': 6,
      'multiline': {
        'max': 3,
        'allowFirstLine': true
      }
    }],
    'vue/html-indent': ['warn', 2, {
      'attribute': 1,
      'closeBracket': 0,
      'alignAttributesVertically': false,
      'ignores': []
    }],
    'vue/singleline-html-element-content-newline': 'off',
    'vue/multiline-html-element-content-newline': ['error', {
        'ignoreWhenEmpty': true,
        'allowEmptyLines': true
    }],
    'vue/no-unused-properties': ['error', {
      'groups': [ 'props', 'data', 'computed', 'methods' ],
      'deepData': true,
      'ignorePublicMembers': true
    }],
    'no-multiple-empty-lines': ['warn', {
      'max': 2
    }],
    // "vue/multiline-html-element-content-newline": ["error", {
    //     "ignoreWhenEmpty": true,
    //     "ignores": ["pre", "textarea", ...INLINE_ELEMENTS],
    //     "allowEmptyLines": false
    // }],

    // 'quasar/check-valid-props': 2,
    // 'quasar/no-invalid-qfield-usage': 2,
    // 'quasar/no-legacy-directives': 2,

    'require-atomic-updates': 'off',

    // allow console.log during development only
    'no-console': process.env.NODE_ENV === 'production' ? 'error' : ["warn", { allow: ["warn", "error"] }],
    // allow debugger during development only
    'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'warn'
  }
}

What did you do?

I have a number of components using an event bus, which contain code such as this:

<script>
  export default {
    mounted () {
      const handlerName = 'eventHandler'
      // Event registration code ommitted, but would end up calling via:
      this[handlerName]
    },
    methods: {
      eventHandler () {
        // Used
      },
      notused () {
        // should show as error
      }
    }
  }
</script>

Note that neither of the methods are flagged as unused. One of them would be called via the event handler, but any use of this[variable] appears to completely defeat any unused method checking (i.e. all methods are assumed as used).

What did you expect to happen?
That any methods not explicitly called would be flagged as unused. Note, this may be the intended behaviour, but I couldn't find anything in the documentation about this use case, or if there was a configuration option for it.

What actually happened?
No output from eslint.

I am using /** @public */ to mark methods that are called externally, and was hoping that internal methods could be handled in the same way—i.e. that all methods used by this event handling approach would be flagged by eslint as unused, and I would manually label each one that is actually used by the event handling code.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions