UNPKG

4.01 kBJavaScriptView Raw
1/**
2 * @fileoverview Reject common XPCOM methods called with useless optional
3 * parameters, or non-existent parameters.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
9
10"use strict";
11
12// -----------------------------------------------------------------------------
13// Rule Definition
14// -----------------------------------------------------------------------------
15
16module.exports = function(context) {
17 function getRangeAfterArgToEnd(argNumber, args) {
18 let sourceCode = context.getSourceCode();
19 return [sourceCode.getTokenAfter(args[argNumber]).range[0],
20 args[args.length - 1].range[1]];
21 }
22
23 // ---------------------------------------------------------------------------
24 // Public
25 // --------------------------------------------------------------------------
26
27 return {
28 "CallExpression": function(node) {
29 let callee = node.callee;
30 if (callee.type !== "MemberExpression" ||
31 callee.property.type !== "Identifier") {
32 return;
33 }
34
35 let isFalse = arg => arg.type === "Literal" && arg.value === false;
36 let isFalsy = arg => arg.type === "Literal" && !arg.value;
37 let isBool = arg => arg.type === "Literal" && (arg.value === false ||
38 arg.value === true);
39 let name = callee.property.name;
40 let args = node.arguments;
41
42 if (["addEventListener", "removeEventListener", "addObserver"]
43 .includes(name) && args.length === 3 && isFalse(args[2])) {
44 context.report({
45 node,
46 fix: fixer => {
47 return fixer.removeRange(getRangeAfterArgToEnd(1, args));
48 },
49 message: `${name}'s third parameter can be omitted when it's false.`
50 });
51 }
52
53 if (name === "clearUserPref" && args.length > 1) {
54 context.report({
55 node,
56 fix: fixer => {
57 return fixer.removeRange(getRangeAfterArgToEnd(0, args));
58 },
59 message: `${name} takes only 1 parameter.`
60 });
61 }
62
63 if (name === "removeObserver" && args.length === 3 && isBool(args[2])) {
64 context.report({
65 node,
66 fix: fixer => {
67 return fixer.removeRange(getRangeAfterArgToEnd(1, args));
68 },
69 message: "removeObserver only takes 2 parameters."
70 });
71 }
72
73 if (name === "appendElement" && args.length === 2 && isFalse(args[1])) {
74 context.report({
75 node,
76 fix: fixer => {
77 return fixer.removeRange(getRangeAfterArgToEnd(0, args));
78 },
79 message: `${name}'s second parameter can be omitted when it's false.`
80 });
81 }
82
83 if (name === "notifyObservers" && args.length === 3 &&
84 isFalsy(args[2])) {
85 context.report({
86 node,
87 fix: fixer => {
88 return fixer.removeRange(getRangeAfterArgToEnd(1, args));
89 },
90 message: `${name}'s third parameter can be omitted.`
91 });
92 }
93
94 if (name === "getComputedStyle" && args.length === 2 &&
95 isFalsy(args[1])) {
96 context.report({
97 node,
98 fix: fixer => {
99 return fixer.removeRange(getRangeAfterArgToEnd(0, args));
100 },
101 message: "getComputedStyle's second parameter can be omitted."
102 });
103 }
104
105 if (name === "newURI" && args.length > 1 &&
106 isFalsy(args[args.length - 1])) {
107 context.report({
108 node,
109 fix: fixer => {
110 if (args.length > 2 && isFalsy(args[args.length - 2])) {
111 return fixer.removeRange(getRangeAfterArgToEnd(0, args));
112 }
113
114 return fixer.removeRange(getRangeAfterArgToEnd(args.length - 2, args));
115 },
116 message: "newURI's last parameters are optional."
117 });
118 }
119 }
120 };
121};