]>
Commit | Line | Data |
---|---|---|
eb39fafa DC |
1 | /** |
2 | * @fileoverview Rule to disallow whitespace before properties | |
3 | * @author Kai Cataldo | |
4 | */ | |
5 | "use strict"; | |
6 | ||
7 | //------------------------------------------------------------------------------ | |
8 | // Requirements | |
9 | //------------------------------------------------------------------------------ | |
10 | ||
11 | const astUtils = require("./utils/ast-utils"); | |
12 | ||
13 | //------------------------------------------------------------------------------ | |
14 | // Rule Definition | |
15 | //------------------------------------------------------------------------------ | |
16 | ||
17 | module.exports = { | |
18 | meta: { | |
19 | type: "layout", | |
20 | ||
21 | docs: { | |
22 | description: "disallow whitespace before properties", | |
eb39fafa DC |
23 | recommended: false, |
24 | url: "https://eslint.org/docs/rules/no-whitespace-before-property" | |
25 | }, | |
26 | ||
27 | fixable: "whitespace", | |
28 | schema: [], | |
29 | ||
30 | messages: { | |
31 | unexpectedWhitespace: "Unexpected whitespace before property {{propName}}." | |
32 | } | |
33 | }, | |
34 | ||
35 | create(context) { | |
36 | const sourceCode = context.getSourceCode(); | |
37 | ||
38 | //-------------------------------------------------------------------------- | |
39 | // Helpers | |
40 | //-------------------------------------------------------------------------- | |
41 | ||
42 | /** | |
43 | * Reports whitespace before property token | |
44 | * @param {ASTNode} node the node to report in the event of an error | |
45 | * @param {Token} leftToken the left token | |
46 | * @param {Token} rightToken the right token | |
47 | * @returns {void} | |
48 | * @private | |
49 | */ | |
50 | function reportError(node, leftToken, rightToken) { | |
eb39fafa DC |
51 | context.report({ |
52 | node, | |
53 | messageId: "unexpectedWhitespace", | |
54 | data: { | |
55 | propName: sourceCode.getText(node.property) | |
56 | }, | |
57 | fix(fixer) { | |
6f036462 TL |
58 | let replacementText = ""; |
59 | ||
60 | if (!node.computed && !node.optional && astUtils.isDecimalInteger(node.object)) { | |
eb39fafa DC |
61 | |
62 | /* | |
63 | * If the object is a number literal, fixing it to something like 5.toString() would cause a SyntaxError. | |
64 | * Don't fix this case. | |
65 | */ | |
66 | return null; | |
67 | } | |
6f036462 TL |
68 | |
69 | // Don't fix if comments exist. | |
70 | if (sourceCode.commentsExistBetween(leftToken, rightToken)) { | |
71 | return null; | |
72 | } | |
73 | ||
74 | if (node.optional) { | |
75 | replacementText = "?."; | |
76 | } else if (!node.computed) { | |
77 | replacementText = "."; | |
78 | } | |
79 | ||
eb39fafa DC |
80 | return fixer.replaceTextRange([leftToken.range[1], rightToken.range[0]], replacementText); |
81 | } | |
82 | }); | |
83 | } | |
84 | ||
85 | //-------------------------------------------------------------------------- | |
86 | // Public | |
87 | //-------------------------------------------------------------------------- | |
88 | ||
89 | return { | |
90 | MemberExpression(node) { | |
91 | let rightToken; | |
92 | let leftToken; | |
93 | ||
94 | if (!astUtils.isTokenOnSameLine(node.object, node.property)) { | |
95 | return; | |
96 | } | |
97 | ||
98 | if (node.computed) { | |
99 | rightToken = sourceCode.getTokenBefore(node.property, astUtils.isOpeningBracketToken); | |
6f036462 | 100 | leftToken = sourceCode.getTokenBefore(rightToken, node.optional ? 1 : 0); |
eb39fafa DC |
101 | } else { |
102 | rightToken = sourceCode.getFirstToken(node.property); | |
103 | leftToken = sourceCode.getTokenBefore(rightToken, 1); | |
104 | } | |
105 | ||
106 | if (sourceCode.isSpaceBetweenTokens(leftToken, rightToken)) { | |
107 | reportError(node, leftToken, rightToken); | |
108 | } | |
109 | } | |
110 | }; | |
111 | } | |
112 | }; |