diff options
author | Florian Dold <florian.dold@gmail.com> | 2017-08-14 05:01:11 +0200 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2017-08-14 05:02:09 +0200 |
commit | 363723fc84f7b8477592e0105aeb331ec9a017af (patch) | |
tree | 29f92724f34131bac64d6a318dd7e30612e631c7 /node_modules/tslint/lib/rules/deprecationRule.js | |
parent | 5634e77ad96bfe1818f6b6ee70b7379652e5487f (diff) |
node_modules
Diffstat (limited to 'node_modules/tslint/lib/rules/deprecationRule.js')
-rw-r--r-- | node_modules/tslint/lib/rules/deprecationRule.js | 179 |
1 files changed, 119 insertions, 60 deletions
diff --git a/node_modules/tslint/lib/rules/deprecationRule.js b/node_modules/tslint/lib/rules/deprecationRule.js index 536bf435f..40b58e96b 100644 --- a/node_modules/tslint/lib/rules/deprecationRule.js +++ b/node_modules/tslint/lib/rules/deprecationRule.js @@ -17,6 +17,7 @@ */ Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); +var tsutils_1 = require("tsutils"); var ts = require("typescript"); var Lint = require("../index"); var Rule = (function (_super) { @@ -25,77 +26,135 @@ var Rule = (function (_super) { return _super !== null && _super.apply(this, arguments) || this; } /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = function (name, message) { + return name + " is deprecated" + (message === "" ? "." : ": " + message.trim()); + }; Rule.prototype.applyWithProgram = function (sourceFile, program) { - return this.applyWithWalker(new Walker(sourceFile, this.getOptions(), program)); + return this.applyWithFunction(sourceFile, function (ctx) { return walk(ctx, program.getTypeChecker()); }); + }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "deprecation", + description: "Warns when deprecated APIs are used.", + descriptionDetails: (_a = ["Any usage of an identifier\n with the @deprecated JSDoc annotation will trigger a warning.\n See http://usejsdoc.org/tags-deprecated.html"], _a.raw = ["Any usage of an identifier\n with the @deprecated JSDoc annotation will trigger a warning.\n See http://usejsdoc.org/tags-deprecated.html"], Lint.Utils.dedent(_a)), + rationale: "Deprecated APIs should be avoided, and usage updated.", + optionsDescription: "", + options: null, + optionExamples: [], + type: "maintainability", + typescriptOnly: false, + requiresTypeInfo: true, }; return Rule; }(Lint.Rules.TypedRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "deprecation", - description: "Warns when deprecated APIs are used.", - descriptionDetails: (_a = ["Any usage of an identifier\n with the @deprecated JSDoc annotation will trigger a warning.\n See http://usejsdoc.org/tags-deprecated.html"], _a.raw = ["Any usage of an identifier\n with the @deprecated JSDoc annotation will trigger a warning.\n See http://usejsdoc.org/tags-deprecated.html"], Lint.Utils.dedent(_a)), - rationale: (_b = ["\n Deprecated APIs should be avoided, and usage updated."], _b.raw = ["\n Deprecated APIs should be avoided, and usage updated."], Lint.Utils.dedent(_b)), - optionsDescription: "", - options: null, - optionExamples: [], - type: "maintainability", - typescriptOnly: false, - requiresTypeInfo: true, -}; exports.Rule = Rule; -var Walker = (function (_super) { - tslib_1.__extends(Walker, _super); - function Walker() { - return _super !== null && _super.apply(this, arguments) || this; - } - // Implementation inspired by angular/tsickle: - // https://github.com/angular/tsickle/blob/cad7c180a2155db6f6fb8d22c44151d7e8a9149f/src/decorator-annotator.ts#L42 - Walker.prototype.visitIdentifier = function (node) { - var decSym = this.getTypeChecker().getSymbolAtLocation(node); - if (decSym !== undefined && Lint.isSymbolFlagSet(decSym, ts.SymbolFlags.Alias)) { - decSym = this.getTypeChecker().getAliasedSymbol(decSym); +function walk(ctx, tc) { + return ts.forEachChild(ctx.sourceFile, function cb(node) { + if (tsutils_1.isIdentifier(node)) { + if (!isDeclaration(node)) { + var deprecation = getDeprecation(node, tc); + if (deprecation !== undefined) { + ctx.addFailureAtNode(node, Rule.FAILURE_STRING(node.text, deprecation)); + } + } } - var declarations = decSym === undefined ? undefined : decSym.getDeclarations(); - if (declarations === undefined) { - _super.prototype.visitIdentifier.call(this, node); - return; + else { + return ts.forEachChild(node, cb); } - for (var _i = 0, declarations_1 = declarations; _i < declarations_1.length; _i++) { - var commentNode = declarations_1[_i]; - // Switch to the TS JSDoc parser in the future to avoid false positives here. - // For example using '@deprecated' in a true comment. - // However, a new TS API would be needed, track at - // https://github.com/Microsoft/TypeScript/issues/7393. - if (commentNode.kind === ts.SyntaxKind.VariableDeclaration) { - commentNode = commentNode.parent; - } - // Go up one more level to VariableDeclarationStatement, where usually - // the comment lives. If the declaration has an 'export', the - // VDList.getFullText will not contain the comment. - if (commentNode.kind === ts.SyntaxKind.VariableDeclarationList) { - commentNode = commentNode.parent; + }); +} +function isDeclaration(identifier) { + var parent = identifier.parent; + switch (parent.kind) { + case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.ClassExpression: + case ts.SyntaxKind.InterfaceDeclaration: + case ts.SyntaxKind.TypeParameter: + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.LabeledStatement: + case ts.SyntaxKind.JsxAttribute: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.MethodSignature: + case ts.SyntaxKind.PropertySignature: + case ts.SyntaxKind.TypeAliasDeclaration: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + case ts.SyntaxKind.EnumDeclaration: + return true; + case ts.SyntaxKind.VariableDeclaration: + case ts.SyntaxKind.TypeAliasDeclaration: + case ts.SyntaxKind.Parameter: + case ts.SyntaxKind.ModuleDeclaration: + case ts.SyntaxKind.PropertyDeclaration: + case ts.SyntaxKind.PropertyAssignment: + case ts.SyntaxKind.EnumMember: + return parent.name === identifier; + case ts.SyntaxKind.BindingElement: + case ts.SyntaxKind.ExportSpecifier: + case ts.SyntaxKind.ImportSpecifier: + // return true for `b` in `import {a as b} from "foo"` + return parent.name === identifier && + parent.propertyName !== undefined; + default: + return false; + } +} +function getDeprecation(node, tc) { + var symbol = tc.getSymbolAtLocation(node); + if (symbol !== undefined && Lint.isSymbolFlagSet(symbol, ts.SymbolFlags.Alias)) { + symbol = tc.getAliasedSymbol(symbol); + } + if (symbol !== undefined) { + return getDeprecationValue(symbol); + } + return undefined; +} +function getDeprecationValue(symbol) { + if (symbol.getJsDocTags !== undefined) { + for (var _i = 0, _a = symbol.getJsDocTags(); _i < _a.length; _i++) { + var tag = _a[_i]; + if (tag.name === "deprecated") { + return tag.text; } - // Don't warn on the declaration of the @deprecated symbol. - if (commentNode.pos <= node.pos - && node.getEnd() <= commentNode.getEnd() - && commentNode.getSourceFile() === this.getSourceFile()) { - continue; + } + return undefined; + } + // for compatibility with typescript@<2.3.0 + return getDeprecationFromDeclarations(symbol.declarations); +} +function getDeprecationFromDeclarations(declarations) { + if (declarations === undefined) { + return undefined; + } + var declaration; + for (var _i = 0, declarations_1 = declarations; _i < declarations_1.length; _i++) { + declaration = declarations_1[_i]; + if (tsutils_1.isBindingElement(declaration)) { + declaration = tsutils_1.getDeclarationOfBindingElement(declaration); + } + if (tsutils_1.isVariableDeclaration(declaration)) { + declaration = declaration.parent; + } + if (tsutils_1.isVariableDeclarationList(declaration)) { + declaration = declaration.parent; + } + for (var _a = 0, _b = declaration.getChildren(); _a < _b.length; _a++) { + var child = _b[_a]; + if (!tsutils_1.isJsDoc(child)) { + break; } - var range = ts.getLeadingCommentRanges(commentNode.getFullText(), 0); - if (range === undefined) { + if (child.tags === undefined) { continue; } - for (var _a = 0, range_1 = range; _a < range_1.length; _a++) { - var _b = range_1[_a], pos = _b.pos, end = _b.end; - var jsDocText = commentNode.getFullText().substring(pos, end); - if (jsDocText.includes("@deprecated")) { - this.addFailureAtNode(node, node.text + " is deprecated."); + for (var _c = 0, _d = child.tags; _c < _d.length; _c++) { + var tag = _d[_c]; + if (tag.tagName.text === "deprecated") { + return tag.comment === undefined ? "" : tag.comment; } } } - _super.prototype.visitIdentifier.call(this, node); - }; - return Walker; -}(Lint.ProgramAwareRuleWalker)); -var _a, _b; + } + return undefined; +} +var _a; |