@motorcycle/tslint
Version:
TSLint for Motorcycle.js Projects
159 lines • 7.82 kB
JavaScript
"use strict";
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 __());
};
})();
exports.__esModule = true;
var Lint = require("tslint");
var ts = require("typescript");
var Rule = (function (_super) {
__extends(Rule, _super);
function Rule() {
return _super !== null && _super.apply(this, arguments) || this;
}
Rule.prototype.apply = function (sourceFile) {
var walker = new BraceStyleWalker(sourceFile, this.getOptions());
return this.applyWithWalker(walker);
};
return Rule;
}(Lint.Rules.AbstractRule));
Rule.FAILURE_STRING = {
open: 'Opening curly brace appears on the same line as controlling statement.',
body: 'Statement inside of curly braces should be on next line.',
close: 'Closing curly brace should be on the same line as opening curly ' +
'brace or on the line after the previous block.'
};
exports.Rule = Rule;
var BraceStyleWalker = (function (_super) {
__extends(BraceStyleWalker, _super);
function BraceStyleWalker(sourceFile, options) {
var _this = _super.call(this, sourceFile, options) || this;
_this.allowSingleLine = false;
_this.srcText = sourceFile.getFullText();
_this.allowSingleLine = _this.getOptions()[1] && _this.getOptions()[1].allowSingleLine;
return _this;
}
/* tslint:disable:cyclomatic-complexity */
BraceStyleWalker.prototype.visitBlock = function (block) {
_super.prototype.visitBlock.call(this, block);
var parent = block.parent;
var parentKind = parent.kind;
if (this.allowSingleLine &&
getStartPosition(block).line === getEndPosition(block).line) {
return;
}
var isFunction = parentKind === ts.SyntaxKind.Constructor ||
parentKind === ts.SyntaxKind.MethodDeclaration ||
parentKind === ts.SyntaxKind.FunctionExpression ||
parentKind === ts.SyntaxKind.FunctionDeclaration;
if (parentKind === ts.SyntaxKind.ArrowFunction ||
parentKind === ts.SyntaxKind.ElseKeyword ||
parentKind === ts.SyntaxKind.ForStatement ||
parentKind === ts.SyntaxKind.ForInStatement ||
parentKind === ts.SyntaxKind.ForOfStatement ||
parentKind === ts.SyntaxKind.TryStatement ||
parentKind === ts.SyntaxKind.CatchKeyword ||
parentKind === ts.SyntaxKind.CatchClause)
return;
if (isFunction && parametersAreOnSameLine(block))
return;
var blockChildren = block.getChildren();
var openingCurlyBrace = blockChildren.filter(function (ch) { return ch.kind === ts.SyntaxKind.OpenBraceToken; }).shift();
var closingCurlyBrace = blockChildren.filter(function (ch) { return ch.kind === ts.SyntaxKind.CloseBraceToken; }).pop();
var syntaxList = blockChildren.filter(function (ch) { return ch.kind === ts.SyntaxKind.SyntaxList; }).shift();
var blockPreviousNode = parent.getChildren()[parent.getChildren().indexOf(block) - 1];
if (!openingCurlyBrace || !closingCurlyBrace || !syntaxList || !blockPreviousNode)
return;
if (parentKind === ts.SyntaxKind.IfStatement) {
var children = parent.getChildren();
var previousNode = children[children.indexOf(block) - 1];
if (previousNode.kind === ts.SyntaxKind.ElseKeyword)
return;
var openingParenthese = children.filter(function (ch) { return ch.kind === ts.SyntaxKind.OpenParenToken; }).shift();
var closingParenthese = children.filter(function (ch) { return ch.kind === ts.SyntaxKind.CloseParenToken; }).shift();
if (!openingParenthese || !closingParenthese)
return;
var parenthesesSameLine = areOnSameLine(openingParenthese, closingParenthese);
if (parenthesesSameLine && areOnSameLine(closingParenthese, openingCurlyBrace))
return;
}
if (parentKind === ts.SyntaxKind.WhileStatement) {
var children = parent.getChildren();
var openingParenthese = children.filter(function (ch) { return ch.kind === ts.SyntaxKind.OpenParenToken; }).shift();
var closingParenthese = children.filter(function (ch) { return ch.kind === ts.SyntaxKind.CloseParenToken; }).shift();
if (!openingParenthese || !closingParenthese)
return;
var parenthesesSameLine = areOnSameLine(openingParenthese, closingParenthese);
if (parenthesesSameLine && areOnSameLine(closingParenthese, openingCurlyBrace))
return;
}
var openingBracketError = areOnSameLine(blockPreviousNode, block);
if (openingBracketError) {
var nextNode = blockChildren[blockChildren.indexOf(openingCurlyBrace) + 1];
var indent = this.getNodeIndent(nextNode);
this.addFailure(this.createFailure(openingCurlyBrace.getStart(), openingCurlyBrace.getWidth(), Rule.FAILURE_STRING.open));
}
if (syntaxList.getChildCount() > 0) {
var bodyError = areOnSameLine(openingCurlyBrace, syntaxList);
if (bodyError) {
this.addFailure(this.createFailure(syntaxList.getStart(), syntaxList.getWidth(), Rule.FAILURE_STRING.body));
}
var nodeBeforeClosingBracket = syntaxList.getChildren()[syntaxList.getChildren().length - 1];
var closingBracketError = areOnSameLine(nodeBeforeClosingBracket, closingCurlyBrace);
if (closingBracketError) {
this.addFailure(this.createFailure(closingCurlyBrace.getStart(), closingCurlyBrace.getWidth(), Rule.FAILURE_STRING.close));
}
}
};
BraceStyleWalker.prototype.getNodeIndent = function (node) {
if (node === this.getSourceFile()) {
return 0;
}
if (node.kind === ts.SyntaxKind.SyntaxList) {
return this.getNodeIndent(node.parent);
}
var endIndex = node.getStart();
var pos = endIndex - 1;
while (pos > 0 && this.srcText.charAt(pos) !== '\n') {
pos -= 1;
}
var str = this.getSourceSubstr(pos + 1, endIndex);
var whiteSpace = (str.match(/^\s+/) || [''])[0];
var indentChars = whiteSpace.split('');
var spaces = indentChars.filter(function (char) { return char === ' '; }).length;
return spaces;
};
BraceStyleWalker.prototype.getSourceSubstr = function (start, end) {
return this.srcText.substr(start, end - start);
};
return BraceStyleWalker;
}(Lint.RuleWalker));
function makeIndentation(num) {
var str = '';
for (var i = 0; i < num - 2; ++i)
str += ' ';
return str;
}
function areOnSameLine(node, nextNode) {
return getEndPosition(node).line === getStartPosition(nextNode).line;
}
function getStartPosition(node) {
return node.getSourceFile().getLineAndCharacterOfPosition(node.getStart());
}
function getEndPosition(node) {
return node.getSourceFile().getLineAndCharacterOfPosition(node.getEnd());
}
function parametersAreOnSameLine(block) {
var parent = block.parent;
var lastParameter = parent.parameters[parent.parameters.length - 1];
if (!lastParameter || areOnSameLine(lastParameter, parent))
return true;
return false;
}
//# sourceMappingURL=motorcycleBraceStyleRule.js.map