1 | import { Rules, RuleWalker } from 'tslint';
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 | var extendStatics = function(d, b) {
|
20 | extendStatics = Object.setPrototypeOf ||
|
21 | ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
22 | function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
23 | return extendStatics(d, b);
|
24 | };
|
25 |
|
26 | function __extends(d, b) {
|
27 | extendStatics(d, b);
|
28 | function __() { this.constructor = d; }
|
29 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
30 | }
|
31 |
|
32 | var BAN_SNIPPETS_RULE_ID = "tsl-ban-snippets";
|
33 |
|
34 | var SNIPPETS_PROP = "snippets";
|
35 | var REGEX_SNIPPETS_PROP = "regexSnippets";
|
36 | var ConfigFactory;
|
37 | (function (ConfigFactory) {
|
38 | function createForBanSnippetsRule(options) {
|
39 | var config = createFromArguments(options, BAN_SNIPPETS_RULE_ID);
|
40 | validate(config, "banned", BAN_SNIPPETS_RULE_ID);
|
41 | config.banned.forEach(function (b) { return validateSnippetsList(b, BAN_SNIPPETS_RULE_ID); });
|
42 | return config;
|
43 | }
|
44 | ConfigFactory.createForBanSnippetsRule = createForBanSnippetsRule;
|
45 | function validate(config, prop, ruleId) {
|
46 | if (!hasProp(config, prop)) {
|
47 | throw new Error("invalid config for rule " + ruleId + " - " + prop + " is missing");
|
48 | }
|
49 | }
|
50 | function hasProp(config, prop) {
|
51 | return config[prop] !== undefined;
|
52 | }
|
53 | function validateSnippetsList(config, ruleId) {
|
54 |
|
55 | var hasSnippets = hasProp(config, SNIPPETS_PROP);
|
56 | var hasRegexSnippets = hasProp(config, REGEX_SNIPPETS_PROP);
|
57 | var isValid = hasSnippets || hasRegexSnippets;
|
58 | var hasBoth = hasSnippets && hasRegexSnippets;
|
59 | if (!isValid || hasBoth) {
|
60 | throw new Error("invalid config for rule " + ruleId + " - either " + SNIPPETS_PROP + " or " + REGEX_SNIPPETS_PROP + " must be set");
|
61 | }
|
62 | }
|
63 | function createFromArguments(options, ruleId) {
|
64 | var args = options.ruleArguments;
|
65 | if (args.length !== 1) {
|
66 | throw new Error("tslint rule is misconfigured (" + ruleId + ") - options.ruleArguments length is " + args.length);
|
67 | }
|
68 | var config = args[0];
|
69 | return config;
|
70 | }
|
71 | })(ConfigFactory || (ConfigFactory = {}));
|
72 |
|
73 | var GeneralRuleUtils;
|
74 | (function (GeneralRuleUtils) {
|
75 | function buildFailureString(message, ruleId) {
|
76 |
|
77 | return message + " (" + ruleId + ")";
|
78 | }
|
79 | GeneralRuleUtils.buildFailureString = buildFailureString;
|
80 | function isFileInPaths(filePath, paths) {
|
81 | return paths.some(function (path) { return filePath.indexOf(path) >= 0; });
|
82 | }
|
83 | GeneralRuleUtils.isFileInPaths = isFileInPaths;
|
84 | })(GeneralRuleUtils || (GeneralRuleUtils = {}));
|
85 |
|
86 | var Rule = (function (_super) {
|
87 | __extends(Rule, _super);
|
88 | function Rule() {
|
89 | return _super !== null && _super.apply(this, arguments) || this;
|
90 | }
|
91 | Rule.prototype.apply = function (sourceFile) {
|
92 | var config = ConfigFactory.createForBanSnippetsRule(this.getOptions());
|
93 | var walker = new StatementsWalker(sourceFile, this.getOptions(), config);
|
94 | this.applyWithWalker(walker);
|
95 | return walker.getFailures();
|
96 | };
|
97 | return Rule;
|
98 | }(Rules.AbstractRule));
|
99 | var StatementsWalker = (function (_super) {
|
100 | __extends(StatementsWalker, _super);
|
101 | function StatementsWalker(sourceFile, options, config) {
|
102 | var _this = _super.call(this, sourceFile, options) || this;
|
103 | _this.config = config;
|
104 | return _this;
|
105 | }
|
106 | StatementsWalker.prototype.visitReturnStatement = function (node) {
|
107 | this.visitSomeNode(node);
|
108 | };
|
109 | StatementsWalker.prototype.visitBinaryExpression = function (node) {
|
110 | this.visitSomeNode(node);
|
111 | _super.prototype.visitBinaryExpression.call(this, node);
|
112 | };
|
113 | StatementsWalker.prototype.visitCallExpression = function (node) {
|
114 | this.visitSomeNode(node);
|
115 | _super.prototype.visitCallExpression.call(this, node);
|
116 | };
|
117 | StatementsWalker.prototype.visitDebuggerStatement = function (node) {
|
118 | this.visitSomeNode(node);
|
119 | _super.prototype.visitDebuggerStatement.call(this, node);
|
120 | };
|
121 | StatementsWalker.prototype.visitSomeNode = function (node) {
|
122 | var _this = this;
|
123 | var text = node.getText();
|
124 | var relevantBanned = this.getRelevantBanned();
|
125 | relevantBanned.forEach(function (banned) {
|
126 | if (banned.snippets) {
|
127 | _this.checkBannedSnippet(banned.snippets, text, node, banned.message);
|
128 | }
|
129 | else if (banned.regexSnippets) {
|
130 | _this.checkRegexBannedSnippet(banned.regexSnippets, text, node, banned.message);
|
131 | }
|
132 | else {
|
133 | throw new Error("Invalid config? No snippets and no regex-snippets");
|
134 | }
|
135 | });
|
136 | };
|
137 | StatementsWalker.prototype.checkBannedSnippet = function (snippets, text, node, message) {
|
138 | var bannedCodeFound = snippets.filter(function (bannedSnippet) { return text.indexOf(bannedSnippet) >= 0; });
|
139 | if (bannedCodeFound.length > 0) {
|
140 | this.failRule(node, bannedCodeFound, message);
|
141 | }
|
142 | };
|
143 | StatementsWalker.prototype.checkRegexBannedSnippet = function (regexSnippets, text, node, message) {
|
144 | var bannedCodeFound = regexSnippets.filter(function (regexSnippet) {
|
145 | var regex = new RegExp(regexSnippet);
|
146 | return regex.test(text);
|
147 | });
|
148 | if (bannedCodeFound.length > 0) {
|
149 | this.failRule(node, bannedCodeFound, message);
|
150 | }
|
151 | };
|
152 | StatementsWalker.prototype.failRule = function (node, bannedCodeFound, message) {
|
153 | var failureNode = node.getFirstToken() || node;
|
154 | this.addFailureAtNode(failureNode, GeneralRuleUtils.buildFailureString(message || "Do not use banned code '" + bannedCodeFound.join("' or '") + "'.", BAN_SNIPPETS_RULE_ID));
|
155 | };
|
156 | StatementsWalker.prototype.getRelevantBanned = function () {
|
157 | var sourceFilePath = this.getSourceFile().fileName;
|
158 | return this.config.banned.filter(function (b) {
|
159 | return (!b.includePaths ||
|
160 | GeneralRuleUtils.isFileInPaths(sourceFilePath, b.includePaths)) &&
|
161 | (!b.excludePaths || !GeneralRuleUtils.isFileInPaths(sourceFilePath, b.excludePaths));
|
162 | });
|
163 | };
|
164 | return StatementsWalker;
|
165 | }(RuleWalker));
|
166 |
|
167 | export { Rule };
|
168 |
|