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