tslint-microsoft-contrib
Version:
TSLint Rules for Microsoft
172 lines • 8.34 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 (b.hasOwnProperty(p)) d[p] = b[p]; };
return extendStatics(d, b);
}
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 AstUtils_1 = require("./AstUtils");
var Scope_1 = require("./Scope");
var TypeGuard_1 = require("./TypeGuard");
var ScopedSymbolTrackingWalker = (function (_super) {
__extends(ScopedSymbolTrackingWalker, _super);
function ScopedSymbolTrackingWalker(sourceFile, options, program) {
var _this = _super.call(this, sourceFile, options) || this;
if (program) {
_this.typeChecker = program.getTypeChecker();
}
return _this;
}
ScopedSymbolTrackingWalker.prototype.getFunctionTargetType = function (expression) {
if (expression.expression.kind === ts.SyntaxKind.PropertyAccessExpression && this.typeChecker) {
var propExp = expression.expression;
var targetType = this.typeChecker.getTypeAtLocation(propExp.expression);
return this.typeChecker.typeToString(targetType);
}
return undefined;
};
ScopedSymbolTrackingWalker.prototype.isExpressionEvaluatingToFunction = function (expression) {
if (expression.kind === ts.SyntaxKind.ArrowFunction || expression.kind === ts.SyntaxKind.FunctionExpression) {
return true;
}
if (expression.kind === ts.SyntaxKind.StringLiteral ||
expression.kind === ts.SyntaxKind.NoSubstitutionTemplateLiteral ||
expression.kind === ts.SyntaxKind.TemplateExpression ||
expression.kind === ts.SyntaxKind.TaggedTemplateExpression ||
expression.kind === ts.SyntaxKind.BinaryExpression) {
return false;
}
if (this.scope !== undefined && this.scope.isFunctionSymbol(expression.getText())) {
return true;
}
if (expression.kind === ts.SyntaxKind.Identifier && this.typeChecker) {
var tsSymbol = this.typeChecker.getSymbolAtLocation(expression);
if (tsSymbol && tsSymbol.flags === ts.SymbolFlags.Function) {
return true;
}
return false;
}
if (ts.isCallExpression(expression)) {
if (TypeGuard_1.isNamed(expression.expression) && expression.expression.name.getText() === 'bind') {
return true;
}
try {
if (!this.typeChecker) {
return true;
}
var signature = this.typeChecker.getResolvedSignature(expression);
if (signature !== undefined) {
var expressionType = this.typeChecker.getReturnTypeOfSignature(signature);
return this.isFunctionType(expressionType, this.typeChecker);
}
}
catch (e) {
return false;
}
}
if (!this.typeChecker) {
return true;
}
return this.isFunctionType(this.typeChecker.getTypeAtLocation(expression), this.typeChecker);
};
ScopedSymbolTrackingWalker.prototype.isFunctionType = function (expressionType, typeChecker) {
var signatures = typeChecker.getSignaturesOfType(expressionType, ts.SignatureKind.Call);
if (signatures !== undefined && signatures.length > 0) {
var signatureDeclaration = signatures[0].declaration;
if (signatureDeclaration !== undefined && signatureDeclaration.kind === ts.SyntaxKind.FunctionType) {
return true;
}
}
return false;
};
ScopedSymbolTrackingWalker.prototype.visitSourceFile = function (node) {
this.scope = new Scope_1.Scope(undefined);
this.scope.addGlobalScope(node, node, this.getOptions());
_super.prototype.visitSourceFile.call(this, node);
this.scope = undefined;
};
ScopedSymbolTrackingWalker.prototype.visitModuleDeclaration = function (node) {
this.scope = new Scope_1.Scope(this.scope);
this.scope.addGlobalScope(node.body, this.getSourceFile(), this.getOptions());
_super.prototype.visitModuleDeclaration.call(this, node);
this.scope = this.scope.parent;
};
ScopedSymbolTrackingWalker.prototype.visitClassDeclaration = function (node) {
var scope = (this.scope = new Scope_1.Scope(this.scope));
node.members.forEach(function (element) {
var prefix = AstUtils_1.AstUtils.isStatic(element) && node.name !== undefined ? node.name.getText() + '.' : 'this.';
if (element.kind === ts.SyntaxKind.MethodDeclaration) {
scope.addFunctionSymbol(prefix + element.name.getText());
}
else if (element.kind === ts.SyntaxKind.PropertyDeclaration) {
var prop = element;
if (AstUtils_1.AstUtils.isDeclarationFunctionType(prop)) {
scope.addFunctionSymbol(prefix + element.name.getText());
}
else {
scope.addNonFunctionSymbol(prefix + element.name.getText());
}
}
});
_super.prototype.visitClassDeclaration.call(this, node);
this.scope = this.scope.parent;
};
ScopedSymbolTrackingWalker.prototype.visitFunctionDeclaration = function (node) {
this.scope = new Scope_1.Scope(this.scope);
this.scope.addParameters(node.parameters);
_super.prototype.visitFunctionDeclaration.call(this, node);
this.scope = this.scope.parent;
};
ScopedSymbolTrackingWalker.prototype.visitConstructorDeclaration = function (node) {
this.scope = new Scope_1.Scope(this.scope);
this.scope.addParameters(node.parameters);
_super.prototype.visitConstructorDeclaration.call(this, node);
this.scope = this.scope.parent;
};
ScopedSymbolTrackingWalker.prototype.visitMethodDeclaration = function (node) {
this.scope = new Scope_1.Scope(this.scope);
this.scope.addParameters(node.parameters);
_super.prototype.visitMethodDeclaration.call(this, node);
this.scope = this.scope.parent;
};
ScopedSymbolTrackingWalker.prototype.visitArrowFunction = function (node) {
this.scope = new Scope_1.Scope(this.scope);
this.scope.addParameters(node.parameters);
_super.prototype.visitArrowFunction.call(this, node);
this.scope = this.scope.parent;
};
ScopedSymbolTrackingWalker.prototype.visitFunctionExpression = function (node) {
this.scope = new Scope_1.Scope(this.scope);
this.scope.addParameters(node.parameters);
_super.prototype.visitFunctionExpression.call(this, node);
this.scope = this.scope.parent;
};
ScopedSymbolTrackingWalker.prototype.visitSetAccessor = function (node) {
this.scope = new Scope_1.Scope(this.scope);
this.scope.addParameters(node.parameters);
_super.prototype.visitSetAccessor.call(this, node);
this.scope = this.scope.parent;
};
ScopedSymbolTrackingWalker.prototype.visitVariableDeclaration = function (node) {
if (AstUtils_1.AstUtils.isDeclarationFunctionType(node)) {
this.scope.addFunctionSymbol(node.name.getText());
}
else {
this.scope.addNonFunctionSymbol(node.name.getText());
}
_super.prototype.visitVariableDeclaration.call(this, node);
};
return ScopedSymbolTrackingWalker;
}(Lint.RuleWalker));
exports.ScopedSymbolTrackingWalker = ScopedSymbolTrackingWalker;
//# sourceMappingURL=ScopedSymbolTrackingWalker.js.map