UNPKG

3.82 kBJavaScriptView Raw
1/**
2 * @fileoverview Rule to check the spacing around the * in generator functions.
3 * @author Jamund Ferguson
4 * @copyright 2015 Brandon Mills. All rights reserved.
5 * @copyright 2014 Jamund Ferguson. All rights reserved.
6 */
7
8"use strict";
9
10//------------------------------------------------------------------------------
11// Rule Definition
12//------------------------------------------------------------------------------
13
14module.exports = function(context) {
15
16 var mode = (function(option) {
17 if (!option || typeof option === "string") {
18 return {
19 before: { before: true, after: false },
20 after: { before: false, after: true },
21 both: { before: true, after: true },
22 neither: { before: false, after: false }
23 }[option || "before"];
24 }
25 return option;
26 }(context.options[0]));
27
28 /**
29 * Checks the spacing between two tokens before or after the star token.
30 * @param {string} side Either "before" or "after".
31 * @param {Token} leftToken `function` keyword token if side is "before", or
32 * star token if side is "after".
33 * @param {Token} rightToken Star token if side is "before", or identifier
34 * token if side is "after".
35 * @returns {void}
36 */
37 function checkSpacing(side, leftToken, rightToken) {
38 if (!!(rightToken.range[0] - leftToken.range[1]) !== mode[side]) {
39 var after = leftToken.value === "*";
40 var spaceRequired = mode[side];
41 var node = after ? leftToken : rightToken;
42 var type = spaceRequired ? "Missing" : "Unexpected";
43 var message = type + " space " + side + " *.";
44 context.report({
45 node: node,
46 message: message,
47 fix: function(fixer) {
48 if (spaceRequired) {
49 if (after) {
50 return fixer.insertTextAfter(node, " ");
51 }
52 return fixer.insertTextBefore(node, " ");
53 }
54 return fixer.removeRange([leftToken.range[1], rightToken.range[0]]);
55 }
56 });
57 }
58 }
59
60 /**
61 * Enforces the spacing around the star if node is a generator function.
62 * @param {ASTNode} node A function expression or declaration node.
63 * @returns {void}
64 */
65 function checkFunction(node) {
66 var prevToken, starToken, nextToken;
67
68 if (!node.generator) {
69 return;
70 }
71
72 if (node.parent.method || node.parent.type === "MethodDefinition") {
73 starToken = context.getTokenBefore(node, 1);
74 } else {
75 starToken = context.getFirstToken(node, 1);
76 }
77
78 // Only check before when preceded by `function` keyword
79 prevToken = context.getTokenBefore(starToken);
80 if (prevToken.value === "function" || prevToken.value === "static") {
81 checkSpacing("before", prevToken, starToken);
82 }
83
84 // Only check after when followed by an identifier
85 nextToken = context.getTokenAfter(starToken);
86 if (nextToken.type === "Identifier") {
87 checkSpacing("after", starToken, nextToken);
88 }
89 }
90
91 return {
92 "FunctionDeclaration": checkFunction,
93 "FunctionExpression": checkFunction
94 };
95
96};
97
98module.exports.schema = [
99 {
100 "oneOf": [
101 {
102 "enum": ["before", "after", "both", "neither"]
103 },
104 {
105 "type": "object",
106 "properties": {
107 "before": {"type": "boolean"},
108 "after": {"type": "boolean"}
109 },
110 "additionalProperties": false
111 }
112 ]
113 }
114];