123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- /**
- * @fileoverview disallow usage of `this` in template.
- * @author Armano
- */
- 'use strict'
- // ------------------------------------------------------------------------------
- // Requirements
- // ------------------------------------------------------------------------------
- const utils = require('../utils')
- const RESERVED_NAMES = new Set(require('../utils/js-reserved.json'))
- // ------------------------------------------------------------------------------
- // Rule Definition
- // ------------------------------------------------------------------------------
- module.exports = {
- meta: {
- type: 'suggestion',
- docs: {
- description: 'disallow usage of `this` in template',
- category: 'recommended',
- url: 'https://eslint.vuejs.org/rules/this-in-template.html'
- },
- fixable: null,
- schema: [
- {
- enum: ['always', 'never']
- }
- ]
- },
- /**
- * Creates AST event handlers for this-in-template.
- *
- * @param {RuleContext} context - The rule context.
- * @returns {Object} AST event handlers.
- */
- create (context) {
- const options = context.options[0] !== 'always' ? 'never' : 'always'
- let scope = {
- parent: null,
- nodes: []
- }
- return utils.defineTemplateBodyVisitor(context, Object.assign({
- VElement (node) {
- scope = {
- parent: scope,
- nodes: scope.nodes.slice() // make copy
- }
- if (node.variables) {
- for (const variable of node.variables) {
- const varNode = variable.id
- const name = varNode.name
- if (!scope.nodes.some(node => node.name === name)) { // Prevent adding duplicates
- scope.nodes.push(varNode)
- }
- }
- }
- },
- 'VElement:exit' (node) {
- scope = scope.parent
- }
- }, options === 'never'
- ? {
- 'VExpressionContainer MemberExpression > ThisExpression' (node) {
- const propertyName = utils.getStaticPropertyName(node.parent.property)
- if (!propertyName ||
- scope.nodes.some(el => el.name === propertyName) ||
- RESERVED_NAMES.has(propertyName) || // this.class | this['class']
- /^[0-9].*$|[^a-zA-Z0-9_]/.test(propertyName) // this['0aaaa'] | this['foo-bar bas']
- ) {
- return
- }
- context.report({
- node,
- loc: node.loc,
- message: "Unexpected usage of 'this'."
- })
- }
- }
- : {
- 'VExpressionContainer' (node) {
- if (node.references) {
- for (const reference of node.references) {
- if (!scope.nodes.some(el => el.name === reference.id.name)) {
- context.report({
- node: reference.id,
- loc: reference.id.loc,
- message: "Expected 'this'."
- })
- }
- }
- }
- }
- }
- ))
- }
- }
|