UNPKG

7.03 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 ErrorTolerantWalker = require('./utils/ErrorTolerantWalker');
8var AstUtils = require('./utils/AstUtils');
9var Utils = require('./utils/Utils');
10var SyntaxKind = require('./utils/SyntaxKind');
11var Rule = (function (_super) {
12 __extends(Rule, _super);
13 function Rule() {
14 _super.apply(this, arguments);
15 }
16 Rule.prototype.apply = function (sourceFile) {
17 return this.applyWithWalker(new JQueryDeferredAnalyzer(sourceFile, this.getOptions()));
18 };
19 Rule.isPromiseInstantiation = function (expression) {
20 if (expression != null && expression.kind === SyntaxKind.current().CallExpression) {
21 var functionName = AstUtils.getFunctionName(expression);
22 var functionTarget = AstUtils.getFunctionTarget(expression);
23 if (functionName === 'Deferred' &&
24 (functionTarget === '$' || /^(jquery)$/i.test(functionTarget))) {
25 return true;
26 }
27 }
28 return false;
29 };
30 Rule.isCompletionFunction = function (functionName) {
31 return /^(resolve|reject)$/.test(functionName);
32 };
33 Rule.FAILURE_STRING = 'A JQuery deferred was found that appears to not have resolve or reject invoked on all code paths: ';
34 return Rule;
35})(Lint.Rules.AbstractRule);
36exports.Rule = Rule;
37var JQueryDeferredAnalyzer = (function (_super) {
38 __extends(JQueryDeferredAnalyzer, _super);
39 function JQueryDeferredAnalyzer() {
40 _super.apply(this, arguments);
41 }
42 JQueryDeferredAnalyzer.prototype.visitBinaryExpression = function (node) {
43 if (node.operatorToken.getText() === '=' && Rule.isPromiseInstantiation(node.right)) {
44 if (node.left.kind === SyntaxKind.current().Identifier) {
45 if (node.left.text != null) {
46 var name_1 = node.left;
47 this.validateDeferredUsage(node, name_1);
48 }
49 }
50 }
51 _super.prototype.visitBinaryExpression.call(this, node);
52 };
53 JQueryDeferredAnalyzer.prototype.visitVariableDeclaration = function (node) {
54 if (Rule.isPromiseInstantiation(node.initializer)) {
55 if (node.name.text != null) {
56 var name_2 = node.name;
57 this.validateDeferredUsage(node, name_2);
58 }
59 }
60 _super.prototype.visitVariableDeclaration.call(this, node);
61 };
62 JQueryDeferredAnalyzer.prototype.validateDeferredUsage = function (rootNode, deferredIdentifier) {
63 var parent = AstUtils.findParentBlock(rootNode);
64 var blockAnalyzer = new DeferredCompletionWalker(this.getSourceFile(), this.getOptions(), deferredIdentifier);
65 blockAnalyzer.visitNode(parent);
66 if (!blockAnalyzer.isAlwaysCompleted()) {
67 var failureString = Rule.FAILURE_STRING + '\'' + rootNode.getText() + '\'';
68 var failure = this.createFailure(rootNode.getStart(), rootNode.getWidth(), failureString);
69 this.addFailure(failure);
70 }
71 };
72 return JQueryDeferredAnalyzer;
73})(ErrorTolerantWalker);
74var DeferredCompletionWalker = (function (_super) {
75 __extends(DeferredCompletionWalker, _super);
76 function DeferredCompletionWalker(sourceFile, options, deferredIdentifier) {
77 _super.call(this, sourceFile, options);
78 this.wasCompleted = false;
79 this.allBranchesCompleted = true;
80 this.hasBranches = false;
81 this.walkerOptions = options;
82 this.deferredIdentifier = deferredIdentifier;
83 }
84 DeferredCompletionWalker.prototype.visitNode = function (node) {
85 _super.prototype.visitNode.call(this, node);
86 };
87 DeferredCompletionWalker.prototype.isAlwaysCompleted = function () {
88 if (this.wasCompleted) {
89 return true;
90 }
91 if (!this.hasBranches) {
92 return false;
93 }
94 return this.allBranchesCompleted;
95 };
96 DeferredCompletionWalker.prototype.visitIfStatement = function (node) {
97 this.hasBranches = true;
98 var ifAnalyzer = new DeferredCompletionWalker(this.getSourceFile(), this.walkerOptions, this.deferredIdentifier);
99 var elseAnalyzer = new DeferredCompletionWalker(this.getSourceFile(), this.walkerOptions, this.deferredIdentifier);
100 ifAnalyzer.visitNode(node.thenStatement);
101 if (!ifAnalyzer.isAlwaysCompleted()) {
102 this.allBranchesCompleted = false;
103 }
104 else if (node.elseStatement != null) {
105 elseAnalyzer.visitNode(node.elseStatement);
106 if (!elseAnalyzer.isAlwaysCompleted()) {
107 this.allBranchesCompleted = false;
108 }
109 }
110 };
111 DeferredCompletionWalker.prototype.visitCallExpression = function (node) {
112 var _this = this;
113 if (node.expression.kind === SyntaxKind.current().PropertyAccessExpression) {
114 var prop = node.expression;
115 if (AstUtils.isSameIdentifer(this.deferredIdentifier, prop.expression)) {
116 var functionName = prop.name.getText();
117 if (Rule.isCompletionFunction(functionName)) {
118 this.wasCompleted = true;
119 return;
120 }
121 }
122 }
123 var referenceEscaped = Utils.exists(node.arguments, function (argument) {
124 return AstUtils.isSameIdentifer(_this.deferredIdentifier, argument);
125 });
126 if (referenceEscaped) {
127 this.wasCompleted = true;
128 return;
129 }
130 _super.prototype.visitCallExpression.call(this, node);
131 };
132 DeferredCompletionWalker.prototype.visitArrowFunction = function (node) {
133 var _this = this;
134 var isDeferredShadowed = Utils.exists(node.parameters, function (param) {
135 return AstUtils.isSameIdentifer(_this.deferredIdentifier, param.name);
136 });
137 if (isDeferredShadowed) {
138 this.hasBranches = true;
139 this.allBranchesCompleted = false;
140 return;
141 }
142 _super.prototype.visitArrowFunction.call(this, node);
143 };
144 DeferredCompletionWalker.prototype.visitFunctionExpression = function (node) {
145 var _this = this;
146 var isDeferredShadowed = Utils.exists(node.parameters, function (param) {
147 return AstUtils.isSameIdentifer(_this.deferredIdentifier, param.name);
148 });
149 if (isDeferredShadowed) {
150 this.hasBranches = true;
151 this.allBranchesCompleted = false;
152 return;
153 }
154 _super.prototype.visitFunctionExpression.call(this, node);
155 };
156 return DeferredCompletionWalker;
157})(ErrorTolerantWalker);
158//# sourceMappingURL=jqueryDeferredMustCompleteRule.js.map
\No newline at end of file