UNPKG

3.42 kBJavaScriptView Raw
1/**
2 * @fileoverview Validates newlines before and after dots
3 * @author Greg Cochard
4 */
5
6"use strict";
7
8const astUtils = require("./utils/ast-utils");
9
10//------------------------------------------------------------------------------
11// Rule Definition
12//------------------------------------------------------------------------------
13
14module.exports = {
15 meta: {
16 type: "layout",
17
18 docs: {
19 description: "enforce consistent newlines before and after dots",
20 category: "Best Practices",
21 recommended: false,
22 url: "https://eslint.org/docs/rules/dot-location"
23 },
24
25 schema: [
26 {
27 enum: ["object", "property"]
28 }
29 ],
30
31 fixable: "code",
32
33 messages: {
34 expectedDotAfterObject: "Expected dot to be on same line as object.",
35 expectedDotBeforeProperty: "Expected dot to be on same line as property."
36 }
37 },
38
39 create(context) {
40
41 const config = context.options[0];
42
43 // default to onObject if no preference is passed
44 const onObject = config === "object" || !config;
45
46 const sourceCode = context.getSourceCode();
47
48 /**
49 * Reports if the dot between object and property is on the correct location.
50 * @param {ASTNode} node The `MemberExpression` node.
51 * @returns {void}
52 */
53 function checkDotLocation(node) {
54 const property = node.property;
55 const dotToken = sourceCode.getTokenBefore(property);
56
57 if (onObject) {
58
59 // `obj` expression can be parenthesized, but those paren tokens are not a part of the `obj` node.
60 const tokenBeforeDot = sourceCode.getTokenBefore(dotToken);
61
62 if (!astUtils.isTokenOnSameLine(tokenBeforeDot, dotToken)) {
63 context.report({
64 node,
65 loc: dotToken.loc,
66 messageId: "expectedDotAfterObject",
67 *fix(fixer) {
68 if (dotToken.value.startsWith(".") && astUtils.isDecimalIntegerNumericToken(tokenBeforeDot)) {
69 yield fixer.insertTextAfter(tokenBeforeDot, ` ${dotToken.value}`);
70 } else {
71 yield fixer.insertTextAfter(tokenBeforeDot, dotToken.value);
72 }
73 yield fixer.remove(dotToken);
74 }
75 });
76 }
77 } else if (!astUtils.isTokenOnSameLine(dotToken, property)) {
78 context.report({
79 node,
80 loc: dotToken.loc,
81 messageId: "expectedDotBeforeProperty",
82 *fix(fixer) {
83 yield fixer.remove(dotToken);
84 yield fixer.insertTextBefore(property, dotToken.value);
85 }
86 });
87 }
88 }
89
90 /**
91 * Checks the spacing of the dot within a member expression.
92 * @param {ASTNode} node The node to check.
93 * @returns {void}
94 */
95 function checkNode(node) {
96 if (!node.computed) {
97 checkDotLocation(node);
98 }
99 }
100
101 return {
102 MemberExpression: checkNode
103 };
104 }
105};