type2docfx
Version:
A tool to convert json format output from TypeDoc to universal reference model for DocFx to consume.
278 lines (277 loc) • 13.5 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 Lint = require("tslint");
var ngWalker_1 = require("./angular/ngWalker");
var ast = require("@angular/compiler");
var basicTemplateAstVisitor_1 = require("./angular/templates/basicTemplateAstVisitor");
var expressionTypes_1 = require("./angular/expressionTypes");
var config_1 = require("./angular/config");
var recursiveAngularExpressionVisitor_1 = require("./angular/templates/recursiveAngularExpressionVisitor");
var stickyFlagUsable = (function () {
try {
var reg = new RegExp('\d', 'y');
return true;
}
catch (e) {
return false;
}
})();
var InterpolationOpen = config_1.Config.interpolation[0];
var InterpolationClose = config_1.Config.interpolation[1];
var InterpolationWhitespaceRe = new RegExp(InterpolationOpen + "(\\s*)(.*?)(\\s*)" + InterpolationClose, 'g');
var SemicolonNoWhitespaceNotInSimpleQuoteRe = stickyFlagUsable ?
new RegExp("(?:[^';]|'[^']*'|;(?=\\s))+;(?=\\S)", 'gy') : /(?:[^';]|'[^']*')+;/g;
var SemicolonNoWhitespaceNotInDoubleQuoteRe = stickyFlagUsable ?
new RegExp("(?:[^\";]|\"[^\"]*\"|;(?=\\s))+;(?=\\S)", 'gy') : /(?:[^";]|"[^"]*")+;/g;
var getSemicolonReplacements = function (absolutePosition) {
return [
new Lint.Replacement(absolutePosition, 1, '; ')
];
};
var checkSemicolonNoWhitespaceWithSticky = function (reg, context, expr, fixedOffset) {
var error = 'Missing whitespace after semicolon; expecting \'; expr\'';
var exprMatch;
while (exprMatch = reg.exec(expr)) {
var start = fixedOffset + reg.lastIndex;
var absolutePosition = context.getSourcePosition(start - 1);
context.addFailure(context.createFailure(start, 2, error, getSemicolonReplacements(absolutePosition)));
}
};
var checkSemicolonNoWhitespaceWithoutSticky = function (reg, context, expr, fixedOffset) {
var error = 'Missing whitespace after semicolon; expecting \'; expr\'';
var lastIndex = 0;
var exprMatch;
while (exprMatch = reg.exec(expr)) {
if (lastIndex !== exprMatch.index) {
break;
}
var nextIndex = reg.lastIndex;
if (nextIndex < expr.length && /\S/.test(expr[nextIndex])) {
var start = fixedOffset + nextIndex;
var absolutePosition = context.getSourcePosition(start - 1);
context.addFailure(context.createFailure(start, 2, error, getSemicolonReplacements(absolutePosition)));
}
lastIndex = nextIndex;
}
};
var checkSemicolonNoWhitespace = stickyFlagUsable ?
checkSemicolonNoWhitespaceWithSticky :
checkSemicolonNoWhitespaceWithoutSticky;
var InterpolationWhitespaceVisitor = (function (_super) {
__extends(InterpolationWhitespaceVisitor, _super);
function InterpolationWhitespaceVisitor() {
return _super !== null && _super.apply(this, arguments) || this;
}
InterpolationWhitespaceVisitor.prototype.visitBoundText = function (text, context) {
if (expressionTypes_1.ExpTypes.ASTWithSource(text.value)) {
var error = null;
var expr = text.value.source;
var checkWhiteSpace = function (subMatch, location, fixTo, position, absolutePosition, lengthFix) {
var length = subMatch.length;
if (length === 1) {
return;
}
var errorText = length === 0 ? 'Missing' : 'Extra';
context.addFailure(context.createFailure(position, length + lengthFix, errorText + " whitespace in interpolation " + location + "; expecting " + InterpolationOpen + " expr " + InterpolationClose, [
new Lint.Replacement(absolutePosition, length + lengthFix, fixTo)
]));
};
InterpolationWhitespaceRe.lastIndex = 0;
var match = void 0;
while (match = InterpolationWhitespaceRe.exec(expr)) {
var start = text.sourceSpan.start.offset + match.index;
var absolutePosition = context.getSourcePosition(start);
checkWhiteSpace(match[1], 'start', InterpolationOpen + " ", start, absolutePosition, InterpolationOpen.length);
var positionFix = InterpolationOpen.length + match[1].length + match[2].length;
checkWhiteSpace(match[3], 'end', " " + InterpolationClose, start + positionFix, absolutePosition + positionFix, InterpolationClose.length);
}
}
_super.prototype.visitBoundText.call(this, text, context);
return null;
};
InterpolationWhitespaceVisitor.prototype.getOption = function () {
return 'check-interpolation';
};
return InterpolationWhitespaceVisitor;
}(basicTemplateAstVisitor_1.BasicTemplateAstVisitor));
var SemicolonTemplateVisitor = (function (_super) {
__extends(SemicolonTemplateVisitor, _super);
function SemicolonTemplateVisitor() {
return _super !== null && _super.apply(this, arguments) || this;
}
SemicolonTemplateVisitor.prototype.visitDirectiveProperty = function (prop, context) {
if (prop.sourceSpan) {
var directive = prop.sourceSpan.toString();
var match = /^([^=]+=\s*)([^]*?)\s*$/.exec(directive);
var rawExpression = match[2];
var positionFix = match[1].length + 1;
var expr = rawExpression.slice(1, -1).trim();
var doubleQuote = rawExpression[0] === '"';
var reg = doubleQuote ? SemicolonNoWhitespaceNotInSimpleQuoteRe : SemicolonNoWhitespaceNotInDoubleQuoteRe;
reg.lastIndex = 0;
checkSemicolonNoWhitespace(reg, context, expr, prop.sourceSpan.start.offset + positionFix);
}
};
SemicolonTemplateVisitor.prototype.getOption = function () {
return 'check-semicolon';
};
return SemicolonTemplateVisitor;
}(basicTemplateAstVisitor_1.BasicTemplateAstVisitor));
var WhitespaceTemplateVisitor = (function (_super) {
__extends(WhitespaceTemplateVisitor, _super);
function WhitespaceTemplateVisitor() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.visitors = [
new InterpolationWhitespaceVisitor(_this.getSourceFile(), _this.getOptions(), _this.context, _this.templateStart),
new SemicolonTemplateVisitor(_this.getSourceFile(), _this.getOptions(), _this.context, _this.templateStart)
];
return _this;
}
WhitespaceTemplateVisitor.prototype.visitBoundText = function (text, context) {
var _this = this;
var options = this.getOptions();
this.visitors
.filter(function (v) { return options.indexOf(v.getOption()) >= 0; })
.map(function (v) { return v.visitBoundText(text, _this); })
.filter(function (f) { return !!f; })
.forEach(function (f) { return _this.addFailure(f); });
_super.prototype.visitBoundText.call(this, text, context);
};
WhitespaceTemplateVisitor.prototype.visitDirectiveProperty = function (prop, context) {
var _this = this;
var options = this.getOptions();
this.visitors
.filter(function (v) { return options.indexOf(v.getOption()) >= 0; })
.map(function (v) { return v.visitDirectiveProperty(prop, _this); })
.filter(function (f) { return !!f; })
.forEach(function (f) { return _this.addFailure(f); });
_super.prototype.visitDirectiveProperty.call(this, prop, context);
};
return WhitespaceTemplateVisitor;
}(basicTemplateAstVisitor_1.BasicTemplateAstVisitor));
var PipeWhitespaceVisitor = (function (_super) {
__extends(PipeWhitespaceVisitor, _super);
function PipeWhitespaceVisitor() {
return _super !== null && _super.apply(this, arguments) || this;
}
PipeWhitespaceVisitor.prototype.visitPipe = function (ast, context) {
var exprStart, exprEnd, exprText, sf;
exprStart = context.getSourcePosition(ast.exp.span.start);
exprEnd = context.getSourcePosition(ast.exp.span.end);
sf = context.getSourceFile().getFullText();
exprText = sf.substring(exprStart, exprEnd);
var replacements = [];
var parentheses = false;
var leftBeginning;
if (sf[exprEnd] === ')') {
parentheses = true;
leftBeginning = exprEnd + 1 + 2;
}
else {
leftBeginning = exprEnd + 1;
}
if (sf[leftBeginning] === ' ') {
var ignoreSpace = 1;
while (sf[leftBeginning + ignoreSpace] === ' ') {
ignoreSpace += 1;
}
if (ignoreSpace > 1) {
replacements.push(new Lint.Replacement(exprEnd + 1, ignoreSpace, ' '));
}
}
else {
replacements.push(new Lint.Replacement(exprEnd + 1, 0, ' '));
}
if (exprText[exprText.length - 1] === ' ') {
var ignoreSpace = 1;
while (exprText[exprText.length - 1 - ignoreSpace] === ' ') {
ignoreSpace += 1;
}
if (ignoreSpace > 1) {
replacements.push(new Lint.Replacement(exprEnd - ignoreSpace, ignoreSpace, ' '));
}
}
else {
if (!parentheses) {
replacements.push(new Lint.Replacement(exprEnd, 0, ' '));
}
}
if (replacements.length) {
context.addFailure(context.createFailure(ast.exp.span.end - 1, 3, 'The pipe operator should be surrounded by one space on each side, i.e. " | ".', replacements));
}
_super.prototype.visitPipe.call(this, ast, context);
return null;
};
PipeWhitespaceVisitor.prototype.getOption = function () {
return 'check-pipe';
};
PipeWhitespaceVisitor.prototype.isAsyncBinding = function (expr) {
return expr instanceof ast.BindingPipe && expr.name === 'async';
};
return PipeWhitespaceVisitor;
}(recursiveAngularExpressionVisitor_1.RecursiveAngularExpressionVisitor));
var TemplateExpressionVisitor = (function (_super) {
__extends(TemplateExpressionVisitor, _super);
function TemplateExpressionVisitor() {
var _this = _super !== null && _super.apply(this, arguments) || this;
_this.visitors = [
new PipeWhitespaceVisitor(_this.getSourceFile(), _this.getOptions(), _this.context, _this.basePosition)
];
return _this;
}
TemplateExpressionVisitor.prototype.visitPipe = function (expr, context) {
var _this = this;
var options = this.getOptions();
this.visitors
.map(function (v) { return v.addParentAST(_this.parentAST); })
.filter(function (v) { return options.indexOf(v.getOption()) >= 0; })
.map(function (v) { return v.visitPipe(expr, _this); })
.filter(function (f) { return !!f; })
.forEach(function (f) { return _this.addFailure(f); });
};
return TemplateExpressionVisitor;
}(recursiveAngularExpressionVisitor_1.RecursiveAngularExpressionVisitor));
var Rule = (function (_super) {
__extends(Rule, _super);
function Rule() {
return _super !== null && _super.apply(this, arguments) || this;
}
Rule.prototype.apply = function (sourceFile) {
return this.applyWithWalker(new ngWalker_1.NgWalker(sourceFile, this.getOptions(), {
templateVisitorCtrl: WhitespaceTemplateVisitor,
expressionVisitorCtrl: TemplateExpressionVisitor,
}));
};
Rule.metadata = {
ruleName: 'angular-whitespace',
type: 'style',
description: 'Ensures the proper formatting of Angular expressions.',
rationale: 'Having whitespace in the right places in an Angular expression makes the template more readable.',
optionsDescription: (_a = ["\n Arguments may be optionally provided:\n * `\"check-interpolation\"` checks for whitespace before and after the interpolation characters\n * `\"check-pipe\"` checks for whitespace before and after a pipe\n * `\"check-semicolon\"` checks for whitespace after semicolon"], _a.raw = ["\n Arguments may be optionally provided:\n * \\`\"check-interpolation\"\\` checks for whitespace before and after the interpolation characters\n * \\`\"check-pipe\"\\` checks for whitespace before and after a pipe\n * \\`\"check-semicolon\"\\` checks for whitespace after semicolon"], Lint.Utils.dedent(_a)),
options: {
type: 'array',
items: {
type: 'string',
enum: ['check-interpolation', 'check-pipe', 'check-semicolon'],
},
minLength: 0,
maxLength: 3,
},
optionExamples: ['[true, "check-interpolation"]'],
typescriptOnly: true,
hasFix: true
};
return Rule;
}(Lint.Rules.AbstractRule));
exports.Rule = Rule;
var _a;