tslint-origin-ordered-imports-rule
Version:
tslint rule to check order of imports
138 lines • 6.25 kB
JavaScript
"use strict";
var __extends = (this && this.__extends) || (function () {
var extendStatics = function (d, b) {
extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
return extendStatics(d, b);
};
return function (d, b) {
if (typeof b !== "function" && b !== null)
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
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 tsutils = require("tsutils");
var originOrderedImportsRule_1 = require("./originOrderedImportsRule");
var anyImportSyntaxKind = new Set([ts.SyntaxKind.ImportDeclaration, ts.SyntaxKind.ImportEqualsDeclaration]);
var Walker = /** @class */ (function (_super) {
__extends(Walker, _super);
function Walker() {
return _super !== null && _super.apply(this, arguments) || this;
}
Walker.prototype.walk = function (sourceFile) {
var _this = this;
var cb = function (node) {
if (node.kind === ts.SyntaxKind.ImportDeclaration) {
_this.visitImportDeclaration(node);
}
if (node.kind === ts.SyntaxKind.ImportEqualsDeclaration) {
_this.visitImportEqualsDeclaration(node);
}
return ts.forEachChild(node, cb);
};
return ts.forEachChild(sourceFile, cb);
};
/**
* For expressions like: import { A, B } from 'foo'
*/
Walker.prototype.visitImportDeclaration = function (node) {
this.check(node, this.getModuleName(node));
};
/**
* For expressions like: import foo = require('foo')
*/
Walker.prototype.visitImportEqualsDeclaration = function (node) {
this.check(node, this.getModuleName(node));
};
Walker.prototype.getModuleName = function (node) {
if (node.kind === ts.SyntaxKind.ImportDeclaration) {
return this.removeQuotes(node.moduleSpecifier.getText());
}
if (node.moduleReference.kind === ts.SyntaxKind.ExternalModuleReference) {
var moduleRef = node.moduleReference;
if (moduleRef.expression.kind === ts.SyntaxKind.StringLiteral) {
return this.removeQuotes(moduleRef.expression.text);
}
}
return this.removeQuotes(node.moduleReference.getText());
};
Walker.prototype.check = function (node, source) {
this.checkOrder(node, source);
if (this.options.blankLines !== originOrderedImportsRule_1.BlankLinesOption.AnyNumber) {
this.checkEmptyLine(node, source);
}
};
Walker.prototype.checkOrder = function (node, source) {
if (!this.options.modulesOrder.check(source)) {
var current = this.options.modulesOrder.findImportGroup(source);
var prev = this.options.modulesOrder.getCurrentImportGroup();
this.addFailureAtNode(node, "\"" + current.getTitle() + "\" must be higher than \"" + prev.getTitle() + "\"");
}
};
Walker.prototype.checkEmptyLine = function (node, source) {
var importGroup = this.options.modulesOrder.findImportGroup(source);
var nodeLine = ts
.getLineAndCharacterOfPosition(this.getSourceFile(), node.getEnd())
.line;
var nextNode = tsutils.getNextStatement(node);
if (!nextNode || !anyImportSyntaxKind.has(nextNode.kind)) {
return;
}
var nextSource = this.getModuleName(nextNode);
var nextImportGroup = this.options.modulesOrder.findImportGroup(nextSource);
if (nextImportGroup.index <= importGroup.index) {
return;
}
var nextNodeLine = ts
.getLineAndCharacterOfPosition(this.getSourceFile(), nextNode.getStart(this.getSourceFile()))
.line;
var totalLinesCountBetweenNodes = nextNodeLine - nodeLine - 1;
var blankLinesCount = totalLinesCountBetweenNodes - this.getNodeLeadingCommentedLinesCount(nextNode);
var postfix = "between \"" + importGroup.getTitle() + "\" and \"" + nextImportGroup.getTitle() + "\"";
var failed = false;
var whyFailed = '';
switch (this.options.blankLines) {
case originOrderedImportsRule_1.BlankLinesOption.One:
failed = blankLinesCount !== 1;
whyFailed = "One blank line required " + postfix;
break;
case originOrderedImportsRule_1.BlankLinesOption.No:
failed = blankLinesCount !== 0;
whyFailed = "Blank lines " + postfix;
break;
case originOrderedImportsRule_1.BlankLinesOption.AtLeastOne:
failed = blankLinesCount === 0;
whyFailed = "At least one blank line required " + postfix;
}
if (failed) {
this.addFailureAtNode(node, whyFailed);
}
};
Walker.prototype.getNodeLeadingCommentedLinesCount = function (node) {
var _this = this;
var comments = ts.getLeadingCommentRanges(this.getSourceFile().text, node.pos);
if (!comments)
return 0;
return comments
.reduce(function (count, comment) {
var startLine = ts.getLineAndCharacterOfPosition(_this.getSourceFile(), comment.pos).line;
var endLine = ts.getLineAndCharacterOfPosition(_this.getSourceFile(), comment.end).line;
return count + (endLine - startLine + 1);
}, 0);
};
Walker.prototype.removeQuotes = function (value) {
if (value && value.length > 1 && (value[0] === "'" || value[0] === "\"")) {
value = value.substr(1, value.length - 2);
}
return value;
};
return Walker;
}(Lint.AbstractWalker));
exports.default = Walker;
//# sourceMappingURL=../src/dist/walker.js.map