]>
git.proxmox.com Git - pve-eslint.git/blob - eslint/lib/rules/dot-notation.js
2 * @fileoverview Rule to warn about using dot notation instead of square bracket notation when possible.
7 //------------------------------------------------------------------------------
9 //------------------------------------------------------------------------------
11 const astUtils
= require("./utils/ast-utils");
12 const keywords
= require("./utils/keywords");
14 //------------------------------------------------------------------------------
16 //------------------------------------------------------------------------------
18 const validIdentifier
= /^[a-zA-Z_$][a-zA-Z0-9_$]*$/u;
20 // `null` literal must be handled separately.
21 const literalTypesToCheck
= new Set(["string", "boolean"]);
23 /** @type {import('../shared/types').Rule} */
29 description
: "Enforce dot notation whenever possible",
31 url
: "https://eslint.org/docs/rules/dot-notation"
47 additionalProperties
: false
54 useDot
: "[{{key}}] is better written in dot notation.",
55 useBrackets
: ".{{key}} is a syntax error."
60 const options
= context
.options
[0] || {};
61 const allowKeywords
= options
.allowKeywords
=== void 0 || options
.allowKeywords
;
62 const sourceCode
= context
.getSourceCode();
66 if (options
.allowPattern
) {
67 allowPattern
= new RegExp(options
.allowPattern
, "u");
71 * Check if the property is valid dot notation
72 * @param {ASTNode} node The dot notation node
73 * @param {string} value Value which is to be checked
76 function checkComputedProperty(node
, value
) {
78 validIdentifier
.test(value
) &&
79 (allowKeywords
|| !keywords
.includes(String(value
))) &&
80 !(allowPattern
&& allowPattern
.test(value
))
82 const formattedValue
= node
.property
.type
=== "Literal" ? JSON
.stringify(value
) : `\`${value}
\``;
91 const leftBracket
= sourceCode
.getTokenAfter(node
.object
, astUtils
.isOpeningBracketToken
);
92 const rightBracket
= sourceCode
.getLastToken(node
);
93 const nextToken
= sourceCode
.getTokenAfter(node
);
95 // Don't perform any fixes if there are comments inside the brackets.
96 if (sourceCode
.commentsExistBetween(leftBracket
, rightBracket
)) {
100 // Replace the brackets by an identifier.
101 if (!node
.optional
) {
102 yield fixer
.insertTextBefore(
104 astUtils
.isDecimalInteger(node
.object
) ? " ." : "."
107 yield fixer
.replaceTextRange(
108 [leftBracket
.range
[0], rightBracket
.range
[1]],
112 // Insert a space after the property if it will be connected to the next token.
115 rightBracket
.range
[1] === nextToken
.range
[0] &&
116 !astUtils
.canTokensBeAdjacent(String(value
), nextToken
)
118 yield fixer
.insertTextAfter(node
, " ");
126 MemberExpression(node
) {
129 node
.property
.type
=== "Literal" &&
130 (literalTypesToCheck
.has(typeof node
.property
.value
) || astUtils
.isNullLiteral(node
.property
))
132 checkComputedProperty(node
, node
.property
.value
);
136 node
.property
.type
=== "TemplateLiteral" &&
137 node
.property
.expressions
.length
=== 0
139 checkComputedProperty(node
, node
.property
.quasis
[0].value
.cooked
);
144 node
.property
.type
=== "Identifier" &&
145 keywords
.includes(String(node
.property
.name
))
149 messageId
: "useBrackets",
151 key
: node
.property
.name
154 const dotToken
= sourceCode
.getTokenBefore(node
.property
);
156 // A statement that starts with `let[` is parsed as a destructuring variable declaration, not a MemberExpression.
157 if (node
.object
.type
=== "Identifier" && node
.object
.name
=== "let" && !node
.optional
) {
161 // Don't perform any fixes if there are comments between the dot and the property name.
162 if (sourceCode
.commentsExistBetween(dotToken
, node
.property
)) {
166 // Replace the identifier to brackets.
167 if (!node
.optional
) {
168 yield fixer
.remove(dotToken
);
170 yield fixer
.replaceText(node
.property
, `["${node.property.name}"]`);