UNPKG

2.47 kBJavaScriptView Raw
1/**
2 * @fileoverview Rule to flag when using constructor without parentheses
3 * @author Ilya Volodin
4 */
5
6"use strict";
7
8//------------------------------------------------------------------------------
9// Helpers
10//------------------------------------------------------------------------------
11
12/**
13 * Checks whether the given token is an opening parenthesis or not.
14 *
15 * @param {Token} token - The token to check.
16 * @returns {boolean} `true` if the token is an opening parenthesis.
17 */
18function isOpeningParen(token) {
19 return token.type === "Punctuator" && token.value === "(";
20}
21
22/**
23 * Checks whether the given token is an closing parenthesis or not.
24 *
25 * @param {Token} token - The token to check.
26 * @returns {boolean} `true` if the token is an closing parenthesis.
27 */
28function isClosingParen(token) {
29 return token.type === "Punctuator" && token.value === ")";
30}
31
32/**
33 * Checks whether the given node is inside of another given node.
34 *
35 * @param {ASTNode|Token} inner - The inner node to check.
36 * @param {ASTNode|Token} outer - The outer node to check.
37 * @returns {boolean} `true` if the `inner` is in `outer`.
38 */
39function isInRange(inner, outer) {
40 const ir = inner.range;
41 const or = outer.range;
42
43 return or[0] <= ir[0] && ir[1] <= or[1];
44}
45
46//------------------------------------------------------------------------------
47// Rule Definition
48//------------------------------------------------------------------------------
49
50module.exports = {
51 meta: {
52 docs: {
53 description: "require parentheses when invoking a constructor with no arguments",
54 category: "Stylistic Issues",
55 recommended: false
56 },
57
58 schema: [],
59
60 fixable: "code"
61 },
62
63 create(context) {
64 const sourceCode = context.getSourceCode();
65
66 return {
67 NewExpression(node) {
68 let token = sourceCode.getTokenAfter(node.callee);
69
70 // Skip ')'
71 while (token && isClosingParen(token)) {
72 token = sourceCode.getTokenAfter(token);
73 }
74
75 if (!(token && isOpeningParen(token) && isInRange(token, node))) {
76 context.report({
77 node,
78 message: "Missing '()' invoking a constructor.",
79 fix: fixer => fixer.insertTextAfter(node, "()")
80 });
81 }
82 }
83 };
84 }
85};