UNPKG

eslint-plugin-stylistic-compat

Version:

Compatibility version of @stylistic/eslint-plugin for Node.js >= 12 and ESLint v8

383 lines (378 loc) 15.3 kB
'use strict'; var _mapInstanceProperty = require('@babel/runtime-corejs3/core-js/instance/map'); var utils = require('../utils.js'); var vendor = require('../vendor.js'); var _includesInstanceProperty = require('@babel/runtime-corejs3/core-js/instance/includes'); var _filterInstanceProperty = require('@babel/runtime-corejs3/core-js/instance/filter'); var _forEachInstanceProperty = require('@babel/runtime-corejs3/core-js/instance/for-each'); require('@babel/runtime-corejs3/core-js/object/from-entries'); require('@babel/runtime-corejs3/core-js/object/entries'); require('@babel/runtime-corejs3/core-js/set'); require('@babel/runtime-corejs3/core-js/instance/flags'); require('@babel/runtime-corejs3/core-js/instance/starts-with'); require('@babel/runtime-corejs3/core-js/array/from'); require('@babel/runtime-corejs3/core-js/array/is-array'); require('@babel/runtime-corejs3/core-js/instance/concat'); require('@babel/runtime-corejs3/core-js/object/keys'); require('@babel/runtime-corejs3/core-js/instance/reduce'); require('@babel/runtime-corejs3/core-js/object/assign'); require('@babel/runtime-corejs3/core-js/instance/keys'); require('@babel/runtime-corejs3/core-js/instance/find'); require('@babel/runtime-corejs3/core-js/instance/reverse'); require('@babel/runtime-corejs3/core-js/object/define-property'); require('@babel/runtime-corejs3/core-js/instance/slice'); require('@babel/runtime-corejs3/core-js/object/create'); require('@babel/runtime-corejs3/core-js/object/freeze'); require('@babel/runtime-corejs3/core-js/instance/last-index-of'); require('@babel/runtime-corejs3/core-js/object/define-properties'); require('@babel/runtime-corejs3/core-js/instance/index-of'); require('@babel/runtime-corejs3/core-js/instance/at'); require('@babel/runtime-corejs3/core-js/symbol'); require('@babel/runtime-corejs3/core-js/symbol/iterator'); require('@babel/runtime-corejs3/core-js/parse-int'); require('@babel/runtime-corejs3/core-js/parse-float'); require('@babel/runtime-corejs3/core-js/weak-map'); require('@babel/runtime-corejs3/core-js/global-this'); require('eslint/use-at-your-own-risk'); require('eslint'); require('@babel/runtime-corejs3/core-js/object/get-own-property-descriptor'); require('@babel/runtime-corejs3/core-js/map'); require('@babel/runtime-corejs3/core-js/instance/some'); require('@babel/runtime-corejs3/core-js/instance/every'); require('@babel/runtime-corejs3/core-js/instance/sort'); require('@babel/runtime-corejs3/core-js/array/of'); require('@babel/runtime-corejs3/core-js/instance/entries'); require('@babel/runtime-corejs3/core-js/instance/find-index'); require('@babel/runtime-corejs3/core-js/instance/flat'); require('@babel/runtime-corejs3/core-js/instance/values'); require('@babel/runtime-corejs3/core-js/object/get-own-property-names'); require('@babel/runtime-corejs3/core-js/number/is-finite'); require('@babel/runtime-corejs3/core-js/number/is-nan'); require('@babel/runtime-corejs3/core-js/number/parse-float'); require('@babel/runtime-corejs3/core-js/number/parse-int'); require('@babel/runtime-corejs3/core-js/object/is'); require('@babel/runtime-corejs3/core-js/object/is-extensible'); require('@babel/runtime-corejs3/core-js/object/is-frozen'); require('@babel/runtime-corejs3/core-js/object/is-sealed'); require('@babel/runtime-corejs3/core-js/object/values'); require('@babel/runtime-corejs3/core-js/string/from-code-point'); require('@babel/runtime-corejs3/core-js/string/raw'); require('@babel/runtime-corejs3/core-js/instance/code-point-at'); require('@babel/runtime-corejs3/core-js/instance/ends-with'); require('@babel/runtime-corejs3/core-js/instance/pad-end'); require('@babel/runtime-corejs3/core-js/instance/pad-start'); require('@babel/runtime-corejs3/core-js/instance/trim'); require('@babel/runtime-corejs3/core-js/instance/trim-end'); require('@babel/runtime-corejs3/core-js/instance/trim-left'); require('@babel/runtime-corejs3/core-js/instance/trim-right'); require('@babel/runtime-corejs3/core-js/instance/trim-start'); require('@babel/runtime-corejs3/core-js/symbol/for'); require('@babel/runtime-corejs3/core-js/symbol/key-for'); require('@babel/runtime-corejs3/core-js/object/prevent-extensions'); require('@babel/runtime-corejs3/core-js/object/seal'); require('@babel/runtime-corejs3/core-js/object/get-prototype-of'); require('@babel/runtime-corejs3/core-js/symbol/replace'); require('@babel/runtime-corejs3/core-js/instance/bind'); require('@babel/runtime-corejs3/core-js/instance/splice'); require('@babel/runtime-corejs3/core-js/instance/repeat'); var _baseRule = utils.createRule({ name: "quote-props", package: "js", meta: { type: "layout", docs: { description: "Require quotes around object literal property names" }, schema: { anyOf: [{ type: "array", items: [{ type: "string", enum: ["always", "as-needed", "consistent", "consistent-as-needed"] }], minItems: 0, maxItems: 1 }, { type: "array", items: [{ type: "string", enum: ["always", "as-needed", "consistent", "consistent-as-needed"] }, { type: "object", properties: { keywords: { type: "boolean" }, unnecessary: { type: "boolean" }, numbers: { type: "boolean" } }, additionalProperties: false }], minItems: 0, maxItems: 2 }] }, fixable: "code", messages: { requireQuotesDueToReservedWord: "Properties should be quoted as '{{property}}' is a reserved word.", inconsistentlyQuotedProperty: "Inconsistently quoted property '{{key}}' found.", unnecessarilyQuotedProperty: "Unnecessarily quoted property '{{property}}' found.", unquotedReservedProperty: "Unquoted reserved word '{{property}}' used as key.", unquotedNumericProperty: "Unquoted number literal '{{property}}' used as key.", unquotedPropertyFound: "Unquoted property '{{property}}' found.", redundantQuoting: "Properties shouldn't be quoted as all quotes are redundant." } }, create(context) { const MODE = context.options[0]; const KEYWORDS = context.options[1] && context.options[1].keywords; const CHECK_UNNECESSARY = !context.options[1] || context.options[1].unnecessary !== false; const NUMBERS = context.options[1] && context.options[1].numbers; const sourceCode = context.sourceCode; function isKeyword(tokenStr) { return _includesInstanceProperty(utils.KEYWORDS_JS).call(utils.KEYWORDS_JS, tokenStr); } function areQuotesRedundant(rawKey, tokens, skipNumberLiterals = false) { var _context; return tokens.length === 1 && tokens[0].start === 0 && tokens[0].end === rawKey.length && (_includesInstanceProperty(_context = ["Identifier", "Keyword", "Null", "Boolean"]).call(_context, tokens[0].type) || tokens[0].type === "Numeric" && !skipNumberLiterals && String(+tokens[0].value) === tokens[0].value); } function getUnquotedKey(key) { return key.type === "Identifier" ? key.name : key.value; } function getQuotedKey(key) { if (key.type === "Literal" && typeof key.value === "string") { return sourceCode.getText(key); } return `"${key.type === "Identifier" ? key.name : key.value}"`; } function checkUnnecessaryQuotes(node) { const key = node.key; if (node.type !== "ImportAttribute" && (node.method || node.computed || node.shorthand)) return; if (key.type === "Literal" && typeof key.value === "string") { let tokens; try { tokens = vendor.tokenize(key.value); } catch { return; } if (tokens.length !== 1) return; const isKeywordToken = isKeyword(tokens[0].value); if (isKeywordToken && KEYWORDS) return; if (CHECK_UNNECESSARY && areQuotesRedundant(key.value, tokens, NUMBERS)) { context.report({ node, messageId: "unnecessarilyQuotedProperty", data: { property: key.value }, fix: fixer => fixer.replaceText(key, getUnquotedKey(key)) }); } } else if (KEYWORDS && key.type === "Identifier" && isKeyword(key.name)) { context.report({ node, messageId: "unquotedReservedProperty", data: { property: key.name }, fix: fixer => fixer.replaceText(key, getQuotedKey(key)) }); } else if (NUMBERS && key.type === "Literal" && utils.isNumericLiteral(key)) { context.report({ node, messageId: "unquotedNumericProperty", data: { property: key.value }, fix: fixer => fixer.replaceText(key, getQuotedKey(key)) }); } } function checkOmittedQuotes(node) { if (node.type !== "ImportAttribute" && (node.method || node.computed || node.shorthand)) return; const key = node.key; if (key.type === "Literal" && typeof key.value === "string") return; context.report({ node, messageId: "unquotedPropertyFound", data: { property: key.name || key.value }, fix: fixer => fixer.replaceText(key, getQuotedKey(key)) }); } function checkConsistencyForObject(node, checkQuotesRedundancy) { var _context2; checkConsistency(_filterInstanceProperty(_context2 = node.properties).call(_context2, property => property.type !== "SpreadElement" && property.key && !property.method && !property.computed && !property.shorthand), checkQuotesRedundancy); } function checkImportAttributes(attributes) { if (!attributes) return; if (MODE === "consistent") checkConsistency(attributes, false); if (MODE === "consistent-as-needed") checkConsistency(attributes, true); } function checkConsistency(properties, checkQuotesRedundancy) { const quotedProps = []; const unquotedProps = []; let keywordKeyName = null; let necessaryQuotes = false; _forEachInstanceProperty(properties).call(properties, property => { const key = property.key; if (key.type === "Literal" && typeof key.value === "string") { quotedProps.push(property); if (checkQuotesRedundancy) { let tokens; try { tokens = vendor.tokenize(key.value); } catch { necessaryQuotes = true; return; } necessaryQuotes = necessaryQuotes || !areQuotesRedundant(key.value, tokens) || KEYWORDS && isKeyword(tokens[0].value); } } else if (KEYWORDS && checkQuotesRedundancy && key.type === "Identifier" && isKeyword(key.name)) { unquotedProps.push(property); necessaryQuotes = true; keywordKeyName = key.name; } else { unquotedProps.push(property); } }); if (checkQuotesRedundancy && quotedProps.length && !necessaryQuotes) { _forEachInstanceProperty(quotedProps).call(quotedProps, property => { const key = property.key; context.report({ node: property, messageId: "redundantQuoting", fix: fixer => fixer.replaceText(key, getUnquotedKey(key)) }); }); } else if (unquotedProps.length && keywordKeyName) { _forEachInstanceProperty(unquotedProps).call(unquotedProps, property => { context.report({ node: property, messageId: "requireQuotesDueToReservedWord", data: { property: keywordKeyName }, fix: fixer => fixer.replaceText(property.key, getQuotedKey(property.key)) }); }); } else if (quotedProps.length && unquotedProps.length) { _forEachInstanceProperty(unquotedProps).call(unquotedProps, property => { context.report({ node: property, messageId: "inconsistentlyQuotedProperty", data: { key: property.key.name || property.key.value }, fix: fixer => fixer.replaceText(property.key, getQuotedKey(property.key)) }); }); } } return { Property(node) { if (MODE === "always" || !MODE) checkOmittedQuotes(node); if (MODE === "as-needed") checkUnnecessaryQuotes(node); }, ObjectExpression(node) { if (MODE === "consistent") checkConsistencyForObject(node, false); if (MODE === "consistent-as-needed") checkConsistencyForObject(node, true); }, ImportAttribute(node) { if (MODE === "always" || !MODE) checkOmittedQuotes(node); if (MODE === "as-needed") checkUnnecessaryQuotes(node); }, ImportDeclaration(node) { checkImportAttributes(node.attributes); }, ExportAllDeclaration(node) { checkImportAttributes(node.attributes); }, ExportNamedDeclaration(node) { checkImportAttributes(node.attributes); } }; } }); const baseRule = /* @__PURE__ */utils.castRuleModule(_baseRule); var quoteProps = utils.createRule({ name: "quote-props", package: "ts", meta: { ...baseRule.meta, docs: { description: "Require quotes around object literal, type literal, interfaces and enums property names" } }, defaultOptions: ["always"], create(context) { const rules = baseRule.create(context); return { ...rules, TSPropertySignature(node) { return rules.Property({ ...node, type: vendor.distExports.AST_NODE_TYPES.Property, shorthand: false, method: false, kind: "init", value: null }); }, TSMethodSignature(node) { return rules.Property({ ...node, type: vendor.distExports.AST_NODE_TYPES.Property, shorthand: false, method: true, kind: "init", value: null }); }, TSEnumMember(node) { return rules.Property({ ...node, type: vendor.distExports.AST_NODE_TYPES.Property, key: node.id, optional: false, shorthand: false, method: false, kind: "init", value: null }); }, TSTypeLiteral(node) { return rules.ObjectExpression({ ...node, type: vendor.distExports.AST_NODE_TYPES.ObjectExpression, properties: node.members }); }, TSInterfaceBody(node) { return rules.ObjectExpression({ ...node, type: vendor.distExports.AST_NODE_TYPES.ObjectExpression, properties: node.body }); }, TSEnumDeclaration(node) { var _node$body; const members = ((_node$body = node.body) == null ? undefined : _node$body.members) || node.members; return rules.ObjectExpression({ ...node, type: vendor.distExports.AST_NODE_TYPES.ObjectExpression, properties: _mapInstanceProperty(members).call(members, member => ({ ...member, key: member.id })) }); } }; } }); module.exports = quoteProps;