type2docfx
Version:
A tool to convert json format output from TypeDoc to universal reference model for DocFx to consume.
78 lines (77 loc) • 4.12 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 recursiveAngularExpressionVisitor_1 = require("./angular/templates/recursiveAngularExpressionVisitor");
var ast = require("@angular/compiler");
var unstrictEqualityOperator = '==';
var TemplateToNgTemplateVisitor = (function (_super) {
__extends(TemplateToNgTemplateVisitor, _super);
function TemplateToNgTemplateVisitor() {
return _super !== null && _super.apply(this, arguments) || this;
}
TemplateToNgTemplateVisitor.prototype.visitBinary = function (expr, context) {
if (!this.isAsyncBinding(expr.left)) {
return _super.prototype.visitBinary.call(this, expr, context);
}
if (!(expr.right instanceof ast.LiteralPrimitive) || expr.right.value !== false || expr.operation !== unstrictEqualityOperator) {
return _super.prototype.visitBinary.call(this, expr, context);
}
var operator = this.codeWithMap.code.slice(expr.left.span.end, expr.right.span.start);
var operatorStart = (/^.*==/).exec(operator)[0].length - unstrictEqualityOperator.length;
this.addFailure(this.createFailure(expr.span.start, expr.span.end - expr.span.start, 'Async pipes must use strict equality `===` when comparing with `false`', [
new Lint.Replacement(this.getSourcePosition(expr.left.span.end) + operatorStart, unstrictEqualityOperator.length, '==='),
]));
};
TemplateToNgTemplateVisitor.prototype.visitPrefixNot = function (expr, context) {
if (!this.isAsyncBinding(expr.expression)) {
return _super.prototype.visitPrefixNot.call(this, expr, context);
}
var width = expr.span.end - expr.span.start;
var absoluteStart = this.getSourcePosition(expr.span.start);
var expressionSource = this.codeWithMap.code.slice(expr.span.start, expr.span.end);
var concreteWidth = width - (/ *$/).exec(expressionSource)[0].length;
this.addFailure(this.createFailure(expr.span.start, width, 'Async pipes can not be negated, use (observable | async) === false instead', [
new Lint.Replacement(absoluteStart + concreteWidth, 1, ' === false '),
new Lint.Replacement(absoluteStart, 1, ''),
]));
};
TemplateToNgTemplateVisitor.prototype.isAsyncBinding = function (expr) {
return expr instanceof ast.BindingPipe && expr.name === 'async';
};
return TemplateToNgTemplateVisitor;
}(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(), {
expressionVisitorCtrl: TemplateToNgTemplateVisitor
}));
};
Rule.metadata = {
ruleName: 'templates-no-negated-async',
type: 'functionality',
description: 'Ensures that strict equality is used when evaluating negations on async pipe outout.',
rationale: 'Async pipe evaluate to `null` before the observable or promise emits, which can lead to layout thrashing as' +
' components load. Prefer strict `=== false` checks instead.',
options: null,
optionsDescription: 'Not configurable.',
typescriptOnly: true,
hasFix: true
};
return Rule;
}(Lint.Rules.AbstractRule));
exports.Rule = Rule;