tslint-clean-code
Version:
TSLint rules for enforcing Clean Code
125 lines • 5.99 kB
JavaScript
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var ts = require("typescript");
var Lint = require("tslint");
var ErrorTolerantWalker_1 = require("./utils/ErrorTolerantWalker");
var Rule = (function (_super) {
__extends(Rule, _super);
function Rule() {
return _super !== null && _super.apply(this, arguments) || this;
}
Rule.FAILURE_STRING = function (switchExpression, caseExpressions) {
var cases = caseExpressions.map(function (text) { return " case " + text + ":\n // ...\n break;"; });
return ("Don't Repeat Yourself in If statements. Try using a Switch statement instead:\n" +
(" switch (" + switchExpression + ") {\n" + cases.join('\n') + "\n default:\n // ...\n}"));
};
Rule.prototype.apply = function (sourceFile) {
return this.applyWithWalker(new PreferDryConditionalsRuleWalker(sourceFile, this.getOptions()));
};
Rule.metadata = {
ruleName: 'prefer-dry-conditionals',
type: 'maintainability',
description: "Don't-Repeat-Yourself in if statement conditionals, instead use Switch statements.",
options: null,
optionsDescription: '',
optionExamples: [],
typescriptOnly: false,
issueClass: 'Non-SDL',
issueType: 'Warning',
severity: 'Low',
level: 'Opportunity for Excellence',
group: 'Clarity',
commonWeaknessEnumeration: '',
};
return Rule;
}(Lint.Rules.AbstractRule));
exports.Rule = Rule;
var PreferDryConditionalsRuleWalker = (function (_super) {
__extends(PreferDryConditionalsRuleWalker, _super);
function PreferDryConditionalsRuleWalker(sourceFile, options) {
var _this = _super.call(this, sourceFile, options) || this;
_this.threshold = 1;
_this.parseOptions();
return _this;
}
PreferDryConditionalsRuleWalker.prototype.visitIfStatement = function (node) {
this.checkAndReport(node);
_super.prototype.visitIfStatement.call(this, node);
};
PreferDryConditionalsRuleWalker.prototype.checkAndReport = function (node) {
var expression = node.expression, parent = node.parent;
if (!ts.isIfStatement(parent) && ts.isBinaryExpression(expression)) {
var ifStatements = this.allNestedIfStatements(node);
var exceedsThreshold = ifStatements.length > this.threshold;
if (!exceedsThreshold) {
return;
}
var areAllBinaryExpressions = ifStatements.every(function (statement) { return ts.isBinaryExpression(statement.expression); });
if (areAllBinaryExpressions) {
var binaryExpressions = ifStatements.map(function (statement) { return statement.expression; });
this.checkBinaryExpressions(binaryExpressions);
}
}
};
PreferDryConditionalsRuleWalker.prototype.allNestedIfStatements = function (node) {
var ifStatements = [node];
var curr = node;
while (ts.isIfStatement(curr.elseStatement)) {
ifStatements.push(curr.elseStatement);
curr = curr.elseStatement;
}
return ifStatements;
};
PreferDryConditionalsRuleWalker.prototype.checkBinaryExpressions = function (expressions) {
if (expressions.length <= 1) {
return;
}
var firstExpression = expressions[0];
var expectedOperatorToken = firstExpression.operatorToken;
var isEqualityCheck = expectedOperatorToken.kind === ts.SyntaxKind.EqualsEqualsToken ||
expectedOperatorToken.kind === ts.SyntaxKind.EqualsEqualsEqualsToken;
if (!isEqualityCheck) {
return;
}
var expectedLeft = firstExpression.left;
var expectedRight = firstExpression.right;
var hasSameOperator = expressions.every(function (expression) { return expression.operatorToken.kind === expectedOperatorToken.kind; });
if (!hasSameOperator) {
return;
}
var leftExpressions = expressions.map(function (expression) { return expression.left; });
var rightExpressions = expressions.map(function (expression) { return expression.right; });
var hasSameLeft = leftExpressions.every(function (expression) { return expression.getText() === expectedLeft.getText(); });
var hasSameRight = rightExpressions.every(function (expression) { return expression.getText() === expectedRight.getText(); });
if (hasSameLeft) {
this.addFailureAtNode(firstExpression.parent, Rule.FAILURE_STRING(expectedLeft.getText(), rightExpressions.map(function (expression) { return expression.getText(); })));
}
else if (hasSameRight) {
this.addFailureAtNode(firstExpression.parent, Rule.FAILURE_STRING(expectedRight.getText(), leftExpressions.map(function (expression) { return expression.getText(); })));
}
};
PreferDryConditionalsRuleWalker.prototype.parseOptions = function () {
var _this = this;
this.getOptions().forEach(function (opt) {
if (typeof opt === 'boolean') {
return;
}
if (typeof opt === 'number') {
_this.threshold = Math.max(1, opt);
return;
}
});
};
return PreferDryConditionalsRuleWalker;
}(ErrorTolerantWalker_1.ErrorTolerantWalker));
//# sourceMappingURL=preferDryConditionalsRule.js.map
;