UNPKG

2.19 kBJavaScriptView Raw
1/**
2 * @fileoverview Rule to enforce declarations in program or function body root.
3 * @author Brandon Mills
4 * @copyright 2014 Brandon Mills. All rights reserved.
5 */
6
7"use strict";
8
9//------------------------------------------------------------------------------
10// Rule Definition
11//------------------------------------------------------------------------------
12
13module.exports = function(context) {
14
15 /**
16 * Find the nearest Program or Function ancestor node.
17 * @returns {Object} Ancestor's type and distance from node.
18 */
19 function nearestBody() {
20 var ancestors = context.getAncestors(),
21 ancestor = ancestors.pop(),
22 generation = 1;
23
24 while (ancestor && ["Program", "FunctionDeclaration",
25 "FunctionExpression", "ArrowFunctionExpression"
26 ].indexOf(ancestor.type) < 0) {
27 generation += 1;
28 ancestor = ancestors.pop();
29 }
30
31 return {
32 // Type of containing ancestor
33 type: ancestor.type,
34 // Separation between ancestor and node
35 distance: generation
36 };
37 }
38
39 /**
40 * Ensure that a given node is at a program or function body's root.
41 * @param {ASTNode} node Declaration node to check.
42 * @returns {void}
43 */
44 function check(node) {
45 var body = nearestBody(node),
46 valid = ((body.type === "Program" && body.distance === 1) ||
47 body.distance === 2);
48
49 if (!valid) {
50 context.report(node, "Move {{type}} declaration to {{body}} root.",
51 {
52 type: (node.type === "FunctionDeclaration" ?
53 "function" : "variable"),
54 body: (body.type === "Program" ?
55 "program" : "function body")
56 }
57 );
58 }
59 }
60
61 return {
62
63 "FunctionDeclaration": check,
64 "VariableDeclaration": function(node) {
65 if (context.options[0] === "both" && node.kind === "var") {
66 check(node);
67 }
68 }
69
70 };
71
72};
73
74module.exports.schema = [
75 {
76 "enum": ["functions", "both"]
77 }
78];