UNPKG

7.78 kBJavaScriptView Raw
1var __extends = (this && this.__extends) || function (d, b) {
2 for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
3 function __() { this.constructor = d; }
4 __.prototype = b.prototype;
5 d.prototype = new __();
6};
7var SyntaxKind = require('./utils/SyntaxKind');
8var ErrorTolerantWalker = require('./utils/ErrorTolerantWalker');
9var AstUtils = require('./utils/AstUtils');
10var Rule = (function (_super) {
11 __extends(Rule, _super);
12 function Rule() {
13 _super.apply(this, arguments);
14 }
15 Rule.prototype.apply = function (sourceFile) {
16 return this.applyWithWalker(new NoUnnecessaryBindRuleWalker(sourceFile, this.getOptions()));
17 };
18 Rule.FAILURE_FUNCTION_WITH_BIND = 'Binding function literal with \'this\' context. Use lambdas instead';
19 Rule.FAILURE_ARROW_WITH_BIND = 'Binding lambda with \'this\' context. Lambdas already have \'this\' bound';
20 Rule.UNDERSCORE_BINARY_FUNCTION_NAMES = [
21 'all', 'any', 'collect', 'countBy', 'detect', 'each',
22 'every', 'filter', 'find', 'forEach', 'groupBy', 'indexBy',
23 'map', 'max', 'max', 'min', 'partition', 'reject',
24 'select', 'some', 'sortBy', 'times', 'uniq', 'unique'
25 ];
26 Rule.UNDERSCORE_TERNARY_FUNCTION_NAMES = [
27 'foldl', 'foldr', 'inject', 'reduce', 'reduceRight'
28 ];
29 return Rule;
30})(Lint.Rules.AbstractRule);
31exports.Rule = Rule;
32var NoUnnecessaryBindRuleWalker = (function (_super) {
33 __extends(NoUnnecessaryBindRuleWalker, _super);
34 function NoUnnecessaryBindRuleWalker() {
35 _super.apply(this, arguments);
36 }
37 NoUnnecessaryBindRuleWalker.prototype.visitCallExpression = function (node) {
38 var _this = this;
39 var analyzers = [
40 new TypeScriptFunctionAnalyzer(), new UnderscoreStaticAnalyzer(), new UnderscoreInstanceAnalyzer()
41 ];
42 analyzers.forEach(function (analyzer) {
43 if (analyzer.canHandle(node)) {
44 var contextArgument = analyzer.getContextArgument(node);
45 var functionArgument = analyzer.getFunctionArgument(node);
46 if (contextArgument == null || functionArgument == null) {
47 return;
48 }
49 if (contextArgument.getText() === 'this') {
50 if (isArrowFunction(functionArgument)) {
51 _this.addFailure(_this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_ARROW_WITH_BIND));
52 }
53 else if (isFunctionLiteral(functionArgument)) {
54 _this.addFailure(_this.createFailure(node.getStart(), node.getWidth(), Rule.FAILURE_FUNCTION_WITH_BIND));
55 }
56 }
57 }
58 });
59 _super.prototype.visitCallExpression.call(this, node);
60 };
61 return NoUnnecessaryBindRuleWalker;
62})(ErrorTolerantWalker);
63var TypeScriptFunctionAnalyzer = (function () {
64 function TypeScriptFunctionAnalyzer() {
65 }
66 TypeScriptFunctionAnalyzer.prototype.canHandle = function (node) {
67 return !!(AstUtils.getFunctionName(node) === 'bind'
68 && node.arguments.length === 1
69 && node.expression.kind === SyntaxKind.current().PropertyAccessExpression);
70 };
71 TypeScriptFunctionAnalyzer.prototype.getContextArgument = function (node) {
72 return node.arguments[0];
73 };
74 TypeScriptFunctionAnalyzer.prototype.getFunctionArgument = function (node) {
75 return node.expression.expression;
76 };
77 return TypeScriptFunctionAnalyzer;
78})();
79var UnderscoreStaticAnalyzer = (function () {
80 function UnderscoreStaticAnalyzer() {
81 }
82 UnderscoreStaticAnalyzer.prototype.canHandle = function (node) {
83 var isUnderscore = AstUtils.getFunctionTarget(node) === '_';
84 if (isUnderscore) {
85 var functionName = AstUtils.getFunctionName(node);
86 if (functionName === 'bind') {
87 return node.arguments.length === 2;
88 }
89 }
90 return isUnderscore;
91 };
92 UnderscoreStaticAnalyzer.prototype.getContextArgument = function (node) {
93 var functionName = AstUtils.getFunctionName(node);
94 if (Rule.UNDERSCORE_BINARY_FUNCTION_NAMES.indexOf(functionName) !== -1) {
95 return node.arguments[2];
96 }
97 else if (Rule.UNDERSCORE_TERNARY_FUNCTION_NAMES.indexOf(functionName) !== -1) {
98 return node.arguments[3];
99 }
100 else if (functionName === 'sortedIndex') {
101 return node.arguments[3];
102 }
103 else if (functionName === 'bind') {
104 return node.arguments[1];
105 }
106 return null;
107 };
108 UnderscoreStaticAnalyzer.prototype.getFunctionArgument = function (node) {
109 var functionName = AstUtils.getFunctionName(node);
110 if (Rule.UNDERSCORE_BINARY_FUNCTION_NAMES.indexOf(functionName) !== -1) {
111 return node.arguments[1];
112 }
113 else if (Rule.UNDERSCORE_TERNARY_FUNCTION_NAMES.indexOf(functionName) !== -1) {
114 return node.arguments[1];
115 }
116 else if (functionName === 'sortedIndex') {
117 return node.arguments[2];
118 }
119 else if (functionName === 'bind') {
120 return node.arguments[0];
121 }
122 return null;
123 };
124 return UnderscoreStaticAnalyzer;
125})();
126var UnderscoreInstanceAnalyzer = (function () {
127 function UnderscoreInstanceAnalyzer() {
128 }
129 UnderscoreInstanceAnalyzer.prototype.canHandle = function (node) {
130 if (node.expression.kind === SyntaxKind.current().PropertyAccessExpression) {
131 var propExpression = node.expression;
132 if (propExpression.expression.kind === SyntaxKind.current().CallExpression) {
133 var call = propExpression.expression;
134 return call.expression.getText() === '_';
135 }
136 }
137 return false;
138 };
139 UnderscoreInstanceAnalyzer.prototype.getContextArgument = function (node) {
140 var functionName = AstUtils.getFunctionName(node);
141 if (Rule.UNDERSCORE_BINARY_FUNCTION_NAMES.indexOf(functionName) !== -1) {
142 return node.arguments[1];
143 }
144 else if (Rule.UNDERSCORE_TERNARY_FUNCTION_NAMES.indexOf(functionName) !== -1) {
145 return node.arguments[2];
146 }
147 else if (functionName === 'sortedIndex') {
148 return node.arguments[2];
149 }
150 return null;
151 };
152 UnderscoreInstanceAnalyzer.prototype.getFunctionArgument = function (node) {
153 var functionName = AstUtils.getFunctionName(node);
154 if (Rule.UNDERSCORE_BINARY_FUNCTION_NAMES.indexOf(functionName) !== -1) {
155 return node.arguments[0];
156 }
157 else if (Rule.UNDERSCORE_TERNARY_FUNCTION_NAMES.indexOf(functionName) !== -1) {
158 return node.arguments[0];
159 }
160 else if (functionName === 'sortedIndex') {
161 return node.arguments[1];
162 }
163 return null;
164 };
165 return UnderscoreInstanceAnalyzer;
166})();
167function isFunctionLiteral(expression) {
168 if (expression.kind === SyntaxKind.current().FunctionExpression) {
169 return true;
170 }
171 if (expression.kind === SyntaxKind.current().ParenthesizedExpression) {
172 return isFunctionLiteral(expression.expression);
173 }
174 return false;
175}
176function isArrowFunction(expression) {
177 if (expression.kind === SyntaxKind.current().ArrowFunction) {
178 return true;
179 }
180 if (expression.kind === SyntaxKind.current().ParenthesizedExpression) {
181 return isArrowFunction(expression.expression);
182 }
183 return false;
184}
185//# sourceMappingURL=noUnnecessaryBindRule.js.map
\No newline at end of file