• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/**
2 * @fileoverview Rule to disallow whitespace before properties
3 * @author Kai Cataldo
4 */
5"use strict";
6
7//------------------------------------------------------------------------------
8// Requirements
9//------------------------------------------------------------------------------
10
11const astUtils = require("./utils/ast-utils");
12
13//------------------------------------------------------------------------------
14// Rule Definition
15//------------------------------------------------------------------------------
16
17module.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) {
52            context.report({
53                node,
54                messageId: "unexpectedWhitespace",
55                data: {
56                    propName: sourceCode.getText(node.property)
57                },
58                fix(fixer) {
59                    let replacementText = "";
60
61                    if (!node.computed && !node.optional && astUtils.isDecimalInteger(node.object)) {
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                    }
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
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);
101                    leftToken = sourceCode.getTokenBefore(rightToken, node.optional ? 1 : 0);
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};
114