/** * @author Yosuke Ota * See LICENSE file in root directory for full license. */ "use strict" const { getFunctionNameWithKind, getPropertyName, } = require("@eslint-community/eslint-utils") const { getSourceCode } = require("eslint-compat-utils") /** * Get the name and kind of the given PropertyDefinition node. * @param {PropertyDefinition} node - The PropertyDefinition node to get. * @param {SourceCode} sourceCode The source code object to get the code of computed property keys. * @returns {string} The name and kind of the PropertyDefinition node. */ function getFieldNameWithKind(node, sourceCode) { const tokens = [] if (node.static) { tokens.push("static") } if (node.key.type === "PrivateIdentifier") { tokens.push("private") } tokens.push("field") if (node.key.type === "PrivateIdentifier") { tokens.push(`#${node.key.name}`) } else { const name = getPropertyName(node) if (name) { tokens.push(`'${name}'`) } else if (sourceCode) { const keyText = sourceCode.getText(node.key) if (!keyText.includes("\n")) { tokens.push(`[${keyText}]`) } } } return tokens.join(" ") } module.exports = { meta: { docs: { description: "disallow class fields.", category: "ES2022", recommended: false, url: "http://eslint-community.github.io/eslint-plugin-es-x/rules/no-class-fields.html", }, fixable: null, messages: { forbidden: "ES2022 {{nameWithKind}} is forbidden.", }, schema: [], type: "problem", }, create(context) { return { PropertyDefinition(node) { if (node.declare || node.parent.parent.declare) { return } context.report({ node: node.key, messageId: "forbidden", data: { nameWithKind: getFieldNameWithKind( node, getSourceCode(context), ), }, }) }, "MethodDefinition:exit"(node) { if (node.key.type !== "PrivateIdentifier") { return } context.report({ node: node.key, messageId: "forbidden", data: { nameWithKind: getFunctionNameWithKind( node.value, getSourceCode(context), ), }, }) }, ":not(PropertyDefinition, MethodDefinition) > PrivateIdentifier"( node, ) { const parent = node.parent context.report({ node, messageId: "forbidden", data: { nameWithKind: parent.parent.type === "CallExpression" && parent.parent.callee === parent ? `private method call #${node.name}()` : `private access #${node.name}`, }, }) }, } }, }