1 | "use strict";
|
2 | var __extends = (this && this.__extends) || (function () {
|
3 | var extendStatics = Object.setPrototypeOf ||
|
4 | ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
5 | function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
6 | return function (d, b) {
|
7 | extendStatics(d, b);
|
8 | function __() { this.constructor = d; }
|
9 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
10 | };
|
11 | })();
|
12 | Object.defineProperty(exports, "__esModule", { value: true });
|
13 | var ts = require("typescript");
|
14 | var Lint = require("tslint");
|
15 | var ErrorTolerantWalker_1 = require("./utils/ErrorTolerantWalker");
|
16 | var AstUtils_1 = require("./utils/AstUtils");
|
17 | var FAILURE_STATIC_FOUND = 'Static invocation of underscore function found. Prefer instance version instead: ';
|
18 | var FAILURE_INSTANCE_FOUND = 'Underscore instance wrapping of variable found. Prefer underscore static functions instead: ';
|
19 | var FUNCTION_NAMES = [
|
20 | 'each', 'forEach', 'map', 'collect',
|
21 | 'reduce', 'inject', 'foldl', 'reduceRight',
|
22 | 'foldr', 'find', 'detect', 'filter',
|
23 | 'select', 'where', 'findWhere', 'reject',
|
24 | 'every', 'all', 'some', 'any',
|
25 | 'contains', 'include', 'invoke', 'pluck',
|
26 | 'max', 'min', 'sortBy', 'groupBy',
|
27 | 'indexBy', 'countBy', 'shuffle', 'sample',
|
28 | 'toArray', 'size', 'partition', 'first',
|
29 | 'head', 'take', 'initial', 'last',
|
30 | 'rest', 'tail', 'drop', 'compact',
|
31 | 'flatten', 'without', 'union', 'intersection',
|
32 | 'difference', 'uniq', 'unique', 'object',
|
33 | 'zip', 'unzip', 'indexOf', 'findIndex',
|
34 | 'lastIndexOf', 'findLastIndex', 'sortedIndex', 'range'
|
35 | ];
|
36 | var Rule = (function (_super) {
|
37 | __extends(Rule, _super);
|
38 | function Rule() {
|
39 | return _super !== null && _super.apply(this, arguments) || this;
|
40 | }
|
41 | Rule.prototype.apply = function (sourceFile) {
|
42 | return this.applyWithWalker(new UnderscoreConsistentInvocationRuleWalker(sourceFile, this.getOptions()));
|
43 | };
|
44 | Rule.metadata = {
|
45 | ruleName: 'underscore-consistent-invocation',
|
46 | type: 'maintainability',
|
47 | description: 'Enforce a consistent usage of the _ functions',
|
48 | options: null,
|
49 | optionsDescription: '',
|
50 | typescriptOnly: true,
|
51 | issueClass: 'Non-SDL',
|
52 | issueType: 'Warning',
|
53 | severity: 'Low',
|
54 | level: 'Opportunity for Excellence',
|
55 | group: 'Clarity',
|
56 | commonWeaknessEnumeration: '398, 710'
|
57 | };
|
58 | return Rule;
|
59 | }(Lint.Rules.AbstractRule));
|
60 | exports.Rule = Rule;
|
61 | var UnderscoreConsistentInvocationRuleWalker = (function (_super) {
|
62 | __extends(UnderscoreConsistentInvocationRuleWalker, _super);
|
63 | function UnderscoreConsistentInvocationRuleWalker(sourceFile, options) {
|
64 | var _this = _super.call(this, sourceFile, options) || this;
|
65 | _this.style = 'instance';
|
66 | _this.getOptions().forEach(function (opt) {
|
67 | if (typeof (opt) === 'object') {
|
68 | if (opt.style === 'static') {
|
69 | _this.style = 'static';
|
70 | }
|
71 | }
|
72 | });
|
73 | return _this;
|
74 | }
|
75 | UnderscoreConsistentInvocationRuleWalker.prototype.visitCallExpression = function (node) {
|
76 | var functionName = AstUtils_1.AstUtils.getFunctionName(node);
|
77 | if (this.style === 'instance' && this.isStaticUnderscoreInvocation(node)) {
|
78 | this.addFailureAt(node.getStart(), node.getWidth(), FAILURE_STATIC_FOUND + '_.' + functionName);
|
79 | }
|
80 | if (this.style === 'static' && this.isStaticUnderscoreInstanceInvocation(node)) {
|
81 | this.addFailureAt(node.getStart(), node.getWidth(), FAILURE_INSTANCE_FOUND + node.expression.getText());
|
82 | }
|
83 | _super.prototype.visitCallExpression.call(this, node);
|
84 | };
|
85 | UnderscoreConsistentInvocationRuleWalker.prototype.isStaticUnderscoreInstanceInvocation = function (node) {
|
86 | if (node.expression.kind === ts.SyntaxKind.PropertyAccessExpression) {
|
87 | var propExpression = node.expression;
|
88 | if (propExpression.expression.kind === ts.SyntaxKind.CallExpression) {
|
89 | var call = propExpression.expression;
|
90 | var target = AstUtils_1.AstUtils.getFunctionTarget(call);
|
91 | var functionName = AstUtils_1.AstUtils.getFunctionName(call);
|
92 | if (target == null && functionName === '_' && call.arguments.length === 1) {
|
93 | var underscoreFunctionName = AstUtils_1.AstUtils.getFunctionName(node);
|
94 | return FUNCTION_NAMES.indexOf(underscoreFunctionName) > -1;
|
95 | }
|
96 | }
|
97 | }
|
98 | return false;
|
99 | };
|
100 | UnderscoreConsistentInvocationRuleWalker.prototype.isStaticUnderscoreInvocation = function (node) {
|
101 | var target = AstUtils_1.AstUtils.getFunctionTarget(node);
|
102 | if (target !== '_') {
|
103 | return false;
|
104 | }
|
105 | var functionName = AstUtils_1.AstUtils.getFunctionName(node);
|
106 | return FUNCTION_NAMES.indexOf(functionName) > -1;
|
107 | };
|
108 | return UnderscoreConsistentInvocationRuleWalker;
|
109 | }(ErrorTolerantWalker_1.ErrorTolerantWalker));
|
110 |
|
\ | No newline at end of file |