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 | |
parent | 5634e77ad96bfe1818f6b6ee70b7379652e5487f (diff) |
node_modules
Diffstat (limited to 'node_modules/tslint/lib/rules')
159 files changed, 4787 insertions, 3527 deletions
diff --git a/node_modules/tslint/lib/rules/adjacentOverloadSignaturesRule.js b/node_modules/tslint/lib/rules/adjacentOverloadSignaturesRule.js index d3fb5ba1e..62a7bbcff 100644 --- a/node_modules/tslint/lib/rules/adjacentOverloadSignaturesRule.js +++ b/node_modules/tslint/lib/rules/adjacentOverloadSignaturesRule.js @@ -32,19 +32,19 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "adjacent-overload-signatures", + description: "Enforces function overloads to be consecutive.", + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + rationale: "Improves readability and organization by grouping naturally related items together.", + type: "typescript", + typescriptOnly: true, + }; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "adjacent-overload-signatures", - description: "Enforces function overloads to be consecutive.", - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - rationale: "Improves readability and organization by grouping naturally related items together.", - type: "typescript", - typescriptOnly: true, -}; exports.Rule = Rule; function walk(ctx) { var sourceFile = ctx.sourceFile; @@ -61,7 +61,6 @@ function walk(ctx) { addFailures(getMisplacedOverloads(members, function (member) { return utils.isSignatureDeclaration(member) ? getOverloadKey(member) : undefined; })); - break; } } return ts.forEachChild(node, cb); @@ -111,7 +110,7 @@ function getOverloadKey(node) { if (info === undefined) { return undefined; } - var _a = typeof info === "string" ? [false, info] : [info.computed === true, info.name], computed = _a[0], name = _a[1]; + var _a = typeof info === "string" ? [false, info] : [info.computed, info.name], computed = _a[0], name = _a[1]; var isStatic = Lint.hasModifier(node.modifiers, ts.SyntaxKind.StaticKeyword); return (computed ? "0" : "1") + (isStatic ? "0" : "1") + name; } diff --git a/node_modules/tslint/lib/rules/alignRule.js b/node_modules/tslint/lib/rules/alignRule.js index d86f2f550..7d70b9229 100644 --- a/node_modules/tslint/lib/rules/alignRule.js +++ b/node_modules/tslint/lib/rules/alignRule.js @@ -39,30 +39,30 @@ var Rule = (function (_super) { statements: this.ruleArguments.indexOf(OPTION_STATEMENTS) !== -1, })); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "align", + description: "Enforces vertical alignment.", + hasFix: true, + rationale: "Helps maintain a readable, consistent style in your codebase.", + optionsDescription: (_a = ["\n Five arguments may be optionally provided:\n\n * `\"", "\"` checks alignment of function parameters.\n * `\"", "\"` checks alignment of function call arguments.\n * `\"", "\"` checks alignment of statements.\n * `\"", "\"` checks alignment of members of classes, interfaces, type literal, object literals and\n object destructuring.\n * `\"", "\"` checks alignment of elements of array iterals, array destructuring and tuple types."], _a.raw = ["\n Five arguments may be optionally provided:\n\n * \\`\"", "\"\\` checks alignment of function parameters.\n * \\`\"", "\"\\` checks alignment of function call arguments.\n * \\`\"", "\"\\` checks alignment of statements.\n * \\`\"", "\"\\` checks alignment of members of classes, interfaces, type literal, object literals and\n object destructuring.\n * \\`\"", "\"\\` checks alignment of elements of array iterals, array destructuring and tuple types."], Lint.Utils.dedent(_a, OPTION_PARAMETERS, OPTION_ARGUMENTS, OPTION_STATEMENTS, OPTION_MEMBERS, OPTION_ELEMENTS)), + options: { + type: "array", + items: { + type: "string", + enum: [OPTION_ARGUMENTS, OPTION_ELEMENTS, OPTION_MEMBERS, OPTION_PARAMETERS, OPTION_STATEMENTS], + }, + minLength: 1, + maxLength: 5, + }, + optionExamples: [[true, "parameters", "statements"]], + type: "style", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING_SUFFIX = " are not aligned"; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "align", - description: "Enforces vertical alignment.", - hasFix: true, - rationale: "Helps maintain a readable, consistent style in your codebase.", - optionsDescription: (_a = ["\n Five arguments may be optionally provided:\n\n * `\"", "\"` checks alignment of function parameters.\n * `\"", "\"` checks alignment of function call arguments.\n * `\"", "\"` checks alignment of statements.\n * `\"", "\"` checks alignment of members of classes, interfaces, type literal, object literals and\n object destructuring.\n * `\"", "\"` checks alignment of elements of array iterals, array destructuring and tuple types."], _a.raw = ["\n Five arguments may be optionally provided:\n\n * \\`\"", "\"\\` checks alignment of function parameters.\n * \\`\"", "\"\\` checks alignment of function call arguments.\n * \\`\"", "\"\\` checks alignment of statements.\n * \\`\"", "\"\\` checks alignment of members of classes, interfaces, type literal, object literals and\n object destructuring.\n * \\`\"", "\"\\` checks alignment of elements of array iterals, array destructuring and tuple types."], Lint.Utils.dedent(_a, OPTION_PARAMETERS, OPTION_ARGUMENTS, OPTION_STATEMENTS, OPTION_MEMBERS, OPTION_ELEMENTS)), - options: { - type: "array", - items: { - type: "string", - enum: [OPTION_ARGUMENTS, OPTION_ELEMENTS, OPTION_MEMBERS, OPTION_PARAMETERS, OPTION_STATEMENTS], - }, - minLength: 1, - maxLength: 5, - }, - optionExamples: [[true, "parameters", "statements"]], - type: "style", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING_SUFFIX = " are not aligned"; exports.Rule = Rule; var AlignWalker = (function (_super) { tslib_1.__extends(AlignWalker, _super); @@ -73,7 +73,7 @@ var AlignWalker = (function (_super) { var _this = this; var cb = function (node) { if (_this.options.statements && tsutils_1.isBlockLike(node)) { - _this.checkAlignment(node.statements.filter(function (s) { return !tsutils_1.isEmptyStatement(s); }), OPTION_STATEMENTS); + _this.checkAlignment(node.statements.filter(function (s) { return s.kind !== ts.SyntaxKind.EmptyStatement; }), OPTION_STATEMENTS); } else { switch (node.kind) { @@ -123,7 +123,11 @@ var AlignWalker = (function (_super) { } break; case ts.SyntaxKind.ClassDeclaration: - case ts.SyntaxKind.ClassDeclaration: + case ts.SyntaxKind.ClassExpression: + if (_this.options.members) { + _this.checkAlignment(node.members.filter(function (m) { return m.kind !== ts.SyntaxKind.SemicolonClassElement; }), OPTION_MEMBERS); + } + break; case ts.SyntaxKind.InterfaceDeclaration: case ts.SyntaxKind.TypeLiteral: if (_this.options.members) { @@ -151,7 +155,7 @@ var AlignWalker = (function (_super) { if (line !== pos.line && pos.character !== alignToColumn) { var diff = alignToColumn - pos.character; var fix = void 0; - if (0 < diff) { + if (diff >= 0) { fix = Lint.Replacement.appendText(start, " ".repeat(diff)); } else if (node.pos <= start + diff && /^\s+$/.test(sourceFile.text.substring(start + diff, start))) { diff --git a/node_modules/tslint/lib/rules/arrayTypeRule.js b/node_modules/tslint/lib/rules/arrayTypeRule.js index 1c86b72b2..0253b8317 100644 --- a/node_modules/tslint/lib/rules/arrayTypeRule.js +++ b/node_modules/tslint/lib/rules/arrayTypeRule.js @@ -30,27 +30,27 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk, this.ruleArguments[0]); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "array-type", + description: "Requires using either 'T[]' or 'Array<T>' for arrays.", + hasFix: true, + optionsDescription: (_a = ["\n One of the following arguments must be provided:\n\n * `\"", "\"` enforces use of `T[]` for all types T.\n * `\"", "\"` enforces use of `Array<T>` for all types T.\n * `\"", "\"` enforces use of `T[]` if `T` is a simple type (primitive or type reference)."], _a.raw = ["\n One of the following arguments must be provided:\n\n * \\`\"", "\"\\` enforces use of \\`T[]\\` for all types T.\n * \\`\"", "\"\\` enforces use of \\`Array<T>\\` for all types T.\n * \\`\"", "\"\\` enforces use of \\`T[]\\` if \\`T\\` is a simple type (primitive or type reference)."], Lint.Utils.dedent(_a, OPTION_ARRAY, OPTION_GENERIC, OPTION_ARRAY_SIMPLE)), + options: { + type: "string", + enum: [OPTION_ARRAY, OPTION_GENERIC, OPTION_ARRAY_SIMPLE], + }, + optionExamples: [[true, OPTION_ARRAY], [true, OPTION_GENERIC], [true, OPTION_ARRAY_SIMPLE]], + type: "style", + typescriptOnly: true, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING_ARRAY = "Array type using 'Array<T>' is forbidden. Use 'T[]' instead."; + Rule.FAILURE_STRING_GENERIC = "Array type using 'T[]' is forbidden. Use 'Array<T>' instead."; + Rule.FAILURE_STRING_ARRAY_SIMPLE = "Array type using 'Array<T>' is forbidden for simple types. Use 'T[]' instead."; + Rule.FAILURE_STRING_GENERIC_SIMPLE = "Array type using 'T[]' is forbidden for non-simple types. Use 'Array<T>' instead."; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "array-type", - description: "Requires using either 'T[]' or 'Array<T>' for arrays.", - hasFix: true, - optionsDescription: (_a = ["\n One of the following arguments must be provided:\n\n * `\"", "\"` enforces use of `T[]` for all types T.\n * `\"", "\"` enforces use of `Array<T>` for all types T.\n * `\"", "\"` enforces use of `T[]` if `T` is a simple type (primitive or type reference)."], _a.raw = ["\n One of the following arguments must be provided:\n\n * \\`\"", "\"\\` enforces use of \\`T[]\\` for all types T.\n * \\`\"", "\"\\` enforces use of \\`Array<T>\\` for all types T.\n * \\`\"", "\"\\` enforces use of \\`T[]\\` if \\`T\\` is a simple type (primitive or type reference)."], Lint.Utils.dedent(_a, OPTION_ARRAY, OPTION_GENERIC, OPTION_ARRAY_SIMPLE)), - options: { - type: "string", - enum: [OPTION_ARRAY, OPTION_GENERIC, OPTION_ARRAY_SIMPLE], - }, - optionExamples: [[true, OPTION_ARRAY], [true, OPTION_GENERIC], [true, OPTION_ARRAY_SIMPLE]], - type: "style", - typescriptOnly: true, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING_ARRAY = "Array type using 'Array<T>' is forbidden. Use 'T[]' instead."; -Rule.FAILURE_STRING_GENERIC = "Array type using 'T[]' is forbidden. Use 'Array<T>' instead."; -Rule.FAILURE_STRING_ARRAY_SIMPLE = "Array type using 'Array<T>' is forbidden for simple types. Use 'T[]' instead."; -Rule.FAILURE_STRING_GENERIC_SIMPLE = "Array type using 'T[]' is forbidden for non-simple types. Use 'Array<T>' instead."; exports.Rule = Rule; function walk(ctx) { var sourceFile = ctx.sourceFile, option = ctx.options; @@ -61,7 +61,6 @@ function walk(ctx) { break; case ts.SyntaxKind.TypeReference: checkTypeReference(node); - break; } return ts.forEachChild(node, cb); }); @@ -89,8 +88,7 @@ function walk(ctx) { var failureString = option === "array" ? Rule.FAILURE_STRING_ARRAY : Rule.FAILURE_STRING_ARRAY_SIMPLE; if (typeArguments === undefined || typeArguments.length === 0) { // Create an 'any' array - var fix_1 = Lint.Replacement.replaceFromTo(node.getStart(), node.getEnd(), "any[]"); - ctx.addFailureAtNode(node, failureString, fix_1); + ctx.addFailureAtNode(node, failureString, Lint.Replacement.replaceFromTo(node.getStart(), node.getEnd(), "any[]")); return; } if (typeArguments.length !== 1 || (option === "array-simple" && !isSimpleType(typeArguments[0]))) { @@ -98,13 +96,12 @@ function walk(ctx) { } var type = typeArguments[0]; var parens = typeNeedsParentheses(type); - var fix = [ + ctx.addFailureAtNode(node, failureString, [ // Delete 'Array<' Lint.Replacement.replaceFromTo(node.getStart(), type.getStart(), parens ? "(" : ""), // Delete '>' and replace with '[] Lint.Replacement.replaceFromTo(type.getEnd(), node.getEnd(), parens ? ")[]" : "[]"), - ]; - ctx.addFailureAtNode(node, failureString, fix); + ]); } } function typeNeedsParentheses(type) { @@ -134,6 +131,7 @@ function isSimpleType(nodeType) { case ts.SyntaxKind.SymbolKeyword: case ts.SyntaxKind.VoidKeyword: case ts.SyntaxKind.NeverKeyword: + case ts.SyntaxKind.ThisType: return true; case ts.SyntaxKind.TypeReference: // TypeReferences must be non-generic or be another Array with a simple type diff --git a/node_modules/tslint/lib/rules/arrowParensRule.js b/node_modules/tslint/lib/rules/arrowParensRule.js index 9884d62e3..116110560 100644 --- a/node_modules/tslint/lib/rules/arrowParensRule.js +++ b/node_modules/tslint/lib/rules/arrowParensRule.js @@ -31,26 +31,26 @@ var Rule = (function (_super) { banSingleArgParens: this.ruleArguments.indexOf(BAN_SINGLE_ARG_PARENS) !== -1, }); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "arrow-parens", + description: "Requires parentheses around the parameters of arrow function definitions.", + hasFix: true, + rationale: "Maintains stylistic consistency with other arrow function definitions.", + optionsDescription: (_a = ["\n If `", "` is specified, then arrow functions with one parameter\n must not have parentheses if removing them is allowed by TypeScript."], _a.raw = ["\n If \\`", "\\` is specified, then arrow functions with one parameter\n must not have parentheses if removing them is allowed by TypeScript."], Lint.Utils.dedent(_a, BAN_SINGLE_ARG_PARENS)), + options: { + type: "string", + enum: [BAN_SINGLE_ARG_PARENS], + }, + optionExamples: [true, [true, BAN_SINGLE_ARG_PARENS]], + type: "style", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING_MISSING = "Parentheses are required around the parameters of an arrow function definition"; + Rule.FAILURE_STRING_EXISTS = "Parentheses are prohibited around the parameter in this single parameter arrow function"; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "arrow-parens", - description: "Requires parentheses around the parameters of arrow function definitions.", - hasFix: true, - rationale: "Maintains stylistic consistency with other arrow function definitions.", - optionsDescription: (_a = ["\n If `", "` is specified, then arrow functions with one parameter\n must not have parentheses if removing them is allowed by TypeScript."], _a.raw = ["\n If \\`", "\\` is specified, then arrow functions with one parameter\n must not have parentheses if removing them is allowed by TypeScript."], Lint.Utils.dedent(_a, BAN_SINGLE_ARG_PARENS)), - options: { - type: "string", - enum: [BAN_SINGLE_ARG_PARENS], - }, - optionExamples: [true, [true, BAN_SINGLE_ARG_PARENS]], - type: "style", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING_MISSING = "Parentheses are required around the parameters of an arrow function definition"; -Rule.FAILURE_STRING_EXISTS = "Parentheses are prohibited around the parameter in this single parameter arrow function"; exports.Rule = Rule; function walk(ctx) { function cb(node) { diff --git a/node_modules/tslint/lib/rules/arrowReturnShorthandRule.js b/node_modules/tslint/lib/rules/arrowReturnShorthandRule.js index 1954d2d17..74010faa2 100644 --- a/node_modules/tslint/lib/rules/arrowReturnShorthandRule.js +++ b/node_modules/tslint/lib/rules/arrowReturnShorthandRule.js @@ -35,25 +35,25 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk, { multiline: this.ruleArguments.indexOf(OPTION_MULTILINE) !== -1 }); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "arrow-return-shorthand", + description: "Suggests to convert `() => { return x; }` to `() => x`.", + hasFix: true, + optionsDescription: (_a = ["\n If `", "` is specified, then this will warn even if the function spans multiple lines."], _a.raw = ["\n If \\`", "\\` is specified, then this will warn even if the function spans multiple lines."], Lint.Utils.dedent(_a, OPTION_MULTILINE)), + options: { + type: "string", + enum: [OPTION_MULTILINE], + }, + optionExamples: [ + true, + [true, OPTION_MULTILINE], + ], + type: "style", + typescriptOnly: false, + }; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "arrow-return-shorthand", - description: "Suggests to convert `() => { return x; }` to `() => x`.", - hasFix: true, - optionsDescription: (_a = ["\n If `", "` is specified, then this will warn even if the function spans multiple lines."], _a.raw = ["\n If \\`", "\\` is specified, then this will warn even if the function spans multiple lines."], Lint.Utils.dedent(_a, OPTION_MULTILINE)), - options: { - type: "string", - enum: [OPTION_MULTILINE], - }, - optionExamples: [ - true, - [true, OPTION_MULTILINE], - ], - type: "style", - typescriptOnly: false, -}; exports.Rule = Rule; function walk(ctx) { var sourceFile = ctx.sourceFile, multiline = ctx.options.multiline; diff --git a/node_modules/tslint/lib/rules/awaitPromiseRule.js b/node_modules/tslint/lib/rules/awaitPromiseRule.js index 18c255e72..ba26774f6 100644 --- a/node_modules/tslint/lib/rules/awaitPromiseRule.js +++ b/node_modules/tslint/lib/rules/awaitPromiseRule.js @@ -30,27 +30,27 @@ var Rule = (function (_super) { var tc = program.getTypeChecker(); return this.applyWithFunction(sourceFile, function (ctx) { return walk(ctx, tc, promiseTypes); }); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "await-promise", + description: "Warns for an awaited value that is not a Promise.", + optionsDescription: (_a = ["\n A list of 'string' names of any additional classes that should also be handled as Promises.\n "], _a.raw = ["\n A list of 'string' names of any additional classes that should also be handled as Promises.\n "], Lint.Utils.dedent(_a)), + options: { + type: "list", + listType: { + type: "array", + items: { type: "string" }, + }, + }, + optionExamples: [true, [true, "Thenable"]], + type: "functionality", + typescriptOnly: true, + requiresTypeInfo: true, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "'await' of non-Promise."; return Rule; }(Lint.Rules.TypedRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "await-promise", - description: "Warns for an awaited value that is not a Promise.", - optionsDescription: (_a = ["\n A list of 'string' names of any additional classes that should also be handled as Promises.\n "], _a.raw = ["\n A list of 'string' names of any additional classes that should also be handled as Promises.\n "], Lint.Utils.dedent(_a)), - options: { - type: "list", - listType: { - type: "array", - items: { type: "string" }, - }, - }, - optionExamples: [true, [true, "Thenable"]], - type: "functionality", - typescriptOnly: true, - requiresTypeInfo: true, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "'await' of non-Promise."; exports.Rule = Rule; function walk(ctx, tc, promiseTypes) { return ts.forEachChild(ctx.sourceFile, cb); @@ -64,7 +64,7 @@ function walk(ctx, tc, promiseTypes) { if (Lint.isTypeFlagSet(type, ts.TypeFlags.Any) || isPromiseType(type)) { return true; } - if (isUnionType(type)) { + if (tsutils_1.isUnionOrIntersectionType(type)) { return type.types.some(couldBePromise); } var bases = type.getBaseTypes(); @@ -75,7 +75,4 @@ function walk(ctx, tc, promiseTypes) { return target !== undefined && target.symbol !== undefined && promiseTypes.has(target.symbol.name); } } -function isUnionType(type) { - return Lint.isTypeFlagSet(type, ts.TypeFlags.Union); -} var _a; diff --git a/node_modules/tslint/lib/rules/banRule.d.ts b/node_modules/tslint/lib/rules/banRule.d.ts index 182b981ac..44311c6eb 100644 --- a/node_modules/tslint/lib/rules/banRule.d.ts +++ b/node_modules/tslint/lib/rules/banRule.d.ts @@ -1,19 +1,3 @@ -/** - * @license - * Copyright 2013 Palantir Technologies, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ import * as ts from "typescript"; import * as Lint from "../index"; export declare class Rule extends Lint.Rules.AbstractRule { @@ -21,11 +5,3 @@ export declare class Rule extends Lint.Rules.AbstractRule { static FAILURE_STRING_FACTORY(expression: string, messageAddition?: string): string; apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; } -export declare class BanFunctionWalker extends Lint.RuleWalker { - private bannedGlobalFunctions; - private bannedFunctions; - addBannedFunction(bannedFunction: string[]): void; - visitCallExpression(node: ts.CallExpression): void; - private checkForObjectMethodBan(expression); - private checkForGlobalBan(expression); -} diff --git a/node_modules/tslint/lib/rules/banRule.js b/node_modules/tslint/lib/rules/banRule.js index e7ee21f15..4b402160e 100644 --- a/node_modules/tslint/lib/rules/banRule.js +++ b/node_modules/tslint/lib/rules/banRule.js @@ -1,4 +1,6 @@ "use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = require("tslib"); /** * @license * Copyright 2013 Palantir Technologies, Inc. @@ -15,8 +17,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -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) { @@ -29,95 +30,145 @@ var Rule = (function (_super) { return "Calls to '" + expression + "' are not allowed." + (messageAddition !== undefined ? " " + messageAddition : ""); }; Rule.prototype.apply = function (sourceFile) { - var options = this.getOptions(); - var banFunctionWalker = new BanFunctionWalker(sourceFile, options); - var functionsToBan = options.ruleArguments; - if (functionsToBan !== undefined) { - functionsToBan.forEach(function (f) { return banFunctionWalker.addBannedFunction(f); }); - } - return this.applyWithWalker(banFunctionWalker); + return this.applyWithWalker(new BanFunctionWalker(sourceFile, this.ruleName, parseOptions(this.ruleArguments))); }; - return Rule; -}(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "ban", - description: "Bans the use of specific functions or global methods.", - optionsDescription: (_a = ["\n A list of `['object', 'method', 'optional explanation here']` or `['globalMethod']` which ban `object.method()`\n or respectively `globalMethod()`."], _a.raw = ["\n A list of \\`['object', 'method', 'optional explanation here']\\` or \\`['globalMethod']\\` which ban \\`object.method()\\`\n or respectively \\`globalMethod()\\`."], Lint.Utils.dedent(_a)), - options: { - type: "list", - listType: { - type: "array", - items: { type: "string" }, - minLength: 1, - maxLength: 3, + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "ban", + description: "Bans the use of specific functions or global methods.", + optionsDescription: (_a = ["\n A list of banned functions or methods in the following format:\n\n * banning functions:\n * just the name of the function: `\"functionName\"`\n * the name of the function in an array with one element: `[\"functionName\"]`\n * an object in the following format: `{\"name\": \"functionName\", \"message\": \"optional explanation message\"}`\n * banning methods:\n * an array with the object name, method name and optional message: `[\"functionName\", \"methodName\", \"optional message\"]`\n * an object in the following format: `{\"name\": [\"objectName\", \"methodName\"], \"message\": \"optional message\"}`\n * you can also ban deeply nested methods: `{\"name\": [\"foo\", \"bar\", \"baz\"]}` bans `foo.bar.baz()`\n * the first element can contain a wildcard (`*`) that matches everything. `{\"name\": [\"*\", \"forEach\"]}` bans `[].forEach(...)`, `$(...).forEach(...)`, `arr.forEach(...)`, etc.\n "], _a.raw = ["\n A list of banned functions or methods in the following format:\n\n * banning functions:\n * just the name of the function: \\`\"functionName\"\\`\n * the name of the function in an array with one element: \\`[\"functionName\"]\\`\n * an object in the following format: \\`{\"name\": \"functionName\", \"message\": \"optional explanation message\"}\\`\n * banning methods:\n * an array with the object name, method name and optional message: \\`[\"functionName\", \"methodName\", \"optional message\"]\\`\n * an object in the following format: \\`{\"name\": [\"objectName\", \"methodName\"], \"message\": \"optional message\"}\\`\n * you can also ban deeply nested methods: \\`{\"name\": [\"foo\", \"bar\", \"baz\"]}\\` bans \\`foo.bar.baz()\\`\n * the first element can contain a wildcard (\\`*\\`) that matches everything. \\`{\"name\": [\"*\", \"forEach\"]}\\` bans\\\n \\`[].forEach(...)\\`, \\`$(...).forEach(...)\\`, \\`arr.forEach(...)\\`, etc.\n "], Lint.Utils.dedent(_a)), + options: { + type: "list", + listType: { + anyOf: [ + { + type: "string", + }, + { + type: "array", + items: { type: "string" }, + minLength: 1, + maxLength: 3, + }, + { + type: "object", + properties: { + name: { + anyOf: [ + { type: "string" }, + { type: "array", items: { type: "string" }, minLength: 1 }, + ], + }, + message: { type: "string" }, + }, + required: ["name"], + }, + ], + }, }, - }, - optionExamples: [ - [ - true, - ["someGlobalMethod"], - ["someObject", "someFunction"], - ["someObject", "otherFunction", "Optional explanation"], + optionExamples: [ + [ + true, + "eval", + { name: "$", message: "please don't" }, + ["describe", "only"], + { name: ["it", "only"], message: "don't focus tests" }, + { name: ["chai", "assert", "equal"], message: "Use 'strictEqual' instead." }, + { name: ["*", "forEach"], message: "Use a regular for loop instead." }, + ], ], - ], - type: "functionality", - typescriptOnly: false, -}; + type: "functionality", + typescriptOnly: false, + }; + return Rule; +}(Lint.Rules.AbstractRule)); exports.Rule = Rule; +function parseOptions(args) { + var functions = []; + var methods = []; + for (var _i = 0, args_1 = args; _i < args_1.length; _i++) { + var arg = args_1[_i]; + if (typeof arg === "string") { + functions.push({ name: arg }); + } + else if (Array.isArray(arg)) { + switch (arg.length) { + case 0: + break; + case 1: + functions.push({ name: arg[0] }); + break; + default: + methods.push({ object: [arg[0]], name: arg[1], message: arg[2] }); + } + } + else if (!Array.isArray(arg.name)) { + functions.push(arg); + } + else { + switch (arg.name.length) { + case 0: + break; + case 1: + functions.push({ name: arg.name[0], message: arg.message }); + break; + default: + methods.push({ name: arg.name[arg.name.length - 1], object: arg.name.slice(0, -1), message: arg.message }); + } + } + } + return { functions: functions, methods: methods }; +} var BanFunctionWalker = (function (_super) { tslib_1.__extends(BanFunctionWalker, _super); function BanFunctionWalker() { - var _this = _super !== null && _super.apply(this, arguments) || this; - _this.bannedGlobalFunctions = []; - _this.bannedFunctions = []; - return _this; + return _super !== null && _super.apply(this, arguments) || this; } - BanFunctionWalker.prototype.addBannedFunction = function (bannedFunction) { - if (bannedFunction.length === 1) { - this.bannedGlobalFunctions.push(bannedFunction[0]); - } - else if (bannedFunction.length >= 2) { - this.bannedFunctions.push(bannedFunction); - } - }; - BanFunctionWalker.prototype.visitCallExpression = function (node) { - var expression = node.expression; - this.checkForObjectMethodBan(expression); - this.checkForGlobalBan(expression); - _super.prototype.visitCallExpression.call(this, node); + BanFunctionWalker.prototype.walk = function (sourceFile) { + var _this = this; + var cb = function (node) { + if (tsutils_1.isCallExpression(node)) { + if (tsutils_1.isIdentifier(node.expression)) { + _this.checkFunctionBan(node.expression); + } + else if (tsutils_1.isPropertyAccessExpression(node.expression)) { + _this.checkForObjectMethodBan(node.expression); + } + } + return ts.forEachChild(node, cb); + }; + return ts.forEachChild(sourceFile, cb); }; BanFunctionWalker.prototype.checkForObjectMethodBan = function (expression) { - if (expression.kind === ts.SyntaxKind.PropertyAccessExpression - && expression.getChildCount() >= 3) { - var firstToken = expression.getFirstToken(); - var firstChild = expression.getChildAt(0); - var secondChild = expression.getChildAt(1); - var thirdChild = expression.getChildAt(2); - var rightSideExpression = thirdChild.getFullText(); - var leftSideExpression = firstChild.getChildCount() > 0 - ? firstChild.getLastToken().getText() - : firstToken.getText(); - if (secondChild.kind === ts.SyntaxKind.DotToken) { - for (var _i = 0, _a = this.bannedFunctions; _i < _a.length; _i++) { - var bannedFunction = _a[_i]; - if (leftSideExpression === bannedFunction[0] && rightSideExpression === bannedFunction[1]) { - var failure = Rule.FAILURE_STRING_FACTORY(leftSideExpression + "." + rightSideExpression, bannedFunction[2]); - this.addFailureAtNode(expression, failure); - } + for (var _i = 0, _a = this.options.methods; _i < _a.length; _i++) { + var ban = _a[_i]; + if (expression.name.text !== ban.name) { + continue; + } + var current = expression.expression; + for (var i = ban.object.length - 1; i > 0; --i) { + if (!tsutils_1.isPropertyAccessExpression(current) || current.name.text !== ban.object[i]) { + continue; } + current = current.expression; + } + if (ban.object[0] === "*" || + tsutils_1.isIdentifier(current) && current.text === ban.object[0]) { + this.addFailureAtNode(expression, Rule.FAILURE_STRING_FACTORY(ban.object.join(".") + "." + ban.name, ban.message)); + break; } } }; - BanFunctionWalker.prototype.checkForGlobalBan = function (expression) { - if (expression.kind === ts.SyntaxKind.Identifier) { - var identifierName = expression.text; - if (this.bannedGlobalFunctions.indexOf(identifierName) !== -1) { - this.addFailureAtNode(expression, Rule.FAILURE_STRING_FACTORY("" + identifierName)); + BanFunctionWalker.prototype.checkFunctionBan = function (name) { + var text = name.text; + for (var _i = 0, _a = this.options.functions; _i < _a.length; _i++) { + var ban = _a[_i]; + if (ban.name === text) { + this.addFailureAtNode(name, Rule.FAILURE_STRING_FACTORY(text, ban.message)); + break; } } }; return BanFunctionWalker; -}(Lint.RuleWalker)); -exports.BanFunctionWalker = BanFunctionWalker; +}(Lint.AbstractWalker)); var _a; diff --git a/node_modules/tslint/lib/rules/banTypesRule.js b/node_modules/tslint/lib/rules/banTypesRule.js index 494f7859a..0f6fdc682 100644 --- a/node_modules/tslint/lib/rules/banTypesRule.js +++ b/node_modules/tslint/lib/rules/banTypesRule.js @@ -32,26 +32,26 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk, this.ruleArguments.map(parseOption)); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "ban-types", + description: (_a = ["\n Bans specific types from being used. Does not ban the\n corresponding runtime objects from being used."], _a.raw = ["\n Bans specific types from being used. Does not ban the\n corresponding runtime objects from being used."], Lint.Utils.dedent(_a)), + options: { + type: "list", + listType: { + type: "array", + items: { type: "string" }, + minLength: 1, + maxLength: 2, + }, + }, + optionsDescription: (_b = ["\n A list of `[\"regex\", \"optional explanation here\"]`, which bans\n types that match `regex`"], _b.raw = ["\n A list of \\`[\"regex\", \"optional explanation here\"]\\`, which bans\n types that match \\`regex\\`"], Lint.Utils.dedent(_b)), + optionExamples: [[true, ["Object", "Use {} instead."], ["String"]]], + type: "typescript", + typescriptOnly: true, + }; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "ban-types", - description: (_a = ["\n Bans specific types from being used. Does not ban the\n corresponding runtime objects from being used."], _a.raw = ["\n Bans specific types from being used. Does not ban the\n corresponding runtime objects from being used."], Lint.Utils.dedent(_a)), - options: { - type: "list", - listType: { - type: "array", - items: { type: "string" }, - minLength: 1, - maxLength: 2, - }, - }, - optionsDescription: (_b = ["\n A list of `[\"regex\", \"optional explanation here\"]`, which bans\n types that match `regex`"], _b.raw = ["\n A list of \\`[\"regex\", \"optional explanation here\"]\\`, which bans\n types that match \\`regex\\`"], Lint.Utils.dedent(_b)), - optionExamples: [[true, ["Object", "Use {} instead."], ["String"]]], - type: "typescript", - typescriptOnly: true, -}; exports.Rule = Rule; function parseOption(_a) { var pattern = _a[0], message = _a[1]; diff --git a/node_modules/tslint/lib/rules/binaryExpressionOperandOrderRule.d.ts b/node_modules/tslint/lib/rules/binaryExpressionOperandOrderRule.d.ts new file mode 100644 index 000000000..cce59d100 --- /dev/null +++ b/node_modules/tslint/lib/rules/binaryExpressionOperandOrderRule.d.ts @@ -0,0 +1,7 @@ +import * as ts from "typescript"; +import * as Lint from "../index"; +export declare class Rule extends Lint.Rules.AbstractRule { + static metadata: Lint.IRuleMetadata; + static FAILURE_STRING: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/node_modules/tslint/lib/rules/binaryExpressionOperandOrderRule.js b/node_modules/tslint/lib/rules/binaryExpressionOperandOrderRule.js new file mode 100644 index 000000000..03a50391c --- /dev/null +++ b/node_modules/tslint/lib/rules/binaryExpressionOperandOrderRule.js @@ -0,0 +1,93 @@ +"use strict"; +/** + * @license + * Copyright 2017 Palantir Technologies, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +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 utils_1 = require("../language/utils"); +var Rule = (function (_super) { + tslib_1.__extends(Rule, _super); + function Rule() { + return _super !== null && _super.apply(this, arguments) || this; + } + Rule.prototype.apply = function (sourceFile) { + return this.applyWithFunction(sourceFile, walk); + }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "binary-expression-operand-order", + description: (_a = ["\n In a binary expression, a literal should always be on the right-hand side if possible.\n For example, prefer 'x + 1' over '1 + x'."], _a.raw = ["\n In a binary expression, a literal should always be on the right-hand side if possible.\n For example, prefer 'x + 1' over '1 + x'."], Lint.Utils.dedent(_a)), + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "style", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "Literal expression should be on the right-hand side of a binary expression."; + return Rule; +}(Lint.Rules.AbstractRule)); +exports.Rule = Rule; +function walk(ctx) { + ts.forEachChild(ctx.sourceFile, function cb(node) { + if (tsutils_1.isBinaryExpression(node) && isLiteral(node.left) && !isLiteral(node.right) && !isAllowedOrderedOperator(node)) { + ctx.addFailureAtNode(node, Rule.FAILURE_STRING); + } + ts.forEachChild(node, cb); + }); +} +/** Allows certain inherently ordered operators that can't easily be written with the literal on the right. */ +function isAllowedOrderedOperator(node) { + switch (node.operatorToken.kind) { + case ts.SyntaxKind.PlusToken: + // Allow `"foo" + x` but not `1 + x`. + return node.left.kind === ts.SyntaxKind.StringLiteral; + case ts.SyntaxKind.MinusToken: + case ts.SyntaxKind.SlashToken: + case ts.SyntaxKind.PercentToken: + case ts.SyntaxKind.LessThanLessThanToken: + case ts.SyntaxKind.GreaterThanGreaterThanToken: + case ts.SyntaxKind.GreaterThanGreaterThanGreaterThanToken: + case ts.SyntaxKind.AsteriskAsteriskToken: + case ts.SyntaxKind.InKeyword: + case ts.SyntaxKind.CommaToken: + return true; + default: + return false; + } +} +function isLiteral(node) { + switch (node.kind) { + case ts.SyntaxKind.StringLiteral: + case ts.SyntaxKind.NumericLiteral: + case ts.SyntaxKind.TrueKeyword: + case ts.SyntaxKind.FalseKeyword: + case ts.SyntaxKind.NullKeyword: + return true; + case ts.SyntaxKind.Identifier: + return node.originalKeywordKind === ts.SyntaxKind.UndefinedKeyword; + case ts.SyntaxKind.PrefixUnaryExpression: + return utils_1.isNegativeNumberLiteral(node); + case ts.SyntaxKind.ParenthesizedExpression: + return isLiteral(node.expression); + default: + return false; + } +} +var _a; diff --git a/node_modules/tslint/lib/rules/callableTypesRule.js b/node_modules/tslint/lib/rules/callableTypesRule.js index 485aa230e..42c26aac2 100644 --- a/node_modules/tslint/lib/rules/callableTypesRule.js +++ b/node_modules/tslint/lib/rules/callableTypesRule.js @@ -32,19 +32,19 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "callable-types", + description: "An interface or literal type with just a call signature can be written as a function type.", + rationale: "style", + optionsDescription: "Not configurable.", + options: null, + type: "style", + typescriptOnly: true, + hasFix: true, + }; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "callable-types", - description: "An interface or literal type with just a call signature can be written as a function type.", - rationale: "style", - optionsDescription: "Not configurable.", - options: null, - type: "style", - typescriptOnly: true, - hasFix: true, -}; exports.Rule = Rule; function walk(ctx) { return ts.forEachChild(ctx.sourceFile, function cb(node) { @@ -56,7 +56,10 @@ function walk(ctx) { // avoid bad parse member.type !== undefined) { var suggestion = renderSuggestion(member, node, ctx.sourceFile); - ctx.addFailureAtNode(member, Rule.FAILURE_STRING_FACTORY(node.kind === ts.SyntaxKind.TypeLiteral ? "Type literal" : "Interface", suggestion), Lint.Replacement.replaceNode(node, suggestion)); + var fixStart = node.kind === ts.SyntaxKind.TypeLiteral + ? node.getStart(ctx.sourceFile) + : tsutils_1.getChildOfKind(node, ts.SyntaxKind.InterfaceKeyword).getStart(ctx.sourceFile); + ctx.addFailureAtNode(member, Rule.FAILURE_STRING_FACTORY(node.kind === ts.SyntaxKind.TypeLiteral ? "Type literal" : "Interface", suggestion), Lint.Replacement.replaceFromTo(fixStart, node.end, suggestion)); } } return ts.forEachChild(node, cb); diff --git a/node_modules/tslint/lib/rules/classNameRule.js b/node_modules/tslint/lib/rules/classNameRule.js index da5e7d92c..6673fda84 100644 --- a/node_modules/tslint/lib/rules/classNameRule.js +++ b/node_modules/tslint/lib/rules/classNameRule.js @@ -29,21 +29,21 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "class-name", + description: "Enforces PascalCased class and interface names.", + rationale: "Makes it easy to differentiate classes from regular variables at a glance.", + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "style", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "Class name must be in pascal case"; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "class-name", - description: "Enforces PascalCased class and interface names.", - rationale: "Makes it easy to differentiate classes from regular variables at a glance.", - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "style", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "Class name must be in pascal case"; exports.Rule = Rule; function walk(ctx) { return ts.forEachChild(ctx.sourceFile, function cb(node) { diff --git a/node_modules/tslint/lib/rules/commentFormatRule.js b/node_modules/tslint/lib/rules/commentFormatRule.js index af7da92c5..067607139 100644 --- a/node_modules/tslint/lib/rules/commentFormatRule.js +++ b/node_modules/tslint/lib/rules/commentFormatRule.js @@ -19,6 +19,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var utils = require("tsutils"); var ts = require("typescript"); +var enableDisableRules_1 = require("../enableDisableRules"); var Lint = require("../index"); var utils_1 = require("../utils"); var OPTION_SPACE = "check-space"; @@ -30,175 +31,135 @@ var Rule = (function (_super) { return _super !== null && _super.apply(this, arguments) || this; } Rule.prototype.apply = function (sourceFile) { - return this.applyWithWalker(new CommentWalker(sourceFile, this.getOptions())); + return this.applyWithFunction(sourceFile, walk, parseOptions(this.ruleArguments)); }; - return Rule; -}(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "comment-format", - description: "Enforces formatting rules for single-line comments.", - rationale: "Helps maintain a consistent, readable style in your codebase.", - optionsDescription: (_a = ["\n Three arguments may be optionally provided:\n\n * `\"check-space\"` requires that all single-line comments must begin with a space, as in `// comment`\n * note that comments starting with `///` are also allowed, for things such as `///<reference>`\n * `\"check-lowercase\"` requires that the first non-whitespace character of a comment must be lowercase, if applicable.\n * `\"check-uppercase\"` requires that the first non-whitespace character of a comment must be uppercase, if applicable.\n\n Exceptions to `\"check-lowercase\"` or `\"check-uppercase\"` can be managed with object that may be passed as last argument.\n\n One of two options can be provided in this object:\n\n * `\"ignore-words\"` - array of strings - words that will be ignored at the beginning of the comment.\n * `\"ignore-pattern\"` - string - RegExp pattern that will be ignored at the beginning of the comment.\n "], _a.raw = ["\n Three arguments may be optionally provided:\n\n * \\`\"check-space\"\\` requires that all single-line comments must begin with a space, as in \\`// comment\\`\n * note that comments starting with \\`///\\` are also allowed, for things such as \\`///<reference>\\`\n * \\`\"check-lowercase\"\\` requires that the first non-whitespace character of a comment must be lowercase, if applicable.\n * \\`\"check-uppercase\"\\` requires that the first non-whitespace character of a comment must be uppercase, if applicable.\n\n Exceptions to \\`\"check-lowercase\"\\` or \\`\"check-uppercase\"\\` can be managed with object that may be passed as last argument.\n\n One of two options can be provided in this object:\n\n * \\`\"ignore-words\"\\` - array of strings - words that will be ignored at the beginning of the comment.\n * \\`\"ignore-pattern\"\\` - string - RegExp pattern that will be ignored at the beginning of the comment.\n "], Lint.Utils.dedent(_a)), - options: { - type: "array", - items: { - anyOf: [ - { - type: "string", - enum: [ - "check-space", - "check-lowercase", - "check-uppercase", - ], - }, - { - type: "object", - properties: { - "ignore-words": { - type: "array", - items: { + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "comment-format", + description: "Enforces formatting rules for single-line comments.", + rationale: "Helps maintain a consistent, readable style in your codebase.", + optionsDescription: (_a = ["\n Three arguments may be optionally provided:\n\n * `\"check-space\"` requires that all single-line comments must begin with a space, as in `// comment`\n * note that for comments starting with multiple slashes, e.g. `///`, leading slashes are ignored\n * TypeScript reference comments are ignored completely\n * `\"check-lowercase\"` requires that the first non-whitespace character of a comment must be lowercase, if applicable.\n * `\"check-uppercase\"` requires that the first non-whitespace character of a comment must be uppercase, if applicable.\n\n Exceptions to `\"check-lowercase\"` or `\"check-uppercase\"` can be managed with object that may be passed as last argument.\n\n One of two options can be provided in this object:\n\n * `\"ignore-words\"` - array of strings - words that will be ignored at the beginning of the comment.\n * `\"ignore-pattern\"` - string - RegExp pattern that will be ignored at the beginning of the comment.\n "], _a.raw = ["\n Three arguments may be optionally provided:\n\n * \\`\"check-space\"\\` requires that all single-line comments must begin with a space, as in \\`// comment\\`\n * note that for comments starting with multiple slashes, e.g. \\`///\\`, leading slashes are ignored\n * TypeScript reference comments are ignored completely\n * \\`\"check-lowercase\"\\` requires that the first non-whitespace character of a comment must be lowercase, if applicable.\n * \\`\"check-uppercase\"\\` requires that the first non-whitespace character of a comment must be uppercase, if applicable.\n\n Exceptions to \\`\"check-lowercase\"\\` or \\`\"check-uppercase\"\\` can be managed with object that may be passed as last argument.\n\n One of two options can be provided in this object:\n\n * \\`\"ignore-words\"\\` - array of strings - words that will be ignored at the beginning of the comment.\n * \\`\"ignore-pattern\"\\` - string - RegExp pattern that will be ignored at the beginning of the comment.\n "], Lint.Utils.dedent(_a)), + options: { + type: "array", + items: { + anyOf: [ + { + type: "string", + enum: [ + "check-space", + "check-lowercase", + "check-uppercase", + ], + }, + { + type: "object", + properties: { + "ignore-words": { + type: "array", + items: { + type: "string", + }, + }, + "ignore-pattern": { type: "string", }, }, - "ignore-pattern": { - type: "string", - }, + minProperties: 1, + maxProperties: 1, }, - minProperties: 1, - maxProperties: 1, - }, - ], + ], + }, + minLength: 1, + maxLength: 4, }, - minLength: 1, - maxLength: 4, - }, - optionExamples: [ - [true, "check-space", "check-uppercase"], - [true, "check-lowercase", { "ignore-words": ["TODO", "HACK"] }], - [true, "check-lowercase", { "ignore-pattern": "STD\\w{2,3}\\b" }], - ], - type: "style", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.LOWERCASE_FAILURE = "comment must start with lowercase letter"; -Rule.UPPERCASE_FAILURE = "comment must start with uppercase letter"; -Rule.LEADING_SPACE_FAILURE = "comment must start with a space"; -Rule.IGNORE_WORDS_FAILURE_FACTORY = function (words) { return " or the word(s): " + words.join(", "); }; -Rule.IGNORE_PATTERN_FAILURE_FACTORY = function (pattern) { return " or its start must match the regex pattern \"" + pattern + "\""; }; -exports.Rule = Rule; -var CommentWalker = (function (_super) { - tslib_1.__extends(CommentWalker, _super); - function CommentWalker(sourceFile, options) { - var _this = _super.call(this, sourceFile, options) || this; - _this.failureIgnorePart = ""; - _this.exceptionsRegExp = _this.composeExceptionsRegExp(); - return _this; - } - CommentWalker.prototype.visitSourceFile = function (node) { - var _this = this; - utils.forEachComment(node, function (fullText, comment) { - if (comment.kind === ts.SyntaxKind.SingleLineCommentTrivia) { - var commentText = fullText.substring(comment.pos, comment.end); - var startPosition = comment.pos + 2; - var width = commentText.length - 2; - if (_this.hasOption(OPTION_SPACE)) { - if (!startsWithSpace(commentText)) { - _this.addFailureAt(startPosition, width, Rule.LEADING_SPACE_FAILURE); - } - } - if (_this.hasOption(OPTION_LOWERCASE)) { - if (!startsWithLowercase(commentText) && !_this.startsWithException(commentText)) { - _this.addFailureAt(startPosition, width, Rule.LOWERCASE_FAILURE + _this.failureIgnorePart); - } - } - if (_this.hasOption(OPTION_UPPERCASE)) { - if (!startsWithUppercase(commentText) && !isEnableDisableFlag(commentText) && !_this.startsWithException(commentText)) { - _this.addFailureAt(startPosition, width, Rule.UPPERCASE_FAILURE + _this.failureIgnorePart); - } - } - } - }); + optionExamples: [ + [true, "check-space", "check-uppercase"], + [true, "check-lowercase", { "ignore-words": ["TODO", "HACK"] }], + [true, "check-lowercase", { "ignore-pattern": "STD\\w{2,3}\\b" }], + ], + type: "style", + typescriptOnly: false, }; - CommentWalker.prototype.startsWithException = function (commentText) { - if (this.exceptionsRegExp == null) { - return false; - } - return this.exceptionsRegExp.test(commentText); - }; - CommentWalker.prototype.composeExceptionsRegExp = function () { - var optionsList = this.getOptions(); - var exceptionsObject = optionsList[optionsList.length - 1]; - // early return if last element is string instead of exceptions object - if (typeof exceptionsObject === "string" || exceptionsObject === undefined) { - return null; - } - if (exceptionsObject["ignore-pattern"] !== undefined) { - var ignorePattern = exceptionsObject["ignore-pattern"]; - this.failureIgnorePart = Rule.IGNORE_PATTERN_FAILURE_FACTORY(ignorePattern); - // regex is "start of string"//"any amount of whitespace" followed by user provided ignore pattern - return new RegExp("^//\\s*(" + ignorePattern + ")"); - } - if (exceptionsObject["ignore-words"] !== undefined) { - var ignoreWords = exceptionsObject["ignore-words"]; - this.failureIgnorePart = Rule.IGNORE_WORDS_FAILURE_FACTORY(ignoreWords); - // Converts all exceptions values to strings, trim whitespace, escapes RegExp special characters and combines into alternation - var wordsPattern = ignoreWords - .map(String) - .map(function (str) { return str.trim(); }) - .map(utils_1.escapeRegExp) - .join("|"); - // regex is "start of string"//"any amount of whitespace"("any word from ignore list") followed by non alphanumeric character - return new RegExp("^//\\s*(" + wordsPattern + ")\\b"); - } - return null; - }; - return CommentWalker; -}(Lint.RuleWalker)); -function startsWith(commentText, changeCase) { - if (commentText.length <= 2) { - return true; // comment is "//"? Technically not a violation. - } - // regex is "start of string"//"any amount of whitespace"("word character") - var firstCharacterMatch = commentText.match(/^\/\/\s*(\w)/); - if (firstCharacterMatch != null) { - // the first group matched, i.e. the thing in the parens, is the first non-space character, if it's alphanumeric - var firstCharacter = firstCharacterMatch[1]; - return firstCharacter === changeCase(firstCharacter); - } - else { - // first character isn't alphanumeric/doesn't exist? Technically not a violation - return true; - } -} -function startsWithLowercase(commentText) { - return startsWith(commentText, function (c) { return c.toLowerCase(); }); -} -function startsWithUppercase(commentText) { - return startsWith(commentText, function (c) { return c.toUpperCase(); }); + /* tslint:enable:object-literal-sort-keys */ + Rule.LOWERCASE_FAILURE = "comment must start with lowercase letter"; + Rule.UPPERCASE_FAILURE = "comment must start with uppercase letter"; + Rule.LEADING_SPACE_FAILURE = "comment must start with a space"; + Rule.IGNORE_WORDS_FAILURE_FACTORY = function (words) { return " or the word(s): " + words.join(", "); }; + Rule.IGNORE_PATTERN_FAILURE_FACTORY = function (pattern) { return " or its start must match the regex pattern \"" + pattern + "\""; }; + return Rule; +}(Lint.Rules.AbstractRule)); +exports.Rule = Rule; +function parseOptions(options) { + return tslib_1.__assign({ case: options.indexOf(OPTION_LOWERCASE) !== -1 + ? 1 /* Lower */ + : options.indexOf(OPTION_UPPERCASE) !== -1 + ? 2 /* Upper */ + : 0 /* None */, failureSuffix: "", space: options.indexOf(OPTION_SPACE) !== -1 }, composeExceptions(options[options.length - 1])); } -function startsWithSpace(commentText) { - if (commentText.length <= 2) { - return true; // comment is "//"? Technically not a violation. +function composeExceptions(option) { + if (typeof option !== "object") { + return undefined; } - var commentBody = commentText.substring(2); - // whitelist //#region and //#endregion - if ((/^#(end)?region/).test(commentBody)) { - return true; + var ignorePattern = option["ignore-pattern"]; + if (ignorePattern !== undefined) { + return { + exceptions: new RegExp("^\\s*(" + ignorePattern + ")"), + failureSuffix: Rule.IGNORE_PATTERN_FAILURE_FACTORY(ignorePattern), + }; } - // whitelist JetBrains IDEs' "//noinspection ..." - if ((/^noinspection\s/).test(commentBody)) { - return true; + var ignoreWords = option["ignore-words"]; + if (ignoreWords !== undefined && ignoreWords.length !== 0) { + return { + exceptions: new RegExp("^\\s*(?:" + ignoreWords.map(function (word) { return utils_1.escapeRegExp(word.trim()); }).join("|") + ")\\b"), + failureSuffix: Rule.IGNORE_WORDS_FAILURE_FACTORY(ignoreWords), + }; } - var firstCharacter = commentBody.charAt(0); - // three slashes (///) also works, to allow for ///<reference> - return firstCharacter === " " || firstCharacter === "/"; + return undefined; } -function isEnableDisableFlag(commentText) { - // regex is: start of string followed by "/*" or "//" - // followed by any amount of whitespace followed by "tslint:" - // followed by either "enable" or "disable" - return /^(\/\*|\/\/)\s*tslint:(enable|disable)/.test(commentText); +function walk(ctx) { + utils.forEachComment(ctx.sourceFile, function (fullText, _a) { + var kind = _a.kind, pos = _a.pos, end = _a.end; + var start = pos + 2; + if (kind !== ts.SyntaxKind.SingleLineCommentTrivia || + // exclude empty comments + start === end || + // exclude /// <reference path="..."> + fullText[start] === "/" && ctx.sourceFile.referencedFiles.some(function (ref) { return ref.pos >= pos && ref.end <= end; })) { + return; + } + // skip all leading slashes + while (fullText[start] === "/") { + ++start; + } + if (start === end) { + return; + } + var commentText = fullText.slice(start, end); + // whitelist //#region and //#endregion and JetBrains IDEs' "//noinspection ..." + if (/^(?:#(?:end)?region|noinspection\s)/.test(commentText)) { + return; + } + if (ctx.options.space && commentText[0] !== " ") { + ctx.addFailure(start, end, Rule.LEADING_SPACE_FAILURE); + } + if (ctx.options.case === 0 /* None */ || + ctx.options.exceptions !== undefined && ctx.options.exceptions.test(commentText) || + enableDisableRules_1.ENABLE_DISABLE_REGEX.test(commentText)) { + return; + } + // search for first non-space character to check if lower or upper + var charPos = commentText.search(/\S/); + if (charPos === -1) { + return; + } + if (ctx.options.case === 1 /* Lower */) { + if (!utils_1.isLowerCase(commentText[charPos])) { + ctx.addFailure(start, end, Rule.LOWERCASE_FAILURE + ctx.options.failureSuffix); + } + } + else if (!utils_1.isUpperCase(commentText[charPos])) { + ctx.addFailure(start, end, Rule.UPPERCASE_FAILURE + ctx.options.failureSuffix); + } + }); } var _a; diff --git a/node_modules/tslint/lib/rules/completedDocsRule.d.ts b/node_modules/tslint/lib/rules/completedDocsRule.d.ts index 491c4edf5..560f436e7 100644 --- a/node_modules/tslint/lib/rules/completedDocsRule.d.ts +++ b/node_modules/tslint/lib/rules/completedDocsRule.d.ts @@ -1,19 +1,3 @@ -/** - * @license - * Copyright 2013 Palantir Technologies, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ import * as ts from "typescript"; import * as Lint from "../index"; export interface IBlockRequirementDescriptor { @@ -30,6 +14,7 @@ export interface IRequirementDescriptors { export declare const ALL = "all"; export declare const ARGUMENT_CLASSES = "classes"; export declare const ARGUMENT_ENUMS = "enums"; +export declare const ARGUMENT_ENUM_MEMBERS = "enum-members"; export declare const ARGUMENT_FUNCTIONS = "functions"; export declare const ARGUMENT_INTERFACES = "interfaces"; export declare const ARGUMENT_METHODS = "methods"; @@ -48,7 +33,7 @@ export declare const PRIVACY_PUBLIC = "public"; export declare const VISIBILITY_EXPORTED = "exported"; export declare const VISIBILITY_INTERNAL = "internal"; export declare type All = typeof ALL; -export declare type DocType = All | typeof ARGUMENT_CLASSES | typeof ARGUMENT_ENUMS | typeof ARGUMENT_FUNCTIONS | typeof ARGUMENT_INTERFACES | typeof ARGUMENT_METHODS | typeof ARGUMENT_NAMESPACES | typeof ARGUMENT_PROPERTIES | typeof ARGUMENT_TYPES | typeof ARGUMENT_VARIABLES; +export declare type DocType = All | typeof ARGUMENT_CLASSES | typeof ARGUMENT_ENUMS | typeof ARGUMENT_ENUM_MEMBERS | typeof ARGUMENT_FUNCTIONS | typeof ARGUMENT_INTERFACES | typeof ARGUMENT_METHODS | typeof ARGUMENT_NAMESPACES | typeof ARGUMENT_PROPERTIES | typeof ARGUMENT_TYPES | typeof ARGUMENT_VARIABLES; export declare type Location = All | typeof LOCATION_INSTANCE | typeof LOCATION_STATIC; export declare type Privacy = All | typeof PRIVACY_PRIVATE | typeof PRIVACY_PROTECTED | typeof PRIVACY_PUBLIC; export declare type Visibility = All | typeof VISIBILITY_EXPORTED | typeof VISIBILITY_INTERNAL; diff --git a/node_modules/tslint/lib/rules/completedDocsRule.js b/node_modules/tslint/lib/rules/completedDocsRule.js index 6107859a6..515ca257d 100644 --- a/node_modules/tslint/lib/rules/completedDocsRule.js +++ b/node_modules/tslint/lib/rules/completedDocsRule.js @@ -17,12 +17,14 @@ */ 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 utils_1 = require("../utils"); exports.ALL = "all"; exports.ARGUMENT_CLASSES = "classes"; exports.ARGUMENT_ENUMS = "enums"; +exports.ARGUMENT_ENUM_MEMBERS = "enum-members"; exports.ARGUMENT_FUNCTIONS = "functions"; exports.ARGUMENT_INTERFACES = "interfaces"; exports.ARGUMENT_METHODS = "methods"; @@ -58,100 +60,101 @@ var Rule = (function (_super) { } return Requirement.constructRequirements(ruleArguments); }; - return Rule; -}(Lint.Rules.TypedRule)); -Rule.FAILURE_STRING_EXIST = "Documentation must exist for "; -Rule.defaultArguments = [ - exports.ARGUMENT_CLASSES, - exports.ARGUMENT_FUNCTIONS, - exports.ARGUMENT_METHODS, - exports.ARGUMENT_PROPERTIES, -]; -Rule.ARGUMENT_DESCRIPTOR_BLOCK = { - properties: (_a = {}, - _a[exports.DESCRIPTOR_VISIBILITIES] = { - enum: [ - exports.ALL, - exports.VISIBILITY_EXPORTED, - exports.VISIBILITY_INTERNAL, - ], - type: "string", - }, - _a), - type: "object", -}; -Rule.ARGUMENT_DESCRIPTOR_CLASS = { - properties: (_b = {}, - _b[exports.DESCRIPTOR_LOCATIONS] = { - enum: [ - exports.ALL, - exports.LOCATION_INSTANCE, - exports.LOCATION_STATIC, - ], - type: "string", - }, - _b[exports.DESCRIPTOR_PRIVACIES] = { - enum: [ - exports.ALL, - exports.PRIVACY_PRIVATE, - exports.PRIVACY_PROTECTED, - exports.PRIVACY_PUBLIC, - ], - type: "string", - }, - _b), - type: "object", -}; -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "completed-docs", - description: "Enforces documentation for important items be filled out.", - optionsDescription: (_c = ["\n `true` to enable for [\"", "\", \"", "\", \"", "\", \"", "\"],\n or an array with each item in one of two formats:\n\n * `string` to enable for that type\n * `object` keying types to when their documentation is required:\n * `\"", "\"` and `\"", "\"` may specify:\n * `\"", "\"`:\n * `\"", "\"`\n * `\"", "\"`\n * `\"", "\"`\n * `\"", "\"`\n * `\"", "\"`:\n * `\"", "\"`\n * `\"", "\"`\n * `\"", "\"`\n * All other types may specify `\"", "\"`:\n * `\"", "\"`\n * `\"", "\"`\n * `\"", "\"`\n\n Types that may be enabled are:\n\n * `\"", "\"`\n * `\"", "\"`\n * `\"", "\"`\n * `\"", "\"`\n * `\"", "\"`\n * `\"", "\"`\n * `\"", "\"`\n * `\"", "\"`\n * `\"", "\"`"], _c.raw = ["\n \\`true\\` to enable for [\"", "\", \"", "\", \"", "\", \"", "\"],\n or an array with each item in one of two formats:\n\n * \\`string\\` to enable for that type\n * \\`object\\` keying types to when their documentation is required:\n * \\`\"", "\"\\` and \\`\"", "\"\\` may specify:\n * \\`\"", "\"\\`:\n * \\`\"", "\"\\`\n * \\`\"", "\"\\`\n * \\`\"", "\"\\`\n * \\`\"", "\"\\`\n * \\`\"", "\"\\`:\n * \\`\"", "\"\\`\n * \\`\"", "\"\\`\n * \\`\"", "\"\\`\n * All other types may specify \\`\"", "\"\\`:\n * \\`\"", "\"\\`\n * \\`\"", "\"\\`\n * \\`\"", "\"\\`\n\n Types that may be enabled are:\n\n * \\`\"", "\"\\`\n * \\`\"", "\"\\`\n * \\`\"", "\"\\`\n * \\`\"", "\"\\`\n * \\`\"", "\"\\`\n * \\`\"", "\"\\`\n * \\`\"", "\"\\`\n * \\`\"", "\"\\`\n * \\`\"", "\"\\`"], Lint.Utils.dedent(_c, exports.ARGUMENT_CLASSES, exports.ARGUMENT_FUNCTIONS, exports.ARGUMENT_METHODS, exports.ARGUMENT_PROPERTIES, exports.ARGUMENT_METHODS, exports.ARGUMENT_PROPERTIES, exports.DESCRIPTOR_PRIVACIES, exports.ALL, exports.PRIVACY_PRIVATE, exports.PRIVACY_PROTECTED, exports.PRIVACY_PUBLIC, exports.DESCRIPTOR_LOCATIONS, exports.ALL, exports.LOCATION_INSTANCE, exports.LOCATION_STATIC, exports.DESCRIPTOR_VISIBILITIES, exports.ALL, exports.VISIBILITY_EXPORTED, exports.VISIBILITY_INTERNAL, exports.ARGUMENT_CLASSES, exports.ARGUMENT_ENUMS, exports.ARGUMENT_FUNCTIONS, exports.ARGUMENT_INTERFACES, exports.ARGUMENT_METHODS, exports.ARGUMENT_NAMESPACES, exports.ARGUMENT_PROPERTIES, exports.ARGUMENT_TYPES, exports.ARGUMENT_VARIABLES)), - options: { - type: "array", - items: { - anyOf: [ - { - enum: Rule.defaultArguments, - type: "string", - }, - { - type: "object", - properties: (_d = {}, - _d[exports.ARGUMENT_CLASSES] = Rule.ARGUMENT_DESCRIPTOR_BLOCK, - _d[exports.ARGUMENT_ENUMS] = Rule.ARGUMENT_DESCRIPTOR_BLOCK, - _d[exports.ARGUMENT_FUNCTIONS] = Rule.ARGUMENT_DESCRIPTOR_BLOCK, - _d[exports.ARGUMENT_INTERFACES] = Rule.ARGUMENT_DESCRIPTOR_BLOCK, - _d[exports.ARGUMENT_METHODS] = Rule.ARGUMENT_DESCRIPTOR_CLASS, - _d[exports.ARGUMENT_NAMESPACES] = Rule.ARGUMENT_DESCRIPTOR_BLOCK, - _d[exports.ARGUMENT_PROPERTIES] = Rule.ARGUMENT_DESCRIPTOR_CLASS, - _d[exports.ARGUMENT_TYPES] = Rule.ARGUMENT_DESCRIPTOR_BLOCK, - _d[exports.ARGUMENT_VARIABLES] = Rule.ARGUMENT_DESCRIPTOR_BLOCK, - _d), - }, - ], + Rule.FAILURE_STRING_EXIST = "Documentation must exist for "; + Rule.defaultArguments = [ + exports.ARGUMENT_CLASSES, + exports.ARGUMENT_FUNCTIONS, + exports.ARGUMENT_METHODS, + exports.ARGUMENT_PROPERTIES, + ]; + Rule.ARGUMENT_DESCRIPTOR_BLOCK = { + properties: (_a = {}, + _a[exports.DESCRIPTOR_VISIBILITIES] = { + enum: [ + exports.ALL, + exports.VISIBILITY_EXPORTED, + exports.VISIBILITY_INTERNAL, + ], + type: "string", + }, + _a), + type: "object", + }; + Rule.ARGUMENT_DESCRIPTOR_CLASS = { + properties: (_b = {}, + _b[exports.DESCRIPTOR_LOCATIONS] = { + enum: [ + exports.ALL, + exports.LOCATION_INSTANCE, + exports.LOCATION_STATIC, + ], + type: "string", + }, + _b[exports.DESCRIPTOR_PRIVACIES] = { + enum: [ + exports.ALL, + exports.PRIVACY_PRIVATE, + exports.PRIVACY_PROTECTED, + exports.PRIVACY_PUBLIC, + ], + type: "string", + }, + _b), + type: "object", + }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "completed-docs", + description: "Enforces documentation for important items be filled out.", + optionsDescription: (_c = ["\n `true` to enable for [\"", "\", \"", "\", \"", "\", \"", "\"],\n or an array with each item in one of two formats:\n\n * `string` to enable for that type\n * `object` keying types to when their documentation is required:\n * `\"", "\"` and `\"", "\"` may specify:\n * `\"", "\"`:\n * `\"", "\"`\n * `\"", "\"`\n * `\"", "\"`\n * `\"", "\"`\n * `\"", "\"`:\n * `\"", "\"`\n * `\"", "\"`\n * `\"", "\"`\n * All other types may specify `\"", "\"`:\n * `\"", "\"`\n * `\"", "\"`\n * `\"", "\"`\n\n Types that may be enabled are:\n\n * `\"", "\"`\n * `\"", "\"`\n * `\"", "\"`\n * `\"", "\"`\n * `\"", "\"`\n * `\"", "\"`\n * `\"", "\"`\n * `\"", "\"`\n * `\"", "\"`\n * `\"", "\"`"], _c.raw = ["\n \\`true\\` to enable for [\"", "\", \"", "\", \"", "\", \"", "\"],\n or an array with each item in one of two formats:\n\n * \\`string\\` to enable for that type\n * \\`object\\` keying types to when their documentation is required:\n * \\`\"", "\"\\` and \\`\"", "\"\\` may specify:\n * \\`\"", "\"\\`:\n * \\`\"", "\"\\`\n * \\`\"", "\"\\`\n * \\`\"", "\"\\`\n * \\`\"", "\"\\`\n * \\`\"", "\"\\`:\n * \\`\"", "\"\\`\n * \\`\"", "\"\\`\n * \\`\"", "\"\\`\n * All other types may specify \\`\"", "\"\\`:\n * \\`\"", "\"\\`\n * \\`\"", "\"\\`\n * \\`\"", "\"\\`\n\n Types that may be enabled are:\n\n * \\`\"", "\"\\`\n * \\`\"", "\"\\`\n * \\`\"", "\"\\`\n * \\`\"", "\"\\`\n * \\`\"", "\"\\`\n * \\`\"", "\"\\`\n * \\`\"", "\"\\`\n * \\`\"", "\"\\`\n * \\`\"", "\"\\`\n * \\`\"", "\"\\`"], Lint.Utils.dedent(_c, exports.ARGUMENT_CLASSES, exports.ARGUMENT_FUNCTIONS, exports.ARGUMENT_METHODS, exports.ARGUMENT_PROPERTIES, exports.ARGUMENT_METHODS, exports.ARGUMENT_PROPERTIES, exports.DESCRIPTOR_PRIVACIES, exports.ALL, exports.PRIVACY_PRIVATE, exports.PRIVACY_PROTECTED, exports.PRIVACY_PUBLIC, exports.DESCRIPTOR_LOCATIONS, exports.ALL, exports.LOCATION_INSTANCE, exports.LOCATION_STATIC, exports.DESCRIPTOR_VISIBILITIES, exports.ALL, exports.VISIBILITY_EXPORTED, exports.VISIBILITY_INTERNAL, exports.ARGUMENT_CLASSES, exports.ARGUMENT_ENUMS, exports.ARGUMENT_ENUM_MEMBERS, exports.ARGUMENT_FUNCTIONS, exports.ARGUMENT_INTERFACES, exports.ARGUMENT_METHODS, exports.ARGUMENT_NAMESPACES, exports.ARGUMENT_PROPERTIES, exports.ARGUMENT_TYPES, exports.ARGUMENT_VARIABLES)), + options: { + type: "array", + items: { + anyOf: [ + { + enum: Rule.defaultArguments, + type: "string", + }, + { + type: "object", + properties: (_d = {}, + _d[exports.ARGUMENT_CLASSES] = Rule.ARGUMENT_DESCRIPTOR_BLOCK, + _d[exports.ARGUMENT_ENUMS] = Rule.ARGUMENT_DESCRIPTOR_BLOCK, + _d[exports.ARGUMENT_ENUM_MEMBERS] = Rule.ARGUMENT_DESCRIPTOR_BLOCK, + _d[exports.ARGUMENT_FUNCTIONS] = Rule.ARGUMENT_DESCRIPTOR_BLOCK, + _d[exports.ARGUMENT_INTERFACES] = Rule.ARGUMENT_DESCRIPTOR_BLOCK, + _d[exports.ARGUMENT_METHODS] = Rule.ARGUMENT_DESCRIPTOR_CLASS, + _d[exports.ARGUMENT_NAMESPACES] = Rule.ARGUMENT_DESCRIPTOR_BLOCK, + _d[exports.ARGUMENT_PROPERTIES] = Rule.ARGUMENT_DESCRIPTOR_CLASS, + _d[exports.ARGUMENT_TYPES] = Rule.ARGUMENT_DESCRIPTOR_BLOCK, + _d[exports.ARGUMENT_VARIABLES] = Rule.ARGUMENT_DESCRIPTOR_BLOCK, + _d), + }, + ], + }, }, - }, - optionExamples: [ - true, - [true, exports.ARGUMENT_ENUMS, exports.ARGUMENT_FUNCTIONS, exports.ARGUMENT_METHODS], - [ + optionExamples: [ true, - (_e = {}, - _e[exports.ARGUMENT_ENUMS] = true, - _e[exports.ARGUMENT_FUNCTIONS] = (_f = {}, - _f[exports.DESCRIPTOR_VISIBILITIES] = [exports.VISIBILITY_EXPORTED], - _f), - _e[exports.ARGUMENT_METHODS] = (_g = {}, - _g[exports.DESCRIPTOR_LOCATIONS] = exports.LOCATION_INSTANCE, - _g[exports.DESCRIPTOR_PRIVACIES] = [exports.PRIVACY_PUBLIC, exports.PRIVACY_PROTECTED], - _g), - _e), + [true, exports.ARGUMENT_ENUMS, exports.ARGUMENT_FUNCTIONS, exports.ARGUMENT_METHODS], + [ + true, + (_e = {}, + _e[exports.ARGUMENT_ENUMS] = true, + _e[exports.ARGUMENT_FUNCTIONS] = (_f = {}, + _f[exports.DESCRIPTOR_VISIBILITIES] = [exports.VISIBILITY_EXPORTED], + _f), + _e[exports.ARGUMENT_METHODS] = (_g = {}, + _g[exports.DESCRIPTOR_LOCATIONS] = exports.LOCATION_INSTANCE, + _g[exports.DESCRIPTOR_PRIVACIES] = [exports.PRIVACY_PUBLIC, exports.PRIVACY_PROTECTED], + _g), + _e), + ], ], - ], - type: "style", - typescriptOnly: false, -}; + type: "style", + typescriptOnly: false, + }; + return Rule; +}(Lint.Rules.TypedRule)); exports.Rule = Rule; var Requirement = (function () { // tslint:disable-next-line no-object-literal-type-assertion @@ -256,6 +259,12 @@ var CompletedDocsWalker = (function (_super) { this.checkNode(node, exports.ARGUMENT_ENUMS); _super.prototype.visitEnumDeclaration.call(this, node); }; + CompletedDocsWalker.prototype.visitEnumMember = function (node) { + // Enum members don't have modifiers, so use the parent + // enum declaration when checking the requirements. + this.checkNode(node, exports.ARGUMENT_ENUM_MEMBERS, node.parent); + _super.prototype.visitEnumMember.call(this, node); + }; CompletedDocsWalker.prototype.visitFunctionDeclaration = function (node) { this.checkNode(node, exports.ARGUMENT_FUNCTIONS); _super.prototype.visitFunctionDeclaration.call(this, node); @@ -281,16 +290,36 @@ var CompletedDocsWalker = (function (_super) { _super.prototype.visitTypeAliasDeclaration.call(this, node); }; CompletedDocsWalker.prototype.visitVariableDeclaration = function (node) { - this.checkNode(node, exports.ARGUMENT_VARIABLES); + this.checkVariable(node); _super.prototype.visitVariableDeclaration.call(this, node); }; - CompletedDocsWalker.prototype.checkNode = function (node, nodeType) { + CompletedDocsWalker.prototype.checkVariable = function (node) { + // Only check variables in variable declaration lists + // and not variables in catch clauses and for loops. + var list = node.parent; + if (!tsutils_1.isVariableDeclarationList(list)) { + return; + } + var statement = list.parent; + if (!tsutils_1.isVariableStatement(statement)) { + return; + } + // Only check variables at the namespace/module-level or file-level + // and not variables declared inside functions and other things. + switch (statement.parent.kind) { + case ts.SyntaxKind.SourceFile: + case ts.SyntaxKind.ModuleBlock: + this.checkNode(node, exports.ARGUMENT_VARIABLES, statement); + } + }; + CompletedDocsWalker.prototype.checkNode = function (node, nodeType, requirementNode) { + if (requirementNode === void 0) { requirementNode = node; } var name = node.name; if (name === undefined) { return; } var requirement = this.requirements.get(nodeType); - if (requirement === undefined || !requirement.shouldNodeBeDocumented(node)) { + if (requirement === undefined || !requirement.shouldNodeBeDocumented(requirementNode)) { return; } var symbol = this.getTypeChecker().getSymbolAtLocation(name); @@ -298,17 +327,20 @@ var CompletedDocsWalker = (function (_super) { return; } var comments = symbol.getDocumentationComment(); - this.checkComments(node, nodeType, comments); + this.checkComments(node, this.describeNode(nodeType), comments, requirementNode); + }; + CompletedDocsWalker.prototype.describeNode = function (nodeType) { + return nodeType.replace("-", " "); }; - CompletedDocsWalker.prototype.checkComments = function (node, nodeDescriptor, comments) { + CompletedDocsWalker.prototype.checkComments = function (node, nodeDescriptor, comments, requirementNode) { if (comments.map(function (comment) { return comment.text; }).join("").trim() === "") { - this.addDocumentationFailure(node, nodeDescriptor); + this.addDocumentationFailure(node, nodeDescriptor, requirementNode); } }; - CompletedDocsWalker.prototype.addDocumentationFailure = function (node, nodeType) { + CompletedDocsWalker.prototype.addDocumentationFailure = function (node, nodeType, requirementNode) { var start = node.getStart(); var width = node.getText().split(/\r|\n/g)[0].length; - var description = this.describeDocumentationFailure(node, nodeType); + var description = this.describeDocumentationFailure(requirementNode, nodeType); this.addFailureAt(start, width, description); }; CompletedDocsWalker.prototype.describeDocumentationFailure = function (node, nodeType) { @@ -324,9 +356,9 @@ var CompletedDocsWalker = (function (_super) { var alias = CompletedDocsWalker.modifierAliases[description]; return alias !== undefined ? alias : description; }; + CompletedDocsWalker.modifierAliases = { + export: "exported", + }; return CompletedDocsWalker; }(Lint.ProgramAwareRuleWalker)); -CompletedDocsWalker.modifierAliases = { - export: "exported", -}; var _a, _b, _c, _d, _e, _f, _g; diff --git a/node_modules/tslint/lib/rules/curlyRule.d.ts b/node_modules/tslint/lib/rules/curlyRule.d.ts index 1f50117ab..929f3f551 100644 --- a/node_modules/tslint/lib/rules/curlyRule.d.ts +++ b/node_modules/tslint/lib/rules/curlyRule.d.ts @@ -2,6 +2,7 @@ import * as ts from "typescript"; import * as Lint from "../index"; export declare class Rule extends Lint.Rules.AbstractRule { static metadata: Lint.IRuleMetadata; + static FAILURE_STRING_AS_NEEDED: string; static FAILURE_STRING_FACTORY(kind: string): string; apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; } diff --git a/node_modules/tslint/lib/rules/curlyRule.js b/node_modules/tslint/lib/rules/curlyRule.js index af2e04d2d..cd2bc205a 100644 --- a/node_modules/tslint/lib/rules/curlyRule.js +++ b/node_modules/tslint/lib/rules/curlyRule.js @@ -20,43 +20,83 @@ var tslib_1 = require("tslib"); var tsutils_1 = require("tsutils"); var ts = require("typescript"); var Lint = require("../index"); +var OPTION_AS_NEEDED = "as-needed"; var OPTION_IGNORE_SAME_LINE = "ignore-same-line"; var Rule = (function (_super) { tslib_1.__extends(Rule, _super); function Rule() { return _super !== null && _super.apply(this, arguments) || this; } - /* tslint:enable:object-literal-sort-keys */ Rule.FAILURE_STRING_FACTORY = function (kind) { return kind + " statements must be braced"; }; Rule.prototype.apply = function (sourceFile) { + if (this.ruleArguments.indexOf(OPTION_AS_NEEDED) !== -1) { + return this.applyWithFunction(sourceFile, walkAsNeeded); + } return this.applyWithWalker(new CurlyWalker(sourceFile, this.ruleName, { ignoreSameLine: this.ruleArguments.indexOf(OPTION_IGNORE_SAME_LINE) !== -1, })); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "curly", + description: "Enforces braces for `if`/`for`/`do`/`while` statements.", + rationale: (_a = ["\n ```ts\n if (foo === bar)\n foo++;\n bar++;\n ```\n\n In the code above, the author almost certainly meant for both `foo++` and `bar++`\n to be executed only if `foo === bar`. However, he forgot braces and `bar++` will be executed\n no matter what. This rule could prevent such a mistake."], _a.raw = ["\n \\`\\`\\`ts\n if (foo === bar)\n foo++;\n bar++;\n \\`\\`\\`\n\n In the code above, the author almost certainly meant for both \\`foo++\\` and \\`bar++\\`\n to be executed only if \\`foo === bar\\`. However, he forgot braces and \\`bar++\\` will be executed\n no matter what. This rule could prevent such a mistake."], Lint.Utils.dedent(_a)), + optionsDescription: (_b = ["\n One of the following options may be provided:\n\n * `\"", "\"` forbids any unnecessary curly braces.\n * `\"", "\"` skips checking braces for control-flow statements\n that are on one line and start on the same line as their control-flow keyword\n "], _b.raw = ["\n One of the following options may be provided:\n\n * \\`\"", "\"\\` forbids any unnecessary curly braces.\n * \\`\"", "\"\\` skips checking braces for control-flow statements\n that are on one line and start on the same line as their control-flow keyword\n "], Lint.Utils.dedent(_b, OPTION_AS_NEEDED, OPTION_IGNORE_SAME_LINE)), + options: { + type: "array", + items: { + type: "string", + enum: [ + OPTION_AS_NEEDED, + OPTION_IGNORE_SAME_LINE, + ], + }, + }, + optionExamples: [ + true, + [true, OPTION_IGNORE_SAME_LINE], + [true, OPTION_AS_NEEDED], + ], + type: "functionality", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING_AS_NEEDED = "Block contains only one statement; remove the curly braces."; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "curly", - description: "Enforces braces for `if`/`for`/`do`/`while` statements.", - rationale: (_a = ["\n ```ts\n if (foo === bar)\n foo++;\n bar++;\n ```\n\n In the code above, the author almost certainly meant for both `foo++` and `bar++`\n to be executed only if `foo === bar`. However, he forgot braces and `bar++` will be executed\n no matter what. This rule could prevent such a mistake."], _a.raw = ["\n \\`\\`\\`ts\n if (foo === bar)\n foo++;\n bar++;\n \\`\\`\\`\n\n In the code above, the author almost certainly meant for both \\`foo++\\` and \\`bar++\\`\n to be executed only if \\`foo === bar\\`. However, he forgot braces and \\`bar++\\` will be executed\n no matter what. This rule could prevent such a mistake."], Lint.Utils.dedent(_a)), - optionsDescription: (_b = ["\n The rule may be set to `true`, or to the following:\n\n * `\"", "\"` skips checking braces for control-flow statements\n that are on one line and start on the same line as their control-flow keyword\n "], _b.raw = ["\n The rule may be set to \\`true\\`, or to the following:\n\n * \\`\"", "\"\\` skips checking braces for control-flow statements\n that are on one line and start on the same line as their control-flow keyword\n "], Lint.Utils.dedent(_b, OPTION_IGNORE_SAME_LINE)), - options: { - type: "array", - items: { - type: "string", - enum: [ - OPTION_IGNORE_SAME_LINE, - ], - }, - }, - optionExamples: [true, [true, "ignore-same-line"]], - type: "functionality", - typescriptOnly: false, -}; exports.Rule = Rule; +function walkAsNeeded(ctx) { + ts.forEachChild(ctx.sourceFile, function cb(node) { + if (tsutils_1.isBlock(node) && isBlockUnnecessary(node)) { + ctx.addFailureAtNode(Lint.childOfKind(node, ts.SyntaxKind.OpenBraceToken), Rule.FAILURE_STRING_AS_NEEDED); + } + ts.forEachChild(node, cb); + }); +} +function isBlockUnnecessary(node) { + var parent = node.parent; + if (node.statements.length !== 1) { + return false; + } + var statement = node.statements[0]; + if (tsutils_1.isIterationStatement(parent)) { + return true; + } + /* + Watch out for this case: + if (so) { + if (also) + foo(); + } else + bar(); + */ + return tsutils_1.isIfStatement(parent) && !(tsutils_1.isIfStatement(statement) + && statement.elseStatement === undefined + && parent.thenStatement === node + && parent.elseStatement !== undefined); +} var CurlyWalker = (function (_super) { tslib_1.__extends(CurlyWalker, _super); function CurlyWalker() { diff --git a/node_modules/tslint/lib/rules/cyclomaticComplexityRule.js b/node_modules/tslint/lib/rules/cyclomaticComplexityRule.js index f79bbe02c..e92eb1431 100644 --- a/node_modules/tslint/lib/rules/cyclomaticComplexityRule.js +++ b/node_modules/tslint/lib/rules/cyclomaticComplexityRule.js @@ -48,25 +48,25 @@ var Rule = (function (_super) { enumerable: true, configurable: true }); + Rule.DEFAULT_THRESHOLD = 20; + Rule.MINIMUM_THRESHOLD = 2; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "cyclomatic-complexity", + description: "Enforces a threshold of cyclomatic complexity.", + descriptionDetails: (_a = ["\n Cyclomatic complexity is assessed for each function of any type. A starting value of 0\n is assigned and this value is then incremented for every statement which can branch the\n control flow within the function. The following statements and expressions contribute\n to cyclomatic complexity:\n * `catch`\n * `if` and `? :`\n * `||` and `&&` due to short-circuit evaluation\n * `for`, `for in` and `for of` loops\n * `while` and `do while` loops\n * `case` clauses that contain statements"], _a.raw = ["\n Cyclomatic complexity is assessed for each function of any type. A starting value of 0\n is assigned and this value is then incremented for every statement which can branch the\n control flow within the function. The following statements and expressions contribute\n to cyclomatic complexity:\n * \\`catch\\`\n * \\`if\\` and \\`? :\\`\n * \\`||\\` and \\`&&\\` due to short-circuit evaluation\n * \\`for\\`, \\`for in\\` and \\`for of\\` loops\n * \\`while\\` and \\`do while\\` loops\n * \\`case\\` clauses that contain statements"], Lint.Utils.dedent(_a)), + rationale: (_b = ["\n Cyclomatic complexity is a code metric which indicates the level of complexity in a\n function. High cyclomatic complexity indicates confusing code which may be prone to\n errors or difficult to modify."], _b.raw = ["\n Cyclomatic complexity is a code metric which indicates the level of complexity in a\n function. High cyclomatic complexity indicates confusing code which may be prone to\n errors or difficult to modify."], Lint.Utils.dedent(_b)), + optionsDescription: (_c = ["\n An optional upper limit for cyclomatic complexity can be specified. If no limit option\n is provided a default value of ", " will be used."], _c.raw = ["\n An optional upper limit for cyclomatic complexity can be specified. If no limit option\n is provided a default value of ", " will be used."], Lint.Utils.dedent(_c, Rule.DEFAULT_THRESHOLD)), + options: { + type: "number", + minimum: Rule.MINIMUM_THRESHOLD, + }, + optionExamples: [true, [true, 20]], + type: "maintainability", + typescriptOnly: false, + }; return Rule; }(Lint.Rules.AbstractRule)); -Rule.DEFAULT_THRESHOLD = 20; -Rule.MINIMUM_THRESHOLD = 2; -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "cyclomatic-complexity", - description: "Enforces a threshold of cyclomatic complexity.", - descriptionDetails: (_a = ["\n Cyclomatic complexity is assessed for each function of any type. A starting value of 20\n is assigned and this value is then incremented for every statement which can branch the\n control flow within the function. The following statements and expressions contribute\n to cyclomatic complexity:\n * `catch`\n * `if` and `? :`\n * `||` and `&&` due to short-circuit evaluation\n * `for`, `for in` and `for of` loops\n * `while` and `do while` loops"], _a.raw = ["\n Cyclomatic complexity is assessed for each function of any type. A starting value of 20\n is assigned and this value is then incremented for every statement which can branch the\n control flow within the function. The following statements and expressions contribute\n to cyclomatic complexity:\n * \\`catch\\`\n * \\`if\\` and \\`? :\\`\n * \\`||\\` and \\`&&\\` due to short-circuit evaluation\n * \\`for\\`, \\`for in\\` and \\`for of\\` loops\n * \\`while\\` and \\`do while\\` loops"], Lint.Utils.dedent(_a)), - rationale: (_b = ["\n Cyclomatic complexity is a code metric which indicates the level of complexity in a\n function. High cyclomatic complexity indicates confusing code which may be prone to\n errors or difficult to modify."], _b.raw = ["\n Cyclomatic complexity is a code metric which indicates the level of complexity in a\n function. High cyclomatic complexity indicates confusing code which may be prone to\n errors or difficult to modify."], Lint.Utils.dedent(_b)), - optionsDescription: (_c = ["\n An optional upper limit for cyclomatic complexity can be specified. If no limit option\n is provided a default value of $(Rule.DEFAULT_THRESHOLD) will be used."], _c.raw = ["\n An optional upper limit for cyclomatic complexity can be specified. If no limit option\n is provided a default value of $(Rule.DEFAULT_THRESHOLD) will be used."], Lint.Utils.dedent(_c)), - options: { - type: "number", - minimum: "$(Rule.MINIMUM_THRESHOLD)", - }, - optionExamples: [true, [true, 20]], - type: "maintainability", - typescriptOnly: false, -}; exports.Rule = Rule; function walk(ctx) { var threshold = ctx.options.threshold; @@ -94,6 +94,7 @@ function walk(ctx) { function increasesComplexity(node) { switch (node.kind) { case ts.SyntaxKind.CaseClause: + return node.statements.length > 0; case ts.SyntaxKind.CatchClause: case ts.SyntaxKind.ConditionalExpression: case ts.SyntaxKind.DoStatement: diff --git a/node_modules/tslint/lib/rules/deprecationRule.d.ts b/node_modules/tslint/lib/rules/deprecationRule.d.ts index b5624e93c..790b1c9e9 100644 --- a/node_modules/tslint/lib/rules/deprecationRule.d.ts +++ b/node_modules/tslint/lib/rules/deprecationRule.d.ts @@ -1,22 +1,7 @@ -/** - * @license - * Copyright 2016 Palantir Technologies, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ import * as ts from "typescript"; import * as Lint from "../index"; export declare class Rule extends Lint.Rules.TypedRule { static metadata: Lint.IRuleMetadata; + static FAILURE_STRING(name: string, message: string): string; applyWithProgram(sourceFile: ts.SourceFile, program: ts.Program): Lint.RuleFailure[]; } 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; diff --git a/node_modules/tslint/lib/rules/encodingRule.js b/node_modules/tslint/lib/rules/encodingRule.js index 776bfc4fe..eda50bfa6 100644 --- a/node_modules/tslint/lib/rules/encodingRule.js +++ b/node_modules/tslint/lib/rules/encodingRule.js @@ -32,18 +32,18 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "encoding", + description: "Enforces UTF-8 file encoding.", + optionsDescription: "Not configurable.", + options: null, + optionExamples: ["true"], + type: "style", + typescriptOnly: false, + }; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "encoding", - description: "Enforces UTF-8 file encoding.", - optionsDescription: "Not configurable.", - options: null, - optionExamples: ["true"], - type: "style", - typescriptOnly: false, -}; exports.Rule = Rule; function walk(ctx) { var encoding = detectEncoding(ctx.sourceFile.fileName); @@ -68,5 +68,6 @@ function detectEncoding(fileName) { var maxBytesRead = 3; // Only need 3 bytes to detect the encoding. var buffer = new Buffer(maxBytesRead); var bytesRead = fs.readSync(fd, buffer, /*offset*/ 0, /*length*/ maxBytesRead, /*position*/ 0); + fs.closeSync(fd); return utils_1.detectBufferEncoding(buffer, bytesRead); } diff --git a/node_modules/tslint/lib/rules/eoflineRule.js b/node_modules/tslint/lib/rules/eoflineRule.js index 92497bbdd..c41ad92b0 100644 --- a/node_modules/tslint/lib/rules/eoflineRule.js +++ b/node_modules/tslint/lib/rules/eoflineRule.js @@ -36,21 +36,21 @@ var Rule = (function (_super) { } return [new Lint.RuleFailure(sourceFile, length, length, Rule.FAILURE_STRING, this.ruleName, fix)]; }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "eofline", + description: "Ensures the file ends with a newline.", + descriptionDetails: "Fix for single-line files is not supported.", + rationale: "It is a [standard convention](http://stackoverflow.com/q/729692/3124288) to end files with a newline.", + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + hasFix: true, + type: "maintainability", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "file should end with a newline"; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "eofline", - description: "Ensures the file ends with a newline.", - descriptionDetails: "Fix for single-line files is not supported.", - rationale: "It is a [standard convention](http://stackoverflow.com/q/729692/3124288) to end files with a newline.", - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - hasFix: true, - type: "maintainability", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "file should end with a newline"; exports.Rule = Rule; diff --git a/node_modules/tslint/lib/rules/fileHeaderRule.js b/node_modules/tslint/lib/rules/fileHeaderRule.js index 8cd3d11eb..ff8a24b62 100644 --- a/node_modules/tslint/lib/rules/fileHeaderRule.js +++ b/node_modules/tslint/lib/rules/fileHeaderRule.js @@ -29,9 +29,7 @@ var Rule = (function (_super) { // ignore shebang if it exists var offset = text.startsWith("#!") ? text.indexOf("\n") : 0; // returns the text of the first comment or undefined - var commentText = ts.forEachLeadingCommentRange(text, offset, function (pos, end, kind) { - return text.substring(pos + 2, kind === ts.SyntaxKind.SingleLineCommentTrivia ? end : end - 2); - }); + var commentText = ts.forEachLeadingCommentRange(text, offset, function (pos, end, kind) { return text.substring(pos + 2, kind === ts.SyntaxKind.SingleLineCommentTrivia ? end : end - 2); }); if (commentText === undefined || !new RegExp(this.ruleArguments[0]).test(commentText)) { if (offset !== 0) { ++offset; // show warning in next line after shebang @@ -40,20 +38,20 @@ var Rule = (function (_super) { } return []; }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "file-header", + description: "Enforces a certain header comment for all files, matched by a regular expression.", + optionsDescription: "Regular expression to match the header.", + options: { + type: "string", + }, + optionExamples: [[true, "Copyright \\d{4}"]], + type: "style", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "missing file header"; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "file-header", - description: "Enforces a certain header comment for all files, matched by a regular expression.", - optionsDescription: "Regular expression to match the header.", - options: { - type: "string", - }, - optionExamples: [[true, "Copyright \\d{4}"]], - type: "style", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "missing file header"; exports.Rule = Rule; diff --git a/node_modules/tslint/lib/rules/forinRule.js b/node_modules/tslint/lib/rules/forinRule.js index cc501fc6a..f33bf3537 100644 --- a/node_modules/tslint/lib/rules/forinRule.js +++ b/node_modules/tslint/lib/rules/forinRule.js @@ -28,21 +28,21 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "forin", + description: "Requires a `for ... in` statement to be filtered with an `if` statement.", + rationale: (_a = ["\n ```ts\n for (let key in someObject) {\n if (someObject.hasOwnProperty(key)) {\n // code here\n }\n }\n ```\n Prevents accidental iteration over properties inherited from an object's prototype.\n See [MDN's `for...in`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in)\n documentation for more information about `for...in` loops."], _a.raw = ["\n \\`\\`\\`ts\n for (let key in someObject) {\n if (someObject.hasOwnProperty(key)) {\n // code here\n }\n }\n \\`\\`\\`\n Prevents accidental iteration over properties inherited from an object's prototype.\n See [MDN's \\`for...in\\`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in)\n documentation for more information about \\`for...in\\` loops."], Lint.Utils.dedent(_a)), + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "functionality", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "for (... in ...) statements must be filtered with an if statement"; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "forin", - description: "Requires a `for ... in` statement to be filtered with an `if` statement.", - rationale: (_a = ["\n ```ts\n for (let key in someObject) {\n if (someObject.hasOwnProperty(key)) {\n // code here\n }\n }\n ```\n Prevents accidental iteration over properties inherited from an object's prototype.\n See [MDN's `for...in`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in)\n documentation for more information about `for...in` loops."], _a.raw = ["\n \\`\\`\\`ts\n for (let key in someObject) {\n if (someObject.hasOwnProperty(key)) {\n // code here\n }\n }\n \\`\\`\\`\n Prevents accidental iteration over properties inherited from an object's prototype.\n See [MDN's \\`for...in\\`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in)\n documentation for more information about \\`for...in\\` loops."], Lint.Utils.dedent(_a)), - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "functionality", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "for (... in ...) statements must be filtered with an if statement"; exports.Rule = Rule; function walk(ctx) { return ts.forEachChild(ctx.sourceFile, function cb(node) { diff --git a/node_modules/tslint/lib/rules/importBlacklistRule.js b/node_modules/tslint/lib/rules/importBlacklistRule.js index 84acf959a..c4bbd7fac 100644 --- a/node_modules/tslint/lib/rules/importBlacklistRule.js +++ b/node_modules/tslint/lib/rules/importBlacklistRule.js @@ -31,26 +31,26 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithWalker(new ImportBlacklistWalker(sourceFile, this.ruleName, this.ruleArguments)); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "import-blacklist", + description: (_a = ["\n Disallows importing the specified modules directly via `import` and `require`.\n Instead only sub modules may be imported from that module."], _a.raw = ["\n Disallows importing the specified modules directly via \\`import\\` and \\`require\\`.\n Instead only sub modules may be imported from that module."], Lint.Utils.dedent(_a)), + rationale: (_b = ["\n Some libraries allow importing their submodules instead of the entire module.\n This is good practise as it avoids loading unused modules."], _b.raw = ["\n Some libraries allow importing their submodules instead of the entire module.\n This is good practise as it avoids loading unused modules."], Lint.Utils.dedent(_b)), + optionsDescription: "A list of blacklisted modules.", + options: { + type: "array", + items: { + type: "string", + }, + minLength: 1, + }, + optionExamples: [true, [true, "rxjs", "lodash"]], + type: "functionality", + typescriptOnly: false, + }; + Rule.FAILURE_STRING = "This import is blacklisted, import a submodule instead"; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "import-blacklist", - description: (_a = ["\n Disallows importing the specified modules directly via `import` and `require`.\n Instead only sub modules may be imported from that module."], _a.raw = ["\n Disallows importing the specified modules directly via \\`import\\` and \\`require\\`.\n Instead only sub modules may be imported from that module."], Lint.Utils.dedent(_a)), - rationale: (_b = ["\n Some libraries allow importing their submodules instead of the entire module.\n This is good practise as it avoids loading unused modules."], _b.raw = ["\n Some libraries allow importing their submodules instead of the entire module.\n This is good practise as it avoids loading unused modules."], Lint.Utils.dedent(_b)), - optionsDescription: "A list of blacklisted modules.", - options: { - type: "array", - items: { - type: "string", - }, - minLength: 1, - }, - optionExamples: [true, [true, "rxjs", "lodash"]], - type: "functionality", - typescriptOnly: false, -}; -Rule.FAILURE_STRING = "This import is blacklisted, import a submodule instead"; exports.Rule = Rule; var ImportBlacklistWalker = (function (_super) { tslib_1.__extends(ImportBlacklistWalker, _super); diff --git a/node_modules/tslint/lib/rules/importSpacingRule.d.ts b/node_modules/tslint/lib/rules/importSpacingRule.d.ts index b1e1f6d7b..ffc41c23b 100644 --- a/node_modules/tslint/lib/rules/importSpacingRule.d.ts +++ b/node_modules/tslint/lib/rules/importSpacingRule.d.ts @@ -1,19 +1,3 @@ -/** - * @license - * Copyright 2017 Palantir Technologies, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ import * as ts from "typescript"; import * as Lint from "../index"; export declare class Rule extends Lint.Rules.AbstractRule { diff --git a/node_modules/tslint/lib/rules/importSpacingRule.js b/node_modules/tslint/lib/rules/importSpacingRule.js index 2794bdfa9..ba3cf601e 100644 --- a/node_modules/tslint/lib/rules/importSpacingRule.js +++ b/node_modules/tslint/lib/rules/importSpacingRule.js @@ -17,87 +17,102 @@ */ 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 LINE_BREAK_REGEX = /\n|\r\n/; +var LINE_BREAK_REGEX = /\r?\n/; var Rule = (function (_super) { tslib_1.__extends(Rule, _super); function Rule() { return _super !== null && _super.apply(this, arguments) || this; } Rule.prototype.apply = function (sourceFile) { - var comparisonWalker = new ImportStatementWalker(sourceFile, this.getOptions()); - return this.applyWithWalker(comparisonWalker); + return this.applyWithWalker(new Walker(sourceFile, this.ruleName, undefined)); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "import-spacing", + description: "Ensures proper spacing between import statement keywords", + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "style", + typescriptOnly: false, + }; + Rule.ADD_SPACE_AFTER_IMPORT = "Add space after 'import'"; + Rule.TOO_MANY_SPACES_AFTER_IMPORT = "Too many spaces after 'import'"; + Rule.ADD_SPACE_AFTER_STAR = "Add space after '*'"; + Rule.TOO_MANY_SPACES_AFTER_STAR = "Too many spaces after '*'"; + Rule.ADD_SPACE_AFTER_FROM = "Add space after 'from'"; + Rule.TOO_MANY_SPACES_AFTER_FROM = "Too many spaces after 'from'"; + Rule.ADD_SPACE_BEFORE_FROM = "Add space before 'from'"; + Rule.TOO_MANY_SPACES_BEFORE_FROM = "Too many spaces before 'from'"; + Rule.NO_LINE_BREAKS = "Line breaks are not allowed in import declaration"; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "import-spacing", - description: "Ensures proper spacing between import statement keywords", - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "style", - typescriptOnly: false, -}; -Rule.ADD_SPACE_AFTER_IMPORT = "Add space after 'import'"; -Rule.TOO_MANY_SPACES_AFTER_IMPORT = "Too many spaces after 'import'"; -Rule.ADD_SPACE_AFTER_STAR = "Add space after '*'"; -Rule.TOO_MANY_SPACES_AFTER_STAR = "Too many spaces after '*'"; -Rule.ADD_SPACE_AFTER_FROM = "Add space after 'from'"; -Rule.TOO_MANY_SPACES_AFTER_FROM = "Too many spaces after 'from'"; -Rule.ADD_SPACE_BEFORE_FROM = "Add space before 'from'"; -Rule.TOO_MANY_SPACES_BEFORE_FROM = "Too many spaces before 'from'"; -Rule.NO_LINE_BREAKS = "Line breaks are not allowed in import declaration"; exports.Rule = Rule; -var ImportStatementWalker = (function (_super) { - tslib_1.__extends(ImportStatementWalker, _super); - function ImportStatementWalker() { +var Walker = (function (_super) { + tslib_1.__extends(Walker, _super); + function Walker() { return _super !== null && _super.apply(this, arguments) || this; } - ImportStatementWalker.prototype.visitImportDeclaration = function (node) { - if (node.importClause === undefined) { - this.checkModuleWithSideEffect(node); - } - else { - var nodeStart = node.getStart(); - var importKeywordEnd = node.getStart() + "import".length; - var moduleSpecifierStart = node.moduleSpecifier.getStart(); - var importClauseEnd = node.importClause.getEnd(); - var importClauseStart = node.importClause.getStart(); - if (importKeywordEnd === importClauseStart) { - this.addFailureAt(nodeStart, "import".length, Rule.ADD_SPACE_AFTER_IMPORT); - } - else if (importClauseStart > (importKeywordEnd + 1)) { - this.addFailureFromStartToEnd(nodeStart, importClauseStart, Rule.TOO_MANY_SPACES_AFTER_IMPORT); - } - var fromString = node.getText().substring(importClauseEnd - nodeStart, moduleSpecifierStart - nodeStart); - if (/from$/.test(fromString)) { - this.addFailureAt(importClauseEnd, fromString.length, Rule.ADD_SPACE_AFTER_FROM); - } - else if (/from\s{2,}$/.test(fromString)) { - this.addFailureAt(importClauseEnd, fromString.length, Rule.TOO_MANY_SPACES_AFTER_FROM); + Walker.prototype.walk = function (_a) { + var statements = _a.statements; + for (var _i = 0, statements_1 = statements; _i < statements_1.length; _i++) { + var statement = statements_1[_i]; + if (!tsutils_1.isImportDeclaration(statement)) { + continue; } - if (/^\s{2,}from/.test(fromString)) { - this.addFailureAt(importClauseEnd, fromString.length, Rule.TOO_MANY_SPACES_BEFORE_FROM); + var importClause = statement.importClause; + if (importClause === undefined) { + this.checkModuleWithSideEffect(statement); } - else if (/^from/.test(fromString)) { - this.addFailureAt(importClauseEnd, fromString.length, Rule.ADD_SPACE_BEFORE_FROM); - } - var text = node.getText(); - var beforeImportClauseText = text.substring(0, importClauseStart - nodeStart); - var afterImportClauseText = text.substring(importClauseEnd - nodeStart); - if (LINE_BREAK_REGEX.test(beforeImportClauseText)) { - this.addFailureFromStartToEnd(nodeStart, importClauseStart - 1, Rule.NO_LINE_BREAKS); - } - if (LINE_BREAK_REGEX.test(afterImportClauseText)) { - this.addFailureFromStartToEnd(importClauseEnd, node.getEnd(), Rule.NO_LINE_BREAKS); + else { + this.checkImportClause(statement, importClause); + var namedBindings = importClause.namedBindings; + if (namedBindings !== undefined && tsutils_1.isNamespaceImport(namedBindings)) { + this.checkNamespaceImport(namedBindings); + } } } - _super.prototype.visitImportDeclaration.call(this, node); }; - ImportStatementWalker.prototype.visitNamespaceImport = function (node) { - var text = node.getText(); + Walker.prototype.checkImportClause = function (node, importClause) { + var text = node.getText(this.sourceFile); + var nodeStart = node.getStart(this.sourceFile); + var importKeywordEnd = nodeStart + "import".length; + var moduleSpecifierStart = node.moduleSpecifier.getStart(this.sourceFile); + var importClauseEnd = importClause.getEnd(); + var importClauseStart = importClause.getStart(this.sourceFile); + if (importKeywordEnd === importClauseStart) { + this.addFailureAt(nodeStart, "import".length, Rule.ADD_SPACE_AFTER_IMPORT); + } + else if (importClauseStart > importKeywordEnd + 1) { + this.addFailure(nodeStart, importClauseStart, Rule.TOO_MANY_SPACES_AFTER_IMPORT); + } + var fromString = text.substring(importClauseEnd - nodeStart, moduleSpecifierStart - nodeStart); + if (/from$/.test(fromString)) { + this.addFailureAt(importClauseEnd, fromString.length, Rule.ADD_SPACE_AFTER_FROM); + } + else if (/from\s{2,}$/.test(fromString)) { + this.addFailureAt(importClauseEnd, fromString.length, Rule.TOO_MANY_SPACES_AFTER_FROM); + } + if (/^\s{2,}from/.test(fromString)) { + this.addFailureAt(importClauseEnd, fromString.length, Rule.TOO_MANY_SPACES_BEFORE_FROM); + } + else if (/^from/.test(fromString)) { + this.addFailureAt(importClauseEnd, fromString.length, Rule.ADD_SPACE_BEFORE_FROM); + } + var beforeImportClauseText = text.substring(0, importClauseStart - nodeStart); + var afterImportClauseText = text.substring(importClauseEnd - nodeStart); + if (LINE_BREAK_REGEX.test(beforeImportClauseText)) { + this.addFailure(nodeStart, importClauseStart - 1, Rule.NO_LINE_BREAKS); + } + if (LINE_BREAK_REGEX.test(afterImportClauseText)) { + this.addFailure(importClauseEnd, node.getEnd(), Rule.NO_LINE_BREAKS); + } + }; + Walker.prototype.checkNamespaceImport = function (node) { + var text = node.getText(this.sourceFile); if (text.indexOf("*as") > -1) { this.addFailureAtNode(node, Rule.ADD_SPACE_AFTER_STAR); } @@ -107,20 +122,19 @@ var ImportStatementWalker = (function (_super) { else if (LINE_BREAK_REGEX.test(text)) { this.addFailureAtNode(node, Rule.NO_LINE_BREAKS); } - _super.prototype.visitNamespaceImport.call(this, node); }; - ImportStatementWalker.prototype.checkModuleWithSideEffect = function (node) { - var moduleSpecifierStart = node.moduleSpecifier.getStart(); - var nodeStart = node.getStart(); - if ((nodeStart + "import".length + 1) < moduleSpecifierStart) { - this.addFailureFromStartToEnd(nodeStart, moduleSpecifierStart, Rule.TOO_MANY_SPACES_AFTER_IMPORT); + Walker.prototype.checkModuleWithSideEffect = function (node) { + var nodeStart = node.getStart(this.sourceFile); + var moduleSpecifierStart = node.moduleSpecifier.getStart(this.sourceFile); + if (nodeStart + "import".length + 1 < moduleSpecifierStart) { + this.addFailure(nodeStart, moduleSpecifierStart, Rule.TOO_MANY_SPACES_AFTER_IMPORT); } - else if ((nodeStart + "import".length) === moduleSpecifierStart) { - this.addFailureAt(nodeStart, "import".length, Rule.ADD_SPACE_AFTER_IMPORT); + else if (nodeStart + "import".length === moduleSpecifierStart) { + this.addFailureAtNode(Lint.childOfKind(node, ts.SyntaxKind.ImportKeyword), Rule.ADD_SPACE_AFTER_IMPORT); } if (LINE_BREAK_REGEX.test(node.getText())) { - this.addFailureAt(nodeStart, node.getWidth(), Rule.NO_LINE_BREAKS); + this.addFailureAtNode(node, Rule.NO_LINE_BREAKS); } }; - return ImportStatementWalker; -}(Lint.RuleWalker)); + return Walker; +}(Lint.AbstractWalker)); diff --git a/node_modules/tslint/lib/rules/indentRule.d.ts b/node_modules/tslint/lib/rules/indentRule.d.ts index 71542b985..49096c1b4 100644 --- a/node_modules/tslint/lib/rules/indentRule.d.ts +++ b/node_modules/tslint/lib/rules/indentRule.d.ts @@ -1,24 +1,7 @@ -/** - * @license - * Copyright 2013 Palantir Technologies, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ import * as ts from "typescript"; import * as Lint from "../index"; export declare class Rule extends Lint.Rules.AbstractRule { static metadata: Lint.IRuleMetadata; - static FAILURE_STRING_TABS: string; - static FAILURE_STRING_SPACES: string; + static FAILURE_STRING(expected: string): string; apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; } diff --git a/node_modules/tslint/lib/rules/indentRule.js b/node_modules/tslint/lib/rules/indentRule.js index 7d133a13b..7aa3459ba 100644 --- a/node_modules/tslint/lib/rules/indentRule.js +++ b/node_modules/tslint/lib/rules/indentRule.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 OPTION_USE_TABS = "tabs"; @@ -28,152 +29,96 @@ var Rule = (function (_super) { function Rule() { return _super !== null && _super.apply(this, arguments) || this; } + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = function (expected) { + return expected + " indentation expected"; + }; Rule.prototype.apply = function (sourceFile) { - return this.applyWithWalker(new IndentWalker(sourceFile, this.getOptions())); + var options = parseOptions(this.ruleArguments); + return options === undefined ? [] : this.applyWithFunction(sourceFile, walk, options); + }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "indent", + description: "Enforces indentation with tabs or spaces.", + rationale: (_a = ["\n Using only one of tabs or spaces for indentation leads to more consistent editor behavior,\n cleaner diffs in version control, and easier programmatic manipulation."], _a.raw = ["\n Using only one of tabs or spaces for indentation leads to more consistent editor behavior,\n cleaner diffs in version control, and easier programmatic manipulation."], Lint.Utils.dedent(_a)), + optionsDescription: (_b = ["\n One of the following arguments must be provided:\n\n * `", "` enforces consistent spaces.\n * `", "` enforces consistent tabs.\n\n A second optional argument specifies indentation size:\n\n * `", "` enforces 2 space indentation.\n * `", "` enforces 4 space indentation.\n\n Indentation size is required for auto-fixing, but not for rule checking.\n "], _b.raw = ["\n One of the following arguments must be provided:\n\n * \\`", "\\` enforces consistent spaces.\n * \\`", "\\` enforces consistent tabs.\n\n A second optional argument specifies indentation size:\n\n * \\`", "\\` enforces 2 space indentation.\n * \\`", "\\` enforces 4 space indentation.\n\n Indentation size is required for auto-fixing, but not for rule checking.\n "], Lint.Utils.dedent(_b, OPTION_USE_SPACES, OPTION_USE_TABS, OPTION_INDENT_SIZE_2.toString(), OPTION_INDENT_SIZE_4.toString())), + options: { + type: "array", + items: [ + { + type: "string", + enum: [OPTION_USE_TABS, OPTION_USE_SPACES], + }, + { + type: "number", + enum: [OPTION_INDENT_SIZE_2, OPTION_INDENT_SIZE_4], + }, + ], + minLength: 0, + maxLength: 5, + }, + optionExamples: [ + [true, OPTION_USE_SPACES], + [true, OPTION_USE_SPACES, OPTION_INDENT_SIZE_4], + [true, OPTION_USE_TABS, OPTION_INDENT_SIZE_2], + ], + type: "maintainability", + typescriptOnly: false, }; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "indent", - description: "Enforces indentation with tabs or spaces.", - rationale: (_a = ["\n Using only one of tabs or spaces for indentation leads to more consistent editor behavior,\n cleaner diffs in version control, and easier programmatic manipulation."], _a.raw = ["\n Using only one of tabs or spaces for indentation leads to more consistent editor behavior,\n cleaner diffs in version control, and easier programmatic manipulation."], Lint.Utils.dedent(_a)), - optionsDescription: (_b = ["\n One of the following arguments must be provided:\n\n * `", "` enforces consistent spaces.\n * `", "` enforces consistent tabs.\n\n A second optional argument specifies indentation size:\n\n * `", "` enforces 2 space indentation.\n * `", "` enforces 4 space indentation.\n\n Indentation size is required for auto-fixing, but not for rule checking.\n "], _b.raw = ["\n One of the following arguments must be provided:\n\n * \\`", "\\` enforces consistent spaces.\n * \\`", "\\` enforces consistent tabs.\n\n A second optional argument specifies indentation size:\n\n * \\`", "\\` enforces 2 space indentation.\n * \\`", "\\` enforces 4 space indentation.\n\n Indentation size is required for auto-fixing, but not for rule checking.\n "], Lint.Utils.dedent(_b, OPTION_USE_SPACES, OPTION_USE_TABS, OPTION_INDENT_SIZE_2.toString(), OPTION_INDENT_SIZE_4.toString())), - options: { - type: "array", - items: [ - { - type: "string", - enum: [OPTION_USE_TABS, OPTION_USE_SPACES], - }, - { - type: "number", - enum: [OPTION_INDENT_SIZE_2, OPTION_INDENT_SIZE_4], - }, - ], - minLength: 0, - maxLength: 5, - }, - optionExamples: [ - [true, OPTION_USE_SPACES], - [true, OPTION_USE_SPACES, OPTION_INDENT_SIZE_4], - [true, OPTION_USE_TABS, OPTION_INDENT_SIZE_2], - ], - type: "maintainability", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING_TABS = "tab indentation expected"; -Rule.FAILURE_STRING_SPACES = "space indentation expected"; exports.Rule = Rule; -// visit every token and enforce that only the right character is used for indentation -var IndentWalker = (function (_super) { - tslib_1.__extends(IndentWalker, _super); - function IndentWalker(sourceFile, options) { - var _this = _super.call(this, sourceFile, options) || this; - // fixer is only provided with the indent size arg - if (_this.getOptions().length === 2 && typeof _this.getOptions()[1] === "number" - && (_this.getOptions()[1] === OPTION_INDENT_SIZE_2 || _this.getOptions()[1] === OPTION_INDENT_SIZE_4)) { - // tslint:disable-next-line:no-unsafe-any - var size_1 = _this.getOptions()[1]; - var replaceRegExp_1; - var replaceIndent_1; - if (_this.hasOption(OPTION_USE_TABS)) { - _this.regExp = new RegExp(" ".repeat(size_1)); - _this.failureString = Rule.FAILURE_STRING_TABS; - // we want to find every group of `size` spaces, plus up to one 'incomplete' group - replaceRegExp_1 = new RegExp("^( {" + size_1 + "})+( {1," + (size_1 - 1) + "})?", "g"); - replaceIndent_1 = "\t"; - } - else if (_this.hasOption(OPTION_USE_SPACES)) { - _this.regExp = new RegExp("\t"); - _this.failureString = size_1 + " " + Rule.FAILURE_STRING_SPACES; - replaceRegExp_1 = new RegExp("\t", "g"); - replaceIndent_1 = " ".repeat(size_1); - } - _this.replacementFactory = function (lineStart, fullLeadingWhitespace) { - return new Lint.Replacement(lineStart, fullLeadingWhitespace.length, fullLeadingWhitespace.replace(replaceRegExp_1, function (match) { return replaceIndent_1.repeat(Math.ceil(match.length / size_1)); })); - }; +function parseOptions(ruleArguments) { + var type = ruleArguments[0]; + if (type !== OPTION_USE_TABS && type !== OPTION_USE_SPACES) { + return undefined; + } + var size = ruleArguments[1]; + return { + size: size === OPTION_INDENT_SIZE_2 || size === OPTION_INDENT_SIZE_4 ? size : undefined, + tabs: type === OPTION_USE_TABS, + }; +} +function walk(ctx) { + var sourceFile = ctx.sourceFile, _a = ctx.options, tabs = _a.tabs, size = _a.size; + var regExp = tabs ? new RegExp(" ".repeat(size === undefined ? 1 : size)) : /\t/; + var failure = Rule.FAILURE_STRING(tabs ? "tab" : size === undefined ? "space" : size + " space"); + for (var _i = 0, _b = tsutils_1.getLineRanges(sourceFile); _i < _b.length; _i++) { + var _c = _b[_i], pos = _c.pos, contentLength = _c.contentLength; + if (contentLength === 0) { + continue; } - else { - if (_this.hasOption(OPTION_USE_TABS)) { - _this.regExp = new RegExp(" "); - _this.failureString = Rule.FAILURE_STRING_TABS; - } - else if (_this.hasOption(OPTION_USE_SPACES)) { - _this.regExp = new RegExp("\t"); - _this.failureString = Rule.FAILURE_STRING_SPACES; - } - _this.replacementFactory = function () { return undefined; }; + var line = sourceFile.text.substr(pos, contentLength); + var indentEnd = line.search(/\S/); + if (indentEnd === 0) { + continue; } - return _this; - } - IndentWalker.prototype.visitSourceFile = function (node) { - if (!this.hasOption(OPTION_USE_TABS) && !this.hasOption(OPTION_USE_SPACES)) { - // if we don't have either option, no need to check anything, and no need to call super, so just return - return; + if (indentEnd === -1) { + indentEnd = contentLength; } - var endOfComment = -1; - var endOfTemplateString = -1; - var scanner = ts.createScanner(ts.ScriptTarget.ES5, false, ts.LanguageVariant.Standard, node.text); - for (var _i = 0, _a = node.getLineStarts(); _i < _a.length; _i++) { - var lineStart = _a[_i]; - if (lineStart < endOfComment || lineStart < endOfTemplateString) { - // skip checking lines inside multi-line comments or template strings - continue; - } - scanner.setTextPos(lineStart); - var currentScannedType = scanner.scan(); - var fullLeadingWhitespace = ""; - var lastStartPos = -1; - while (currentScannedType === ts.SyntaxKind.WhitespaceTrivia) { - var startPos = scanner.getStartPos(); - if (startPos === lastStartPos) { - break; - } - lastStartPos = startPos; - fullLeadingWhitespace += scanner.getTokenText(); - currentScannedType = scanner.scan(); - } - var commentRanges = ts.getTrailingCommentRanges(node.text, lineStart); - if (commentRanges !== undefined) { - endOfComment = commentRanges[commentRanges.length - 1].end; - } - else { - var scanType = currentScannedType; - // scan until we reach end of line, skipping over template strings - while (scanType !== ts.SyntaxKind.NewLineTrivia && scanType !== ts.SyntaxKind.EndOfFileToken) { - if (scanType === ts.SyntaxKind.NoSubstitutionTemplateLiteral) { - // template string without expressions - skip past it - endOfTemplateString = scanner.getStartPos() + scanner.getTokenText().length; - } - else if (scanType === ts.SyntaxKind.TemplateHead) { - // find end of template string containing expressions... - while (scanType !== ts.SyntaxKind.TemplateTail && scanType !== ts.SyntaxKind.EndOfFileToken) { - scanType = scanner.scan(); - if (scanType === ts.SyntaxKind.CloseBraceToken) { - scanType = scanner.reScanTemplateToken(); - } - } - // ... and skip past it - endOfTemplateString = scanner.getStartPos() + scanner.getTokenText().length; - } - scanType = scanner.scan(); - } - } - switch (currentScannedType) { - case ts.SyntaxKind.SingleLineCommentTrivia: - case ts.SyntaxKind.MultiLineCommentTrivia: - case ts.SyntaxKind.NewLineTrivia: - // ignore lines that have comments before the first token - continue; - } - if (this.regExp.test(fullLeadingWhitespace)) { - this.addFailureAt(lineStart, fullLeadingWhitespace.length, this.failureString, this.replacementFactory(lineStart, fullLeadingWhitespace)); - } + var whitespace = line.slice(0, indentEnd); + if (!regExp.test(whitespace)) { + continue; } - // no need to call super to visit the rest of the nodes, so don't call super here - }; - return IndentWalker; -}(Lint.RuleWalker)); + var token = tsutils_1.getTokenAtPosition(sourceFile, pos); + if (token.kind !== ts.SyntaxKind.JsxText && + (pos >= token.getStart(sourceFile) || tsutils_1.isPositionInComment(sourceFile, pos, token))) { + continue; + } + ctx.addFailureAt(pos, indentEnd, failure, createFix(pos, whitespace, tabs, size)); + } +} +function createFix(lineStart, fullLeadingWhitespace, tabs, size) { + if (size === undefined) { + return undefined; + } + var replaceRegExp = tabs + ? new RegExp("^( {" + size + "})+( {1," + (size - 1) + "})?", "g") + : /\t/g; + var replacement = fullLeadingWhitespace.replace(replaceRegExp, function (match) { + return (tabs ? "\t" : " ".repeat(size)).repeat(Math.ceil(match.length / size)); + }); + return new Lint.Replacement(lineStart, fullLeadingWhitespace.length, replacement); +} var _a, _b; diff --git a/node_modules/tslint/lib/rules/interfaceNameRule.js b/node_modules/tslint/lib/rules/interfaceNameRule.js index 4b14a487b..050352bf9 100644 --- a/node_modules/tslint/lib/rules/interfaceNameRule.js +++ b/node_modules/tslint/lib/rules/interfaceNameRule.js @@ -31,25 +31,25 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk, { never: this.ruleArguments.indexOf(OPTION_NEVER) !== -1 }); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "interface-name", + description: "Requires interface names to begin with a capital 'I'", + rationale: "Makes it easy to differentiate interfaces from regular classes at a glance.", + optionsDescription: (_a = ["\n One of the following two options must be provided:\n\n * `\"", "\"` requires interface names to start with an \"I\"\n * `\"", "\"` requires interface names to not have an \"I\" prefix"], _a.raw = ["\n One of the following two options must be provided:\n\n * \\`\"", "\"\\` requires interface names to start with an \"I\"\n * \\`\"", "\"\\` requires interface names to not have an \"I\" prefix"], Lint.Utils.dedent(_a, OPTION_ALWAYS, OPTION_NEVER)), + options: { + type: "string", + enum: [OPTION_ALWAYS, OPTION_NEVER], + }, + optionExamples: [[true, OPTION_ALWAYS], [true, OPTION_NEVER]], + type: "style", + typescriptOnly: true, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "interface name must start with a capitalized I"; + Rule.FAILURE_STRING_NO_PREFIX = 'interface name must not have an "I" prefix'; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "interface-name", - description: "Requires interface names to begin with a capital 'I'", - rationale: "Makes it easy to differentiate interfaces from regular classes at a glance.", - optionsDescription: (_a = ["\n One of the following two options must be provided:\n\n * `\"", "\"` requires interface names to start with an \"I\"\n * `\"", "\"` requires interface names to not have an \"I\" prefix"], _a.raw = ["\n One of the following two options must be provided:\n\n * \\`\"", "\"\\` requires interface names to start with an \"I\"\n * \\`\"", "\"\\` requires interface names to not have an \"I\" prefix"], Lint.Utils.dedent(_a, OPTION_ALWAYS, OPTION_NEVER)), - options: { - type: "string", - enum: [OPTION_ALWAYS, OPTION_NEVER], - }, - optionExamples: [[true, OPTION_ALWAYS], [true, OPTION_NEVER]], - type: "style", - typescriptOnly: true, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "interface name must start with a capitalized I"; -Rule.FAILURE_STRING_NO_PREFIX = 'interface name must not have an "I" prefix'; exports.Rule = Rule; function walk(ctx) { var never = ctx.options.never; diff --git a/node_modules/tslint/lib/rules/interfaceOverTypeLiteralRule.js b/node_modules/tslint/lib/rules/interfaceOverTypeLiteralRule.js index abda0f111..e8da59c1b 100644 --- a/node_modules/tslint/lib/rules/interfaceOverTypeLiteralRule.js +++ b/node_modules/tslint/lib/rules/interfaceOverTypeLiteralRule.js @@ -28,22 +28,22 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "interface-over-type-literal", + description: "Prefer an interface declaration over a type literal (`type T = { ... }`)", + rationale: "Interfaces are generally preferred over type literals because interfaces can be implemented, extended and merged.", + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "style", + typescriptOnly: true, + hasFix: true, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "Use an interface instead of a type literal."; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "interface-over-type-literal", - description: "Prefer an interface declaration over a type literal (`type T = { ... }`)", - rationale: "Interfaces are generally preferred over type literals because interfaces can be implemented, extended and merged.", - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "style", - typescriptOnly: true, - hasFix: true, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "Use an interface instead of a type literal."; exports.Rule = Rule; function walk(ctx) { return ts.forEachChild(ctx.sourceFile, function cb(node) { diff --git a/node_modules/tslint/lib/rules/jsdocFormatRule.js b/node_modules/tslint/lib/rules/jsdocFormatRule.js index f9b4fea19..1359ce867 100644 --- a/node_modules/tslint/lib/rules/jsdocFormatRule.js +++ b/node_modules/tslint/lib/rules/jsdocFormatRule.js @@ -28,23 +28,23 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "jsdoc-format", + description: "Enforces basic format rules for JSDoc comments.", + descriptionDetails: (_a = ["\n The following rules are enforced for JSDoc comments (comments starting with `/**`):\n\n * each line contains an asterisk and asterisks must be aligned\n * each asterisk must be followed by either a space or a newline (except for the first and the last)\n * the only characters before the asterisk on each line must be whitespace characters\n * one line comments must start with `/** ` and end with `*/`"], _a.raw = ["\n The following rules are enforced for JSDoc comments (comments starting with \\`/**\\`):\n\n * each line contains an asterisk and asterisks must be aligned\n * each asterisk must be followed by either a space or a newline (except for the first and the last)\n * the only characters before the asterisk on each line must be whitespace characters\n * one line comments must start with \\`/** \\` and end with \\`*/\\`"], Lint.Utils.dedent(_a)), + rationale: "Helps maintain a consistent, readable style for JSDoc comments.", + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "style", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.ALIGNMENT_FAILURE_STRING = "asterisks in jsdoc must be aligned"; + Rule.FORMAT_FAILURE_STRING = "jsdoc is not formatted correctly on this line"; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "jsdoc-format", - description: "Enforces basic format rules for JSDoc comments.", - descriptionDetails: (_a = ["\n The following rules are enforced for JSDoc comments (comments starting with `/**`):\n\n * each line contains an asterisk and asterisks must be aligned\n * each asterisk must be followed by either a space or a newline (except for the first and the last)\n * the only characters before the asterisk on each line must be whitespace characters\n * one line comments must start with `/** ` and end with `*/`"], _a.raw = ["\n The following rules are enforced for JSDoc comments (comments starting with \\`/**\\`):\n\n * each line contains an asterisk and asterisks must be aligned\n * each asterisk must be followed by either a space or a newline (except for the first and the last)\n * the only characters before the asterisk on each line must be whitespace characters\n * one line comments must start with \\`/** \\` and end with \\`*/\\`"], Lint.Utils.dedent(_a)), - rationale: "Helps maintain a consistent, readable style for JSDoc comments.", - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "style", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.ALIGNMENT_FAILURE_STRING = "asterisks in jsdoc must be aligned"; -Rule.FORMAT_FAILURE_STRING = "jsdoc is not formatted correctly on this line"; exports.Rule = Rule; function walk(ctx) { return utils.forEachComment(ctx.sourceFile, function (fullText, _a) { diff --git a/node_modules/tslint/lib/rules/labelPositionRule.js b/node_modules/tslint/lib/rules/labelPositionRule.js index e90ee4a77..ef961ee4c 100644 --- a/node_modules/tslint/lib/rules/labelPositionRule.js +++ b/node_modules/tslint/lib/rules/labelPositionRule.js @@ -28,22 +28,22 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "label-position", + description: "Only allows labels in sensible locations.", + descriptionDetails: "This rule only allows labels to be on `do/for/while/switch` statements.", + rationale: (_a = ["\n Labels in JavaScript only can be used in conjunction with `break` or `continue`,\n constructs meant to be used for loop flow control. While you can theoretically use\n labels on any block statement in JS, it is considered poor code structure to do so."], _a.raw = ["\n Labels in JavaScript only can be used in conjunction with \\`break\\` or \\`continue\\`,\n constructs meant to be used for loop flow control. While you can theoretically use\n labels on any block statement in JS, it is considered poor code structure to do so."], Lint.Utils.dedent(_a)), + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "functionality", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "unexpected label on statement"; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "label-position", - description: "Only allows labels in sensible locations.", - descriptionDetails: "This rule only allows labels to be on `do/for/while/switch` statements.", - rationale: (_a = ["\n Labels in JavaScript only can be used in conjunction with `break` or `continue`,\n constructs meant to be used for loop flow control. While you can theoretically use\n labels on any block statement in JS, it is considered poor code structure to do so."], _a.raw = ["\n Labels in JavaScript only can be used in conjunction with \\`break\\` or \\`continue\\`,\n constructs meant to be used for loop flow control. While you can theoretically use\n labels on any block statement in JS, it is considered poor code structure to do so."], Lint.Utils.dedent(_a)), - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "functionality", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "unexpected label on statement"; exports.Rule = Rule; function walk(ctx) { return ts.forEachChild(ctx.sourceFile, function cb(node) { diff --git a/node_modules/tslint/lib/rules/linebreakStyleRule.js b/node_modules/tslint/lib/rules/linebreakStyleRule.js index 845438617..fed387732 100644 --- a/node_modules/tslint/lib/rules/linebreakStyleRule.js +++ b/node_modules/tslint/lib/rules/linebreakStyleRule.js @@ -28,25 +28,25 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk, this.ruleArguments.indexOf(OPTION_LINEBREAK_STYLE_CRLF) !== -1); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "linebreak-style", + description: "Enforces a consistent linebreak style.", + optionsDescription: (_a = ["\n One of the following options must be provided:\n\n * `\"", "\"` requires LF (`\\n`) linebreaks\n * `\"", "\"` requires CRLF (`\\r\\n`) linebreaks"], _a.raw = ["\n One of the following options must be provided:\n\n * \\`\"", "\"\\` requires LF (\\`\\\\n\\`) linebreaks\n * \\`\"", "\"\\` requires CRLF (\\`\\\\r\\\\n\\`) linebreaks"], Lint.Utils.dedent(_a, OPTION_LINEBREAK_STYLE_LF, OPTION_LINEBREAK_STYLE_CRLF)), + options: { + type: "string", + enum: [OPTION_LINEBREAK_STYLE_LF, OPTION_LINEBREAK_STYLE_CRLF], + }, + optionExamples: [[true, OPTION_LINEBREAK_STYLE_LF], [true, OPTION_LINEBREAK_STYLE_CRLF]], + type: "maintainability", + typescriptOnly: false, + hasFix: true, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_CRLF = "Expected linebreak to be '" + OPTION_LINEBREAK_STYLE_CRLF + "'"; + Rule.FAILURE_LF = "Expected linebreak to be '" + OPTION_LINEBREAK_STYLE_LF + "'"; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "linebreak-style", - description: "Enforces a consistent linebreak style.", - optionsDescription: (_a = ["\n One of the following options must be provided:\n\n * `\"", "\"` requires LF (`\\n`) linebreaks\n * `\"", "\"` requires CRLF (`\\r\\n`) linebreaks"], _a.raw = ["\n One of the following options must be provided:\n\n * \\`\"", "\"\\` requires LF (\\`\\\\n\\`) linebreaks\n * \\`\"", "\"\\` requires CRLF (\\`\\\\r\\\\n\\`) linebreaks"], Lint.Utils.dedent(_a, OPTION_LINEBREAK_STYLE_LF, OPTION_LINEBREAK_STYLE_CRLF)), - options: { - type: "string", - enum: [OPTION_LINEBREAK_STYLE_LF, OPTION_LINEBREAK_STYLE_CRLF], - }, - optionExamples: [[true, OPTION_LINEBREAK_STYLE_LF], [true, OPTION_LINEBREAK_STYLE_CRLF]], - type: "maintainability", - typescriptOnly: false, - hasFix: true, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_CRLF = "Expected linebreak to be '" + OPTION_LINEBREAK_STYLE_CRLF + "'"; -Rule.FAILURE_LF = "Expected linebreak to be '" + OPTION_LINEBREAK_STYLE_LF + "'"; exports.Rule = Rule; function walk(ctx) { var expectedCr = ctx.options; diff --git a/node_modules/tslint/lib/rules/matchDefaultExportNameRule.js b/node_modules/tslint/lib/rules/matchDefaultExportNameRule.js index 89d961775..06602d375 100644 --- a/node_modules/tslint/lib/rules/matchDefaultExportNameRule.js +++ b/node_modules/tslint/lib/rules/matchDefaultExportNameRule.js @@ -32,19 +32,19 @@ var Rule = (function (_super) { Rule.prototype.applyWithProgram = function (sourceFile, program) { return this.applyWithFunction(sourceFile, function (ctx) { return walk(ctx, program.getTypeChecker()); }); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "match-default-export-name", + description: (_a = ["\n Requires that a default import have the same name as the declaration it imports.\n Does nothing for anonymous default exports."], _a.raw = ["\n Requires that a default import have the same name as the declaration it imports.\n Does nothing for anonymous default exports."], Lint.Utils.dedent(_a)), + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "style", + typescriptOnly: true, + requiresTypeInfo: true, + }; return Rule; }(Lint.Rules.TypedRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "match-default-export-name", - description: (_a = ["\n Requires that a default import have the same name as the declaration it imports.\n Does nothing for anonymous default exports."], _a.raw = ["\n Requires that a default import have the same name as the declaration it imports.\n Does nothing for anonymous default exports."], Lint.Utils.dedent(_a)), - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "style", - typescriptOnly: true, - requiresTypeInfo: true, -}; exports.Rule = Rule; function walk(ctx, tc) { for (var _i = 0, _a = ctx.sourceFile.statements; _i < _a.length; _i++) { diff --git a/node_modules/tslint/lib/rules/maxClassesPerFileRule.js b/node_modules/tslint/lib/rules/maxClassesPerFileRule.js index 0e0ef6c68..c70766a86 100644 --- a/node_modules/tslint/lib/rules/maxClassesPerFileRule.js +++ b/node_modules/tslint/lib/rules/maxClassesPerFileRule.js @@ -35,30 +35,30 @@ var Rule = (function (_super) { var maxClasses = isNaN(argument) || argument > 0 ? argument : 1; return this.applyWithFunction(sourceFile, walk, { maxClasses: maxClasses }); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "max-classes-per-file", + description: (_a = ["\n A file may not contain more than the specified number of classes"], _a.raw = ["\n A file may not contain more than the specified number of classes"], Lint.Utils.dedent(_a)), + rationale: (_b = ["\n Ensures that files have a single responsibility so that that classes each exist in their own files"], _b.raw = ["\n Ensures that files have a single responsibility so that that classes each exist in their own files"], Lint.Utils.dedent(_b)), + optionsDescription: (_c = ["\n The one required argument is an integer indicating the maximum number of classes that can appear in a file."], _c.raw = ["\n The one required argument is an integer indicating the maximum number of classes that can appear in a file."], Lint.Utils.dedent(_c)), + options: { + type: "array", + items: [ + { + type: "number", + minimum: 1, + }, + ], + additionalItems: false, + minLength: 1, + maxLength: 2, + }, + optionExamples: [[true, 1], [true, 5]], + type: "maintainability", + typescriptOnly: false, + }; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "max-classes-per-file", - description: (_a = ["\n A file may not contain more than the specified number of classes"], _a.raw = ["\n A file may not contain more than the specified number of classes"], Lint.Utils.dedent(_a)), - rationale: (_b = ["\n Ensures that files have a single responsibility so that that classes each exist in their own files"], _b.raw = ["\n Ensures that files have a single responsibility so that that classes each exist in their own files"], Lint.Utils.dedent(_b)), - optionsDescription: (_c = ["\n The one required argument is an integer indicating the maximum number of classes that can appear in a file."], _c.raw = ["\n The one required argument is an integer indicating the maximum number of classes that can appear in a file."], Lint.Utils.dedent(_c)), - options: { - type: "array", - items: [ - { - type: "number", - minimum: 1, - }, - ], - additionalItems: false, - minLength: 1, - maxLength: 2, - }, - optionExamples: [[true, 1], [true, 5]], - type: "maintainability", - typescriptOnly: false, -}; exports.Rule = Rule; function walk(ctx) { var sourceFile = ctx.sourceFile, maxClasses = ctx.options.maxClasses; diff --git a/node_modules/tslint/lib/rules/maxFileLineCountRule.js b/node_modules/tslint/lib/rules/maxFileLineCountRule.js index 652a76268..c29761d19 100644 --- a/node_modules/tslint/lib/rules/maxFileLineCountRule.js +++ b/node_modules/tslint/lib/rules/maxFileLineCountRule.js @@ -40,21 +40,21 @@ var Rule = (function (_super) { var len = sourceFile.text.length; return [new Lint.RuleFailure(sourceFile, len - 1, len, Rule.FAILURE_STRING(lineCount, lineLimit), this.ruleName)]; }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "max-file-line-count", + description: "Requires files to remain under a certain number of lines", + rationale: (_a = ["\n Limiting the number of lines allowed in a file allows files to remain small,\n single purpose, and maintainable."], _a.raw = ["\n Limiting the number of lines allowed in a file allows files to remain small,\n single purpose, and maintainable."], Lint.Utils.dedent(_a)), + optionsDescription: "An integer indicating the maximum number of lines.", + options: { + type: "number", + minimum: "1", + }, + optionExamples: [[true, 300]], + type: "maintainability", + typescriptOnly: false, + }; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "max-file-line-count", - description: "Requires files to remain under a certain number of lines", - rationale: (_a = ["\n Limiting the number of lines allowed in a file allows files to remain small,\n single purpose, and maintainable."], _a.raw = ["\n Limiting the number of lines allowed in a file allows files to remain small,\n single purpose, and maintainable."], Lint.Utils.dedent(_a)), - optionsDescription: "An integer indicating the maximum number of lines.", - options: { - type: "number", - minimum: "1", - }, - optionExamples: [[true, 300]], - type: "maintainability", - typescriptOnly: false, -}; exports.Rule = Rule; var _a; diff --git a/node_modules/tslint/lib/rules/maxLineLengthRule.js b/node_modules/tslint/lib/rules/maxLineLengthRule.js index dc9b89dc8..5324c073c 100644 --- a/node_modules/tslint/lib/rules/maxLineLengthRule.js +++ b/node_modules/tslint/lib/rules/maxLineLengthRule.js @@ -34,22 +34,22 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk, this.ruleArguments[0]); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "max-line-length", + description: "Requires lines to be under a certain max length.", + rationale: (_a = ["\n Limiting the length of a line of code improves code readability.\n It also makes comparing code side-by-side easier and improves compatibility with\n various editors, IDEs, and diff viewers."], _a.raw = ["\n Limiting the length of a line of code improves code readability.\n It also makes comparing code side-by-side easier and improves compatibility with\n various editors, IDEs, and diff viewers."], Lint.Utils.dedent(_a)), + optionsDescription: "An integer indicating the max length of lines.", + options: { + type: "number", + minimum: "1", + }, + optionExamples: [[true, 120]], + type: "maintainability", + typescriptOnly: false, + }; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "max-line-length", - description: "Requires lines to be under a certain max length.", - rationale: (_a = ["\n Limiting the length of a line of code improves code readability.\n It also makes comparing code side-by-side easier and improves compatibility with\n various editors, IDEs, and diff viewers."], _a.raw = ["\n Limiting the length of a line of code improves code readability.\n It also makes comparing code side-by-side easier and improves compatibility with\n various editors, IDEs, and diff viewers."], Lint.Utils.dedent(_a)), - optionsDescription: "An integer indicating the max length of lines.", - options: { - type: "number", - minimum: "1", - }, - optionExamples: [[true, 120]], - type: "maintainability", - typescriptOnly: false, -}; exports.Rule = Rule; function walk(ctx) { var limit = ctx.options; diff --git a/node_modules/tslint/lib/rules/memberAccessRule.js b/node_modules/tslint/lib/rules/memberAccessRule.js index c25b3826a..2143f15d4 100644 --- a/node_modules/tslint/lib/rules/memberAccessRule.js +++ b/node_modules/tslint/lib/rules/memberAccessRule.js @@ -19,6 +19,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var tsutils_1 = require("tsutils"); var ts = require("typescript"); +var error_1 = require("../error"); var Lint = require("../index"); var OPTION_NO_PUBLIC = "no-public"; var OPTION_CHECK_ACCESSOR = "check-accessor"; @@ -39,37 +40,44 @@ var Rule = (function (_super) { var checkConstructor = options.indexOf(OPTION_CHECK_CONSTRUCTOR) !== -1; if (noPublic) { if (checkAccessor || checkConstructor) { - throw new Error("If 'no-public' is present, it should be the only option."); + error_1.showWarningOnce("Warning: " + this.ruleName + " - If 'no-public' is present, it should be the only option."); + return []; } checkAccessor = checkConstructor = true; } - return this.applyWithFunction(sourceFile, function (ctx) { return walk(ctx, noPublic, checkAccessor, checkConstructor); }); + return this.applyWithFunction(sourceFile, walk, { + checkAccessor: checkAccessor, + checkConstructor: checkConstructor, + noPublic: noPublic, + }); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "member-access", + description: "Requires explicit visibility declarations for class members.", + rationale: "Explicit visibility declarations can make code more readable and accessible for those new to TS.", + optionsDescription: (_a = ["\n These arguments may be optionally provided:\n\n * `\"no-public\"` forbids public accessibility to be specified, because this is the default.\n * `\"check-accessor\"` enforces explicit visibility on get/set accessors\n * `\"check-constructor\"` enforces explicit visibility on constructors"], _a.raw = ["\n These arguments may be optionally provided:\n\n * \\`\"no-public\"\\` forbids public accessibility to be specified, because this is the default.\n * \\`\"check-accessor\"\\` enforces explicit visibility on get/set accessors\n * \\`\"check-constructor\"\\` enforces explicit visibility on constructors"], Lint.Utils.dedent(_a)), + options: { + type: "array", + items: { + type: "string", + enum: [OPTION_NO_PUBLIC, OPTION_CHECK_ACCESSOR, OPTION_CHECK_CONSTRUCTOR], + }, + minLength: 0, + maxLength: 3, + }, + optionExamples: [true, [true, OPTION_NO_PUBLIC], [true, OPTION_CHECK_ACCESSOR]], + type: "typescript", + typescriptOnly: true, + hasFix: true, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING_NO_PUBLIC = "'public' is implicit."; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "member-access", - description: "Requires explicit visibility declarations for class members.", - rationale: "Explicit visibility declarations can make code more readable and accessible for those new to TS.", - optionsDescription: (_a = ["\n These arguments may be optionally provided:\n\n * `\"no-public\"` forbids public accessibility to be specified, because this is the default.\n * `\"check-accessor\"` enforces explicit visibility on get/set accessors\n * `\"check-constructor\"` enforces explicit visibility on constructors"], _a.raw = ["\n These arguments may be optionally provided:\n\n * \\`\"no-public\"\\` forbids public accessibility to be specified, because this is the default.\n * \\`\"check-accessor\"\\` enforces explicit visibility on get/set accessors\n * \\`\"check-constructor\"\\` enforces explicit visibility on constructors"], Lint.Utils.dedent(_a)), - options: { - type: "array", - items: { - type: "string", - enum: [OPTION_NO_PUBLIC, OPTION_CHECK_ACCESSOR, OPTION_CHECK_CONSTRUCTOR], - }, - minLength: 0, - maxLength: 3, - }, - optionExamples: [true, [true, OPTION_NO_PUBLIC], [true, OPTION_CHECK_ACCESSOR]], - type: "typescript", - typescriptOnly: true, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING_NO_PUBLIC = "'public' is implicit."; exports.Rule = Rule; -function walk(ctx, noPublic, checkAccessor, checkConstructor) { +function walk(ctx) { + var _a = ctx.options, noPublic = _a.noPublic, checkAccessor = _a.checkAccessor, checkConstructor = _a.checkConstructor; return ts.forEachChild(ctx.sourceFile, function recur(node) { if (tsutils_1.isClassLikeDeclaration(node)) { for (var _i = 0, _a = node.members; _i < _a.length; _i++) { @@ -99,21 +107,21 @@ function walk(ctx, noPublic, checkAccessor, checkConstructor) { if (Lint.hasModifier(node.modifiers, ts.SyntaxKind.ProtectedKeyword, ts.SyntaxKind.PrivateKeyword)) { return; } - var isPublic = Lint.hasModifier(node.modifiers, ts.SyntaxKind.PublicKeyword); - if (noPublic && isPublic) { - var publicKeyword = node.modifiers.find(function (m) { return m.kind === ts.SyntaxKind.PublicKeyword; }); - ctx.addFailureAtNode(publicKeyword, Rule.FAILURE_STRING_NO_PUBLIC); + var publicKeyword = tsutils_1.getModifier(node, ts.SyntaxKind.PublicKeyword); + if (noPublic && publicKeyword !== undefined) { + var start = publicKeyword.end - "public".length; + ctx.addFailure(start, publicKeyword.end, Rule.FAILURE_STRING_NO_PUBLIC, Lint.Replacement.deleteFromTo(start, tsutils_1.getNextToken(publicKeyword, ctx.sourceFile).getStart(ctx.sourceFile))); } - if (!noPublic && !isPublic) { - var nameNode = tsutils_1.isConstructorDeclaration(node) - ? tsutils_1.getChildOfKind(node, ts.SyntaxKind.ConstructorKeyword) + if (!noPublic && publicKeyword === undefined) { + var nameNode = node.kind === ts.SyntaxKind.Constructor + ? tsutils_1.getChildOfKind(node, ts.SyntaxKind.ConstructorKeyword, ctx.sourceFile) : node.name !== undefined ? node.name : node; - var memberName = node.name !== undefined && tsutils_1.isIdentifier(node.name) ? node.name.text : undefined; - ctx.addFailureAtNode(nameNode, Rule.FAILURE_STRING_FACTORY(memberType(node), memberName)); + var memberName = node.name !== undefined && node.name.kind === ts.SyntaxKind.Identifier ? node.name.text : undefined; + ctx.addFailureAtNode(nameNode, Rule.FAILURE_STRING_FACTORY(typeToString(node), memberName), Lint.Replacement.appendText(node.getStart(ctx.sourceFile), "public ")); } } } -function memberType(node) { +function typeToString(node) { switch (node.kind) { case ts.SyntaxKind.MethodDeclaration: return "class method"; diff --git a/node_modules/tslint/lib/rules/memberOrderingRule.js b/node_modules/tslint/lib/rules/memberOrderingRule.js index e7a27dcf9..c96c89e80 100644 --- a/node_modules/tslint/lib/rules/memberOrderingRule.js +++ b/node_modules/tslint/lib/rules/memberOrderingRule.js @@ -18,6 +18,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var ts = require("typescript"); +var error_1 = require("../error"); var Lint = require("../index"); var utils_1 = require("../utils"); var OPTION_ORDER = "order"; @@ -109,68 +110,76 @@ var Rule = (function (_super) { }; /* tslint:enable:object-literal-sort-keys */ Rule.prototype.apply = function (sourceFile) { - return this.applyWithWalker(new MemberOrderingWalker(sourceFile, this.ruleName, parseOptions(this.ruleArguments))); + var options; + try { + options = parseOptions(this.ruleArguments); + } + catch (e) { + error_1.showWarningOnce("Warning: " + this.ruleName + " - " + e.message); + return []; + } + return this.applyWithWalker(new MemberOrderingWalker(sourceFile, this.ruleName, options)); }; - return Rule; -}(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "member-ordering", - description: "Enforces member ordering.", - rationale: "A consistent ordering for class members can make classes easier to read, navigate, and edit.", - optionsDescription: optionsDescription, - options: { - type: "object", - properties: { - order: { - oneOf: [ - { - type: "string", - enum: PRESET_NAMES, - }, - { - type: "array", - items: { + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "member-ordering", + description: "Enforces member ordering.", + rationale: "A consistent ordering for class members can make classes easier to read, navigate, and edit.", + optionsDescription: optionsDescription, + options: { + type: "object", + properties: { + order: { + oneOf: [ + { type: "string", - enum: allMemberKindNames, + enum: PRESET_NAMES, + }, + { + type: "array", + items: { + type: "string", + enum: allMemberKindNames, + }, + maxLength: 13, }, - maxLength: 13, - }, - ], + ], + }, }, + additionalProperties: false, }, - additionalProperties: false, - }, - optionExamples: [ - [true, { order: "fields-first" }], - [true, { - order: [ - "static-field", - "instance-field", - "constructor", - "public-instance-method", - "protected-instance-method", - "private-instance-method", - ], - }], - [true, { - order: [ - { - name: "static non-private", - kinds: [ - "public-static-field", - "protected-static-field", - "public-static-method", - "protected-static-method", - ], - }, - "constructor", - ], - }], - ], - type: "typescript", - typescriptOnly: false, -}; + optionExamples: [ + [true, { order: "fields-first" }], + [true, { + order: [ + "static-field", + "instance-field", + "constructor", + "public-instance-method", + "protected-instance-method", + "private-instance-method", + ], + }], + [true, { + order: [ + { + name: "static non-private", + kinds: [ + "public-static-field", + "protected-static-field", + "public-static-method", + "protected-static-method", + ], + }, + "constructor", + ], + }], + ], + type: "typescript", + typescriptOnly: false, + }; + return Rule; +}(Lint.Rules.AbstractRule)); exports.Rule = Rule; var MemberOrderingWalker = (function (_super) { tslib_1.__extends(MemberOrderingWalker, _super); diff --git a/node_modules/tslint/lib/rules/newParensRule.js b/node_modules/tslint/lib/rules/newParensRule.js index 57144f35c..e207cedc6 100644 --- a/node_modules/tslint/lib/rules/newParensRule.js +++ b/node_modules/tslint/lib/rules/newParensRule.js @@ -27,21 +27,21 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "new-parens", + description: "Requires parentheses when invoking a constructor via the `new` keyword.", + rationale: "Maintains stylistic consistency with other function calls.", + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "style", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "Parentheses are required when invoking a constructor"; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "new-parens", - description: "Requires parentheses when invoking a constructor via the `new` keyword.", - rationale: "Maintains stylistic consistency with other function calls.", - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "style", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "Parentheses are required when invoking a constructor"; exports.Rule = Rule; function walk(ctx) { return ts.forEachChild(ctx.sourceFile, function cb(node) { diff --git a/node_modules/tslint/lib/rules/newlineBeforeReturnRule.js b/node_modules/tslint/lib/rules/newlineBeforeReturnRule.js index 40aac0f39..50d353457 100644 --- a/node_modules/tslint/lib/rules/newlineBeforeReturnRule.js +++ b/node_modules/tslint/lib/rules/newlineBeforeReturnRule.js @@ -28,21 +28,21 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithWalker(new NewlineBeforeReturnWalker(sourceFile, this.ruleName, undefined)); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "newline-before-return", + description: "Enforces blank line before return when not the only line in the block.", + rationale: "Helps maintain a readable style in your codebase.", + optionsDescription: "Not configurable.", + options: {}, + optionExamples: [true], + type: "style", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "Missing blank line before return"; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "newline-before-return", - description: "Enforces blank line before return when not the only line in the block.", - rationale: "Helps maintain a readable style in your codebase.", - optionsDescription: "Not configurable.", - options: {}, - optionExamples: [true], - type: "style", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "Missing blank line before return"; exports.Rule = Rule; var NewlineBeforeReturnWalker = (function (_super) { tslib_1.__extends(NewlineBeforeReturnWalker, _super); diff --git a/node_modules/tslint/lib/rules/noAngleBracketTypeAssertionRule.js b/node_modules/tslint/lib/rules/noAngleBracketTypeAssertionRule.js index 9031694f9..9cf180943 100644 --- a/node_modules/tslint/lib/rules/noAngleBracketTypeAssertionRule.js +++ b/node_modules/tslint/lib/rules/noAngleBracketTypeAssertionRule.js @@ -28,22 +28,22 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-angle-bracket-type-assertion", + description: "Requires the use of `as Type` for type assertions instead of `<Type>`.", + hasFix: true, + rationale: (_a = ["\n Both formats of type assertions have the same effect, but only `as` type assertions\n work in `.tsx` files. This rule ensures that you have a consistent type assertion style\n across your codebase."], _a.raw = ["\n Both formats of type assertions have the same effect, but only \\`as\\` type assertions\n work in \\`.tsx\\` files. This rule ensures that you have a consistent type assertion style\n across your codebase."], Lint.Utils.dedent(_a)), + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "style", + typescriptOnly: true, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "Type assertion using the '<>' syntax is forbidden. Use the 'as' syntax instead."; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-angle-bracket-type-assertion", - description: "Requires the use of `as Type` for type assertions instead of `<Type>`.", - hasFix: true, - rationale: (_a = ["\n Both formats of type assertions have the same effect, but only `as` type assertions\n work in `.tsx` files. This rule ensures that you have a consistent type assertion style\n across your codebase."], _a.raw = ["\n Both formats of type assertions have the same effect, but only \\`as\\` type assertions\n work in \\`.tsx\\` files. This rule ensures that you have a consistent type assertion style\n across your codebase."], Lint.Utils.dedent(_a)), - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "style", - typescriptOnly: true, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "Type assertion using the '<>' syntax is forbidden. Use the 'as' syntax instead."; exports.Rule = Rule; function walk(ctx) { return ts.forEachChild(ctx.sourceFile, function cb(node) { diff --git a/node_modules/tslint/lib/rules/noAnyRule.js b/node_modules/tslint/lib/rules/noAnyRule.js index d2e6ecdd7..939311248 100644 --- a/node_modules/tslint/lib/rules/noAnyRule.js +++ b/node_modules/tslint/lib/rules/noAnyRule.js @@ -27,25 +27,24 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-any", + description: "Disallows usages of `any` as a type declaration.", + hasFix: false, + rationale: "Using `any` as a type declaration nullifies the compile-time benefits of the type system.", + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "typescript", + typescriptOnly: true, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "Type declaration of 'any' loses type-safety. " + + "Consider replacing it with a more precise type, the empty type ('{}'), " + + "or suppress this occurrence."; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-any", - description: "Disallows usages of `any` as a type declaration.", - hasFix: true, - rationale: "Using `any` as a type declaration nullifies the compile-time benefits of the type system.", - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "typescript", - typescriptOnly: true, -}; -/* tslint:enable:object-literal-sort-keys */ -// tslint:disable-next-line prefer-template (fixed in 5.3) -Rule.FAILURE_STRING = "Type declaration of 'any' loses type-safety. " + - "Consider replacing it with a more precise type, the empty type ('{}'), " + - "or suppress this occurrence."; exports.Rule = Rule; function walk(ctx) { return ts.forEachChild(ctx.sourceFile, function cb(node) { diff --git a/node_modules/tslint/lib/rules/noArgRule.js b/node_modules/tslint/lib/rules/noArgRule.js index dda96d720..dc8a47aaa 100644 --- a/node_modules/tslint/lib/rules/noArgRule.js +++ b/node_modules/tslint/lib/rules/noArgRule.js @@ -28,21 +28,21 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-arg", + description: "Disallows use of `arguments.callee`.", + rationale: (_a = ["\n Using `arguments.callee` makes various performance optimizations impossible.\n See [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments/callee)\n for more details on why to avoid `arguments.callee`."], _a.raw = ["\n Using \\`arguments.callee\\` makes various performance optimizations impossible.\n See [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments/callee)\n for more details on why to avoid \\`arguments.callee\\`."], Lint.Utils.dedent(_a)), + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "functionality", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "Access to arguments.callee is forbidden"; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-arg", - description: "Disallows use of `arguments.callee`.", - rationale: (_a = ["\n Using `arguments.callee` makes various performance optimizations impossible.\n See [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments/callee)\n for more details on why to avoid `arguments.callee`."], _a.raw = ["\n Using \\`arguments.callee\\` makes various performance optimizations impossible.\n See [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments/callee)\n for more details on why to avoid \\`arguments.callee\\`."], Lint.Utils.dedent(_a)), - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "functionality", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "Access to arguments.callee is forbidden"; exports.Rule = Rule; function walk(ctx) { return ts.forEachChild(ctx.sourceFile, function cb(node) { diff --git a/node_modules/tslint/lib/rules/noBitwiseRule.js b/node_modules/tslint/lib/rules/noBitwiseRule.js index cfb75db1d..0d9d7ff85 100644 --- a/node_modules/tslint/lib/rules/noBitwiseRule.js +++ b/node_modules/tslint/lib/rules/noBitwiseRule.js @@ -27,22 +27,22 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-bitwise", + description: "Disallows bitwise operators.", + descriptionDetails: (_a = ["\n Specifically, the following bitwise operators are banned:\n `&`, `&=`, `|`, `|=`,\n `^`, `^=`, `<<`, `<<=`,\n `>>`, `>>=`, `>>>`, `>>>=`, and `~`.\n This rule does not ban the use of `&` and `|` for intersection and union types."], _a.raw = ["\n Specifically, the following bitwise operators are banned:\n \\`&\\`, \\`&=\\`, \\`|\\`, \\`|=\\`,\n \\`^\\`, \\`^=\\`, \\`<<\\`, \\`<<=\\`,\n \\`>>\\`, \\`>>=\\`, \\`>>>\\`, \\`>>>=\\`, and \\`~\\`.\n This rule does not ban the use of \\`&\\` and \\`|\\` for intersection and union types."], Lint.Utils.dedent(_a)), + rationale: (_b = ["\n Bitwise operators are often typos - for example `bool1 & bool2` instead of `bool1 && bool2`.\n They also can be an indicator of overly clever code which decreases maintainability."], _b.raw = ["\n Bitwise operators are often typos - for example \\`bool1 & bool2\\` instead of \\`bool1 && bool2\\`.\n They also can be an indicator of overly clever code which decreases maintainability."], Lint.Utils.dedent(_b)), + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "functionality", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "Forbidden bitwise operation"; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-bitwise", - description: "Disallows bitwise operators.", - descriptionDetails: (_a = ["\n Specifically, the following bitwise operators are banned:\n `&`, `&=`, `|`, `|=`,\n `^`, `^=`, `<<`, `<<=`,\n `>>`, `>>=`, `>>>`, `>>>=`, and `~`.\n This rule does not ban the use of `&` and `|` for intersection and union types."], _a.raw = ["\n Specifically, the following bitwise operators are banned:\n \\`&\\`, \\`&=\\`, \\`|\\`, \\`|=\\`,\n \\`^\\`, \\`^=\\`, \\`<<\\`, \\`<<=\\`,\n \\`>>\\`, \\`>>=\\`, \\`>>>\\`, \\`>>>=\\`, and \\`~\\`.\n This rule does not ban the use of \\`&\\` and \\`|\\` for intersection and union types."], Lint.Utils.dedent(_a)), - rationale: (_b = ["\n Bitwise operators are often typos - for example `bool1 & bool2` instead of `bool1 && bool2`.\n They also can be an indicator of overly clever code which decreases maintainability."], _b.raw = ["\n Bitwise operators are often typos - for example \\`bool1 & bool2\\` instead of \\`bool1 && bool2\\`.\n They also can be an indicator of overly clever code which decreases maintainability."], Lint.Utils.dedent(_b)), - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "functionality", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "Forbidden bitwise operation"; exports.Rule = Rule; function walk(ctx) { return ts.forEachChild(ctx.sourceFile, function cb(node) { diff --git a/node_modules/tslint/lib/rules/noBooleanLiteralCompareRule.js b/node_modules/tslint/lib/rules/noBooleanLiteralCompareRule.js index 23cef48d5..8501972f2 100644 --- a/node_modules/tslint/lib/rules/noBooleanLiteralCompareRule.js +++ b/node_modules/tslint/lib/rules/noBooleanLiteralCompareRule.js @@ -32,20 +32,20 @@ var Rule = (function (_super) { Rule.prototype.applyWithProgram = function (sourceFile, program) { return this.applyWithFunction(sourceFile, function (ctx) { return walk(ctx, program.getTypeChecker()); }); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-boolean-literal-compare", + description: "Warns on comparison to a boolean literal, as in `x === true`.", + hasFix: true, + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "style", + typescriptOnly: true, + requiresTypeInfo: true, + }; return Rule; }(Lint.Rules.TypedRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-boolean-literal-compare", - description: "Warns on comparison to a boolean literal, as in `x === true`.", - hasFix: true, - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "style", - typescriptOnly: true, - requiresTypeInfo: true, -}; exports.Rule = Rule; function walk(ctx, checker) { return ts.forEachChild(ctx.sourceFile, function cb(node) { diff --git a/node_modules/tslint/lib/rules/noConditionalAssignmentRule.js b/node_modules/tslint/lib/rules/noConditionalAssignmentRule.js index 3384b8b29..cefa22d89 100644 --- a/node_modules/tslint/lib/rules/noConditionalAssignmentRule.js +++ b/node_modules/tslint/lib/rules/noConditionalAssignmentRule.js @@ -28,22 +28,22 @@ var Rule = (function (_super) { var walker = new NoConditionalAssignmentWalker(sourceFile, this.getOptions()); return this.applyWithWalker(walker); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-conditional-assignment", + description: "Disallows any type of assignment in conditionals.", + descriptionDetails: "This applies to `do-while`, `for`, `if`, and `while` statements.", + rationale: (_a = ["\n Assignments in conditionals are often typos:\n for example `if (var1 = var2)` instead of `if (var1 == var2)`.\n They also can be an indicator of overly clever code which decreases maintainability."], _a.raw = ["\n Assignments in conditionals are often typos:\n for example \\`if (var1 = var2)\\` instead of \\`if (var1 == var2)\\`.\n They also can be an indicator of overly clever code which decreases maintainability."], Lint.Utils.dedent(_a)), + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "functionality", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "Assignments in conditional expressions are forbidden"; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-conditional-assignment", - description: "Disallows any type of assignment in conditionals.", - descriptionDetails: "This applies to `do-while`, `for`, `if`, and `while` statements.", - rationale: (_a = ["\n Assignments in conditionals are often typos:\n for example `if (var1 = var2)` instead of `if (var1 == var2)`.\n They also can be an indicator of overly clever code which decreases maintainability."], _a.raw = ["\n Assignments in conditionals are often typos:\n for example \\`if (var1 = var2)\\` instead of \\`if (var1 == var2)\\`.\n They also can be an indicator of overly clever code which decreases maintainability."], Lint.Utils.dedent(_a)), - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "functionality", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "Assignments in conditional expressions are forbidden"; exports.Rule = Rule; var NoConditionalAssignmentWalker = (function (_super) { tslib_1.__extends(NoConditionalAssignmentWalker, _super); diff --git a/node_modules/tslint/lib/rules/noConsecutiveBlankLinesRule.js b/node_modules/tslint/lib/rules/noConsecutiveBlankLinesRule.js index b97668024..544e5b309 100644 --- a/node_modules/tslint/lib/rules/noConsecutiveBlankLinesRule.js +++ b/node_modules/tslint/lib/rules/noConsecutiveBlankLinesRule.js @@ -42,24 +42,24 @@ var Rule = (function (_super) { var limit = this.ruleArguments[0]; return this.applyWithFunction(sourceFile, walk, limit !== undefined ? limit : Rule.DEFAULT_ALLOWED_BLANKS); }; + Rule.DEFAULT_ALLOWED_BLANKS = 1; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-consecutive-blank-lines", + description: "Disallows one or more blank lines in a row.", + hasFix: true, + rationale: "Helps maintain a readable style in your codebase.", + optionsDescription: (_a = ["\n An optional number of maximum allowed sequential blanks can be specified. If no value\n is provided, a default of ", " will be used."], _a.raw = ["\n An optional number of maximum allowed sequential blanks can be specified. If no value\n is provided, a default of ", " will be used."], Lint.Utils.dedent(_a, Rule.DEFAULT_ALLOWED_BLANKS)), + options: { + type: "number", + minimum: "1", + }, + optionExamples: [true, [true, 2]], + type: "style", + typescriptOnly: false, + }; return Rule; }(Lint.Rules.AbstractRule)); -Rule.DEFAULT_ALLOWED_BLANKS = 1; -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-consecutive-blank-lines", - description: "Disallows one or more blank lines in a row.", - hasFix: true, - rationale: "Helps maintain a readable style in your codebase.", - optionsDescription: (_a = ["\n An optional number of maximum allowed sequential blanks can be specified. If no value\n is provided, a default of $(Rule.DEFAULT_ALLOWED_BLANKS) will be used."], _a.raw = ["\n An optional number of maximum allowed sequential blanks can be specified. If no value\n is provided, a default of $(Rule.DEFAULT_ALLOWED_BLANKS) will be used."], Lint.Utils.dedent(_a)), - options: { - type: "number", - minimum: "$(Rule.MINIMUM_ALLOWED_BLANKS)", - }, - optionExamples: [true, [true, 2]], - type: "style", - typescriptOnly: false, -}; exports.Rule = Rule; function walk(ctx) { var sourceText = ctx.sourceFile.text; diff --git a/node_modules/tslint/lib/rules/noConsoleRule.js b/node_modules/tslint/lib/rules/noConsoleRule.js index 9e5e394f9..506a017cf 100644 --- a/node_modules/tslint/lib/rules/noConsoleRule.js +++ b/node_modules/tslint/lib/rules/noConsoleRule.js @@ -32,22 +32,22 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk, this.ruleArguments); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-console", + description: "Bans the use of specified `console` methods.", + rationale: "In general, \`console\` methods aren't appropriate for production code.", + optionsDescription: "A list of method names to ban. If no method names are provided, all console methods are banned.", + options: { + type: "array", + items: { type: "string" }, + }, + optionExamples: [[true, "log", "error"]], + type: "functionality", + typescriptOnly: false, + }; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-console", - description: "Bans the use of specified `console` methods.", - rationale: "In general, \`console\` methods aren't appropriate for production code.", - optionsDescription: "A list of method names to ban. If no method names are provided, all console methods are banned.", - options: { - type: "array", - items: { type: "string" }, - }, - optionExamples: [[true, "log", "error"]], - type: "functionality", - typescriptOnly: false, -}; exports.Rule = Rule; function walk(ctx) { return ts.forEachChild(ctx.sourceFile, function cb(node) { diff --git a/node_modules/tslint/lib/rules/noConstructRule.js b/node_modules/tslint/lib/rules/noConstructRule.js index 967a0adb5..a7fccceaa 100644 --- a/node_modules/tslint/lib/rules/noConstructRule.js +++ b/node_modules/tslint/lib/rules/noConstructRule.js @@ -28,22 +28,22 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-construct", + description: "Disallows access to the constructors of `String`, `Number`, and `Boolean`.", + descriptionDetails: "Disallows constructor use such as `new Number(foo)` but does not disallow `Number(foo)`.", + rationale: (_a = ["\n There is little reason to use `String`, `Number`, or `Boolean` as constructors.\n In almost all cases, the regular function-call version is more appropriate.\n [More details](http://stackoverflow.com/q/4719320/3124288) are available on StackOverflow."], _a.raw = ["\n There is little reason to use \\`String\\`, \\`Number\\`, or \\`Boolean\\` as constructors.\n In almost all cases, the regular function-call version is more appropriate.\n [More details](http://stackoverflow.com/q/4719320/3124288) are available on StackOverflow."], Lint.Utils.dedent(_a)), + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "functionality", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "Forbidden constructor, use a literal or simple function call instead"; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-construct", - description: "Disallows access to the constructors of `String`, `Number`, and `Boolean`.", - descriptionDetails: "Disallows constructor use such as `new Number(foo)` but does not disallow `Number(foo)`.", - rationale: (_a = ["\n There is little reason to use `String`, `Number`, or `Boolean` as constructors.\n In almost all cases, the regular function-call version is more appropriate.\n [More details](http://stackoverflow.com/q/4719320/3124288) are available on StackOverflow."], _a.raw = ["\n There is little reason to use \\`String\\`, \\`Number\\`, or \\`Boolean\\` as constructors.\n In almost all cases, the regular function-call version is more appropriate.\n [More details](http://stackoverflow.com/q/4719320/3124288) are available on StackOverflow."], Lint.Utils.dedent(_a)), - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "functionality", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "Forbidden constructor, use a literal or simple function call instead"; exports.Rule = Rule; function walk(ctx) { return ts.forEachChild(ctx.sourceFile, function cb(node) { diff --git a/node_modules/tslint/lib/rules/noDebuggerRule.js b/node_modules/tslint/lib/rules/noDebuggerRule.js index 083f49dc9..00b3e7245 100644 --- a/node_modules/tslint/lib/rules/noDebuggerRule.js +++ b/node_modules/tslint/lib/rules/noDebuggerRule.js @@ -27,21 +27,21 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-debugger", + description: "Disallows `debugger` statements.", + rationale: "In general, \`debugger\` statements aren't appropriate for production code.", + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "functionality", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "Use of debugger statements is forbidden"; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-debugger", - description: "Disallows `debugger` statements.", - rationale: "In general, \`debugger\` statements aren't appropriate for production code.", - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "functionality", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "Use of debugger statements is forbidden"; exports.Rule = Rule; function walk(ctx) { return ts.forEachChild(ctx.sourceFile, function cb(node) { diff --git a/node_modules/tslint/lib/rules/noDefaultExportRule.js b/node_modules/tslint/lib/rules/noDefaultExportRule.js index 19f713c5a..15fa1f729 100644 --- a/node_modules/tslint/lib/rules/noDefaultExportRule.js +++ b/node_modules/tslint/lib/rules/noDefaultExportRule.js @@ -27,22 +27,22 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-default-export", + description: "Disallows default exports in ES6-style modules.", + descriptionDetails: "Use named exports instead.", + rationale: (_a = ["\n Named imports/exports [promote clarity](https://github.com/palantir/tslint/issues/1182#issue-151780453).\n In addition, current tooling differs on the correct way to handle default imports/exports.\n Avoiding them all together can help avoid tooling bugs and conflicts."], _a.raw = ["\n Named imports/exports [promote clarity](https://github.com/palantir/tslint/issues/1182#issue-151780453).\n In addition, current tooling differs on the correct way to handle default imports/exports.\n Avoiding them all together can help avoid tooling bugs and conflicts."], Lint.Utils.dedent(_a)), + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "maintainability", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "Use of default exports is forbidden"; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-default-export", - description: "Disallows default exports in ES6-style modules.", - descriptionDetails: "Use named exports instead.", - rationale: (_a = ["\n Named imports/exports [promote clarity](https://github.com/palantir/tslint/issues/1182#issue-151780453).\n In addition, current tooling differs on the correct way to handle default imports/exports.\n Avoiding them all together can help avoid tooling bugs and conflicts."], _a.raw = ["\n Named imports/exports [promote clarity](https://github.com/palantir/tslint/issues/1182#issue-151780453).\n In addition, current tooling differs on the correct way to handle default imports/exports.\n Avoiding them all together can help avoid tooling bugs and conflicts."], Lint.Utils.dedent(_a)), - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "maintainability", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "Use of default exports is forbidden"; exports.Rule = Rule; function walk(ctx) { if (ctx.sourceFile.isDeclarationFile || !ts.isExternalModule(ctx.sourceFile)) { @@ -51,7 +51,7 @@ function walk(ctx) { for (var _i = 0, _a = ctx.sourceFile.statements; _i < _a.length; _i++) { var statement = _a[_i]; if (statement.kind === ts.SyntaxKind.ExportAssignment) { - if (statement.isExportEquals !== true) { + if (!statement.isExportEquals) { ctx.addFailureAtNode(statement.getChildAt(1, ctx.sourceFile), Rule.FAILURE_STRING); } } diff --git a/node_modules/tslint/lib/rules/noDuplicateImportsRule.d.ts b/node_modules/tslint/lib/rules/noDuplicateImportsRule.d.ts new file mode 100644 index 000000000..419acce16 --- /dev/null +++ b/node_modules/tslint/lib/rules/noDuplicateImportsRule.d.ts @@ -0,0 +1,7 @@ +import * as ts from "typescript"; +import * as Lint from "../index"; +export declare class Rule extends Lint.Rules.AbstractRule { + static metadata: Lint.IRuleMetadata; + static FAILURE_STRING(module: string): string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/node_modules/tslint/lib/rules/noDuplicateImportsRule.js b/node_modules/tslint/lib/rules/noDuplicateImportsRule.js new file mode 100644 index 000000000..18f6f2760 --- /dev/null +++ b/node_modules/tslint/lib/rules/noDuplicateImportsRule.js @@ -0,0 +1,81 @@ +"use strict"; +/** + * @license + * Copyright 2017 Palantir Technologies, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +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) { + tslib_1.__extends(Rule, _super); + function Rule() { + return _super !== null && _super.apply(this, arguments) || this; + } + Rule.FAILURE_STRING = function (module) { + return "Multiple imports from '" + module + "' can be combined into one."; + }; + Rule.prototype.apply = function (sourceFile) { + return this.applyWithWalker(new NoDuplicateImportsWalker(sourceFile, this.ruleName, undefined)); + }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-duplicate-imports", + description: (_a = ["\n Disallows multiple import statements from the same module."], _a.raw = ["\n Disallows multiple import statements from the same module."], Lint.Utils.dedent(_a)), + rationale: (_b = ["\n Using a single import statement per module will make the code clearer because you can see everything being imported\n from that module on one line."], _b.raw = ["\n Using a single import statement per module will make the code clearer because you can see everything being imported\n from that module on one line."], Lint.Utils.dedent(_b)), + optionsDescription: "Not configurable", + options: null, + optionExamples: [true], + type: "maintainability", + typescriptOnly: false, + }; + return Rule; +}(Lint.Rules.AbstractRule)); +exports.Rule = Rule; +var NoDuplicateImportsWalker = (function (_super) { + tslib_1.__extends(NoDuplicateImportsWalker, _super); + function NoDuplicateImportsWalker() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.seenImports = new Set(); + return _this; + } + NoDuplicateImportsWalker.prototype.walk = function (sourceFile) { + this.checkStatements(sourceFile.statements); + }; + NoDuplicateImportsWalker.prototype.checkStatements = function (statements) { + for (var _i = 0, statements_1 = statements; _i < statements_1.length; _i++) { + var statement = statements_1[_i]; + if (tsutils_1.isImportDeclaration(statement)) { + this.checkImport(statement); + } + else if (this.sourceFile.isDeclarationFile && tsutils_1.isModuleDeclaration(statement) && + statement.body !== undefined && statement.name.kind === ts.SyntaxKind.StringLiteral) { + // module augmentations in declaration files can contain imports + this.checkStatements(statement.body.statements); + } + } + }; + NoDuplicateImportsWalker.prototype.checkImport = function (statement) { + if (tsutils_1.isTextualLiteral(statement.moduleSpecifier)) { + if (this.seenImports.has(statement.moduleSpecifier.text)) { + return this.addFailureAtNode(statement, Rule.FAILURE_STRING(statement.moduleSpecifier.text)); + } + this.seenImports.add(statement.moduleSpecifier.text); + } + }; + return NoDuplicateImportsWalker; +}(Lint.AbstractWalker)); +var _a, _b; diff --git a/node_modules/tslint/lib/rules/noDuplicateSuperRule.js b/node_modules/tslint/lib/rules/noDuplicateSuperRule.js index 4dc91877a..1256d81a2 100644 --- a/node_modules/tslint/lib/rules/noDuplicateSuperRule.js +++ b/node_modules/tslint/lib/rules/noDuplicateSuperRule.js @@ -28,22 +28,22 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-duplicate-super", + description: "Warns if 'super()' appears twice in a constructor.", + rationale: "The second call to 'super()' will fail at runtime.", + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "functionality", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING_DUPLICATE = "Multiple calls to 'super()' found. It must be called only once."; + Rule.FAILURE_STRING_LOOP = "'super()' called in a loop. It must be called only once."; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-duplicate-super", - description: "Warns if 'super()' appears twice in a constructor.", - rationale: "The second call to 'super()' will fail at runtime.", - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "functionality", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING_DUPLICATE = "Multiple calls to 'super()' found. It must be called only once."; -Rule.FAILURE_STRING_LOOP = "'super()' called in a loop. It must be called only once."; exports.Rule = Rule; function walk(ctx) { return ts.forEachChild(ctx.sourceFile, function cb(node) { @@ -111,7 +111,6 @@ function walk(ctx) { fallthroughSingle = clauseSuper.node; } foundSingle = clauseSuper.node; - break; } } return foundSingle !== undefined ? { node: foundSingle, break: false } : 0 /* NoSuper */; diff --git a/node_modules/tslint/lib/rules/noDuplicateVariableRule.js b/node_modules/tslint/lib/rules/noDuplicateVariableRule.js index c828bfbff..757d17e4c 100644 --- a/node_modules/tslint/lib/rules/noDuplicateVariableRule.js +++ b/node_modules/tslint/lib/rules/noDuplicateVariableRule.js @@ -20,6 +20,7 @@ var tslib_1 = require("tslib"); var utils = require("tsutils"); var ts = require("typescript"); var Lint = require("../index"); +var OPTION_CHECK_PARAMETERS = "check-parameters"; var Rule = (function (_super) { tslib_1.__extends(Rule, _super); function Rule() { @@ -30,58 +31,78 @@ var Rule = (function (_super) { return "Duplicate variable: '" + name + "'"; }; Rule.prototype.apply = function (sourceFile) { - return this.applyWithFunction(sourceFile, walk); + return this.applyWithWalker(new NoDuplicateVariableWalker(sourceFile, this.ruleName, { + parameters: this.ruleArguments.indexOf(OPTION_CHECK_PARAMETERS) !== -1, + })); + }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-duplicate-variable", + description: "Disallows duplicate variable declarations in the same block scope.", + descriptionDetails: (_a = ["\n This rule is only useful when using the `var` keyword -\n the compiler will detect redeclarations of `let` and `const` variables."], _a.raw = ["\n This rule is only useful when using the \\`var\\` keyword -\n the compiler will detect redeclarations of \\`let\\` and \\`const\\` variables."], Lint.Utils.dedent(_a)), + rationale: (_b = ["\n A variable can be reassigned if necessary -\n there's no good reason to have a duplicate variable declaration."], _b.raw = ["\n A variable can be reassigned if necessary -\n there's no good reason to have a duplicate variable declaration."], Lint.Utils.dedent(_b)), + optionsDescription: "You can specify `\"" + OPTION_CHECK_PARAMETERS + "\"` to check for variables with the same name as a paramter.", + options: { + type: "string", + enum: [OPTION_CHECK_PARAMETERS], + }, + optionExamples: [ + true, + [true, OPTION_CHECK_PARAMETERS], + ], + type: "functionality", + typescriptOnly: false, }; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-duplicate-variable", - description: "Disallows duplicate variable declarations in the same block scope.", - descriptionDetails: (_a = ["\n This rule is only useful when using the `var` keyword -\n the compiler will detect redeclarations of `let` and `const` variables."], _a.raw = ["\n This rule is only useful when using the \\`var\\` keyword -\n the compiler will detect redeclarations of \\`let\\` and \\`const\\` variables."], Lint.Utils.dedent(_a)), - rationale: (_b = ["\n A variable can be reassigned if necessary -\n there's no good reason to have a duplicate variable declaration."], _b.raw = ["\n A variable can be reassigned if necessary -\n there's no good reason to have a duplicate variable declaration."], Lint.Utils.dedent(_b)), - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "functionality", - typescriptOnly: false, -}; exports.Rule = Rule; -function walk(ctx) { - var scope = new Set(); - return ts.forEachChild(ctx.sourceFile, function cb(node) { - if (utils.isFunctionScopeBoundary(node)) { - var oldScope = scope; - scope = new Set(); - ts.forEachChild(node, cb); - scope = oldScope; - return; - } - else if (utils.isVariableDeclaration(node) && !utils.isBlockScopedVariableDeclaration(node)) { - forEachBoundIdentifier(node.name, function (id) { - var text = id.text; - if (scope.has(text)) { - ctx.addFailureAtNode(id, Rule.FAILURE_STRING(text)); - } - else { - scope.add(text); +var NoDuplicateVariableWalker = (function (_super) { + tslib_1.__extends(NoDuplicateVariableWalker, _super); + function NoDuplicateVariableWalker() { + return _super !== null && _super.apply(this, arguments) || this; + } + NoDuplicateVariableWalker.prototype.walk = function (sourceFile) { + var _this = this; + this.scope = new Set(); + var cb = function (node) { + if (utils.isFunctionScopeBoundary(node)) { + var oldScope = _this.scope; + _this.scope = new Set(); + ts.forEachChild(node, cb); + _this.scope = oldScope; + return; + } + if (_this.options.parameters && utils.isParameterDeclaration(node)) { + _this.handleBindingName(node.name, false); + } + else if (utils.isVariableDeclarationList(node) && !utils.isBlockScopedVariableDeclarationList(node)) { + for (var _i = 0, _a = node.declarations; _i < _a.length; _i++) { + var variable = _a[_i]; + _this.handleBindingName(variable.name, true); } - }); + } + return ts.forEachChild(node, cb); + }; + return ts.forEachChild(sourceFile, cb); + }; + NoDuplicateVariableWalker.prototype.handleBindingName = function (name, check) { + if (name.kind === ts.SyntaxKind.Identifier) { + if (check && this.scope.has(name.text)) { + this.addFailureAtNode(name, Rule.FAILURE_STRING(name.text)); + } + else { + this.scope.add(name.text); + } } - return ts.forEachChild(node, cb); - }); -} -function forEachBoundIdentifier(name, action) { - if (name.kind === ts.SyntaxKind.Identifier) { - action(name); - } - else { - for (var _i = 0, _a = name.elements; _i < _a.length; _i++) { - var e = _a[_i]; - if (e.kind !== ts.SyntaxKind.OmittedExpression) { - forEachBoundIdentifier(e.name, action); + else { + for (var _i = 0, _a = name.elements; _i < _a.length; _i++) { + var e = _a[_i]; + if (e.kind !== ts.SyntaxKind.OmittedExpression) { + this.handleBindingName(e.name, check); + } } } - } -} + }; + return NoDuplicateVariableWalker; +}(Lint.AbstractWalker)); var _a, _b; diff --git a/node_modules/tslint/lib/rules/noEmptyInterfaceRule.js b/node_modules/tslint/lib/rules/noEmptyInterfaceRule.js index 8ba57b596..411026490 100644 --- a/node_modules/tslint/lib/rules/noEmptyInterfaceRule.js +++ b/node_modules/tslint/lib/rules/noEmptyInterfaceRule.js @@ -28,28 +28,27 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-empty-interface", + description: "Forbids empty interfaces.", + rationale: "An empty interface is equivalent to its supertype (or `{}`).", + optionsDescription: "Not configurable.", + options: null, + type: "typescript", + typescriptOnly: true, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "An empty interface is equivalent to `{}`."; + Rule.FAILURE_STRING_FOR_EXTENDS = "An interface declaring no members is equivalent to its supertype."; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-empty-interface", - description: "Forbids empty interfaces.", - rationale: "An empty interface is equivalent to its supertype (or `{}`).", - optionsDescription: "Not configurable.", - options: null, - type: "typescript", - typescriptOnly: true, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "An empty interface is equivalent to `{}`."; -Rule.FAILURE_STRING_FOR_EXTENDS = "An interface declaring no members is equivalent to its supertype."; exports.Rule = Rule; function walk(ctx) { return ts.forEachChild(ctx.sourceFile, function cb(node) { if (tsutils_1.isInterfaceDeclaration(node) && node.members.length === 0 && (node.heritageClauses === undefined || - node.heritageClauses[0].types === undefined || // allow interfaces that extend 2 or more interfaces node.heritageClauses[0].types.length < 2)) { return ctx.addFailureAtNode(node.name, node.heritageClauses !== undefined ? Rule.FAILURE_STRING_FOR_EXTENDS : Rule.FAILURE_STRING); diff --git a/node_modules/tslint/lib/rules/noEmptyRule.js b/node_modules/tslint/lib/rules/noEmptyRule.js index 29a0a496d..48af2183e 100644 --- a/node_modules/tslint/lib/rules/noEmptyRule.js +++ b/node_modules/tslint/lib/rules/noEmptyRule.js @@ -20,36 +20,42 @@ var tslib_1 = require("tslib"); var tsutils_1 = require("tsutils"); var ts = require("typescript"); var Lint = require("../index"); +var ALLOW_EMPTY_CATCH = "allow-empty-catch"; var Rule = (function (_super) { tslib_1.__extends(Rule, _super); function Rule() { return _super !== null && _super.apply(this, arguments) || this; } Rule.prototype.apply = function (sourceFile) { - return this.applyWithFunction(sourceFile, walk); + return this.applyWithFunction(sourceFile, walk, { + allowEmptyCatch: this.ruleArguments.indexOf(ALLOW_EMPTY_CATCH) !== -1, + }); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-empty", + description: "Disallows empty blocks.", + descriptionDetails: "Blocks with a comment inside are not considered empty.", + rationale: "Empty blocks are often indicators of missing code.", + optionsDescription: (_a = ["\n If `", "` is specified, then catch blocks are allowed to be empty."], _a.raw = ["\n If \\`", "\\` is specified, then catch blocks are allowed to be empty."], Lint.Utils.dedent(_a, ALLOW_EMPTY_CATCH)), + options: { + type: "string", + enum: [ALLOW_EMPTY_CATCH], + }, + optionExamples: [true, [true, ALLOW_EMPTY_CATCH]], + type: "functionality", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "block is empty"; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-empty", - description: "Disallows empty blocks.", - descriptionDetails: "Blocks with a comment inside are not considered empty.", - rationale: "Empty blocks are often indicators of missing code.", - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "functionality", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "block is empty"; exports.Rule = Rule; function walk(ctx) { return ts.forEachChild(ctx.sourceFile, function cb(node) { if (node.kind === ts.SyntaxKind.Block && node.statements.length === 0 && - !isExcludedConstructor(node.parent)) { + !isExcluded(node.parent, ctx.options)) { var start = node.getStart(ctx.sourceFile); // Block always starts with open brace. Adding 1 to its start gives us the end of the brace, // which can be used to conveniently check for comments between braces @@ -61,7 +67,10 @@ function walk(ctx) { return ts.forEachChild(node, cb); }); } -function isExcludedConstructor(node) { +function isExcluded(node, options) { + if (options.allowEmptyCatch && node.kind === ts.SyntaxKind.CatchClause) { + return true; + } return tsutils_1.isConstructorDeclaration(node) && ( /* If constructor is private or protected, the block is allowed to be empty. @@ -71,3 +80,4 @@ function isExcludedConstructor(node) { tsutils_1.hasModifier(node.modifiers, ts.SyntaxKind.PrivateKeyword, ts.SyntaxKind.ProtectedKeyword) || node.parameters.some(tsutils_1.isParameterProperty)); } +var _a; diff --git a/node_modules/tslint/lib/rules/noEvalRule.js b/node_modules/tslint/lib/rules/noEvalRule.js index 24649df6d..7c24fbca4 100644 --- a/node_modules/tslint/lib/rules/noEvalRule.js +++ b/node_modules/tslint/lib/rules/noEvalRule.js @@ -28,21 +28,21 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-eval", + description: "Disallows `eval` function invocations.", + rationale: (_a = ["\n `eval()` is dangerous as it allows arbitrary code execution with full privileges. There are\n [alternatives](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval)\n for most of the use cases for `eval()`."], _a.raw = ["\n \\`eval()\\` is dangerous as it allows arbitrary code execution with full privileges. There are\n [alternatives](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval)\n for most of the use cases for \\`eval()\\`."], Lint.Utils.dedent(_a)), + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "functionality", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "forbidden eval"; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-eval", - description: "Disallows `eval` function invocations.", - rationale: (_a = ["\n `eval()` is dangerous as it allows arbitrary code execution with full privileges. There are\n [alternatives](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval)\n for most of the use cases for `eval()`."], _a.raw = ["\n \\`eval()\\` is dangerous as it allows arbitrary code execution with full privileges. There are\n [alternatives](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval)\n for most of the use cases for \\`eval()\\`."], Lint.Utils.dedent(_a)), - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "functionality", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "forbidden eval"; exports.Rule = Rule; function walk(ctx) { return ts.forEachChild(ctx.sourceFile, function cb(node) { diff --git a/node_modules/tslint/lib/rules/noFloatingPromisesRule.js b/node_modules/tslint/lib/rules/noFloatingPromisesRule.js index 60839c9dc..6fe6d3329 100644 --- a/node_modules/tslint/lib/rules/noFloatingPromisesRule.js +++ b/node_modules/tslint/lib/rules/noFloatingPromisesRule.js @@ -28,39 +28,52 @@ var Rule = (function (_super) { Rule.prototype.applyWithProgram = function (sourceFile, program) { return this.applyWithFunction(sourceFile, function (ctx) { return walk(ctx, program.getTypeChecker()); }, ["Promise"].concat(this.ruleArguments)); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-floating-promises", + description: "Promises returned by functions must be handled appropriately.", + descriptionDetails: "Use `no-unused-expressions` in addition to this rule to reveal even more floating promises.", + optionsDescription: (_a = ["\n A list of 'string' names of any additional classes that should also be handled as Promises.\n "], _a.raw = ["\n A list of \\'string\\' names of any additional classes that should also be handled as Promises.\n "], Lint.Utils.dedent(_a)), + options: { + type: "list", + listType: { + type: "array", + items: { type: "string" }, + }, + }, + optionExamples: [true, [true, "JQueryPromise"]], + rationale: "Unhandled Promises can cause unexpected behavior, such as resolving at unexpected times.", + type: "functionality", + typescriptOnly: true, + requiresTypeInfo: true, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "Promises must be handled appropriately"; return Rule; }(Lint.Rules.TypedRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-floating-promises", - description: "Promises returned by functions must be handled appropriately.", - descriptionDetails: "Use `no-unused-expressions` in addition to this rule to reveal even more floating promises.", - optionsDescription: (_a = ["\n A list of 'string' names of any additional classes that should also be handled as Promises.\n "], _a.raw = ["\n A list of \\'string\\' names of any additional classes that should also be handled as Promises.\n "], Lint.Utils.dedent(_a)), - options: { - type: "list", - listType: { - type: "array", - items: { type: "string" }, - }, - }, - optionExamples: [true, [true, "JQueryPromise"]], - rationale: "Unhandled Promises can cause unexpected behavior, such as resolving at unexpected times.", - type: "functionality", - typescriptOnly: true, - requiresTypeInfo: true, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "Promises must be handled appropriately"; exports.Rule = Rule; function walk(ctx, tc) { return ts.forEachChild(ctx.sourceFile, function cb(node) { - if (tsutils_1.isExpressionStatement(node) && node.expression.kind === ts.SyntaxKind.CallExpression) { - var symbol = tc.getTypeAtLocation(node.expression).symbol; - if (symbol !== undefined && ctx.options.indexOf(symbol.name) !== -1) { - ctx.addFailureAtNode(node.expression, Rule.FAILURE_STRING); + if (tsutils_1.isExpressionStatement(node)) { + var expression = node.expression; + if (tsutils_1.isCallExpression(expression) && + !isPromiseCatchCall(expression) && + !isPromiseThenCallWithRejectionHandler(expression)) { + var symbol = tc.getTypeAtLocation(expression).symbol; + if (symbol !== undefined && ctx.options.indexOf(symbol.name) !== -1) { + ctx.addFailureAtNode(expression, Rule.FAILURE_STRING); + } } } return ts.forEachChild(node, cb); }); } +function isPromiseCatchCall(expression) { + return tsutils_1.isPropertyAccessExpression(expression.expression) && expression.expression.name.text === "catch"; +} +function isPromiseThenCallWithRejectionHandler(expression) { + return tsutils_1.isPropertyAccessExpression(expression.expression) && + expression.expression.name.text === "then" && + expression.arguments.length >= 2; +} var _a; diff --git a/node_modules/tslint/lib/rules/noForInArrayRule.js b/node_modules/tslint/lib/rules/noForInArrayRule.js index 42035e4eb..732c8bbfd 100644 --- a/node_modules/tslint/lib/rules/noForInArrayRule.js +++ b/node_modules/tslint/lib/rules/noForInArrayRule.js @@ -27,22 +27,22 @@ var Rule = (function (_super) { Rule.prototype.applyWithProgram = function (sourceFile, program) { return this.applyWithFunction(sourceFile, function (ctx) { return walk(ctx, program); }); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-for-in-array", + description: "Disallows iterating over an array with a for-in loop.", + descriptionDetails: (_a = ["\n A for-in loop (`for (var k in o)`) iterates over the properties of an Object.\n\n While it is legal to use for-in loops with array types, it is not common.\n for-in will iterate over the indices of the array as strings, omitting any \"holes\" in\n the array.\n\n More common is to use for-of, which iterates over the values of an array.\n If you want to iterate over the indices, alternatives include:\n\n array.forEach((value, index) => { ... });\n for (const [index, value] of array.entries()) { ... }\n for (let i = 0; i < array.length; i++) { ... }\n "], _a.raw = ["\n A for-in loop (\\`for (var k in o)\\`) iterates over the properties of an Object.\n\n While it is legal to use for-in loops with array types, it is not common.\n for-in will iterate over the indices of the array as strings, omitting any \"holes\" in\n the array.\n\n More common is to use for-of, which iterates over the values of an array.\n If you want to iterate over the indices, alternatives include:\n\n array.forEach((value, index) => { ... });\n for (const [index, value] of array.entries()) { ... }\n for (let i = 0; i < array.length; i++) { ... }\n "], Lint.Utils.dedent(_a)), + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + requiresTypeInfo: true, + type: "functionality", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "for-in loops over arrays are forbidden. Use for-of or array.forEach instead."; return Rule; }(Lint.Rules.TypedRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-for-in-array", - description: "Disallows iterating over an array with a for-in loop.", - descriptionDetails: (_a = ["\n A for-in loop (`for (var k in o)`) iterates over the properties of an Object.\n\n While it is legal to use for-in loops with array types, it is not common.\n for-in will iterate over the indices of the array as strings, omitting any \"holes\" in\n the array.\n\n More common is to use for-of, which iterates over the values of an array.\n If you want to iterate over the indices, alternatives include:\n\n array.forEach((value, index) => { ... });\n for (const [index, value] of array.entries()) { ... }\n for (let i = 0; i < array.length; i++) { ... }\n "], _a.raw = ["\n A for-in loop (\\`for (var k in o)\\`) iterates over the properties of an Object.\n\n While it is legal to use for-in loops with array types, it is not common.\n for-in will iterate over the indices of the array as strings, omitting any \"holes\" in\n the array.\n\n More common is to use for-of, which iterates over the values of an array.\n If you want to iterate over the indices, alternatives include:\n\n array.forEach((value, index) => { ... });\n for (const [index, value] of array.entries()) { ... }\n for (let i = 0; i < array.length; i++) { ... }\n "], Lint.Utils.dedent(_a)), - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - requiresTypeInfo: true, - type: "functionality", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "for-in loops over arrays are forbidden. Use for-of or array.forEach instead."; exports.Rule = Rule; function walk(ctx, program) { return ts.forEachChild(ctx.sourceFile, function cb(node) { diff --git a/node_modules/tslint/lib/rules/noImportSideEffectRule.js b/node_modules/tslint/lib/rules/noImportSideEffectRule.js index 965a9de3c..2821cd7f7 100644 --- a/node_modules/tslint/lib/rules/noImportSideEffectRule.js +++ b/node_modules/tslint/lib/rules/noImportSideEffectRule.js @@ -30,31 +30,31 @@ var Rule = (function (_super) { var ignorePattern = patternConfig === undefined ? undefined : new RegExp(patternConfig[OPTION_IGNORE_MODULE]); return this.applyWithFunction(sourceFile, walk, ignorePattern); }; - return Rule; -}(Lint.Rules.AbstractRule)); -Rule.metadata = { - description: "Avoid import statements with side-effect.", - optionExamples: [true, [true, (_a = {}, _a[OPTION_IGNORE_MODULE] = "(\\.html|\\.css)$", _a)]], - options: { - items: { - properties: { - "ignore-module": { - type: "string", + Rule.metadata = { + description: "Avoid import statements with side-effect.", + optionExamples: [true, [true, (_a = {}, _a[OPTION_IGNORE_MODULE] = "(\\.html|\\.css)$", _a)]], + options: { + items: { + properties: { + "ignore-module": { + type: "string", + }, }, + type: "object", }, - type: "object", + maxLength: 1, + minLength: 0, + type: "array", }, - maxLength: 1, - minLength: 0, - type: "array", - }, - optionsDescription: (_b = ["\n One argument may be optionally provided:\n\n * `", "` allows to specify a regex and ignore modules which it matches."], _b.raw = ["\n One argument may be optionally provided:\n\n * \\`", "\\` allows to specify a regex and ignore modules which it matches."], Lint.Utils.dedent(_b, OPTION_IGNORE_MODULE)), - rationale: "Imports with side effects may have behavior which is hard for static verification.", - ruleName: "no-import-side-effect", - type: "typescript", - typescriptOnly: false, -}; -Rule.FAILURE_STRING = "import with explicit side-effect"; + optionsDescription: (_b = ["\n One argument may be optionally provided:\n\n * `", "` allows to specify a regex and ignore modules which it matches."], _b.raw = ["\n One argument may be optionally provided:\n\n * \\`", "\\` allows to specify a regex and ignore modules which it matches."], Lint.Utils.dedent(_b, OPTION_IGNORE_MODULE)), + rationale: "Imports with side effects may have behavior which is hard for static verification.", + ruleName: "no-import-side-effect", + type: "typescript", + typescriptOnly: false, + }; + Rule.FAILURE_STRING = "import with explicit side-effect"; + return Rule; +}(Lint.Rules.AbstractRule)); exports.Rule = Rule; function walk(ctx) { var ignorePattern = ctx.options, sourceFile = ctx.sourceFile; diff --git a/node_modules/tslint/lib/rules/noInferrableTypesRule.js b/node_modules/tslint/lib/rules/noInferrableTypesRule.js index 386249225..bbb51fab4 100644 --- a/node_modules/tslint/lib/rules/noInferrableTypesRule.js +++ b/node_modules/tslint/lib/rules/noInferrableTypesRule.js @@ -37,32 +37,32 @@ var Rule = (function (_super) { ignoreProperties: this.ruleArguments.indexOf(OPTION_IGNORE_PROPERTIES) !== -1, })); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-inferrable-types", + description: "Disallows explicit type declarations for variables or parameters initialized to a number, string, or boolean.", + rationale: "Explicit types where they can be easily inferred by the compiler make code more verbose.", + optionsDescription: (_a = ["\n Two arguments may be optionally provided:\n\n * `", "` allows specifying an inferrable type annotation for function params.\n This can be useful when combining with the `typedef` rule.\n * `", "` allows specifying an inferrable type annotation for class properties."], _a.raw = ["\n Two arguments may be optionally provided:\n\n * \\`", "\\` allows specifying an inferrable type annotation for function params.\n This can be useful when combining with the \\`typedef\\` rule.\n * \\`", "\\` allows specifying an inferrable type annotation for class properties."], Lint.Utils.dedent(_a, OPTION_IGNORE_PARMS, OPTION_IGNORE_PROPERTIES)), + options: { + type: "array", + items: { + type: "string", + enum: [OPTION_IGNORE_PARMS, OPTION_IGNORE_PROPERTIES], + }, + minLength: 0, + maxLength: 2, + }, + hasFix: true, + optionExamples: [ + true, + [true, OPTION_IGNORE_PARMS], + [true, OPTION_IGNORE_PARMS, OPTION_IGNORE_PROPERTIES], + ], + type: "typescript", + typescriptOnly: true, + }; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-inferrable-types", - description: "Disallows explicit type declarations for variables or parameters initialized to a number, string, or boolean.", - rationale: "Explicit types where they can be easily inferred by the compiler make code more verbose.", - optionsDescription: (_a = ["\n Two arguments may be optionally provided:\n\n * `", "` allows specifying an inferrable type annotation for function params.\n This can be useful when combining with the `typedef` rule.\n * `", "` allows specifying an inferrable type annotation for class properties."], _a.raw = ["\n Two arguments may be optionally provided:\n\n * \\`", "\\` allows specifying an inferrable type annotation for function params.\n This can be useful when combining with the \\`typedef\\` rule.\n * \\`", "\\` allows specifying an inferrable type annotation for class properties."], Lint.Utils.dedent(_a, OPTION_IGNORE_PARMS, OPTION_IGNORE_PROPERTIES)), - options: { - type: "array", - items: { - type: "string", - enum: [OPTION_IGNORE_PARMS, OPTION_IGNORE_PROPERTIES], - }, - minLength: 0, - maxLength: 2, - }, - hasFix: true, - optionExamples: [ - true, - [true, OPTION_IGNORE_PARMS], - [true, OPTION_IGNORE_PARMS, OPTION_IGNORE_PROPERTIES], - ], - type: "typescript", - typescriptOnly: true, -}; exports.Rule = Rule; var NoInferrableTypesWalker = (function (_super) { tslib_1.__extends(NoInferrableTypesWalker, _super); @@ -74,7 +74,8 @@ var NoInferrableTypesWalker = (function (_super) { var cb = function (node) { if (shouldCheck(node, _this.options)) { var name = node.name, type = node.type, initializer = node.initializer; - if (type !== undefined && initializer !== undefined && typeIsInferrable(type.kind, initializer.kind)) { + if (type !== undefined && initializer !== undefined + && typeIsInferrable(type.kind, initializer)) { var fix = Lint.Replacement.deleteFromTo(name.end, type.end); _this.addFailureAtNode(type, Rule.FAILURE_STRING_FACTORY(ts.tokenToString(type.kind)), fix); } @@ -104,11 +105,11 @@ function shouldCheck(node, _a) { function typeIsInferrable(type, initializer) { switch (type) { case ts.SyntaxKind.BooleanKeyword: - return initializer === ts.SyntaxKind.TrueKeyword || initializer === ts.SyntaxKind.FalseKeyword; + return initializer.kind === ts.SyntaxKind.TrueKeyword || initializer.kind === ts.SyntaxKind.FalseKeyword; case ts.SyntaxKind.NumberKeyword: - return initializer === ts.SyntaxKind.NumericLiteral; + return Lint.isNumeric(initializer); case ts.SyntaxKind.StringKeyword: - switch (initializer) { + switch (initializer.kind) { case ts.SyntaxKind.StringLiteral: case ts.SyntaxKind.NoSubstitutionTemplateLiteral: case ts.SyntaxKind.TemplateExpression: diff --git a/node_modules/tslint/lib/rules/noInferredEmptyObjectTypeRule.d.ts b/node_modules/tslint/lib/rules/noInferredEmptyObjectTypeRule.d.ts index 6103d1624..1e9b27cc8 100644 --- a/node_modules/tslint/lib/rules/noInferredEmptyObjectTypeRule.d.ts +++ b/node_modules/tslint/lib/rules/noInferredEmptyObjectTypeRule.d.ts @@ -1,19 +1,3 @@ -/** - * @license - * Copyright 2016 Palantir Technologies, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ import * as ts from "typescript"; import * as Lint from "../index"; export declare class Rule extends Lint.Rules.TypedRule { diff --git a/node_modules/tslint/lib/rules/noInferredEmptyObjectTypeRule.js b/node_modules/tslint/lib/rules/noInferredEmptyObjectTypeRule.js index 6342ac39f..254098ec6 100644 --- a/node_modules/tslint/lib/rules/noInferredEmptyObjectTypeRule.js +++ b/node_modules/tslint/lib/rules/noInferredEmptyObjectTypeRule.js @@ -17,9 +17,9 @@ */ 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 utils_1 = require("../language/utils"); var Rule = (function (_super) { tslib_1.__extends(Rule, _super); function Rule() { @@ -28,22 +28,22 @@ var Rule = (function (_super) { Rule.prototype.applyWithProgram = function (sourceFile, program) { return this.applyWithWalker(new NoInferredEmptyObjectTypeRule(sourceFile, this.ruleName, program.getTypeChecker())); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-inferred-empty-object-type", + description: "Disallow type inference of {} (empty object type) at function and constructor call sites", + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "functionality", + typescriptOnly: true, + requiresTypeInfo: true, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.EMPTY_INTERFACE_INSTANCE = "Explicit type parameter needs to be provided to the constructor"; + Rule.EMPTY_INTERFACE_FUNCTION = "Explicit type parameter needs to be provided to the function call"; return Rule; }(Lint.Rules.TypedRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-inferred-empty-object-type", - description: "Disallow type inference of {} (empty object type) at function and constructor call sites", - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "functionality", - typescriptOnly: true, - requiresTypeInfo: true, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.EMPTY_INTERFACE_INSTANCE = "Explicit type parameter needs to be provided to the constructor"; -Rule.EMPTY_INTERFACE_FUNCTION = "Explicit type parameter needs to be provided to the function call"; exports.Rule = Rule; var NoInferredEmptyObjectTypeRule = (function (_super) { tslib_1.__extends(NoInferredEmptyObjectTypeRule, _super); @@ -68,12 +68,10 @@ var NoInferredEmptyObjectTypeRule = (function (_super) { NoInferredEmptyObjectTypeRule.prototype.checkNewExpression = function (node) { var _this = this; if (node.typeArguments === undefined) { - var objType = this.checker.getTypeAtLocation(node); - if (utils_1.isTypeFlagSet(objType, ts.TypeFlags.Object) && objType.typeArguments !== undefined) { - var typeArgs = objType.typeArguments; - if (typeArgs.some(function (a) { return _this.isEmptyObjectInterface(a); })) { - this.addFailureAtNode(node, Rule.EMPTY_INTERFACE_INSTANCE); - } + var type = this.checker.getTypeAtLocation(node); + if (tsutils_1.isTypeReference(type) && type.typeArguments !== undefined && + type.typeArguments.some(function (a) { return tsutils_1.isObjectType(a) && _this.isEmptyObjectInterface(a); })) { + this.addFailureAtNode(node, Rule.EMPTY_INTERFACE_INSTANCE); } } }; @@ -86,28 +84,20 @@ var NoInferredEmptyObjectTypeRule = (function (_super) { return; } var retType = this.checker.getReturnTypeOfSignature(callSig); - if (this.isEmptyObjectInterface(retType)) { + if (tsutils_1.isObjectType(retType) && this.isEmptyObjectInterface(retType)) { this.addFailureAtNode(node, Rule.EMPTY_INTERFACE_FUNCTION); } }; NoInferredEmptyObjectTypeRule.prototype.isEmptyObjectInterface = function (objType) { var _this = this; - var isAnonymous = utils_1.isObjectFlagSet(objType, ts.ObjectFlags.Anonymous); - var hasProblematicCallSignatures = false; - var hasProperties = (objType.getProperties() !== undefined && objType.getProperties().length > 0); - var hasNumberIndexType = objType.getNumberIndexType() !== undefined; - var hasStringIndexType = objType.getStringIndexType() !== undefined; - var callSig = objType.getCallSignatures(); - if (callSig !== undefined && callSig.length > 0) { - var isClean = callSig.every(function (sig) { - var csigRetType = _this.checker.getReturnTypeOfSignature(sig); - return _this.isEmptyObjectInterface(csigRetType); + return tsutils_1.isObjectFlagSet(objType, ts.ObjectFlags.Anonymous) && + objType.getProperties().length === 0 && + objType.getNumberIndexType() === undefined && + objType.getStringIndexType() === undefined && + objType.getCallSignatures().every(function (signature) { + var type = _this.checker.getReturnTypeOfSignature(signature); + return tsutils_1.isObjectType(type) && _this.isEmptyObjectInterface(type); }); - if (!isClean) { - hasProblematicCallSignatures = true; - } - } - return (isAnonymous && !hasProblematicCallSignatures && !hasProperties && !hasNumberIndexType && !hasStringIndexType); }; return NoInferredEmptyObjectTypeRule; }(Lint.AbstractWalker)); diff --git a/node_modules/tslint/lib/rules/noInternalModuleRule.js b/node_modules/tslint/lib/rules/noInternalModuleRule.js index 33be12aed..85efb2530 100644 --- a/node_modules/tslint/lib/rules/noInternalModuleRule.js +++ b/node_modules/tslint/lib/rules/noInternalModuleRule.js @@ -27,22 +27,22 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithWalker(new NoInternalModuleWalker(sourceFile, this.ruleName, undefined)); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-internal-module", + description: "Disallows internal `module`", + rationale: "Using `module` leads to a confusion of concepts with external modules. Use the newer `namespace` keyword instead.", + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "typescript", + typescriptOnly: true, + hasFix: true, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "The internal 'module' syntax is deprecated, use the 'namespace' keyword instead."; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-internal-module", - description: "Disallows internal `module`", - rationale: "Using `module` leads to a confusion of concepts with external modules. Use the newer `namespace` keyword instead.", - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "typescript", - typescriptOnly: true, - hasFix: true, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "The internal 'module' syntax is deprecated, use the 'namespace' keyword instead."; exports.Rule = Rule; var NoInternalModuleWalker = (function (_super) { tslib_1.__extends(NoInternalModuleWalker, _super); @@ -61,7 +61,7 @@ var NoInternalModuleWalker = (function (_super) { } }; NoInternalModuleWalker.prototype.checkModuleDeclaration = function (node, nested) { - if (nested !== true && + if (!nested && node.name.kind === ts.SyntaxKind.Identifier && !Lint.isNodeFlagSet(node, ts.NodeFlags.Namespace) && // augmenting global uses a special syntax that is allowed diff --git a/node_modules/tslint/lib/rules/noInvalidTemplateStringsRule.js b/node_modules/tslint/lib/rules/noInvalidTemplateStringsRule.js index c62da3755..d3ee747f2 100644 --- a/node_modules/tslint/lib/rules/noInvalidTemplateStringsRule.js +++ b/node_modules/tslint/lib/rules/noInvalidTemplateStringsRule.js @@ -28,21 +28,21 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-invalid-template-strings", + // tslint:disable-next-line no-invalid-template-strings + description: "Warns on use of `${` in non-template strings.", + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "functionality", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "Interpolation will only work for template strings."; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-invalid-template-strings", - // tslint:disable-next-line no-invalid-template-strings - description: "Warns on use of `${` in non-template strings.", - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "functionality", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "Interpolation will only work for template strings."; exports.Rule = Rule; function walk(ctx) { return ts.forEachChild(ctx.sourceFile, function cb(node) { diff --git a/node_modules/tslint/lib/rules/noInvalidThisRule.js b/node_modules/tslint/lib/rules/noInvalidThisRule.js index b2fb22aa5..2c5ce8486 100644 --- a/node_modules/tslint/lib/rules/noInvalidThisRule.js +++ b/node_modules/tslint/lib/rules/noInvalidThisRule.js @@ -32,31 +32,31 @@ var Rule = (function (_super) { var checkFuncInMethod = hasOption(DEPRECATED_OPTION_FUNCTION_IN_METHOD) || hasOption(OPTION_FUNCTION_IN_METHOD); return this.applyWithFunction(sourceFile, walk, checkFuncInMethod); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-invalid-this", + description: "Disallows using the `this` keyword outside of classes.", + rationale: "See [the rule's author's rationale here.](https://github.com/palantir/tslint/pull/1105#issue-147549402)", + optionsDescription: (_a = ["\n One argument may be optionally provided:\n\n * `", "` disallows using the `this` keyword in functions within class methods."], _a.raw = ["\n One argument may be optionally provided:\n\n * \\`", "\\` disallows using the \\`this\\` keyword in functions within class methods."], Lint.Utils.dedent(_a, OPTION_FUNCTION_IN_METHOD)), + options: { + type: "array", + items: { + type: "string", + enum: [OPTION_FUNCTION_IN_METHOD], + }, + minLength: 0, + maxLength: 1, + }, + optionExamples: [true, [true, OPTION_FUNCTION_IN_METHOD]], + type: "functionality", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING_OUTSIDE = "the \"this\" keyword is disallowed outside of a class body"; + Rule.FAILURE_STRING_INSIDE = "the \"this\" keyword is disallowed in function bodies inside class methods, " + + "use arrow functions instead"; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-invalid-this", - description: "Disallows using the `this` keyword outside of classes.", - rationale: "See [the rule's author's rationale here.](https://github.com/palantir/tslint/pull/1105#issue-147549402)", - optionsDescription: (_a = ["\n One argument may be optionally provided:\n\n * `", "` disallows using the `this` keyword in functions within class methods."], _a.raw = ["\n One argument may be optionally provided:\n\n * \\`", "\\` disallows using the \\`this\\` keyword in functions within class methods."], Lint.Utils.dedent(_a, OPTION_FUNCTION_IN_METHOD)), - options: { - type: "array", - items: { - type: "string", - enum: [OPTION_FUNCTION_IN_METHOD], - }, - minLength: 0, - maxLength: 1, - }, - optionExamples: [true, [true, OPTION_FUNCTION_IN_METHOD]], - type: "functionality", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING_OUTSIDE = "the \"this\" keyword is disallowed outside of a class body"; -Rule.FAILURE_STRING_INSIDE = "the \"this\" keyword is disallowed in function bodies inside class methods, " + - "use arrow functions instead"; exports.Rule = Rule; function walk(ctx) { var sourceFile = ctx.sourceFile, checkFuncInMethod = ctx.options; diff --git a/node_modules/tslint/lib/rules/noIrregularWhitespaceRule.js b/node_modules/tslint/lib/rules/noIrregularWhitespaceRule.js index aae8e31d5..d82f0f5da 100644 --- a/node_modules/tslint/lib/rules/noIrregularWhitespaceRule.js +++ b/node_modules/tslint/lib/rules/noIrregularWhitespaceRule.js @@ -26,21 +26,21 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-irregular-whitespace", + description: "Disallow irregular whitespace outside of strings and comments", + hasFix: true, + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "style", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "Irregular whitespace not allowed"; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-irregular-whitespace", - description: "Disallow irregular whitespace outside of strings and comments", - hasFix: true, - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "style", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "Irregular whitespace not allowed"; exports.Rule = Rule; /* Inspired by: https://github.com/eslint/eslint/blob/master/lib/rules/no-irregular-whitespace.js */ /* tslint:disable:max-line-length */ diff --git a/node_modules/tslint/lib/rules/noMagicNumbersRule.d.ts b/node_modules/tslint/lib/rules/noMagicNumbersRule.d.ts index 500d9d5cc..67db20943 100644 --- a/node_modules/tslint/lib/rules/noMagicNumbersRule.d.ts +++ b/node_modules/tslint/lib/rules/noMagicNumbersRule.d.ts @@ -1,3 +1,19 @@ +/** + * @license + * Copyright 2016 Palantir Technologies, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ import * as ts from "typescript"; import * as Lint from "../index"; export declare class Rule extends Lint.Rules.AbstractRule { diff --git a/node_modules/tslint/lib/rules/noMagicNumbersRule.js b/node_modules/tslint/lib/rules/noMagicNumbersRule.js index 1e1b5f5fb..8888ceb38 100644 --- a/node_modules/tslint/lib/rules/noMagicNumbersRule.js +++ b/node_modules/tslint/lib/rules/noMagicNumbersRule.js @@ -17,9 +17,9 @@ */ 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 utils_1 = require("../language/utils"); var Rule = (function (_super) { tslib_1.__extends(Rule, _super); function Rule() { @@ -29,40 +29,40 @@ var Rule = (function (_super) { var allowedNumbers = this.ruleArguments.length > 0 ? this.ruleArguments : Rule.DEFAULT_ALLOWED; return this.applyWithWalker(new NoMagicNumbersWalker(sourceFile, this.ruleName, new Set(allowedNumbers.map(String)))); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-magic-numbers", + description: (_a = ["\n Disallows the use constant number values outside of variable assignments.\n When no list of allowed values is specified, -1, 0 and 1 are allowed by default."], _a.raw = ["\n Disallows the use constant number values outside of variable assignments.\n When no list of allowed values is specified, -1, 0 and 1 are allowed by default."], Lint.Utils.dedent(_a)), + rationale: (_b = ["\n Magic numbers should be avoided as they often lack documentation, forcing\n them to be stored in variables gives them implicit documentation."], _b.raw = ["\n Magic numbers should be avoided as they often lack documentation, forcing\n them to be stored in variables gives them implicit documentation."], Lint.Utils.dedent(_b)), + optionsDescription: "A list of allowed numbers.", + options: { + type: "array", + items: { + type: "number", + }, + minLength: 1, + }, + optionExamples: [true, [true, 1, 2, 3]], + type: "typescript", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "'magic numbers' are not allowed"; + Rule.ALLOWED_NODES = new Set([ + ts.SyntaxKind.ExportAssignment, + ts.SyntaxKind.FirstAssignment, + ts.SyntaxKind.LastAssignment, + ts.SyntaxKind.PropertyAssignment, + ts.SyntaxKind.ShorthandPropertyAssignment, + ts.SyntaxKind.VariableDeclaration, + ts.SyntaxKind.VariableDeclarationList, + ts.SyntaxKind.EnumMember, + ts.SyntaxKind.PropertyDeclaration, + ts.SyntaxKind.Parameter, + ]); + Rule.DEFAULT_ALLOWED = [-1, 0, 1]; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-magic-numbers", - description: (_a = ["\n Disallows the use constant number values outside of variable assignments.\n When no list of allowed values is specified, -1, 0 and 1 are allowed by default."], _a.raw = ["\n Disallows the use constant number values outside of variable assignments.\n When no list of allowed values is specified, -1, 0 and 1 are allowed by default."], Lint.Utils.dedent(_a)), - rationale: (_b = ["\n Magic numbers should be avoided as they often lack documentation, forcing\n them to be stored in variables gives them implicit documentation."], _b.raw = ["\n Magic numbers should be avoided as they often lack documentation, forcing\n them to be stored in variables gives them implicit documentation."], Lint.Utils.dedent(_b)), - optionsDescription: "A list of allowed numbers.", - options: { - type: "array", - items: { - type: "number", - }, - minLength: 1, - }, - optionExamples: [true, [true, 1, 2, 3]], - type: "typescript", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "'magic numbers' are not allowed"; -Rule.ALLOWED_NODES = new Set([ - ts.SyntaxKind.ExportAssignment, - ts.SyntaxKind.FirstAssignment, - ts.SyntaxKind.LastAssignment, - ts.SyntaxKind.PropertyAssignment, - ts.SyntaxKind.ShorthandPropertyAssignment, - ts.SyntaxKind.VariableDeclaration, - ts.SyntaxKind.VariableDeclarationList, - ts.SyntaxKind.EnumMember, - ts.SyntaxKind.PropertyDeclaration, - ts.SyntaxKind.Parameter, -]); -Rule.DEFAULT_ALLOWED = [-1, 0, 1]; exports.Rule = Rule; var NoMagicNumbersWalker = (function (_super) { tslib_1.__extends(NoMagicNumbersWalker, _super); @@ -75,9 +75,7 @@ var NoMagicNumbersWalker = (function (_super) { if (node.kind === ts.SyntaxKind.NumericLiteral) { return _this.checkNumericLiteral(node, node.text); } - if (tsutils_1.isPrefixUnaryExpression(node) && - node.operator === ts.SyntaxKind.MinusToken && - node.operand.kind === ts.SyntaxKind.NumericLiteral) { + if (utils_1.isNegativeNumberLiteral(node)) { return _this.checkNumericLiteral(node, "-" + node.operand.text); } return ts.forEachChild(node, cb); diff --git a/node_modules/tslint/lib/rules/noMergeableNamespaceRule.js b/node_modules/tslint/lib/rules/noMergeableNamespaceRule.js index 9b644aef4..82d24ed0e 100644 --- a/node_modules/tslint/lib/rules/noMergeableNamespaceRule.js +++ b/node_modules/tslint/lib/rules/noMergeableNamespaceRule.js @@ -31,18 +31,18 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithWalker(new Walker(sourceFile, this.ruleName, undefined)); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-mergeable-namespace", + description: "Disallows mergeable namespaces in the same file.", + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "maintainability", + typescriptOnly: true, + }; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-mergeable-namespace", - description: "Disallows mergeable namespaces in the same file.", - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "maintainability", - typescriptOnly: true, -}; exports.Rule = Rule; var Walker = (function (_super) { tslib_1.__extends(Walker, _super); @@ -83,9 +83,6 @@ var Walker = (function (_super) { break; case ts.SyntaxKind.ModuleDeclaration: this.checkModuleDeclaration(body); - break; - default: - break; } }; Walker.prototype.getLineOfNode = function (node) { diff --git a/node_modules/tslint/lib/rules/noMisusedNewRule.js b/node_modules/tslint/lib/rules/noMisusedNewRule.js index 51f34e5f4..3aa870bc7 100644 --- a/node_modules/tslint/lib/rules/noMisusedNewRule.js +++ b/node_modules/tslint/lib/rules/noMisusedNewRule.js @@ -28,21 +28,21 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-misused-new", + description: "Warns on apparent attempts to define constructors for interfaces or `new` for classes.", + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "functionality", + typescriptOnly: true, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING_INTERFACE = "Interfaces cannot be constructed, only classes. Did you mean `declare class`?"; + Rule.FAILURE_STRING_CLASS = '`new` in a class is a method named "new". Did you mean `constructor`?'; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-misused-new", - description: "Warns on apparent attempts to define constructors for interfaces or `new` for classes.", - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "functionality", - typescriptOnly: true, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING_INTERFACE = "Interfaces cannot be constructed, only classes. Did you mean `declare class`?"; -Rule.FAILURE_STRING_CLASS = '`new` in a class is a method named "new". Did you mean `constructor`?'; exports.Rule = Rule; function walk(ctx) { return ts.forEachChild(ctx.sourceFile, function cb(node) { diff --git a/node_modules/tslint/lib/rules/noNamespaceRule.js b/node_modules/tslint/lib/rules/noNamespaceRule.js index a930e3034..381a211d9 100644 --- a/node_modules/tslint/lib/rules/noNamespaceRule.js +++ b/node_modules/tslint/lib/rules/noNamespaceRule.js @@ -31,30 +31,30 @@ var Rule = (function (_super) { allowDeclarations: this.ruleArguments.indexOf(OPTION_ALLOW_DECLARATIONS) !== -1, }); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-namespace", + description: "Disallows use of internal \`module\`s and \`namespace\`s.", + descriptionDetails: "This rule still allows the use of `declare module ... {}`", + rationale: (_a = ["\n ES6-style external modules are the standard way to modularize code.\n Using `module {}` and `namespace {}` are outdated ways to organize TypeScript code."], _a.raw = ["\n ES6-style external modules are the standard way to modularize code.\n Using \\`module {}\\` and \\`namespace {}\\` are outdated ways to organize TypeScript code."], Lint.Utils.dedent(_a)), + optionsDescription: (_b = ["\n One argument may be optionally provided:\n\n * `", "` allows `declare namespace ... {}` to describe external APIs."], _b.raw = ["\n One argument may be optionally provided:\n\n * \\`", "\\` allows \\`declare namespace ... {}\\` to describe external APIs."], Lint.Utils.dedent(_b, OPTION_ALLOW_DECLARATIONS)), + options: { + type: "array", + items: { + type: "string", + enum: [OPTION_ALLOW_DECLARATIONS], + }, + minLength: 0, + maxLength: 1, + }, + optionExamples: [true, [true, OPTION_ALLOW_DECLARATIONS]], + type: "typescript", + typescriptOnly: true, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "'namespace' and 'module' are disallowed"; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-namespace", - description: "Disallows use of internal \`module\`s and \`namespace\`s.", - descriptionDetails: "This rule still allows the use of `declare module ... {}`", - rationale: (_a = ["\n ES6-style external modules are the standard way to modularize code.\n Using `module {}` and `namespace {}` are outdated ways to organize TypeScript code."], _a.raw = ["\n ES6-style external modules are the standard way to modularize code.\n Using \\`module {}\\` and \\`namespace {}\\` are outdated ways to organize TypeScript code."], Lint.Utils.dedent(_a)), - optionsDescription: (_b = ["\n One argument may be optionally provided:\n\n * `", "` allows `declare namespace ... {}` to describe external APIs."], _b.raw = ["\n One argument may be optionally provided:\n\n * \\`", "\\` allows \\`declare namespace ... {}\\` to describe external APIs."], Lint.Utils.dedent(_b, OPTION_ALLOW_DECLARATIONS)), - options: { - type: "array", - items: { - type: "string", - enum: [OPTION_ALLOW_DECLARATIONS], - }, - minLength: 0, - maxLength: 1, - }, - optionExamples: [true, [true, OPTION_ALLOW_DECLARATIONS]], - type: "typescript", - typescriptOnly: true, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "'namespace' and 'module' are disallowed"; exports.Rule = Rule; function walk(ctx) { // Ignore all .d.ts files by returning and not walking their ASTs. diff --git a/node_modules/tslint/lib/rules/noNonNullAssertionRule.js b/node_modules/tslint/lib/rules/noNonNullAssertionRule.js index 5af273e18..d708687f9 100644 --- a/node_modules/tslint/lib/rules/noNonNullAssertionRule.js +++ b/node_modules/tslint/lib/rules/noNonNullAssertionRule.js @@ -27,21 +27,21 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-non-null-assertion", + description: "Disallows non-null assertions.", + rationale: "Using non-null assertion cancels the benefits of the strict null checking mode.", + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "typescript", + typescriptOnly: true, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "Forbidden non null assertion"; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-non-null-assertion", - description: "Disallows non-null assertions.", - rationale: "Using non-null assertion cancels the benefits of the strict null checking mode.", - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "typescript", - typescriptOnly: true, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "Forbidden non null assertion"; exports.Rule = Rule; function walk(ctx) { return ts.forEachChild(ctx.sourceFile, function cb(node) { diff --git a/node_modules/tslint/lib/rules/noNullKeywordRule.d.ts b/node_modules/tslint/lib/rules/noNullKeywordRule.d.ts index f4050b9de..cce59d100 100644 --- a/node_modules/tslint/lib/rules/noNullKeywordRule.d.ts +++ b/node_modules/tslint/lib/rules/noNullKeywordRule.d.ts @@ -1,19 +1,3 @@ -/** - * @license - * Copyright 2013 Palantir Technologies, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ import * as ts from "typescript"; import * as Lint from "../index"; export declare class Rule extends Lint.Rules.AbstractRule { diff --git a/node_modules/tslint/lib/rules/noNullKeywordRule.js b/node_modules/tslint/lib/rules/noNullKeywordRule.js index ef9a21db3..d02e85130 100644 --- a/node_modules/tslint/lib/rules/noNullKeywordRule.js +++ b/node_modules/tslint/lib/rules/noNullKeywordRule.js @@ -18,6 +18,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); // with due reference to https://github.com/Microsoft/TypeScript/blob/7813121c4d77e50aad0eed3152ef1f1156c7b574/scripts/tslint/noNullRule.ts +var tsutils_1 = require("tsutils"); var ts = require("typescript"); var Lint = require("../index"); var Rule = (function (_super) { @@ -28,32 +29,43 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-null-keyword", + description: "Disallows use of the `null` keyword literal.", + rationale: (_a = ["\n Instead of having the dual concepts of `null` and`undefined` in a codebase,\n this rule ensures that only `undefined` is used."], _a.raw = ["\n Instead of having the dual concepts of \\`null\\` and\\`undefined\\` in a codebase,\n this rule ensures that only \\`undefined\\` is used."], Lint.Utils.dedent(_a)), + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "functionality", + typescriptOnly: false, + hasFix: true, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "Use 'undefined' instead of 'null'"; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-null-keyword", - description: "Disallows use of the `null` keyword literal.", - rationale: (_a = ["\n Instead of having the dual concepts of `null` and`undefined` in a codebase,\n this rule ensures that only `undefined` is used."], _a.raw = ["\n Instead of having the dual concepts of \\`null\\` and\\`undefined\\` in a codebase,\n this rule ensures that only \\`undefined\\` is used."], Lint.Utils.dedent(_a)), - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "functionality", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "Use 'undefined' instead of 'null'"; exports.Rule = Rule; function walk(ctx) { return ts.forEachChild(ctx.sourceFile, cb); function cb(node) { - if (node.kind >= ts.SyntaxKind.FirstTypeNode && node.kind <= ts.SyntaxKind.LastTypeNode) { + if (tsutils_1.isTypeNodeKind(node.kind)) { return; // skip type nodes } - if (node.kind === ts.SyntaxKind.NullKeyword) { - return ctx.addFailureAtNode(node, Rule.FAILURE_STRING); + if (node.kind !== ts.SyntaxKind.NullKeyword) { + return ts.forEachChild(node, cb); + } + var parent = node.parent; + var eq; + if (tsutils_1.isBinaryExpression(parent)) { + eq = Lint.getEqualsKind(parent.operatorToken); + } + if (eq === undefined) { + ctx.addFailureAtNode(node, Rule.FAILURE_STRING); + } + else if (!eq.isStrict) { + ctx.addFailureAtNode(node, Rule.FAILURE_STRING, Lint.Replacement.replaceNode(node, "undefined", ctx.sourceFile)); } - return ts.forEachChild(node, cb); } } var _a; diff --git a/node_modules/tslint/lib/rules/noObjectLiteralTypeAssertionRule.d.ts b/node_modules/tslint/lib/rules/noObjectLiteralTypeAssertionRule.d.ts index 65ed5c49f..cce59d100 100644 --- a/node_modules/tslint/lib/rules/noObjectLiteralTypeAssertionRule.d.ts +++ b/node_modules/tslint/lib/rules/noObjectLiteralTypeAssertionRule.d.ts @@ -1,19 +1,3 @@ -/** - * @license - * Copyright 2017 Palantir Technologies, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ import * as ts from "typescript"; import * as Lint from "../index"; export declare class Rule extends Lint.Rules.AbstractRule { diff --git a/node_modules/tslint/lib/rules/noObjectLiteralTypeAssertionRule.js b/node_modules/tslint/lib/rules/noObjectLiteralTypeAssertionRule.js index 18d4ddd41..dd5a8f8ea 100644 --- a/node_modules/tslint/lib/rules/noObjectLiteralTypeAssertionRule.js +++ b/node_modules/tslint/lib/rules/noObjectLiteralTypeAssertionRule.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) { @@ -27,47 +28,29 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-object-literal-type-assertion", + description: (_a = ["\n Forbids an object literal to appear in a type assertion expression.\n Casting to `any` is still allowed."], _a.raw = ["\n Forbids an object literal to appear in a type assertion expression.\n Casting to \\`any\\` is still allowed."], Lint.Utils.dedent(_a)), + rationale: (_b = ["\n Always prefer `const x: T = { ... };` to `const x = { ... } as T;`.\n The type assertion in the latter case is either unnecessary or hides an error.\n The compiler will warn for excess properties with this syntax, but not missing required fields.\n For example: `const x: { foo: number } = {}` will fail to compile, but\n `const x = {} as { foo: number }` will succeed."], _b.raw = ["\n Always prefer \\`const x: T = { ... };\\` to \\`const x = { ... } as T;\\`.\n The type assertion in the latter case is either unnecessary or hides an error.\n The compiler will warn for excess properties with this syntax, but not missing required fields.\n For example: \\`const x: { foo: number } = {}\\` will fail to compile, but\n \\`const x = {} as { foo: number }\\` will succeed."], Lint.Utils.dedent(_b)), + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "functionality", + typescriptOnly: true, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "Type assertion on object literals is forbidden, use a type annotation instead."; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-object-literal-type-assertion", - description: (_a = ["\n Forbids an object literal to appear in a type assertion expression.\n Casting to `any` is still allowed."], _a.raw = ["\n Forbids an object literal to appear in a type assertion expression.\n Casting to \\`any\\` is still allowed."], Lint.Utils.dedent(_a)), - rationale: (_b = ["\n Always prefer `const x: T = { ... };` to `const x = { ... } as T;`.\n The type assertion in the latter case is either unnecessary or hides an error.\n The compiler will warn for excess properties with this syntax, but not missing required fields.\n For example: `const x: { foo: number } = {}` will fail to compile, but\n `const x = {} as { foo: number }` will succeed."], _b.raw = ["\n Always prefer \\`const x: T = { ... };\\` to \\`const x = { ... } as T;\\`.\n The type assertion in the latter case is either unnecessary or hides an error.\n The compiler will warn for excess properties with this syntax, but not missing required fields.\n For example: \\`const x: { foo: number } = {}\\` will fail to compile, but\n \\`const x = {} as { foo: number }\\` will succeed."], Lint.Utils.dedent(_b)), - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "functionality", - typescriptOnly: true, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "Type assertion on object literals is forbidden, use a type annotation instead."; exports.Rule = Rule; function walk(ctx) { return ts.forEachChild(ctx.sourceFile, function cb(node) { - if (isTypeAssertionLike(node) && isObjectLiteral(node.expression) && node.type.kind !== ts.SyntaxKind.AnyKeyword) { + if (tsutils_1.isAssertionExpression(node) && node.type.kind !== ts.SyntaxKind.AnyKeyword && + tsutils_1.isObjectLiteralExpression(tsutils_1.isParenthesizedExpression(node.expression) ? node.expression.expression : node.expression)) { ctx.addFailureAtNode(node, Rule.FAILURE_STRING); } return ts.forEachChild(node, cb); }); } -function isTypeAssertionLike(node) { - switch (node.kind) { - case ts.SyntaxKind.TypeAssertionExpression: - case ts.SyntaxKind.AsExpression: - return true; - default: - return false; - } -} -function isObjectLiteral(node) { - switch (node.kind) { - case ts.SyntaxKind.ParenthesizedExpression: - return isObjectLiteral(node.expression); - case ts.SyntaxKind.ObjectLiteralExpression: - return true; - default: - return false; - } -} var _a, _b; diff --git a/node_modules/tslint/lib/rules/noParameterPropertiesRule.d.ts b/node_modules/tslint/lib/rules/noParameterPropertiesRule.d.ts index 5e78ab8aa..c7e07066c 100644 --- a/node_modules/tslint/lib/rules/noParameterPropertiesRule.d.ts +++ b/node_modules/tslint/lib/rules/noParameterPropertiesRule.d.ts @@ -1,19 +1,3 @@ -/** - * @license - * Copyright 2013 Palantir Technologies, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ import * as ts from "typescript"; import * as Lint from "../index"; export declare class Rule extends Lint.Rules.AbstractRule { @@ -21,6 +5,3 @@ export declare class Rule extends Lint.Rules.AbstractRule { static FAILURE_STRING_FACTORY(ident: string): string; apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; } -export declare class NoParameterPropertiesWalker extends Lint.RuleWalker { - visitConstructorDeclaration(node: ts.ConstructorDeclaration): void; -} diff --git a/node_modules/tslint/lib/rules/noParameterPropertiesRule.js b/node_modules/tslint/lib/rules/noParameterPropertiesRule.js index 86fa67bad..d0b929650 100644 --- a/node_modules/tslint/lib/rules/noParameterPropertiesRule.js +++ b/node_modules/tslint/lib/rules/noParameterPropertiesRule.js @@ -17,6 +17,8 @@ */ 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) { tslib_1.__extends(Rule, _super); @@ -28,40 +30,33 @@ var Rule = (function (_super) { return "Property '" + ident + "' cannot be declared in the constructor"; }; Rule.prototype.apply = function (sourceFile) { - return this.applyWithWalker(new NoParameterPropertiesWalker(sourceFile, this.getOptions())); + return this.applyWithFunction(sourceFile, walk); + }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-parameter-properties", + description: "Disallows parameter properties in class constructors.", + rationale: (_a = ["\n Parameter properties can be confusing to those new to TS as they are less explicit\n than other ways of declaring and initializing class members."], _a.raw = ["\n Parameter properties can be confusing to those new to TS as they are less explicit\n than other ways of declaring and initializing class members."], Lint.Utils.dedent(_a)), + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "style", + typescriptOnly: true, }; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-parameter-properties", - description: "Disallows parameter properties in class constructors.", - rationale: (_a = ["\n Parameter properties can be confusing to those new to TS as they are less explicit\n than other ways of declaring and initializing class members."], _a.raw = ["\n Parameter properties can be confusing to those new to TS as they are less explicit\n than other ways of declaring and initializing class members."], Lint.Utils.dedent(_a)), - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "style", - typescriptOnly: true, -}; exports.Rule = Rule; -var NoParameterPropertiesWalker = (function (_super) { - tslib_1.__extends(NoParameterPropertiesWalker, _super); - function NoParameterPropertiesWalker() { - return _super !== null && _super.apply(this, arguments) || this; - } - NoParameterPropertiesWalker.prototype.visitConstructorDeclaration = function (node) { - var parameters = node.parameters; - for (var _i = 0, parameters_1 = parameters; _i < parameters_1.length; _i++) { - var parameter = parameters_1[_i]; - if (parameter.modifiers != null && parameter.modifiers.length > 0) { - var errorMessage = Rule.FAILURE_STRING_FACTORY(parameter.name.text); - var lastModifier = parameter.modifiers[parameter.modifiers.length - 1]; - this.addFailureFromStartToEnd(parameter.getStart(), lastModifier.getEnd(), errorMessage); +function walk(ctx) { + return ts.forEachChild(ctx.sourceFile, function cb(node) { + if (node.kind === ts.SyntaxKind.Constructor) { + for (var _i = 0, _a = node.parameters; _i < _a.length; _i++) { + var parameter = _a[_i]; + if (tsutils_1.isParameterProperty(parameter)) { + ctx.addFailure(parameter.getStart(ctx.sourceFile), parameter.name.pos, Rule.FAILURE_STRING_FACTORY(parameter.name.getText(ctx.sourceFile))); + } } } - _super.prototype.visitConstructorDeclaration.call(this, node); - }; - return NoParameterPropertiesWalker; -}(Lint.RuleWalker)); -exports.NoParameterPropertiesWalker = NoParameterPropertiesWalker; + return ts.forEachChild(node, cb); + }); +} var _a; diff --git a/node_modules/tslint/lib/rules/noReferenceImportRule.js b/node_modules/tslint/lib/rules/noReferenceImportRule.js index 8873d869a..25452c73e 100644 --- a/node_modules/tslint/lib/rules/noReferenceImportRule.js +++ b/node_modules/tslint/lib/rules/noReferenceImportRule.js @@ -32,17 +32,17 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithWalker(new NoReferenceImportWalker(sourceFile, this.ruleName, undefined)); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-reference-import", + description: 'Don\'t `<reference types="foo" />` if you import `foo` anyway.', + optionsDescription: "Not configurable.", + options: null, + type: "style", + typescriptOnly: true, + }; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-reference-import", - description: 'Don\'t <reference types="foo" /> if you import "foo" anyway.', - optionsDescription: "Not configurable.", - options: null, - type: "style", - typescriptOnly: true, -}; exports.Rule = Rule; var NoReferenceImportWalker = (function (_super) { tslib_1.__extends(NoReferenceImportWalker, _super); diff --git a/node_modules/tslint/lib/rules/noReferenceRule.js b/node_modules/tslint/lib/rules/noReferenceRule.js index 4e07beb92..56d5b10e9 100644 --- a/node_modules/tslint/lib/rules/noReferenceRule.js +++ b/node_modules/tslint/lib/rules/noReferenceRule.js @@ -26,21 +26,21 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-reference", + description: "Disallows `/// <reference path=>` imports (use ES6-style imports instead).", + rationale: (_a = ["\n Using `/// <reference path=>` comments to load other files is outdated.\n Use ES6-style imports to reference other files."], _a.raw = ["\n Using \\`/// <reference path=>\\` comments to load other files is outdated.\n Use ES6-style imports to reference other files."], Lint.Utils.dedent(_a)), + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "typescript", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "<reference> is not allowed, use imports"; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-reference", - description: "Disallows `/// <reference path=>` imports (use ES6-style imports instead).", - rationale: (_a = ["\n Using `/// <reference path=>` comments to load other files is outdated.\n Use ES6-style imports to reference other files."], _a.raw = ["\n Using \\`/// <reference path=>\\` comments to load other files is outdated.\n Use ES6-style imports to reference other files."], Lint.Utils.dedent(_a)), - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "typescript", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "<reference> is not allowed, use imports"; exports.Rule = Rule; function walk(ctx) { for (var _i = 0, _a = ctx.sourceFile.referencedFiles; _i < _a.length; _i++) { diff --git a/node_modules/tslint/lib/rules/noRequireImportsRule.js b/node_modules/tslint/lib/rules/noRequireImportsRule.js index 194c73eb4..a98236155 100644 --- a/node_modules/tslint/lib/rules/noRequireImportsRule.js +++ b/node_modules/tslint/lib/rules/noRequireImportsRule.js @@ -28,21 +28,21 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-require-imports", + description: "Disallows invocation of `require()`.", + rationale: "Prefer the newer ES6-style imports over `require()`.", + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "maintainability", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "require() style import is forbidden"; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-require-imports", - description: "Disallows invocation of `require()`.", - rationale: "Prefer the newer ES6-style imports over `require()`.", - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "maintainability", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "require() style import is forbidden"; exports.Rule = Rule; function walk(ctx) { return ts.forEachChild(ctx.sourceFile, function cb(node) { diff --git a/node_modules/tslint/lib/rules/noShadowedVariableRule.d.ts b/node_modules/tslint/lib/rules/noShadowedVariableRule.d.ts index 759d5fafb..1cd1b8c5c 100644 --- a/node_modules/tslint/lib/rules/noShadowedVariableRule.d.ts +++ b/node_modules/tslint/lib/rules/noShadowedVariableRule.d.ts @@ -1,19 +1,3 @@ -/** - * @license - * Copyright 2013 Palantir Technologies, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ import * as ts from "typescript"; import * as Lint from "../index"; export declare class Rule extends Lint.Rules.AbstractRule { diff --git a/node_modules/tslint/lib/rules/noShadowedVariableRule.js b/node_modules/tslint/lib/rules/noShadowedVariableRule.js index 53b3db09d..7aa485c18 100644 --- a/node_modules/tslint/lib/rules/noShadowedVariableRule.js +++ b/node_modules/tslint/lib/rules/noShadowedVariableRule.js @@ -17,8 +17,7 @@ */ Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); -// tslint:disable deprecation -// (https://github.com/palantir/tslint/pull/2598) +var tsutils_1 = require("tsutils"); var ts = require("typescript"); var Lint = require("../index"); var Rule = (function (_super) { @@ -28,116 +27,259 @@ var Rule = (function (_super) { } /* tslint:enable:object-literal-sort-keys */ Rule.FAILURE_STRING_FACTORY = function (name) { - return "Shadowed variable: '" + name + "'"; + return "Shadowed name: '" + name + "'"; }; Rule.prototype.apply = function (sourceFile) { - return this.applyWithWalker(new NoShadowedVariableWalker(sourceFile, this.getOptions())); + return this.applyWithWalker(new NoShadowedVariableWalker(sourceFile, this.ruleName, parseOptions(this.ruleArguments[0]))); + }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-shadowed-variable", + description: "Disallows shadowing variable declarations.", + rationale: "Shadowing a variable masks access to it and obscures to what value an identifier actually refers.", + optionsDescription: (_a = ["\n You can optionally pass an object to disable checking for certain kinds of declarations.\n Possible keys are `\"class\"`, `\"enum\"`, `\"function\"`, `\"import\"`, `\"interface\"`, `\"namespace\"`, `\"typeAlias\"`\n and `\"typeParameter\"`. Just set the value to `false` for the check you want to disable.\n All checks default to `true`, i.e. are enabled by default.\n Not that you cannot disable variables and parameters.\n "], _a.raw = ["\n You can optionally pass an object to disable checking for certain kinds of declarations.\n Possible keys are \\`\"class\"\\`, \\`\"enum\"\\`, \\`\"function\"\\`, \\`\"import\"\\`, \\`\"interface\"\\`, \\`\"namespace\"\\`, \\`\"typeAlias\"\\`\n and \\`\"typeParameter\"\\`. Just set the value to \\`false\\` for the check you want to disable.\n All checks default to \\`true\\`, i.e. are enabled by default.\n Not that you cannot disable variables and parameters.\n "], Lint.Utils.dedent(_a)), + options: { + type: "object", + properties: { + class: { type: "boolean" }, + enum: { type: "boolean" }, + function: { type: "boolean" }, + import: { type: "boolean" }, + interface: { type: "boolean" }, + namespace: { type: "boolean" }, + typeAlias: { type: "boolean" }, + typeParameter: { type: "boolean" }, + }, + }, + optionExamples: [ + true, + [true, { class: true, enum: true, function: true, interface: false, namespace: true, typeAlias: false, typeParameter: false }], + ], + type: "functionality", + typescriptOnly: false, }; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-shadowed-variable", - description: "Disallows shadowing variable declarations.", - rationale: "Shadowing a variable masks access to it and obscures to what value an identifier actually refers.", - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "functionality", - typescriptOnly: false, -}; exports.Rule = Rule; +function parseOptions(option) { + return tslib_1.__assign({ class: true, enum: true, function: true, import: true, interface: true, namespace: true, typeAlias: true, typeParameter: true }, option); +} +var Scope = (function () { + function Scope(functionScope) { + this.variables = new Map(); + this.variablesSeen = new Map(); + this.reassigned = new Set(); + // if no functionScope is provided we are in the process of creating a new function scope, which for consistency links to itself + this.functionScope = functionScope !== undefined ? functionScope : this; + } + Scope.prototype.addVariable = function (identifier, blockScoped) { + if (blockScoped === void 0) { blockScoped = true; } + // block scoped variables go to the block scope, function scoped variables to the containing function scope + var scope = blockScoped ? this : this.functionScope; + var list = scope.variables.get(identifier.text); + if (list === undefined) { + scope.variables.set(identifier.text, [identifier]); + } + else { + list.push(identifier); + } + }; + return Scope; +}()); var NoShadowedVariableWalker = (function (_super) { tslib_1.__extends(NoShadowedVariableWalker, _super); function NoShadowedVariableWalker() { return _super !== null && _super.apply(this, arguments) || this; } - NoShadowedVariableWalker.prototype.createScope = function () { - return new Set(); - }; - NoShadowedVariableWalker.prototype.createBlockScope = function () { - return new Set(); - }; - NoShadowedVariableWalker.prototype.visitBindingElement = function (node) { - var isSingleVariable = node.name.kind === ts.SyntaxKind.Identifier; - if (isSingleVariable) { - var name = node.name; - var variableDeclaration = Lint.getBindingElementVariableDeclaration(node); - var isBlockScopedVariable = variableDeclaration !== null && Lint.isBlockScopedVariable(variableDeclaration); - this.handleSingleVariableIdentifier(name, isBlockScopedVariable); - } - _super.prototype.visitBindingElement.call(this, node); - }; - NoShadowedVariableWalker.prototype.visitCatchClause = function (node) { - // don't visit the catch clause variable declaration, just visit the block - // the catch clause variable declaration has its own special scoping rules - this.visitBlock(node.block); - }; - NoShadowedVariableWalker.prototype.visitCallSignature = function (_node) { - // don't call super, we don't need to check parameter names in call signatures - }; - NoShadowedVariableWalker.prototype.visitFunctionType = function (_node) { - // don't call super, we don't need to check names in function types - }; - NoShadowedVariableWalker.prototype.visitConstructorType = function (_node) { - // don't call super, we don't need to check names in constructor types - }; - NoShadowedVariableWalker.prototype.visitIndexSignatureDeclaration = function (_node) { - // don't call super, we don't want to walk index signatures - }; - NoShadowedVariableWalker.prototype.visitMethodSignature = function (_node) { - // don't call super, we don't want to walk method signatures either - }; - NoShadowedVariableWalker.prototype.visitParameterDeclaration = function (node) { - var isSingleParameter = node.name.kind === ts.SyntaxKind.Identifier; - if (isSingleParameter) { - this.handleSingleVariableIdentifier(node.name, false); - } - _super.prototype.visitParameterDeclaration.call(this, node); + NoShadowedVariableWalker.prototype.walk = function (sourceFile) { + var _this = this; + this.scope = new Scope(); + var cb = function (node) { + var parentScope = _this.scope; + if ((_this.options.function && tsutils_1.isFunctionExpression(node) || _this.options.class && tsutils_1.isClassExpression(node)) && + node.name !== undefined) { + /* special handling for named function and class expressions: + technically the name of the function is only visible inside of it, + but variables with the same name declared inside don't cause compiler errors. + Therefore we add an additional function scope only for the function name to avoid merging with other declarations */ + var functionScope = new Scope(); + functionScope.addVariable(node.name, false); + _this.scope = new Scope(); + if (tsutils_1.isClassExpression(node)) { + _this.visitClassLikeDeclaration(node, functionScope, cb); + } + else { + ts.forEachChild(node, cb); + } + _this.onScopeEnd(functionScope); + _this.scope = functionScope; + _this.onScopeEnd(parentScope); + _this.scope = parentScope; + return; + } + /* Visit decorators before entering a function scope. + In the AST decorators are children of the declaration they decorate, but we don't want to warn for the following code: + @decorator((param) => param) + function foo(param) {} + */ + if (node.decorators !== undefined) { + for (var _i = 0, _a = node.decorators; _i < _a.length; _i++) { + var decorator = _a[_i]; + ts.forEachChild(decorator, cb); + } + } + var boundary = tsutils_1.isScopeBoundary(node); + if (boundary === 2 /* Block */) { + _this.scope = new Scope(parentScope.functionScope); + } + else if (boundary === 1 /* Function */) { + _this.scope = new Scope(); + } + switch (node.kind) { + case ts.SyntaxKind.Decorator: + return; // handled above + case ts.SyntaxKind.VariableDeclarationList: + _this.handleVariableDeclarationList(node); + break; + case ts.SyntaxKind.TypeParameter: + if (_this.options.typeParameter) { + _this.scope.addVariable(node.name); + } + break; + case ts.SyntaxKind.FunctionDeclaration: + if (_this.options.function && node.name !== undefined) { + parentScope.addVariable(node.name, false); + } + break; + case ts.SyntaxKind.ClassDeclaration: + if (_this.options.class && node.name !== undefined) { + parentScope.addVariable(node.name); + } + // falls through + case ts.SyntaxKind.ClassExpression: + _this.visitClassLikeDeclaration(node, parentScope, cb); + _this.onScopeEnd(parentScope); + _this.scope = parentScope; + return; + case ts.SyntaxKind.TypeAliasDeclaration: + if (_this.options.typeAlias) { + parentScope.addVariable(node.name); + } + break; + case ts.SyntaxKind.EnumDeclaration: + if (_this.options.enum) { + parentScope.addVariable(node.name); + } + break; + case ts.SyntaxKind.InterfaceDeclaration: + if (_this.options.interface) { + parentScope.addVariable(node.name); + } + break; + case ts.SyntaxKind.Parameter: + if (node.parent.kind !== ts.SyntaxKind.IndexSignature && + !tsutils_1.isThisParameter(node) && + tsutils_1.isFunctionWithBody(node.parent)) { + _this.handleBindingName(node.name, false); + } + break; + case ts.SyntaxKind.ModuleDeclaration: + if (_this.options.namespace && + node.parent.kind !== ts.SyntaxKind.ModuleDeclaration && + node.name.kind === ts.SyntaxKind.Identifier) { + parentScope.addVariable(node.name, false); + } + break; + case ts.SyntaxKind.ImportClause: + if (_this.options.import && node.name !== undefined) { + _this.scope.addVariable(node.name, false); + } + break; + case ts.SyntaxKind.NamespaceImport: + case ts.SyntaxKind.ImportSpecifier: + case ts.SyntaxKind.ImportEqualsDeclaration: + if (_this.options.import) { + _this.scope.addVariable(node.name, false); + } + } + if (boundary !== 0 /* None */) { + ts.forEachChild(node, cb); + _this.onScopeEnd(parentScope); + _this.scope = parentScope; + } + else { + return ts.forEachChild(node, cb); + } + }; + ts.forEachChild(sourceFile, cb); + this.onScopeEnd(); }; - NoShadowedVariableWalker.prototype.visitTypeLiteral = function (_node) { - // don't call super, we don't want to walk the inside of type nodes + NoShadowedVariableWalker.prototype.visitClassLikeDeclaration = function (declaration, parentScope, cb) { + var _this = this; + var currentScope = this.scope; + ts.forEachChild(declaration, function (node) { + if (!tsutils_1.hasModifier(node.modifiers, ts.SyntaxKind.StaticKeyword)) { + return cb(node); + } + /* Don't treat static members as children of the class' scope. That avoid shadowed type parameter warnings on static members. + class C<T> { + static method<T>() {} + } + */ + _this.scope = parentScope; + cb(node); + _this.scope = currentScope; + }); }; - NoShadowedVariableWalker.prototype.visitVariableDeclaration = function (node) { - var isSingleVariable = node.name.kind === ts.SyntaxKind.Identifier; - if (isSingleVariable) { - this.handleSingleVariableIdentifier(node.name, Lint.isBlockScopedVariable(node)); + NoShadowedVariableWalker.prototype.handleVariableDeclarationList = function (node) { + var blockScoped = tsutils_1.isBlockScopedVariableDeclarationList(node); + for (var _i = 0, _a = node.declarations; _i < _a.length; _i++) { + var variable = _a[_i]; + this.handleBindingName(variable.name, blockScoped); } - _super.prototype.visitVariableDeclaration.call(this, node); }; - NoShadowedVariableWalker.prototype.handleSingleVariableIdentifier = function (variableIdentifier, isBlockScoped) { - var variableName = variableIdentifier.text; - if (this.isVarInCurrentScope(variableName) && !this.inCurrentBlockScope(variableName)) { - // shadowing if there's already a `var` of the same name in the scope AND - // it's not in the current block (handled by the 'no-duplicate-variable' rule) - this.addFailureOnIdentifier(variableIdentifier); - } - else if (this.inPreviousBlockScope(variableName)) { - // shadowing if there is a `var`, `let`, 'const`, or parameter in a previous block scope - this.addFailureOnIdentifier(variableIdentifier); + NoShadowedVariableWalker.prototype.handleBindingName = function (node, blockScoped) { + if (node.kind === ts.SyntaxKind.Identifier) { + this.scope.addVariable(node, blockScoped); } - if (!isBlockScoped) { - // `var` variables go on the scope - this.getCurrentScope().add(variableName); + else { + for (var _i = 0, _a = node.elements; _i < _a.length; _i++) { + var element = _a[_i]; + if (element.kind !== ts.SyntaxKind.OmittedExpression) { + this.handleBindingName(element.name, blockScoped); + } + } } - // all variables go on block scope, including `var` - this.getCurrentBlockScope().add(variableName); }; - NoShadowedVariableWalker.prototype.isVarInCurrentScope = function (varName) { - return this.getCurrentScope().has(varName); - }; - NoShadowedVariableWalker.prototype.inCurrentBlockScope = function (varName) { - return this.getCurrentBlockScope().has(varName); - }; - NoShadowedVariableWalker.prototype.inPreviousBlockScope = function (varName) { + NoShadowedVariableWalker.prototype.onScopeEnd = function (parent) { var _this = this; - return this.getAllBlockScopes().some(function (scopeInfo) { - return scopeInfo !== _this.getCurrentBlockScope() && scopeInfo.has(varName); + var _a = this.scope, variables = _a.variables, variablesSeen = _a.variablesSeen; + variablesSeen.forEach(function (identifiers, name) { + if (variables.has(name)) { + for (var _i = 0, identifiers_1 = identifiers; _i < identifiers_1.length; _i++) { + var identifier = identifiers_1[_i]; + _this.addFailureAtNode(identifier, Rule.FAILURE_STRING_FACTORY(name)); + } + } + else if (parent !== undefined) { + addToList(parent.variablesSeen, name, identifiers); + } }); - }; - NoShadowedVariableWalker.prototype.addFailureOnIdentifier = function (ident) { - var failureString = Rule.FAILURE_STRING_FACTORY(ident.text); - this.addFailureAtNode(ident, failureString); + if (parent !== undefined) { + variables.forEach(function (identifiers, name) { + addToList(parent.variablesSeen, name, identifiers); + }); + } }; return NoShadowedVariableWalker; -}(Lint.BlockScopeAwareRuleWalker)); +}(Lint.AbstractWalker)); +function addToList(map, name, identifiers) { + var list = map.get(name); + if (list === undefined) { + map.set(name, identifiers); + } + else { + list.push.apply(list, identifiers); + } +} +var _a; diff --git a/node_modules/tslint/lib/rules/noSparseArraysRule.js b/node_modules/tslint/lib/rules/noSparseArraysRule.js index 15bf3ff32..e8bd49d3e 100644 --- a/node_modules/tslint/lib/rules/noSparseArraysRule.js +++ b/node_modules/tslint/lib/rules/noSparseArraysRule.js @@ -28,21 +28,21 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-sparse-arrays", + description: "Forbids array literals to contain missing elements.", + rationale: "Missing elements are probably an accidentally duplicated comma.", + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "functionality", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "Array has a missing element."; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-sparse-arrays", - description: "Forbids array literals to contain missing elements.", - rationale: "Missing elements are probably an accidentally duplicated comma.", - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "functionality", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "Array has a missing element."; exports.Rule = Rule; function walk(ctx) { return ts.forEachChild(ctx.sourceFile, function cb(node) { @@ -92,7 +92,6 @@ function traverseExpressionsInLHS(node, cb) { traverseExpressionsInLHS(left, cb); cb(right); } - break; } } } diff --git a/node_modules/tslint/lib/rules/noStringLiteralRule.js b/node_modules/tslint/lib/rules/noStringLiteralRule.js index 672e35f89..5786e6f5e 100644 --- a/node_modules/tslint/lib/rules/noStringLiteralRule.js +++ b/node_modules/tslint/lib/rules/noStringLiteralRule.js @@ -28,22 +28,22 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-string-literal", + description: (_a = ["\n Forbids unnecessary string literal property access.\n Allows `obj[\"prop-erty\"]` (can't be a regular property access).\n Disallows `obj[\"property\"]` (should be `obj.property`)."], _a.raw = ["\n Forbids unnecessary string literal property access.\n Allows \\`obj[\"prop-erty\"]\\` (can't be a regular property access).\n Disallows \\`obj[\"property\"]\\` (should be \\`obj.property\\`)."], Lint.Utils.dedent(_a)), + rationale: (_b = ["\n If `--noImplicitAny` is turned off,\n property access via a string literal will be 'any' if the property does not exist."], _b.raw = ["\n If \\`--noImplicitAny\\` is turned off,\n property access via a string literal will be 'any' if the property does not exist."], Lint.Utils.dedent(_b)), + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "functionality", + typescriptOnly: false, + hasFix: true, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "object access via string literals is disallowed"; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-string-literal", - description: "Disallows object access via string literals.", - rationale: "Encourages using strongly-typed property access.", - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "functionality", - typescriptOnly: false, - hasFix: true, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "object access via string literals is disallowed"; exports.Rule = Rule; function walk(ctx) { return ts.forEachChild(ctx.sourceFile, function cb(node) { @@ -58,3 +58,4 @@ function walk(ctx) { return ts.forEachChild(node, cb); }); } +var _a, _b; diff --git a/node_modules/tslint/lib/rules/noStringThrowRule.js b/node_modules/tslint/lib/rules/noStringThrowRule.js index f934407a2..0dddcb10a 100644 --- a/node_modules/tslint/lib/rules/noStringThrowRule.js +++ b/node_modules/tslint/lib/rules/noStringThrowRule.js @@ -28,21 +28,21 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-string-throw", + description: "Flags throwing plain strings or concatenations of strings " + + "because only Errors produce proper stack traces.", + hasFix: true, + options: null, + optionsDescription: "Not configurable.", + type: "functionality", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "Throwing plain strings (not instances of Error) gives no stack traces"; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-string-throw", - description: "Flags throwing plain strings or concatenations of strings " + - "because only Errors produce proper stack traces.", - hasFix: true, - options: null, - optionsDescription: "Not configurable.", - type: "functionality", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "Throwing plain strings (not instances of Error) gives no stack traces"; exports.Rule = Rule; function walk(ctx) { var sourceFile = ctx.sourceFile; diff --git a/node_modules/tslint/lib/rules/noSubmoduleImportsRule.d.ts b/node_modules/tslint/lib/rules/noSubmoduleImportsRule.d.ts new file mode 100644 index 000000000..cce59d100 --- /dev/null +++ b/node_modules/tslint/lib/rules/noSubmoduleImportsRule.d.ts @@ -0,0 +1,7 @@ +import * as ts from "typescript"; +import * as Lint from "../index"; +export declare class Rule extends Lint.Rules.AbstractRule { + static metadata: Lint.IRuleMetadata; + static FAILURE_STRING: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/node_modules/tslint/lib/rules/noSubmoduleImportsRule.js b/node_modules/tslint/lib/rules/noSubmoduleImportsRule.js new file mode 100644 index 000000000..5a638301c --- /dev/null +++ b/node_modules/tslint/lib/rules/noSubmoduleImportsRule.js @@ -0,0 +1,112 @@ +"use strict"; +/** + * @license + * Copyright 2017 Palantir Technologies, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +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) { + tslib_1.__extends(Rule, _super); + function Rule() { + return _super !== null && _super.apply(this, arguments) || this; + } + Rule.prototype.apply = function (sourceFile) { + return this.applyWithWalker(new NoSubmoduleImportsWalker(sourceFile, this.ruleName, this.ruleArguments)); + }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-submodule-imports", + description: (_a = ["\n Disallows importing any submodule."], _a.raw = ["\n Disallows importing any submodule."], Lint.Utils.dedent(_a)), + rationale: (_b = ["\n Submodules of some packages are treated as private APIs and the import\n paths may change without deprecation periods. It's best to stick with\n top-level package exports."], _b.raw = ["\n Submodules of some packages are treated as private APIs and the import\n paths may change without deprecation periods. It's best to stick with\n top-level package exports."], Lint.Utils.dedent(_b)), + optionsDescription: "A list of packages whose submodules are whitelisted.", + options: { + type: "array", + items: { + type: "string", + }, + minLength: 0, + }, + optionExamples: [true, [true, "rxjs", "@angular/core"]], + type: "functionality", + typescriptOnly: false, + }; + Rule.FAILURE_STRING = "Submodule import paths from this package are disallowed; import from the root instead"; + return Rule; +}(Lint.Rules.AbstractRule)); +exports.Rule = Rule; +var NoSubmoduleImportsWalker = (function (_super) { + tslib_1.__extends(NoSubmoduleImportsWalker, _super); + function NoSubmoduleImportsWalker() { + return _super !== null && _super.apply(this, arguments) || this; + } + NoSubmoduleImportsWalker.prototype.walk = function (sourceFile) { + var _this = this; + var findDynamicImport = function (node) { + if (tsutils_1.isCallExpression(node) && node.arguments.length === 1 && + (tsutils_1.isIdentifier(node.expression) && node.expression.text === "require" || + node.expression.kind === ts.SyntaxKind.ImportKeyword)) { + _this.checkForBannedImport(node.arguments[0]); + } + return ts.forEachChild(node, findDynamicImport); + }; + for (var _i = 0, _a = sourceFile.statements; _i < _a.length; _i++) { + var statement = _a[_i]; + if (tsutils_1.isImportDeclaration(statement)) { + this.checkForBannedImport(statement.moduleSpecifier); + } + else if (tsutils_1.isImportEqualsDeclaration(statement)) { + if (tsutils_1.isExternalModuleReference(statement.moduleReference) && statement.moduleReference.expression !== undefined) { + this.checkForBannedImport(statement.moduleReference.expression); + } + } + else { + ts.forEachChild(statement, findDynamicImport); + } + } + }; + NoSubmoduleImportsWalker.prototype.checkForBannedImport = function (expression) { + if (tsutils_1.isTextualLiteral(expression)) { + if (isAbsoluteOrRelativePath(expression.text) || !isSubmodulePath(expression.text)) { + return; + } + /** + * A submodule is being imported. + * Check if its path contains any + * of the whitelist packages. + */ + for (var _i = 0, _a = this.options; _i < _a.length; _i++) { + var option = _a[_i]; + if (expression.text.startsWith(option + "/")) { + return; + } + } + this.addFailureAtNode(expression, Rule.FAILURE_STRING); + } + }; + return NoSubmoduleImportsWalker; +}(Lint.AbstractWalker)); +function isAbsoluteOrRelativePath(path) { + return /^(..?(\/|$)|\/)/.test(path); +} +function isScopedPath(path) { + return path[0] === "@"; +} +function isSubmodulePath(path) { + return path.split("/").length > (isScopedPath(path) ? 2 : 1); +} +var _a, _b; diff --git a/node_modules/tslint/lib/rules/noSwitchCaseFallThroughRule.d.ts b/node_modules/tslint/lib/rules/noSwitchCaseFallThroughRule.d.ts index 1fe06743f..ff699286d 100644 --- a/node_modules/tslint/lib/rules/noSwitchCaseFallThroughRule.d.ts +++ b/node_modules/tslint/lib/rules/noSwitchCaseFallThroughRule.d.ts @@ -6,7 +6,7 @@ export declare class Rule extends Lint.Rules.AbstractRule { apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; } export declare class NoSwitchCaseFallThroughWalker extends Lint.AbstractWalker<void> { - walk(sourceFile: ts.SourceFile): void; + walk(sourceFile: ts.SourceFile): void | undefined; private visitSwitchStatement({caseBlock: {clauses}}); private isFallThroughAllowed(clause); } diff --git a/node_modules/tslint/lib/rules/noSwitchCaseFallThroughRule.js b/node_modules/tslint/lib/rules/noSwitchCaseFallThroughRule.js index 94c570c29..db7d04575 100644 --- a/node_modules/tslint/lib/rules/noSwitchCaseFallThroughRule.js +++ b/node_modules/tslint/lib/rules/noSwitchCaseFallThroughRule.js @@ -32,20 +32,20 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithWalker(new NoSwitchCaseFallThroughWalker(sourceFile, this.ruleName, undefined)); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-switch-case-fall-through", + description: "Disallows falling through case statements.", + descriptionDetails: (_a = ["\n For example, the following is not allowed:\n\n ```ts\n switch(foo) {\n case 1:\n someFunc(foo);\n case 2:\n someOtherFunc(foo);\n }\n ```\n\n However, fall through is allowed when case statements are consecutive or\n a magic `/* falls through */` comment is present. The following is valid:\n\n ```ts\n switch(foo) {\n case 1:\n someFunc(foo);\n /* falls through */\n case 2:\n case 3:\n someOtherFunc(foo);\n }\n ```"], _a.raw = ["\n For example, the following is not allowed:\n\n \\`\\`\\`ts\n switch(foo) {\n case 1:\n someFunc(foo);\n case 2:\n someOtherFunc(foo);\n }\n \\`\\`\\`\n\n However, fall through is allowed when case statements are consecutive or\n a magic \\`/* falls through */\\` comment is present. The following is valid:\n\n \\`\\`\\`ts\n switch(foo) {\n case 1:\n someFunc(foo);\n /* falls through */\n case 2:\n case 3:\n someOtherFunc(foo);\n }\n \\`\\`\\`"], Lint.Utils.dedent(_a)), + rationale: "Fall though in switch statements is often unintentional and a bug.", + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "functionality", + typescriptOnly: false, + }; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-switch-case-fall-through", - description: "Disallows falling through case statements.", - descriptionDetails: (_a = ["\n For example, the following is not allowed:\n\n ```ts\n switch(foo) {\n case 1:\n someFunc(foo);\n case 2:\n someOtherFunc(foo);\n }\n ```\n\n However, fall through is allowed when case statements are consecutive or\n a magic `/* falls through */` comment is present. The following is valid:\n\n ```ts\n switch(foo) {\n case 1:\n someFunc(foo);\n /* falls through */\n case 2:\n case 3:\n someOtherFunc(foo);\n }\n ```"], _a.raw = ["\n For example, the following is not allowed:\n\n \\`\\`\\`ts\n switch(foo) {\n case 1:\n someFunc(foo);\n case 2:\n someOtherFunc(foo);\n }\n \\`\\`\\`\n\n However, fall through is allowed when case statements are consecutive or\n a magic \\`/* falls through */\\` comment is present. The following is valid:\n\n \\`\\`\\`ts\n switch(foo) {\n case 1:\n someFunc(foo);\n /* falls through */\n case 2:\n case 3:\n someOtherFunc(foo);\n }\n \\`\\`\\`"], Lint.Utils.dedent(_a)), - rationale: "Fall though in switch statements is often unintentional and a bug.", - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "functionality", - typescriptOnly: false, -}; exports.Rule = Rule; var NoSwitchCaseFallThroughWalker = (function (_super) { tslib_1.__extends(NoSwitchCaseFallThroughWalker, _super); @@ -78,13 +78,10 @@ var NoSwitchCaseFallThroughWalker = (function (_super) { NoSwitchCaseFallThroughWalker.prototype.isFallThroughAllowed = function (clause) { var _this = this; var comments = ts.getLeadingCommentRanges(this.sourceFile.text, clause.end); - return comments !== undefined && comments.some(function (comment) { return commentText(comment, _this.sourceFile).trim() === "falls through"; }); + return comments !== undefined && + comments.some(function (comment) { return /^\s*falls through\b/i.test(_this.sourceFile.text.slice(comment.pos + 2, comment.end)); }); }; return NoSwitchCaseFallThroughWalker; }(Lint.AbstractWalker)); exports.NoSwitchCaseFallThroughWalker = NoSwitchCaseFallThroughWalker; -function commentText(_a, sourceFile) { - var pos = _a.pos, end = _a.end, kind = _a.kind; - return sourceFile.text.slice(pos + 2, kind === ts.SyntaxKind.MultiLineCommentTrivia ? end - 2 : end); -} var _a; diff --git a/node_modules/tslint/lib/rules/noThisAssignmentRule.d.ts b/node_modules/tslint/lib/rules/noThisAssignmentRule.d.ts new file mode 100644 index 000000000..2eaf0e03c --- /dev/null +++ b/node_modules/tslint/lib/rules/noThisAssignmentRule.d.ts @@ -0,0 +1,8 @@ +import * as ts from "typescript"; +import * as Lint from "../index"; +export declare class Rule extends Lint.Rules.AbstractRule { + static metadata: Lint.IRuleMetadata; + static FAILURE_STRING_BINDINGS: string; + static FAILURE_STRING_FACTORY_IDENTIFIERS(name: string): string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/node_modules/tslint/lib/rules/noThisAssignmentRule.js b/node_modules/tslint/lib/rules/noThisAssignmentRule.js new file mode 100644 index 000000000..64cacccf8 --- /dev/null +++ b/node_modules/tslint/lib/rules/noThisAssignmentRule.js @@ -0,0 +1,128 @@ +"use strict"; +/** + * @license + * Copyright 2017 Palantir Technologies, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +Object.defineProperty(exports, "__esModule", { value: true }); +var tslib_1 = require("tslib"); +var utils = require("tsutils"); +var ts = require("typescript"); +var Lint = require("../index"); +var ALLOW_THIS_DESTRUCTURING = "allow-destructuring"; +var ALLOWED_THIS_NAMES = "allowed-names"; +var parseConfigOptions = function (configOptions) { + var allowedNames = []; + var allowDestructuring = false; + if (configOptions !== undefined) { + allowDestructuring = !!configOptions[ALLOW_THIS_DESTRUCTURING]; + if (configOptions[ALLOWED_THIS_NAMES] !== undefined) { + allowedNames.push.apply(allowedNames, configOptions[ALLOWED_THIS_NAMES]); + } + } + return { allowedNames: allowedNames, allowDestructuring: allowDestructuring }; +}; +var Rule = (function (_super) { + tslib_1.__extends(Rule, _super); + function Rule() { + return _super !== null && _super.apply(this, arguments) || this; + } + Rule.FAILURE_STRING_FACTORY_IDENTIFIERS = function (name) { + return "Assigning `this` reference to local variable not allowed: " + name + "."; + }; + Rule.prototype.apply = function (sourceFile) { + var options = parseConfigOptions(this.ruleArguments[0]); + var noThisAssignmentWalker = new NoThisAssignmentWalker(sourceFile, this.ruleName, options); + return this.applyWithWalker(noThisAssignmentWalker); + }; + Rule.metadata = { + description: "Disallows unnecessary references to `this`.", + optionExamples: [ + true, + [ + true, + (_a = {}, + _a[ALLOWED_THIS_NAMES] = ["^self$"], + _a[ALLOW_THIS_DESTRUCTURING] = true, + _a), + ], + ], + options: { + additionalProperties: false, + properties: (_b = {}, + _b[ALLOW_THIS_DESTRUCTURING] = { + type: "boolean", + }, + _b[ALLOWED_THIS_NAMES] = { + listType: "string", + type: "list", + }, + _b), + type: "object", + }, + optionsDescription: (_c = ["\n Two options may be provided on an object:\n\n * `", "` allows using destructuring to access members of `this` (e.g. `{ foo, bar } = this;`).\n * `", "` may be specified as a list of regular expressions to match allowed variable names."], _c.raw = ["\n Two options may be provided on an object:\n\n * \\`", "\\` allows using destructuring to access members of \\`this\\` (e.g. \\`{ foo, bar } = this;\\`).\n * \\`", "\\` may be specified as a list of regular expressions to match allowed variable names."], Lint.Utils.dedent(_c, ALLOW_THIS_DESTRUCTURING, ALLOWED_THIS_NAMES)), + rationale: "Assigning a variable to `this` instead of properly using arrow lambdas " + + "may be a symptom of pre-ES6 practices or not manging scope well.", + ruleName: "no-this-assignment", + type: "functionality", + typescriptOnly: false, + }; + Rule.FAILURE_STRING_BINDINGS = "Don't assign members of `this` to local variables."; + return Rule; +}(Lint.Rules.AbstractRule)); +exports.Rule = Rule; +var NoThisAssignmentWalker = (function (_super) { + tslib_1.__extends(NoThisAssignmentWalker, _super); + function NoThisAssignmentWalker() { + var _this = _super !== null && _super.apply(this, arguments) || this; + _this.allowedThisNameTesters = _this.options.allowedNames.map(function (allowedThisName) { return new RegExp(allowedThisName); }); + _this.visitNode = function (node) { + if (utils.isVariableDeclaration(node)) { + _this.visitVariableDeclaration(node); + } + ts.forEachChild(node, _this.visitNode); + }; + return _this; + } + NoThisAssignmentWalker.prototype.walk = function (sourceFile) { + ts.forEachChild(sourceFile, this.visitNode); + }; + NoThisAssignmentWalker.prototype.visitVariableDeclaration = function (node) { + if (node.initializer === undefined || node.initializer.kind !== ts.SyntaxKind.ThisKeyword) { + return; + } + switch (node.name.kind) { + case ts.SyntaxKind.Identifier: + if (this.variableNameIsBanned(node.name.text)) { + this.addFailureAtNode(node, Rule.FAILURE_STRING_FACTORY_IDENTIFIERS(node.name.text)); + } + break; + default: + if (!this.options.allowDestructuring) { + this.addFailureAtNode(node, Rule.FAILURE_STRING_BINDINGS); + } + } + }; + NoThisAssignmentWalker.prototype.variableNameIsBanned = function (name) { + for (var _i = 0, _a = this.allowedThisNameTesters; _i < _a.length; _i++) { + var tester = _a[_i]; + if (tester.test(name)) { + return false; + } + } + return true; + }; + return NoThisAssignmentWalker; +}(Lint.AbstractWalker)); +var _a, _b, _c; diff --git a/node_modules/tslint/lib/rules/noTrailingWhitespaceRule.js b/node_modules/tslint/lib/rules/noTrailingWhitespaceRule.js index 56615b1b5..b29aec663 100644 --- a/node_modules/tslint/lib/rules/noTrailingWhitespaceRule.js +++ b/node_modules/tslint/lib/rules/noTrailingWhitespaceRule.js @@ -37,32 +37,32 @@ var Rule = (function (_super) { ignoreTemplates: this.ruleArguments.indexOf(OPTION_IGNORE_TEMPLATE_STRINGS) !== -1, }); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-trailing-whitespace", + description: "Disallows trailing whitespace at the end of a line.", + rationale: "Keeps version control diffs clean as it prevents accidental whitespace from being committed.", + optionsDescription: (_a = ["\n Possible settings are:\n\n * `\"", "\"`: Allows trailing whitespace in template strings.\n * `\"", "\"`: Allows trailing whitespace in comments.\n * `\"", "\"`: Allows trailing whitespace only in JSDoc comments."], _a.raw = ["\n Possible settings are:\n\n * \\`\"", "\"\\`: Allows trailing whitespace in template strings.\n * \\`\"", "\"\\`: Allows trailing whitespace in comments.\n * \\`\"", "\"\\`: Allows trailing whitespace only in JSDoc comments."], Lint.Utils.dedent(_a, OPTION_IGNORE_TEMPLATE_STRINGS, OPTION_IGNORE_COMMENTS, OPTION_IGNORE_JSDOC)), + hasFix: true, + options: { + type: "array", + items: { + type: "string", + enum: [OPTION_IGNORE_COMMENTS, OPTION_IGNORE_JSDOC, OPTION_IGNORE_TEMPLATE_STRINGS], + }, + }, + optionExamples: [ + true, + [true, OPTION_IGNORE_COMMENTS], + [true, OPTION_IGNORE_JSDOC], + ], + type: "style", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "trailing whitespace"; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-trailing-whitespace", - description: "Disallows trailing whitespace at the end of a line.", - rationale: "Keeps version control diffs clean as it prevents accidental whitespace from being committed.", - optionsDescription: (_a = ["\n Possible settings are:\n\n * `\"", "\"`: Allows trailing whitespace in template strings.\n * `\"", "\"`: Allows trailing whitespace in comments.\n * `\"", "\"`: Allows trailing whitespace only in JSDoc comments."], _a.raw = ["\n Possible settings are:\n\n * \\`\"", "\"\\`: Allows trailing whitespace in template strings.\n * \\`\"", "\"\\`: Allows trailing whitespace in comments.\n * \\`\"", "\"\\`: Allows trailing whitespace only in JSDoc comments."], Lint.Utils.dedent(_a, OPTION_IGNORE_TEMPLATE_STRINGS, OPTION_IGNORE_COMMENTS, OPTION_IGNORE_JSDOC)), - hasFix: true, - options: { - type: "array", - items: { - type: "string", - enum: [OPTION_IGNORE_COMMENTS, OPTION_IGNORE_JSDOC, OPTION_IGNORE_TEMPLATE_STRINGS], - }, - }, - optionExamples: [ - true, - [true, OPTION_IGNORE_COMMENTS], - [true, OPTION_IGNORE_JSDOC], - ], - type: "style", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "trailing whitespace"; exports.Rule = Rule; function walk(ctx) { var possibleFailures = []; diff --git a/node_modules/tslint/lib/rules/noUnboundMethodRule.d.ts b/node_modules/tslint/lib/rules/noUnboundMethodRule.d.ts index 4df32174e..d2d51d1d1 100644 --- a/node_modules/tslint/lib/rules/noUnboundMethodRule.d.ts +++ b/node_modules/tslint/lib/rules/noUnboundMethodRule.d.ts @@ -1,19 +1,3 @@ -/** - * @license - * Copyright 2017 Palantir Technologies, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ import * as ts from "typescript"; import * as Lint from "../index"; export declare class Rule extends Lint.Rules.TypedRule { diff --git a/node_modules/tslint/lib/rules/noUnboundMethodRule.js b/node_modules/tslint/lib/rules/noUnboundMethodRule.js index 388cfa404..80804b58d 100644 --- a/node_modules/tslint/lib/rules/noUnboundMethodRule.js +++ b/node_modules/tslint/lib/rules/noUnboundMethodRule.js @@ -17,54 +17,56 @@ */ 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 OPTION_IGNORE_STATIC = "ignore-static"; var Rule = (function (_super) { tslib_1.__extends(Rule, _super); function Rule() { return _super !== null && _super.apply(this, arguments) || this; } 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()); }, { + ignoreStatic: this.ruleArguments.indexOf(OPTION_IGNORE_STATIC) !== -1, + }); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-unbound-method", + description: "Warns when a method is used as outside of a method call.", + optionsDescription: "You may optionally pass \"" + OPTION_IGNORE_STATIC + "\" to ignore static methods.", + options: { + type: "string", + enum: [OPTION_IGNORE_STATIC], + }, + optionExamples: [true, [true, OPTION_IGNORE_STATIC]], + type: "functionality", + typescriptOnly: true, + requiresTypeInfo: true, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "Avoid referencing unbound methods which may cause unintentional scoping of 'this'."; return Rule; }(Lint.Rules.TypedRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-unbound-method", - description: "Warns when a method is used as outside of a method call.", - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "functionality", - typescriptOnly: true, - requiresTypeInfo: true, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "Avoid referencing unbound methods which may cause unintentional scoping of 'this'."; exports.Rule = Rule; -var Walker = (function (_super) { - tslib_1.__extends(Walker, _super); - function Walker() { - return _super !== null && _super.apply(this, arguments) || this; - } - Walker.prototype.visitPropertyAccessExpression = function (node) { - if (!isSafeUse(node)) { - var symbol = this.getTypeChecker().getSymbolAtLocation(node); +function walk(ctx, tc) { + return ts.forEachChild(ctx.sourceFile, function cb(node) { + if (tsutils_1.isPropertyAccessExpression(node) && !isSafeUse(node)) { + var symbol = tc.getSymbolAtLocation(node); var declaration = symbol === undefined ? undefined : symbol.valueDeclaration; - if (declaration !== undefined && isMethod(declaration)) { - this.addFailureAtNode(node, Rule.FAILURE_STRING); + if (declaration !== undefined && isMethod(declaration, ctx.options.ignoreStatic)) { + ctx.addFailureAtNode(node, Rule.FAILURE_STRING); } } - _super.prototype.visitPropertyAccessExpression.call(this, node); - }; - return Walker; -}(Lint.ProgramAwareRuleWalker)); -function isMethod(node) { + return ts.forEachChild(node, cb); + }); +} +function isMethod(node, ignoreStatic) { switch (node.kind) { case ts.SyntaxKind.MethodDeclaration: case ts.SyntaxKind.MethodSignature: - return true; + return !(ignoreStatic && tsutils_1.hasModifier(node.modifiers, ts.SyntaxKind.StaticKeyword)); default: return false; } @@ -82,6 +84,19 @@ function isSafeUse(node) { // Allow most binary operators, but don't allow e.g. `myArray.forEach(obj.method || otherObj.otherMethod)`. case ts.SyntaxKind.BinaryExpression: return parent.operatorToken.kind !== ts.SyntaxKind.BarBarToken; + case ts.SyntaxKind.NonNullExpression: + case ts.SyntaxKind.AsExpression: + case ts.SyntaxKind.TypeAssertionExpression: + case ts.SyntaxKind.ParenthesizedExpression: + return isSafeUse(parent); + // Allow use in conditions + case ts.SyntaxKind.ConditionalExpression: + return parent.condition === node; + case ts.SyntaxKind.IfStatement: + case ts.SyntaxKind.WhileStatement: + case ts.SyntaxKind.DoStatement: + case ts.SyntaxKind.ForStatement: + return true; default: return false; } diff --git a/node_modules/tslint/lib/rules/noUnnecessaryCallbackWrapperRule.js b/node_modules/tslint/lib/rules/noUnnecessaryCallbackWrapperRule.js index ad46a3eb8..69977baf5 100644 --- a/node_modules/tslint/lib/rules/noUnnecessaryCallbackWrapperRule.js +++ b/node_modules/tslint/lib/rules/noUnnecessaryCallbackWrapperRule.js @@ -32,18 +32,18 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-unnecessary-callback-wrapper", + description: (_a = ["\n Replaces `x => f(x)` with just `f`.\n To catch more cases, enable `only-arrow-functions` and `arrow-return-shorthand` too."], _a.raw = ["\n Replaces \\`x => f(x)\\` with just \\`f\\`.\n To catch more cases, enable \\`only-arrow-functions\\` and \\`arrow-return-shorthand\\` too."], Lint.Utils.dedent(_a)), + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "style", + typescriptOnly: false, + }; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-unnecessary-callback-wrapper", - description: (_a = ["\n Replaces `x => f(x)` with just `f`.\n To catch more cases, enable `only-arrow-functions` and `arrow-return-shorthand` too."], _a.raw = ["\n Replaces \\`x => f(x)\\` with just \\`f\\`.\n To catch more cases, enable \\`only-arrow-functions\\` and \\`arrow-return-shorthand\\` too."], Lint.Utils.dedent(_a)), - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "style", - typescriptOnly: false, -}; exports.Rule = Rule; function walk(ctx) { return ts.forEachChild(ctx.sourceFile, cb); diff --git a/node_modules/tslint/lib/rules/noUnnecessaryInitializerRule.js b/node_modules/tslint/lib/rules/noUnnecessaryInitializerRule.js index b147fe076..e02c3a905 100644 --- a/node_modules/tslint/lib/rules/noUnnecessaryInitializerRule.js +++ b/node_modules/tslint/lib/rules/noUnnecessaryInitializerRule.js @@ -28,23 +28,23 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-unnecessary-initializer", + description: "Forbids a 'var'/'let' statement or destructuring initializer to be initialized to 'undefined'.", + hasFix: true, + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "style", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "Unnecessary initialization to 'undefined'."; + Rule.FAILURE_STRING_PARAMETER = "Use an optional parameter instead of initializing to 'undefined'. " + + "Also, the type declaration does not need to include '| undefined'."; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-unnecessary-initializer", - description: "Forbids a 'var'/'let' statement or destructuring initializer to be initialized to 'undefined'.", - hasFix: true, - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "style", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "Unnecessary initialization to 'undefined'."; -Rule.FAILURE_STRING_PARAMETER = "Use an optional parameter instead of initializing to 'undefined'. " + - "Also, the type declaration does not need to include '| undefined'."; exports.Rule = Rule; function walk(ctx) { ts.forEachChild(ctx.sourceFile, function cb(node) { @@ -72,7 +72,6 @@ function walk(ctx) { } } }); - break; } } ts.forEachChild(node, cb); diff --git a/node_modules/tslint/lib/rules/noUnnecessaryQualifierRule.js b/node_modules/tslint/lib/rules/noUnnecessaryQualifierRule.js index 4d8a1e2da..374854d97 100644 --- a/node_modules/tslint/lib/rules/noUnnecessaryQualifierRule.js +++ b/node_modules/tslint/lib/rules/noUnnecessaryQualifierRule.js @@ -32,20 +32,20 @@ var Rule = (function (_super) { Rule.prototype.applyWithProgram = function (sourceFile, program) { return this.applyWithFunction(sourceFile, function (ctx) { return walk(ctx, program.getTypeChecker()); }); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-unnecessary-qualifier", + description: "Warns when a namespace qualifier (`A.x`) is unnecessary.", + hasFix: true, + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "style", + typescriptOnly: true, + requiresTypeInfo: true, + }; return Rule; }(Lint.Rules.TypedRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-unnecessary-qualifier", - description: "Warns when a namespace qualifier (`A.x`) is unnecessary.", - hasFix: true, - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "style", - typescriptOnly: true, - requiresTypeInfo: true, -}; exports.Rule = Rule; function walk(ctx, checker) { var namespacesInScope = []; @@ -94,7 +94,7 @@ function walk(ctx, checker) { } // If the symbol in scope is different, the qualifier is necessary. var fromScope = getSymbolInScope(qualifier, accessedSymbol.flags, name.text); - return fromScope === undefined || fromScope === accessedSymbol; + return fromScope === undefined || Lint.Utils.arraysAreEqual(fromScope.declarations, accessedSymbol.declarations, function (a, b) { return a === b; }); } function getSymbolInScope(node, flags, name) { // TODO:PERF `getSymbolsInScope` gets a long list. Is there a better way? diff --git a/node_modules/tslint/lib/rules/noUnnecessaryTypeAssertionRule.js b/node_modules/tslint/lib/rules/noUnnecessaryTypeAssertionRule.js index 2ee8aa957..aedcf3a1a 100644 --- a/node_modules/tslint/lib/rules/noUnnecessaryTypeAssertionRule.js +++ b/node_modules/tslint/lib/rules/noUnnecessaryTypeAssertionRule.js @@ -27,21 +27,21 @@ var Rule = (function (_super) { Rule.prototype.applyWithProgram = function (sourceFile, program) { return this.applyWithWalker(new Walker(sourceFile, this.ruleName, program.getTypeChecker())); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-unnecessary-type-assertion", + description: "Warns if a type assertion does not change the type of an expression.", + options: null, + optionsDescription: "Not configurable", + type: "typescript", + hasFix: true, + typescriptOnly: true, + requiresTypeInfo: true, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "This assertion is unnecessary since it does not change the type of the expression."; return Rule; }(Lint.Rules.TypedRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-unnecessary-type-assertion", - description: "Warns if a type assertion does not change the type of an expression.", - options: null, - optionsDescription: "Not configurable", - type: "typescript", - hasFix: true, - typescriptOnly: true, - requiresTypeInfo: true, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "This assertion is unnecessary since it does not change the type of the expression."; exports.Rule = Rule; var Walker = (function (_super) { tslib_1.__extends(Walker, _super); diff --git a/node_modules/tslint/lib/rules/noUnsafeAnyRule.d.ts b/node_modules/tslint/lib/rules/noUnsafeAnyRule.d.ts index 2ecf3f4c4..d2d51d1d1 100644 --- a/node_modules/tslint/lib/rules/noUnsafeAnyRule.d.ts +++ b/node_modules/tslint/lib/rules/noUnsafeAnyRule.d.ts @@ -1,19 +1,3 @@ -/** - * @license - * Copyright 2017 Palantir Technologies, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ import * as ts from "typescript"; import * as Lint from "../index"; export declare class Rule extends Lint.Rules.TypedRule { @@ -21,6 +5,3 @@ export declare class Rule extends Lint.Rules.TypedRule { static FAILURE_STRING: string; applyWithProgram(sourceFile: ts.SourceFile, program: ts.Program): Lint.RuleFailure[]; } -declare module "typescript" { - function isExpression(node: ts.Node): node is ts.Expression; -} diff --git a/node_modules/tslint/lib/rules/noUnsafeAnyRule.js b/node_modules/tslint/lib/rules/noUnsafeAnyRule.js index f07eff92b..60ba3aabb 100644 --- a/node_modules/tslint/lib/rules/noUnsafeAnyRule.js +++ b/node_modules/tslint/lib/rules/noUnsafeAnyRule.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) { @@ -27,21 +28,21 @@ var Rule = (function (_super) { Rule.prototype.applyWithProgram = function (sourceFile, program) { return this.applyWithFunction(sourceFile, function (ctx) { return walk(ctx, program.getTypeChecker()); }); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-unsafe-any", + description: (_a = ["\n Warns when using an expression of type 'any' in a dynamic way.\n Uses are only allowed if they would work for `{} | null | undefined`.\n Type casts and tests are allowed.\n Expressions that work on all values (such as `\"\" + x`) are allowed."], _a.raw = ["\n Warns when using an expression of type 'any' in a dynamic way.\n Uses are only allowed if they would work for \\`{} | null | undefined\\`.\n Type casts and tests are allowed.\n Expressions that work on all values (such as \\`\"\" + x\\`) are allowed."], Lint.Utils.dedent(_a)), + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "functionality", + typescriptOnly: true, + requiresTypeInfo: true, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "Unsafe use of expression of type 'any'."; return Rule; }(Lint.Rules.TypedRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-unsafe-any", - description: (_a = ["\n Warns when using an expression of type 'any' in a dynamic way.\n Uses are only allowed if they would work for `{} | null | undefined`.\n Type casts and tests are allowed.\n Expressions that work on all values (such as `\"\" + x`) are allowed."], _a.raw = ["\n Warns when using an expression of type 'any' in a dynamic way.\n Uses are only allowed if they would work for \\`{} | null | undefined\\`.\n Type casts and tests are allowed.\n Expressions that work on all values (such as \\`\"\" + x\\`) are allowed."], Lint.Utils.dedent(_a)), - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "functionality", - typescriptOnly: true, - requiresTypeInfo: true, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "Unsafe use of expression of type 'any'."; exports.Rule = Rule; function walk(ctx, checker) { if (ctx.sourceFile.isDeclarationFile) { @@ -57,6 +58,7 @@ function walk(ctx, checker) { return cb(node.expression, anyOk); case ts.SyntaxKind.Parameter: { var _a = node, type = _a.type, initializer = _a.initializer; + // TODO handle destructuring if (initializer !== undefined) { return cb(initializer, /*anyOk*/ type !== undefined && type.kind === ts.SyntaxKind.AnyKeyword); } @@ -66,6 +68,7 @@ function walk(ctx, checker) { // Ignore label return cb(node.statement); case ts.SyntaxKind.BreakStatement: // Ignore label + case ts.SyntaxKind.ContinueStatement: // Ignore types case ts.SyntaxKind.InterfaceDeclaration: case ts.SyntaxKind.TypeAliasDeclaration: @@ -149,14 +152,71 @@ function walk(ctx, checker) { } return; } + case ts.SyntaxKind.SwitchStatement: { + var _h = node, expression = _h.expression, clauses = _h.caseBlock.clauses; + // Allow `switch (x) {}` where `x` is any + cb(expression, /*anyOk*/ true); + for (var _j = 0, clauses_1 = clauses; _j < clauses_1.length; _j++) { + var clause = clauses_1[_j]; + if (clause.kind === ts.SyntaxKind.CaseClause) { + // Allow `case x:` where `x` is any + cb(clause.expression, /*anyOk*/ true); + } + for (var _k = 0, _l = clause.statements; _k < _l.length; _k++) { + var statement = _l[_k]; + cb(statement); + } + } + break; + } + case ts.SyntaxKind.ModuleDeclaration: { + // In `declare global { ... }`, don't mark `global` as unsafe any. + var body = node.body; + if (body !== undefined) { + cb(body); + } + return; + } + case ts.SyntaxKind.IfStatement: { + var _m = node, expression = _m.expression, thenStatement = _m.thenStatement, elseStatement = _m.elseStatement; + cb(expression, true); // allow truthyness check + cb(thenStatement); + if (elseStatement !== undefined) { + cb(elseStatement); + } + return; + } + case ts.SyntaxKind.PrefixUnaryExpression: { + var _o = node, operator = _o.operator, operand = _o.operand; + cb(operand, operator === ts.SyntaxKind.ExclamationToken); // allow falsyness check + check(); + return; + } + case ts.SyntaxKind.ForStatement: { + var _p = node, initializer = _p.initializer, condition = _p.condition, incrementor = _p.incrementor, statement = _p.statement; + if (initializer !== undefined) { + cb(initializer); + } + if (condition !== undefined) { + cb(condition, true); + } // allow truthyness check + if (incrementor !== undefined) { + cb(incrementor); + } + return cb(statement); + } + case ts.SyntaxKind.DoStatement: + case ts.SyntaxKind.WhileStatement: + cb(node.statement); + return cb(node.expression, true); default: - if (!(ts.isExpression(node) && check())) { + if (!(tsutils_1.isExpression(node) && check())) { return ts.forEachChild(node, cb); } return; } function check() { - var isUnsafe = anyOk !== true && isNodeAny(node, checker); + var isUnsafe = !anyOk && isNodeAny(node, checker); if (isUnsafe) { ctx.addFailureAtNode(node, Rule.FAILURE_STRING); } @@ -184,9 +244,11 @@ function walk(ctx, checker) { return; } switch (operatorToken.kind) { - case ts.SyntaxKind.InstanceOfKeyword: + case ts.SyntaxKind.InstanceOfKeyword:// Allow test return cb(right); - case ts.SyntaxKind.CommaToken: + case ts.SyntaxKind.CommaToken: // Allow `any, any` + case ts.SyntaxKind.BarBarToken: // Allow `any || any` + case ts.SyntaxKind.AmpersandAmpersandToken:// Allow `any && any` cb(left, /*anyOk*/ true); return cb(right, /*anyOk*/ true); case ts.SyntaxKind.EqualsToken: diff --git a/node_modules/tslint/lib/rules/noUnsafeFinallyRule.js b/node_modules/tslint/lib/rules/noUnsafeFinallyRule.js index 74710ce46..4196c41af 100644 --- a/node_modules/tslint/lib/rules/noUnsafeFinallyRule.js +++ b/node_modules/tslint/lib/rules/noUnsafeFinallyRule.js @@ -32,20 +32,20 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-unsafe-finally", + description: (_a = ["\n Disallows control flow statements, such as `return`, `continue`,\n `break` and `throws` in finally blocks."], _a.raw = ["\n Disallows control flow statements, such as \\`return\\`, \\`continue\\`,\n \\`break\\` and \\`throws\\` in finally blocks."], Lint.Utils.dedent(_a)), + descriptionDetails: "", + rationale: (_b = ["\n When used inside `finally` blocks, control flow statements,\n such as `return`, `continue`, `break` and `throws`\n override any other control flow statements in the same try/catch scope.\n This is confusing and unexpected behavior."], _b.raw = ["\n When used inside \\`finally\\` blocks, control flow statements,\n such as \\`return\\`, \\`continue\\`, \\`break\\` and \\`throws\\`\n override any other control flow statements in the same try/catch scope.\n This is confusing and unexpected behavior."], Lint.Utils.dedent(_b)), + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "functionality", + typescriptOnly: false, + }; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-unsafe-finally", - description: (_a = ["\n Disallows control flow statements, such as `return`, `continue`,\n `break` and `throws` in finally blocks."], _a.raw = ["\n Disallows control flow statements, such as \\`return\\`, \\`continue\\`,\n \\`break\\` and \\`throws\\` in finally blocks."], Lint.Utils.dedent(_a)), - descriptionDetails: "", - rationale: (_b = ["\n When used inside `finally` blocks, control flow statements,\n such as `return`, `continue`, `break` and `throws`\n override any other control flow statements in the same try/catch scope.\n This is confusing and unexpected behavior."], _b.raw = ["\n When used inside \\`finally\\` blocks, control flow statements,\n such as \\`return\\`, \\`continue\\`, \\`break\\` and \\`throws\\`\n override any other control flow statements in the same try/catch scope.\n This is confusing and unexpected behavior."], Lint.Utils.dedent(_b)), - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "functionality", - typescriptOnly: false, -}; exports.Rule = Rule; function walk(ctx) { var inFinally = false; diff --git a/node_modules/tslint/lib/rules/noUnusedExpressionRule.js b/node_modules/tslint/lib/rules/noUnusedExpressionRule.js index 5e62e79e8..2e389b732 100644 --- a/node_modules/tslint/lib/rules/noUnusedExpressionRule.js +++ b/node_modules/tslint/lib/rules/noUnusedExpressionRule.js @@ -35,30 +35,30 @@ var Rule = (function (_super) { allowTaggedTemplate: this.ruleArguments.indexOf(ALLOW_TAGGED_TEMPLATE) !== -1, }); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-unused-expression", + description: "Disallows unused expression statements.", + descriptionDetails: (_a = ["\n Unused expressions are expression statements which are not assignments or function calls\n (and thus usually no-ops)."], _a.raw = ["\n Unused expressions are expression statements which are not assignments or function calls\n (and thus usually no-ops)."], Lint.Utils.dedent(_a)), + rationale: (_b = ["\n Detects potential errors where an assignment or function call was intended."], _b.raw = ["\n Detects potential errors where an assignment or function call was intended."], Lint.Utils.dedent(_b)), + optionsDescription: (_c = ["\n Two arguments may be optionally provided:\n\n * `", "` allows to use logical operators to perform fast null checks and perform\n method or function calls for side effects (e.g. `e && e.preventDefault()`).\n * `", "` allows 'new' expressions for side effects (e.g. `new ModifyGlobalState();`.\n * `", "` allows tagged templates for side effects (e.g. `this.add\\`foo\\`;`."], _c.raw = ["\n Two arguments may be optionally provided:\n\n * \\`", "\\` allows to use logical operators to perform fast null checks and perform\n method or function calls for side effects (e.g. \\`e && e.preventDefault()\\`).\n * \\`", "\\` allows 'new' expressions for side effects (e.g. \\`new ModifyGlobalState();\\`.\n * \\`", "\\` allows tagged templates for side effects (e.g. \\`this.add\\\\\\`foo\\\\\\`;\\`."], Lint.Utils.dedent(_c, ALLOW_FAST_NULL_CHECKS, ALLOW_NEW, ALLOW_TAGGED_TEMPLATE)), + options: { + type: "array", + items: { + type: "string", + enum: [ALLOW_FAST_NULL_CHECKS, ALLOW_NEW, ALLOW_TAGGED_TEMPLATE], + }, + minLength: 0, + maxLength: 3, + }, + optionExamples: [true, [true, ALLOW_FAST_NULL_CHECKS]], + type: "functionality", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "unused expression, expected an assignment or function call"; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-unused-expression", - description: "Disallows unused expression statements.", - descriptionDetails: (_a = ["\n Unused expressions are expression statements which are not assignments or function calls\n (and thus usually no-ops)."], _a.raw = ["\n Unused expressions are expression statements which are not assignments or function calls\n (and thus usually no-ops)."], Lint.Utils.dedent(_a)), - rationale: (_b = ["\n Detects potential errors where an assignment or function call was intended."], _b.raw = ["\n Detects potential errors where an assignment or function call was intended."], Lint.Utils.dedent(_b)), - optionsDescription: (_c = ["\n Two arguments may be optionally provided:\n\n * `", "` allows to use logical operators to perform fast null checks and perform\n method or function calls for side effects (e.g. `e && e.preventDefault()`).\n * `", "` allows 'new' expressions for side effects (e.g. `new ModifyGlobalState();`.\n * `", "` allows tagged templates for side effects (e.g. `this.add\\`foo\\`;`."], _c.raw = ["\n Two arguments may be optionally provided:\n\n * \\`", "\\` allows to use logical operators to perform fast null checks and perform\n method or function calls for side effects (e.g. \\`e && e.preventDefault()\\`).\n * \\`", "\\` allows 'new' expressions for side effects (e.g. \\`new ModifyGlobalState();\\`.\n * \\`", "\\` allows tagged templates for side effects (e.g. \\`this.add\\\\\\`foo\\\\\\`;\\`."], Lint.Utils.dedent(_c, ALLOW_FAST_NULL_CHECKS, ALLOW_NEW, ALLOW_TAGGED_TEMPLATE)), - options: { - type: "array", - items: { - type: "string", - enum: [ALLOW_FAST_NULL_CHECKS, ALLOW_NEW, ALLOW_TAGGED_TEMPLATE], - }, - minLength: 0, - maxLength: 3, - }, - optionExamples: [true, [true, ALLOW_FAST_NULL_CHECKS]], - type: "functionality", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "unused expression, expected an assignment or function call"; exports.Rule = Rule; function walk(ctx) { var checking = false; diff --git a/node_modules/tslint/lib/rules/noUnusedVariableRule.js b/node_modules/tslint/lib/rules/noUnusedVariableRule.js index 79fcb599d..e4fab8a3e 100644 --- a/node_modules/tslint/lib/rules/noUnusedVariableRule.js +++ b/node_modules/tslint/lib/rules/noUnusedVariableRule.js @@ -31,45 +31,45 @@ var Rule = (function (_super) { Rule.prototype.applyWithProgram = function (sourceFile, program) { var _this = this; var x = program.getCompilerOptions(); - if (x.noUnusedLocals === true && x.noUnusedParameters === true) { + if (x.noUnusedLocals && x.noUnusedParameters) { console.warn("WARNING: 'no-unused-variable' lint rule does not need to be set if " + "the 'no-unused-locals' and 'no-unused-parameters' compiler options are enabled."); } return this.applyWithFunction(sourceFile, function (ctx) { return walk(ctx, program, parseOptions(_this.ruleArguments)); }); }; - return Rule; -}(Lint.Rules.TypedRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-unused-variable", - description: (_a = ["Disallows unused imports, variables, functions and\n private class members. Similar to tsc's --noUnusedParameters and --noUnusedLocals\n options, but does not interrupt code compilation."], _a.raw = ["Disallows unused imports, variables, functions and\n private class members. Similar to tsc's --noUnusedParameters and --noUnusedLocals\n options, but does not interrupt code compilation."], Lint.Utils.dedent(_a)), - hasFix: true, - optionsDescription: (_b = ["\n Three optional arguments may be optionally provided:\n\n * `\"check-parameters\"` disallows unused function and constructor parameters.\n * NOTE: this option is experimental and does not work with classes\n that use abstract method declarations, among other things.\n * `{\"ignore-pattern\": \"pattern\"}` where pattern is a case-sensitive regexp.\n Variable names that match the pattern will be ignored."], _b.raw = ["\n Three optional arguments may be optionally provided:\n\n * \\`\"check-parameters\"\\` disallows unused function and constructor parameters.\n * NOTE: this option is experimental and does not work with classes\n that use abstract method declarations, among other things.\n * \\`{\"ignore-pattern\": \"pattern\"}\\` where pattern is a case-sensitive regexp.\n Variable names that match the pattern will be ignored."], Lint.Utils.dedent(_b)), - options: { - type: "array", - items: { - oneOf: [ - { - type: "string", - enum: ["check-parameters"], - }, - { - type: "object", - properties: { - "ignore-pattern": { type: "string" }, + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-unused-variable", + description: (_a = ["Disallows unused imports, variables, functions and\n private class members. Similar to tsc's --noUnusedParameters and --noUnusedLocals\n options, but does not interrupt code compilation."], _a.raw = ["Disallows unused imports, variables, functions and\n private class members. Similar to tsc's --noUnusedParameters and --noUnusedLocals\n options, but does not interrupt code compilation."], Lint.Utils.dedent(_a)), + hasFix: true, + optionsDescription: (_b = ["\n Three optional arguments may be optionally provided:\n\n * `\"check-parameters\"` disallows unused function and constructor parameters.\n * NOTE: this option is experimental and does not work with classes\n that use abstract method declarations, among other things.\n * `{\"ignore-pattern\": \"pattern\"}` where pattern is a case-sensitive regexp.\n Variable names that match the pattern will be ignored."], _b.raw = ["\n Three optional arguments may be optionally provided:\n\n * \\`\"check-parameters\"\\` disallows unused function and constructor parameters.\n * NOTE: this option is experimental and does not work with classes\n that use abstract method declarations, among other things.\n * \\`{\"ignore-pattern\": \"pattern\"}\\` where pattern is a case-sensitive regexp.\n Variable names that match the pattern will be ignored."], Lint.Utils.dedent(_b)), + options: { + type: "array", + items: { + oneOf: [ + { + type: "string", + enum: ["check-parameters"], + }, + { + type: "object", + properties: { + "ignore-pattern": { type: "string" }, + }, + additionalProperties: false, }, - additionalProperties: false, - }, - ], + ], + }, + minLength: 0, + maxLength: 3, }, - minLength: 0, - maxLength: 3, - }, - optionExamples: [true, [true, { "ignore-pattern": "^_" }]], - type: "functionality", - typescriptOnly: true, - requiresTypeInfo: true, -}; + optionExamples: [true, [true, { "ignore-pattern": "^_" }]], + type: "functionality", + typescriptOnly: true, + requiresTypeInfo: true, + }; + return Rule; +}(Lint.Rules.TypedRule)); exports.Rule = Rule; function parseOptions(options) { var checkParameters = options.indexOf(OPTION_CHECK_PARAMETERS) !== -1; @@ -93,10 +93,14 @@ function walk(ctx, program, _a) { var unusedCheckedProgram = getUnusedCheckedProgram(program, checkParameters); var diagnostics = ts.getPreEmitDiagnostics(unusedCheckedProgram, sourceFile); var checker = unusedCheckedProgram.getTypeChecker(); // Doesn't matter which program is used for this. + var declaration = program.getCompilerOptions().declaration; // If all specifiers in an import are unused, we elide the entire import. var importSpecifierFailures = new Map(); for (var _i = 0, diagnostics_1 = diagnostics; _i < diagnostics_1.length; _i++) { var diag = diagnostics_1[_i]; + if (diag.start === undefined) { + continue; + } var kind = getUnusedDiagnostic(diag); if (kind === undefined) { continue; @@ -105,7 +109,7 @@ function walk(ctx, program, _a) { if (kind === 0 /* VARIABLE_OR_PARAMETER */) { var importName = findImport(diag.start, sourceFile); if (importName !== undefined) { - if (isImportUsed(importName, sourceFile, checker)) { + if (declaration && isImportUsed(importName, sourceFile, checker)) { continue; } if (importSpecifierFailures.has(importName)) { @@ -133,8 +137,6 @@ function walk(ctx, program, _a) { * - Unused imports are fixable. */ function addImportSpecifierFailures(ctx, failures, sourceFile) { - // tslint:disable return-undefined - // (fixed in tslint 5.3) forEachImport(sourceFile, function (importNode) { if (importNode.kind === ts.SyntaxKind.ImportEqualsDeclaration) { tryRemoveAll(importNode.name); @@ -203,9 +205,28 @@ function addImportSpecifierFailures(ctx, failures, sourceFile) { } } function removeAll(errorNode, failure) { - var fix = Lint.Replacement.deleteFromTo(importNode.getStart(), importNode.getEnd()); + var start = importNode.getStart(); + var end = importNode.getEnd(); + if (isEntireLine(start, end)) { + end = getNextLineStart(end); + } + var fix = Lint.Replacement.deleteFromTo(start, end); ctx.addFailureAtNode(errorNode, failure, fix); } + function isEntireLine(start, end) { + return ctx.sourceFile.getLineAndCharacterOfPosition(start).character === 0 && + ctx.sourceFile.getLineEndOfPosition(end) === end; + } + function getNextLineStart(position) { + var nextLine = ctx.sourceFile.getLineAndCharacterOfPosition(position).line + 1; + var lineStarts = ctx.sourceFile.getLineStarts(); + if (nextLine < lineStarts.length) { + return lineStarts[nextLine]; + } + else { + return position; + } + } }); if (failures.size !== 0) { throw new Error("Should have revisited all import specifier failures."); @@ -242,10 +263,12 @@ function isImportUsed(importSpecifier, sourceFile, checker) { return true; } return ts.forEachChild(child, cb); - }); + }) === true; } function getImplicitType(node, checker) { - if ((utils.isPropertyDeclaration(node) || utils.isVariableDeclaration(node)) && node.type === undefined) { + if ((utils.isPropertyDeclaration(node) || utils.isVariableDeclaration(node)) && + node.type === undefined && node.name.kind === ts.SyntaxKind.Identifier || + utils.isBindingElement(node) && node.name.kind === ts.SyntaxKind.Identifier) { return checker.getTypeAtLocation(node); } else if (utils.isSignatureDeclaration(node) && node.type === undefined) { @@ -327,24 +350,26 @@ function getUnusedCheckedProgram(program, checkParameters) { return checkedProgram; } function makeUnusedCheckedProgram(program, checkParameters) { - var options = tslib_1.__assign({}, program.getCompilerOptions(), { noUnusedLocals: true }, (checkParameters ? { noUnusedParameters: true } : null)); - var sourceFilesByName = new Map(program.getSourceFiles().map(function (s) { return [s.fileName, s]; })); + var originalOptions = program.getCompilerOptions(); + var options = tslib_1.__assign({}, originalOptions, { noEmit: true, noUnusedLocals: true, noUnusedParameters: originalOptions.noUnusedParameters || checkParameters }); + var sourceFilesByName = new Map(program.getSourceFiles().map(function (s) { return [getCanonicalFileName(s.fileName), s]; })); // tslint:disable object-literal-sort-keys return ts.createProgram(Array.from(sourceFilesByName.keys()), options, { - fileExists: function (f) { return sourceFilesByName.has(f); }, - readFile: function (f) { - var s = sourceFilesByName.get(f); - return s.text; - }, - getSourceFile: function (f) { return sourceFilesByName.get(f); }, + fileExists: function (f) { return sourceFilesByName.has(getCanonicalFileName(f)); }, + readFile: function (f) { return sourceFilesByName.get(getCanonicalFileName(f)).text; }, + getSourceFile: function (f) { return sourceFilesByName.get(getCanonicalFileName(f)); }, getDefaultLibFileName: function () { return ts.getDefaultLibFileName(options); }, writeFile: function () { }, getCurrentDirectory: function () { return ""; }, getDirectories: function () { return []; }, - getCanonicalFileName: function (f) { return f; }, - useCaseSensitiveFileNames: function () { return true; }, + getCanonicalFileName: getCanonicalFileName, + useCaseSensitiveFileNames: function () { return ts.sys.useCaseSensitiveFileNames; }, getNewLine: function () { return "\n"; }, }); // tslint:enable object-literal-sort-keys + // We need to be careful with file system case sensitivity + function getCanonicalFileName(fileName) { + return ts.sys.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase(); + } } var _a, _b; diff --git a/node_modules/tslint/lib/rules/noUseBeforeDeclareRule.js b/node_modules/tslint/lib/rules/noUseBeforeDeclareRule.js index 0c0100dcb..c46ebc417 100644 --- a/node_modules/tslint/lib/rules/noUseBeforeDeclareRule.js +++ b/node_modules/tslint/lib/rules/noUseBeforeDeclareRule.js @@ -31,20 +31,20 @@ var Rule = (function (_super) { Rule.prototype.applyWithProgram = function (sourceFile, program) { return this.applyWithFunction(sourceFile, function (ctx) { return walk(ctx, program.getTypeChecker()); }); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-use-before-declare", + description: "Disallows usage of variables before their declaration.", + descriptionDetails: (_a = ["\n This rule is primarily useful when using the `var` keyword -\n the compiler will detect if a `let` and `const` variable is used before it is declared."], _a.raw = ["\n This rule is primarily useful when using the \\`var\\` keyword -\n the compiler will detect if a \\`let\\` and \\`const\\` variable is used before it is declared."], Lint.Utils.dedent(_a)), + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "functionality", + typescriptOnly: false, + requiresTypeInfo: true, + }; return Rule; }(Lint.Rules.TypedRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-use-before-declare", - description: "Disallows usage of variables before their declaration.", - descriptionDetails: (_a = ["\n This rule is primarily useful when using the `var` keyword -\n the compiler will detect if a `let` and `const` variable is used before it is declared."], _a.raw = ["\n This rule is primarily useful when using the \\`var\\` keyword -\n the compiler will detect if a \\`let\\` and \\`const\\` variable is used before it is declared."], Lint.Utils.dedent(_a)), - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "functionality", - typescriptOnly: false, - requiresTypeInfo: true, -}; exports.Rule = Rule; function walk(ctx, checker) { return ts.forEachChild(ctx.sourceFile, function recur(node) { diff --git a/node_modules/tslint/lib/rules/noVarKeywordRule.js b/node_modules/tslint/lib/rules/noVarKeywordRule.js index ecfcec88e..e0b4d3438 100644 --- a/node_modules/tslint/lib/rules/noVarKeywordRule.js +++ b/node_modules/tslint/lib/rules/noVarKeywordRule.js @@ -28,22 +28,22 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-var-keyword", + description: "Disallows usage of the `var` keyword.", + descriptionDetails: "Use `let` or `const` instead.", + hasFix: true, + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "functionality", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "Forbidden 'var' keyword, use 'let' or 'const' instead"; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-var-keyword", - description: "Disallows usage of the `var` keyword.", - descriptionDetails: "Use `let` or `const` instead.", - hasFix: true, - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "functionality", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "Forbidden 'var' keyword, use 'let' or 'const' instead"; exports.Rule = Rule; function walk(ctx) { var sourceFile = ctx.sourceFile; diff --git a/node_modules/tslint/lib/rules/noVarRequiresRule.js b/node_modules/tslint/lib/rules/noVarRequiresRule.js index 47c537b1b..6c8782ca7 100644 --- a/node_modules/tslint/lib/rules/noVarRequiresRule.js +++ b/node_modules/tslint/lib/rules/noVarRequiresRule.js @@ -30,21 +30,21 @@ var Rule = (function (_super) { var requiresWalker = new NoVarRequiresWalker(sourceFile, this.getOptions()); return this.applyWithWalker(requiresWalker); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-var-requires", + description: "Disallows the use of require statements except in import statements.", + descriptionDetails: (_a = ["\n In other words, the use of forms such as `var module = require(\"module\")` are banned.\n Instead use ES6 style imports or `import foo = require('foo')` imports."], _a.raw = ["\n In other words, the use of forms such as \\`var module = require(\"module\")\\` are banned.\n Instead use ES6 style imports or \\`import foo = require('foo')\\` imports."], Lint.Utils.dedent(_a)), + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "typescript", + typescriptOnly: true, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "require statement not part of an import statement"; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-var-requires", - description: "Disallows the use of require statements except in import statements.", - descriptionDetails: (_a = ["\n In other words, the use of forms such as `var module = require(\"module\")` are banned.\n Instead use ES6 style imports or `import foo = require('foo')` imports."], _a.raw = ["\n In other words, the use of forms such as \\`var module = require(\"module\")\\` are banned.\n Instead use ES6 style imports or \\`import foo = require('foo')\\` imports."], Lint.Utils.dedent(_a)), - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "typescript", - typescriptOnly: true, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "require statement not part of an import statement"; exports.Rule = Rule; var NoVarRequiresWalker = (function (_super) { tslib_1.__extends(NoVarRequiresWalker, _super); diff --git a/node_modules/tslint/lib/rules/noVoidExpressionRule.js b/node_modules/tslint/lib/rules/noVoidExpressionRule.js index e80ec2cf6..a580bc5cb 100644 --- a/node_modules/tslint/lib/rules/noVoidExpressionRule.js +++ b/node_modules/tslint/lib/rules/noVoidExpressionRule.js @@ -30,28 +30,28 @@ var Rule = (function (_super) { var ignoreArrowFunctionShorthand = this.ruleArguments.indexOf(OPTION_IGNORE_ARROW_FUNCTION_SHORTHAND) !== -1; return this.applyWithFunction(sourceFile, function (ctx) { return walk(ctx, program.getTypeChecker()); }, { ignoreArrowFunctionShorthand: ignoreArrowFunctionShorthand }); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "no-void-expression", + description: "Requires expressions of type `void` to appear in statement position.", + optionsDescription: (_a = ["\n If `", "` is provided, `() => returnsVoid()` will be allowed.\n Otherwise, it must be written as `() => { returnsVoid(); }`."], _a.raw = ["\n If \\`", "\\` is provided, \\`() => returnsVoid()\\` will be allowed.\n Otherwise, it must be written as \\`() => { returnsVoid(); }\\`."], Lint.Utils.dedent(_a, OPTION_IGNORE_ARROW_FUNCTION_SHORTHAND)), + options: { + type: "array", + items: { + type: "string", + enum: [OPTION_IGNORE_ARROW_FUNCTION_SHORTHAND], + }, + minLength: 0, + maxLength: 1, + }, + requiresTypeInfo: true, + type: "functionality", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "Expression has type `void`. Put it on its own line as a statement."; return Rule; }(Lint.Rules.TypedRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "no-void-expression", - description: "Requires expressions of type `void` to appear in statement position.", - optionsDescription: (_a = ["\n If `", "` is provided, `() => returnsVoid()` will be allowed.\n Otherwise, it must be written as `() => { returnsVoid(); }`."], _a.raw = ["\n If \\`", "\\` is provided, \\`() => returnsVoid()\\` will be allowed.\n Otherwise, it must be written as \\`() => { returnsVoid(); }\\`."], Lint.Utils.dedent(_a, OPTION_IGNORE_ARROW_FUNCTION_SHORTHAND)), - options: { - type: "array", - items: { - type: "string", - enum: [OPTION_IGNORE_ARROW_FUNCTION_SHORTHAND], - }, - minLength: 0, - maxLength: 1, - }, - requiresTypeInfo: true, - type: "functionality", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "Expression has type `void`. Put it on its own line as a statement."; exports.Rule = Rule; function walk(ctx, checker) { var sourceFile = ctx.sourceFile, ignoreArrowFunctionShorthand = ctx.options.ignoreArrowFunctionShorthand; diff --git a/node_modules/tslint/lib/rules/numberLiteralFormatRule.js b/node_modules/tslint/lib/rules/numberLiteralFormatRule.js index b902a30eb..98a15a471 100644 --- a/node_modules/tslint/lib/rules/numberLiteralFormatRule.js +++ b/node_modules/tslint/lib/rules/numberLiteralFormatRule.js @@ -29,24 +29,24 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "number-literal-format", + description: "Checks that decimal literals should begin with '0.' instead of just '.', and should not end with a trailing '0'.", + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "style", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING_LEADING_0 = "Number literal should not have a leading '0'."; + Rule.FAILURE_STRING_TRAILING_0 = "Number literal should not have a trailing '0'."; + Rule.FAILURE_STRING_TRAILING_DECIMAL = "Number literal should not end in '.'."; + Rule.FAILURE_STRING_LEADING_DECIMAL = "Number literal should begin with '0.' and not just '.'."; + Rule.FAILURE_STRING_NOT_UPPERCASE = "Hexadecimal number literal should be uppercase."; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "number-literal-format", - description: "Checks that decimal literals should begin with '0.' instead of just '.', and should not end with a trailing '0'.", - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "style", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING_LEADING_0 = "Number literal should not have a leading '0'."; -Rule.FAILURE_STRING_TRAILING_0 = "Number literal should not have a trailing '0'."; -Rule.FAILURE_STRING_TRAILING_DECIMAL = "Number literal should not end in '.'."; -Rule.FAILURE_STRING_LEADING_DECIMAL = "Number literal should begin with '0.' and not just '.'."; -Rule.FAILURE_STRING_NOT_UPPERCASE = "Hexadecimal number literal should be uppercase."; exports.Rule = Rule; function walk(ctx) { var sourceFile = ctx.sourceFile; diff --git a/node_modules/tslint/lib/rules/objectLiteralKeyQuotesRule.js b/node_modules/tslint/lib/rules/objectLiteralKeyQuotesRule.js index 073bdf035..5ab8bfa3a 100644 --- a/node_modules/tslint/lib/rules/objectLiteralKeyQuotesRule.js +++ b/node_modules/tslint/lib/rules/objectLiteralKeyQuotesRule.js @@ -40,25 +40,25 @@ var Rule = (function (_super) { option: this.ruleArguments.length === 0 ? "always" : this.ruleArguments[0], })); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "object-literal-key-quotes", + description: "Enforces consistent object literal property quote style.", + descriptionDetails: (_a = ["\n Object literal property names can be defined in two ways: using literals or using strings.\n For example, these two objects are equivalent:\n\n var object1 = {\n property: true\n };\n\n var object2 = {\n \"property\": true\n };\n\n In many cases, it doesn\u2019t matter if you choose to use an identifier instead of a string\n or vice-versa. Even so, you might decide to enforce a consistent style in your code.\n\n This rules lets you enforce consistent quoting of property names. Either they should always\n be quoted (default behavior) or quoted only as needed (\"as-needed\")."], _a.raw = ["\n Object literal property names can be defined in two ways: using literals or using strings.\n For example, these two objects are equivalent:\n\n var object1 = {\n property: true\n };\n\n var object2 = {\n \"property\": true\n };\n\n In many cases, it doesn\u2019t matter if you choose to use an identifier instead of a string\n or vice-versa. Even so, you might decide to enforce a consistent style in your code.\n\n This rules lets you enforce consistent quoting of property names. Either they should always\n be quoted (default behavior) or quoted only as needed (\"as-needed\")."], Lint.Utils.dedent(_a)), + hasFix: true, + optionsDescription: (_b = ["\n Possible settings are:\n\n * `\"", "\"`: Property names should always be quoted. (This is the default.)\n * `\"", "\"`: Only property names which require quotes may be quoted (e.g. those with spaces in them).\n * `\"", "\"`: Property names should either all be quoted or unquoted.\n * `\"", "\"`: If any property name requires quotes, then all properties must be quoted. Otherwise, no\n property names may be quoted.\n\n For ES6, computed property names (`{[name]: value}`) and methods (`{foo() {}}`) never need\n to be quoted."], _b.raw = ["\n Possible settings are:\n\n * \\`\"", "\"\\`: Property names should always be quoted. (This is the default.)\n * \\`\"", "\"\\`: Only property names which require quotes may be quoted (e.g. those with spaces in them).\n * \\`\"", "\"\\`: Property names should either all be quoted or unquoted.\n * \\`\"", "\"\\`: If any property name requires quotes, then all properties must be quoted. Otherwise, no\n property names may be quoted.\n\n For ES6, computed property names (\\`{[name]: value}\\`) and methods (\\`{foo() {}}\\`) never need\n to be quoted."], Lint.Utils.dedent(_b, OPTION_ALWAYS, OPTION_AS_NEEDED, OPTION_CONSISTENT, OPTION_CONSISTENT_AS_NEEDED)), + options: { + type: "string", + enum: [OPTION_ALWAYS, OPTION_AS_NEEDED, OPTION_CONSISTENT, OPTION_CONSISTENT_AS_NEEDED], + }, + optionExamples: [[true, OPTION_AS_NEEDED], [true, OPTION_ALWAYS]], + type: "style", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.INCONSISTENT_PROPERTY = "All property names in this object literal must be consistently quoted or unquoted."; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "object-literal-key-quotes", - description: "Enforces consistent object literal property quote style.", - descriptionDetails: (_a = ["\n Object literal property names can be defined in two ways: using literals or using strings.\n For example, these two objects are equivalent:\n\n var object1 = {\n property: true\n };\n\n var object2 = {\n \"property\": true\n };\n\n In many cases, it doesn\u2019t matter if you choose to use an identifier instead of a string\n or vice-versa. Even so, you might decide to enforce a consistent style in your code.\n\n This rules lets you enforce consistent quoting of property names. Either they should always\n be quoted (default behavior) or quoted only as needed (\"as-needed\")."], _a.raw = ["\n Object literal property names can be defined in two ways: using literals or using strings.\n For example, these two objects are equivalent:\n\n var object1 = {\n property: true\n };\n\n var object2 = {\n \"property\": true\n };\n\n In many cases, it doesn\u2019t matter if you choose to use an identifier instead of a string\n or vice-versa. Even so, you might decide to enforce a consistent style in your code.\n\n This rules lets you enforce consistent quoting of property names. Either they should always\n be quoted (default behavior) or quoted only as needed (\"as-needed\")."], Lint.Utils.dedent(_a)), - hasFix: true, - optionsDescription: (_b = ["\n Possible settings are:\n\n * `\"", "\"`: Property names should always be quoted. (This is the default.)\n * `\"", "\"`: Only property names which require quotes may be quoted (e.g. those with spaces in them).\n * `\"", "\"`: Property names should either all be quoted or unquoted.\n * `\"", "\"`: If any property name requires quotes, then all properties must be quoted. Otherwise, no\n property names may be quoted.\n\n For ES6, computed property names (`{[name]: value}`) and methods (`{foo() {}}`) never need\n to be quoted."], _b.raw = ["\n Possible settings are:\n\n * \\`\"", "\"\\`: Property names should always be quoted. (This is the default.)\n * \\`\"", "\"\\`: Only property names which require quotes may be quoted (e.g. those with spaces in them).\n * \\`\"", "\"\\`: Property names should either all be quoted or unquoted.\n * \\`\"", "\"\\`: If any property name requires quotes, then all properties must be quoted. Otherwise, no\n property names may be quoted.\n\n For ES6, computed property names (\\`{[name]: value}\\`) and methods (\\`{foo() {}}\\`) never need\n to be quoted."], Lint.Utils.dedent(_b, OPTION_ALWAYS, OPTION_AS_NEEDED, OPTION_CONSISTENT, OPTION_CONSISTENT_AS_NEEDED)), - options: { - type: "string", - enum: [OPTION_ALWAYS, OPTION_AS_NEEDED, OPTION_CONSISTENT, OPTION_CONSISTENT_AS_NEEDED], - }, - optionExamples: [[true, OPTION_AS_NEEDED], [true, OPTION_ALWAYS]], - type: "style", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.INCONSISTENT_PROPERTY = "All property names in this object literal must be consistently quoted or unquoted."; exports.Rule = Rule; var ObjectLiteralKeyQuotesWalker = (function (_super) { tslib_1.__extends(ObjectLiteralKeyQuotesWalker, _super); diff --git a/node_modules/tslint/lib/rules/objectLiteralShorthandRule.d.ts b/node_modules/tslint/lib/rules/objectLiteralShorthandRule.d.ts index f8528cbbc..8d990f416 100644 --- a/node_modules/tslint/lib/rules/objectLiteralShorthandRule.d.ts +++ b/node_modules/tslint/lib/rules/objectLiteralShorthandRule.d.ts @@ -1,19 +1,3 @@ -/** - * @license - * Copyright 2016 Palantir Technologies, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ import * as ts from "typescript"; import * as Lint from "../index"; export declare class Rule extends Lint.Rules.AbstractRule { diff --git a/node_modules/tslint/lib/rules/objectLiteralShorthandRule.js b/node_modules/tslint/lib/rules/objectLiteralShorthandRule.js index 90a0b34ef..b3e7947e1 100644 --- a/node_modules/tslint/lib/rules/objectLiteralShorthandRule.js +++ b/node_modules/tslint/lib/rules/objectLiteralShorthandRule.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,51 +26,55 @@ var Rule = (function (_super) { return _super !== null && _super.apply(this, arguments) || this; } Rule.prototype.apply = function (sourceFile) { - var objectLiteralShorthandWalker = new ObjectLiteralShorthandWalker(sourceFile, this.getOptions()); - return this.applyWithWalker(objectLiteralShorthandWalker); + return this.applyWithFunction(sourceFile, walk); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "object-literal-shorthand", + description: "Enforces use of ES6 object literal shorthand when possible.", + hasFix: true, + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "style", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.LONGHAND_PROPERTY = "Expected property shorthand in object literal "; + Rule.LONGHAND_METHOD = "Expected method shorthand in object literal "; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "object-literal-shorthand", - description: "Enforces use of ES6 object literal shorthand when possible.", - hasFix: true, - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "style", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.LONGHAND_PROPERTY = "Expected property shorthand in object literal "; -Rule.LONGHAND_METHOD = "Expected method shorthand in object literal "; exports.Rule = Rule; -var ObjectLiteralShorthandWalker = (function (_super) { - tslib_1.__extends(ObjectLiteralShorthandWalker, _super); - function ObjectLiteralShorthandWalker() { - return _super !== null && _super.apply(this, arguments) || this; - } - ObjectLiteralShorthandWalker.prototype.visitPropertyAssignment = function (node) { - var name = node.name; - var value = node.initializer; - if (name.kind === ts.SyntaxKind.Identifier && - value.kind === ts.SyntaxKind.Identifier && - name.getText() === value.getText()) { - // Delete from name start up to value to include the ':'. - var lengthToValueStart = value.getStart() - name.getStart(); - var fix = this.deleteText(name.getStart(), lengthToValueStart); - this.addFailureAtNode(node, Rule.LONGHAND_PROPERTY + "('{" + name.getText() + "}').", fix); - } - if (value.kind === ts.SyntaxKind.FunctionExpression) { - var fnNode = value; - if (fnNode.name !== undefined) { - return; // named function expressions are OK. +function walk(ctx) { + return ts.forEachChild(ctx.sourceFile, function cb(node) { + if (tsutils_1.isPropertyAssignment(node)) { + if (node.name.kind === ts.SyntaxKind.Identifier && + tsutils_1.isIdentifier(node.initializer) && + node.name.text === node.initializer.text) { + ctx.addFailureAtNode(node, Rule.LONGHAND_PROPERTY + "('{" + node.name.text + "}').", Lint.Replacement.deleteFromTo(node.name.end, node.end)); + } + else if (tsutils_1.isFunctionExpression(node.initializer) && + // allow named function expressions + node.initializer.name === undefined) { + var _a = handleLonghandMethod(node.name, node.initializer, ctx.sourceFile), name = _a[0], fix = _a[1]; + ctx.addFailureAtNode(node, Rule.LONGHAND_METHOD + "('{" + name + "() {...}}').", fix); } - var star = fnNode.asteriskToken !== undefined ? fnNode.asteriskToken.getText() : ""; - this.addFailureAtNode(node, Rule.LONGHAND_METHOD + "('{" + name.getText() + star + "() {...}}')."); } - _super.prototype.visitPropertyAssignment.call(this, node); - }; - return ObjectLiteralShorthandWalker; -}(Lint.RuleWalker)); + return ts.forEachChild(node, cb); + }); +} +function handleLonghandMethod(name, initializer, sourceFile) { + var nameStart = name.getStart(sourceFile); + var fix = Lint.Replacement.deleteFromTo(name.end, tsutils_1.getChildOfKind(initializer, ts.SyntaxKind.OpenParenToken).pos); + var prefix = ""; + if (initializer.asteriskToken !== undefined) { + prefix = "*"; + } + if (tsutils_1.hasModifier(initializer.modifiers, ts.SyntaxKind.AsyncKeyword)) { + prefix = "async " + prefix; + } + if (prefix !== "") { + fix = [fix, Lint.Replacement.appendText(nameStart, prefix)]; + } + return [prefix + sourceFile.text.substring(nameStart, name.end), fix]; +} diff --git a/node_modules/tslint/lib/rules/objectLiteralSortKeysRule.js b/node_modules/tslint/lib/rules/objectLiteralSortKeysRule.js index fc116ec1e..6b6ed3303 100644 --- a/node_modules/tslint/lib/rules/objectLiteralSortKeysRule.js +++ b/node_modules/tslint/lib/rules/objectLiteralSortKeysRule.js @@ -35,25 +35,25 @@ var Rule = (function (_super) { ignoreCase: this.ruleArguments.indexOf(OPTION_IGNORE_CASE) !== -1, }); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "object-literal-sort-keys", + description: "Requires keys in object literals to be sorted alphabetically", + rationale: "Useful in preventing merge conflicts", + optionsDescription: "You may optionally pass \"" + OPTION_IGNORE_CASE + "\" to compare keys case insensitive.", + options: { + type: "string", + enum: [OPTION_IGNORE_CASE], + }, + optionExamples: [ + true, + [true, OPTION_IGNORE_CASE], + ], + type: "maintainability", + typescriptOnly: false, + }; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "object-literal-sort-keys", - description: "Requires keys in object literals to be sorted alphabetically", - rationale: "Useful in preventing merge conflicts", - optionsDescription: "You may optionally pass \"" + OPTION_IGNORE_CASE + "\" to compare keys case insensitive.", - options: { - type: "string", - enum: [OPTION_IGNORE_CASE], - }, - optionExamples: [ - true, - [true, OPTION_IGNORE_CASE], - ], - type: "maintainability", - typescriptOnly: false, -}; exports.Rule = Rule; function walk(ctx) { return ts.forEachChild(ctx.sourceFile, function cb(node) { diff --git a/node_modules/tslint/lib/rules/oneLineRule.d.ts b/node_modules/tslint/lib/rules/oneLineRule.d.ts index 0110ef383..435a5db6d 100644 --- a/node_modules/tslint/lib/rules/oneLineRule.d.ts +++ b/node_modules/tslint/lib/rules/oneLineRule.d.ts @@ -1,19 +1,3 @@ -/** - * @license - * Copyright 2013 Palantir Technologies, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ import * as ts from "typescript"; import * as Lint from "../index"; export declare class Rule extends Lint.Rules.AbstractRule { diff --git a/node_modules/tslint/lib/rules/oneLineRule.js b/node_modules/tslint/lib/rules/oneLineRule.js index be8ebd0c6..08d1ef212 100644 --- a/node_modules/tslint/lib/rules/oneLineRule.js +++ b/node_modules/tslint/lib/rules/oneLineRule.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 OPTION_BRACE = "check-open-brace"; @@ -33,32 +34,32 @@ var Rule = (function (_super) { var oneLineWalker = new OneLineWalker(sourceFile, this.getOptions()); return this.applyWithWalker(oneLineWalker); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "one-line", + description: "Requires the specified tokens to be on the same line as the expression preceding them.", + optionsDescription: (_a = ["\n Five arguments may be optionally provided:\n\n * `\"", "\"` checks that `catch` is on the same line as the closing brace for `try`.\n * `\"", "\"` checks that `finally` is on the same line as the closing brace for `catch`.\n * `\"", "\"` checks that `else` is on the same line as the closing brace for `if`.\n * `\"", "\"` checks that an open brace falls on the same line as its preceding expression.\n * `\"", "\"` checks preceding whitespace for the specified tokens."], _a.raw = ["\n Five arguments may be optionally provided:\n\n * \\`\"", "\"\\` checks that \\`catch\\` is on the same line as the closing brace for \\`try\\`.\n * \\`\"", "\"\\` checks that \\`finally\\` is on the same line as the closing brace for \\`catch\\`.\n * \\`\"", "\"\\` checks that \\`else\\` is on the same line as the closing brace for \\`if\\`.\n * \\`\"", "\"\\` checks that an open brace falls on the same line as its preceding expression.\n * \\`\"", "\"\\` checks preceding whitespace for the specified tokens."], Lint.Utils.dedent(_a, OPTION_CATCH, OPTION_FINALLY, OPTION_ELSE, OPTION_BRACE, OPTION_WHITESPACE)), + options: { + type: "array", + items: { + type: "string", + enum: [OPTION_CATCH, OPTION_FINALLY, OPTION_ELSE, OPTION_BRACE, OPTION_WHITESPACE], + }, + minLength: 0, + maxLength: 5, + }, + optionExamples: [[true, OPTION_CATCH, OPTION_FINALLY, OPTION_ELSE]], + type: "style", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.BRACE_FAILURE_STRING = "misplaced opening brace"; + Rule.CATCH_FAILURE_STRING = "misplaced 'catch'"; + Rule.ELSE_FAILURE_STRING = "misplaced 'else'"; + Rule.FINALLY_FAILURE_STRING = "misplaced 'finally'"; + Rule.WHITESPACE_FAILURE_STRING = "missing whitespace"; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "one-line", - description: "Requires the specified tokens to be on the same line as the expression preceding them.", - optionsDescription: (_a = ["\n Five arguments may be optionally provided:\n\n * `\"", "\"` checks that `catch` is on the same line as the closing brace for `try`.\n * `\"", "\"` checks that `finally` is on the same line as the closing brace for `catch`.\n * `\"", "\"` checks that `else` is on the same line as the closing brace for `if`.\n * `\"", "\"` checks that an open brace falls on the same line as its preceding expression.\n * `\"", "\"` checks preceding whitespace for the specified tokens."], _a.raw = ["\n Five arguments may be optionally provided:\n\n * \\`\"", "\"\\` checks that \\`catch\\` is on the same line as the closing brace for \\`try\\`.\n * \\`\"", "\"\\` checks that \\`finally\\` is on the same line as the closing brace for \\`catch\\`.\n * \\`\"", "\"\\` checks that \\`else\\` is on the same line as the closing brace for \\`if\\`.\n * \\`\"", "\"\\` checks that an open brace falls on the same line as its preceding expression.\n * \\`\"", "\"\\` checks preceding whitespace for the specified tokens."], Lint.Utils.dedent(_a, OPTION_CATCH, OPTION_FINALLY, OPTION_ELSE, OPTION_BRACE, OPTION_WHITESPACE)), - options: { - type: "array", - items: { - type: "string", - enum: [OPTION_CATCH, OPTION_FINALLY, OPTION_ELSE, OPTION_BRACE, OPTION_WHITESPACE], - }, - minLength: 0, - maxLength: 5, - }, - optionExamples: [[true, OPTION_CATCH, OPTION_FINALLY, OPTION_ELSE]], - type: "style", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.BRACE_FAILURE_STRING = "misplaced opening brace"; -Rule.CATCH_FAILURE_STRING = "misplaced 'catch'"; -Rule.ELSE_FAILURE_STRING = "misplaced 'else'"; -Rule.FINALLY_FAILURE_STRING = "misplaced 'finally'"; -Rule.WHITESPACE_FAILURE_STRING = "missing whitespace"; exports.Rule = Rule; var OneLineWalker = (function (_super) { tslib_1.__extends(OneLineWalker, _super); @@ -234,15 +235,8 @@ var OneLineWalker = (function (_super) { } }; OneLineWalker.prototype.handleClassLikeDeclaration = function (node) { - var lastNodeOfDeclaration = node.name; var openBraceToken = Lint.childOfKind(node, ts.SyntaxKind.OpenBraceToken); - if (node.heritageClauses != null) { - lastNodeOfDeclaration = node.heritageClauses[node.heritageClauses.length - 1]; - } - else if (node.typeParameters != null) { - lastNodeOfDeclaration = node.typeParameters[node.typeParameters.length - 1]; - } - this.handleOpeningBrace(lastNodeOfDeclaration, openBraceToken); + this.handleOpeningBrace(tsutils_1.getPreviousToken(openBraceToken), openBraceToken); }; OneLineWalker.prototype.handleIterationStatement = function (node) { // last child is the statement, second to last child is the close paren diff --git a/node_modules/tslint/lib/rules/oneVariablePerDeclarationRule.js b/node_modules/tslint/lib/rules/oneVariablePerDeclarationRule.js index 5d1f42191..dc741a54e 100644 --- a/node_modules/tslint/lib/rules/oneVariablePerDeclarationRule.js +++ b/node_modules/tslint/lib/rules/oneVariablePerDeclarationRule.js @@ -29,28 +29,28 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk, { ignoreForLoop: this.ruleArguments.indexOf(OPTION_IGNORE_FOR_LOOP) !== -1 }); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "one-variable-per-declaration", + description: "Disallows multiple variable definitions in the same declaration statement.", + optionsDescription: (_a = ["\n One argument may be optionally provided:\n\n * `", "` allows multiple variable definitions in a for loop declaration."], _a.raw = ["\n One argument may be optionally provided:\n\n * \\`", "\\` allows multiple variable definitions in a for loop declaration."], Lint.Utils.dedent(_a, OPTION_IGNORE_FOR_LOOP)), + options: { + type: "array", + items: { + type: "string", + enum: [OPTION_IGNORE_FOR_LOOP], + }, + minLength: 0, + maxLength: 1, + }, + optionExamples: [true, [true, OPTION_IGNORE_FOR_LOOP]], + type: "style", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "Multiple variable declarations in the same statement are forbidden"; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "one-variable-per-declaration", - description: "Disallows multiple variable definitions in the same declaration statement.", - optionsDescription: (_a = ["\n One argument may be optionally provided:\n\n * `", "` allows multiple variable definitions in a for loop declaration."], _a.raw = ["\n One argument may be optionally provided:\n\n * \\`", "\\` allows multiple variable definitions in a for loop declaration."], Lint.Utils.dedent(_a, OPTION_IGNORE_FOR_LOOP)), - options: { - type: "array", - items: { - type: "string", - enum: [OPTION_IGNORE_FOR_LOOP], - }, - minLength: 0, - maxLength: 1, - }, - optionExamples: [true, [true, OPTION_IGNORE_FOR_LOOP]], - type: "style", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "Multiple variable declarations in the same statement are forbidden"; exports.Rule = Rule; function walk(ctx) { ts.forEachChild(ctx.sourceFile, function cb(node) { diff --git a/node_modules/tslint/lib/rules/onlyArrowFunctionsRule.js b/node_modules/tslint/lib/rules/onlyArrowFunctionsRule.js index f5d8187f8..3d59a921c 100644 --- a/node_modules/tslint/lib/rules/onlyArrowFunctionsRule.js +++ b/node_modules/tslint/lib/rules/onlyArrowFunctionsRule.js @@ -30,29 +30,29 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk, parseOptions(this.ruleArguments)); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "only-arrow-functions", + description: "Disallows traditional (non-arrow) function expressions.", + rationale: "Traditional functions don't bind lexical scope, which can lead to unexpected behavior when accessing 'this'.", + optionsDescription: (_a = ["\n Two arguments may be optionally provided:\n\n * `\"", "\"` allows standalone function declarations.\n * `\"", "\"` allows the expression `function foo() {}` but not `function() {}`.\n "], _a.raw = ["\n Two arguments may be optionally provided:\n\n * \\`\"", "\"\\` allows standalone function declarations.\n * \\`\"", "\"\\` allows the expression \\`function foo() {}\\` but not \\`function() {}\\`.\n "], Lint.Utils.dedent(_a, OPTION_ALLOW_DECLARATIONS, OPTION_ALLOW_NAMED_FUNCTIONS)), + options: { + type: "array", + items: { + type: "string", + enum: [OPTION_ALLOW_DECLARATIONS, OPTION_ALLOW_NAMED_FUNCTIONS], + }, + minLength: 0, + maxLength: 1, + }, + optionExamples: [true, [true, OPTION_ALLOW_DECLARATIONS, OPTION_ALLOW_NAMED_FUNCTIONS]], + type: "typescript", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "non-arrow functions are forbidden"; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "only-arrow-functions", - description: "Disallows traditional (non-arrow) function expressions.", - rationale: "Traditional functions don't bind lexical scope, which can lead to unexpected behavior when accessing 'this'.", - optionsDescription: (_a = ["\n Two arguments may be optionally provided:\n\n * `\"", "\"` allows standalone function declarations.\n * `\"", "\"` allows the expression `function foo() {}` but not `function() {}`.\n "], _a.raw = ["\n Two arguments may be optionally provided:\n\n * \\`\"", "\"\\` allows standalone function declarations.\n * \\`\"", "\"\\` allows the expression \\`function foo() {}\\` but not \\`function() {}\\`.\n "], Lint.Utils.dedent(_a, OPTION_ALLOW_DECLARATIONS, OPTION_ALLOW_NAMED_FUNCTIONS)), - options: { - type: "array", - items: { - type: "string", - enum: [OPTION_ALLOW_DECLARATIONS, OPTION_ALLOW_NAMED_FUNCTIONS], - }, - minLength: 0, - maxLength: 1, - }, - optionExamples: [true, [true, OPTION_ALLOW_DECLARATIONS, OPTION_ALLOW_NAMED_FUNCTIONS]], - type: "typescript", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "non-arrow functions are forbidden"; exports.Rule = Rule; function parseOptions(ruleArguments) { return { @@ -84,7 +84,7 @@ function walk(ctx) { } /** Generator functions and functions using `this` are allowed. */ function functionIsExempt(node) { - return node.asteriskToken !== undefined || hasThisParameter(node) || node.body !== undefined && usesThisInBody(node.body); + return node.asteriskToken !== undefined || hasThisParameter(node) || node.body !== undefined && usesThisInBody(node.body) === true; } function hasThisParameter(node) { var first = node.parameters[0]; diff --git a/node_modules/tslint/lib/rules/orderedImportsRule.d.ts b/node_modules/tslint/lib/rules/orderedImportsRule.d.ts index 878b820e2..3f2362e71 100644 --- a/node_modules/tslint/lib/rules/orderedImportsRule.d.ts +++ b/node_modules/tslint/lib/rules/orderedImportsRule.d.ts @@ -1,19 +1,3 @@ -/** - * @license - * Copyright 2016 Palantir Technologies, Inc. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ import * as ts from "typescript"; import * as Lint from "../index"; export declare class Rule extends Lint.Rules.AbstractRule { diff --git a/node_modules/tslint/lib/rules/orderedImportsRule.js b/node_modules/tslint/lib/rules/orderedImportsRule.js index 1d90c1677..9190d6860 100644 --- a/node_modules/tslint/lib/rules/orderedImportsRule.js +++ b/node_modules/tslint/lib/rules/orderedImportsRule.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,136 +26,144 @@ var Rule = (function (_super) { return _super !== null && _super.apply(this, arguments) || this; } Rule.prototype.apply = function (sourceFile) { - var orderedImportsWalker = new OrderedImportsWalker(sourceFile, this.getOptions()); - return this.applyWithWalker(orderedImportsWalker); + return this.applyWithWalker(new Walker(sourceFile, this.ruleName, parseOptions(this.ruleArguments))); }; - return Rule; -}(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "ordered-imports", - description: "Requires that import statements be alphabetized.", - descriptionDetails: (_a = ["\n Enforce a consistent ordering for ES6 imports:\n - Named imports must be alphabetized (i.e. \"import {A, B, C} from \"foo\";\")\n - The exact ordering can be controlled by the named-imports-order option.\n - \"longName as name\" imports are ordered by \"longName\".\n - Import sources must be alphabetized within groups, i.e.:\n import * as foo from \"a\";\n import * as bar from \"b\";\n - Groups of imports are delineated by blank lines. You can use these to group imports\n however you like, e.g. by first- vs. third-party or thematically."], _a.raw = ["\n Enforce a consistent ordering for ES6 imports:\n - Named imports must be alphabetized (i.e. \"import {A, B, C} from \"foo\";\")\n - The exact ordering can be controlled by the named-imports-order option.\n - \"longName as name\" imports are ordered by \"longName\".\n - Import sources must be alphabetized within groups, i.e.:\n import * as foo from \"a\";\n import * as bar from \"b\";\n - Groups of imports are delineated by blank lines. You can use these to group imports\n however you like, e.g. by first- vs. third-party or thematically."], Lint.Utils.dedent(_a)), - hasFix: true, - optionsDescription: (_b = ["\n You may set the `\"import-sources-order\"` option to control the ordering of source\n imports (the `\"foo\"` in `import {A, B, C} from \"foo\"`).\n\n Possible values for `\"import-sources-order\"` are:\n\n * `\"case-insensitive'`: Correct order is `\"Bar\"`, `\"baz\"`, `\"Foo\"`. (This is the default.)\n * `\"lowercase-first\"`: Correct order is `\"baz\"`, `\"Bar\"`, `\"Foo\"`.\n * `\"lowercase-last\"`: Correct order is `\"Bar\"`, `\"Foo\"`, `\"baz\"`.\n * `\"any\"`: Allow any order.\n\n You may set the `\"named-imports-order\"` option to control the ordering of named\n imports (the `{A, B, C}` in `import {A, B, C} from \"foo\"`).\n\n Possible values for `\"named-imports-order\"` are:\n\n * `\"case-insensitive'`: Correct order is `{A, b, C}`. (This is the default.)\n * `\"lowercase-first\"`: Correct order is `{b, A, C}`.\n * `\"lowercase-last\"`: Correct order is `{A, C, b}`.\n * `\"any\"`: Allow any order.\n\n "], _b.raw = ["\n You may set the \\`\"import-sources-order\"\\` option to control the ordering of source\n imports (the \\`\"foo\"\\` in \\`import {A, B, C} from \"foo\"\\`).\n\n Possible values for \\`\"import-sources-order\"\\` are:\n\n * \\`\"case-insensitive'\\`: Correct order is \\`\"Bar\"\\`, \\`\"baz\"\\`, \\`\"Foo\"\\`. (This is the default.)\n * \\`\"lowercase-first\"\\`: Correct order is \\`\"baz\"\\`, \\`\"Bar\"\\`, \\`\"Foo\"\\`.\n * \\`\"lowercase-last\"\\`: Correct order is \\`\"Bar\"\\`, \\`\"Foo\"\\`, \\`\"baz\"\\`.\n * \\`\"any\"\\`: Allow any order.\n\n You may set the \\`\"named-imports-order\"\\` option to control the ordering of named\n imports (the \\`{A, B, C}\\` in \\`import {A, B, C} from \"foo\"\\`).\n\n Possible values for \\`\"named-imports-order\"\\` are:\n\n * \\`\"case-insensitive'\\`: Correct order is \\`{A, b, C}\\`. (This is the default.)\n * \\`\"lowercase-first\"\\`: Correct order is \\`{b, A, C}\\`.\n * \\`\"lowercase-last\"\\`: Correct order is \\`{A, C, b}\\`.\n * \\`\"any\"\\`: Allow any order.\n\n "], Lint.Utils.dedent(_b)), - options: { - type: "object", - properties: { - "import-sources-order": { - type: "string", - enum: ["case-insensitive", "lowercase-first", "lowercase-last", "any"], - }, - "named-imports-order": { - type: "string", - enum: ["case-insensitive", "lowercase-first", "lowercase-last", "any"], + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "ordered-imports", + description: "Requires that import statements be alphabetized.", + descriptionDetails: (_a = ["\n Enforce a consistent ordering for ES6 imports:\n - Named imports must be alphabetized (i.e. \"import {A, B, C} from \"foo\";\")\n - The exact ordering can be controlled by the named-imports-order option.\n - \"longName as name\" imports are ordered by \"longName\".\n - Import sources must be alphabetized within groups, i.e.:\n import * as foo from \"a\";\n import * as bar from \"b\";\n - Groups of imports are delineated by blank lines. You can use these to group imports\n however you like, e.g. by first- vs. third-party or thematically."], _a.raw = ["\n Enforce a consistent ordering for ES6 imports:\n - Named imports must be alphabetized (i.e. \"import {A, B, C} from \"foo\";\")\n - The exact ordering can be controlled by the named-imports-order option.\n - \"longName as name\" imports are ordered by \"longName\".\n - Import sources must be alphabetized within groups, i.e.:\n import * as foo from \"a\";\n import * as bar from \"b\";\n - Groups of imports are delineated by blank lines. You can use these to group imports\n however you like, e.g. by first- vs. third-party or thematically."], Lint.Utils.dedent(_a)), + hasFix: true, + optionsDescription: (_b = ["\n You may set the `\"import-sources-order\"` option to control the ordering of source\n imports (the `\"foo\"` in `import {A, B, C} from \"foo\"`).\n\n Possible values for `\"import-sources-order\"` are:\n\n * `\"case-insensitive'`: Correct order is `\"Bar\"`, `\"baz\"`, `\"Foo\"`. (This is the default.)\n * `\"lowercase-first\"`: Correct order is `\"baz\"`, `\"Bar\"`, `\"Foo\"`.\n * `\"lowercase-last\"`: Correct order is `\"Bar\"`, `\"Foo\"`, `\"baz\"`.\n * `\"any\"`: Allow any order.\n\n You may set the `\"named-imports-order\"` option to control the ordering of named\n imports (the `{A, B, C}` in `import {A, B, C} from \"foo\"`).\n\n Possible values for `\"named-imports-order\"` are:\n\n * `\"case-insensitive'`: Correct order is `{A, b, C}`. (This is the default.)\n * `\"lowercase-first\"`: Correct order is `{b, A, C}`.\n * `\"lowercase-last\"`: Correct order is `{A, C, b}`.\n * `\"any\"`: Allow any order.\n\n "], _b.raw = ["\n You may set the \\`\"import-sources-order\"\\` option to control the ordering of source\n imports (the \\`\"foo\"\\` in \\`import {A, B, C} from \"foo\"\\`).\n\n Possible values for \\`\"import-sources-order\"\\` are:\n\n * \\`\"case-insensitive'\\`: Correct order is \\`\"Bar\"\\`, \\`\"baz\"\\`, \\`\"Foo\"\\`. (This is the default.)\n * \\`\"lowercase-first\"\\`: Correct order is \\`\"baz\"\\`, \\`\"Bar\"\\`, \\`\"Foo\"\\`.\n * \\`\"lowercase-last\"\\`: Correct order is \\`\"Bar\"\\`, \\`\"Foo\"\\`, \\`\"baz\"\\`.\n * \\`\"any\"\\`: Allow any order.\n\n You may set the \\`\"named-imports-order\"\\` option to control the ordering of named\n imports (the \\`{A, B, C}\\` in \\`import {A, B, C} from \"foo\"\\`).\n\n Possible values for \\`\"named-imports-order\"\\` are:\n\n * \\`\"case-insensitive'\\`: Correct order is \\`{A, b, C}\\`. (This is the default.)\n * \\`\"lowercase-first\"\\`: Correct order is \\`{b, A, C}\\`.\n * \\`\"lowercase-last\"\\`: Correct order is \\`{A, C, b}\\`.\n * \\`\"any\"\\`: Allow any order.\n\n "], Lint.Utils.dedent(_b)), + options: { + type: "object", + properties: { + "import-sources-order": { + type: "string", + enum: ["case-insensitive", "lowercase-first", "lowercase-last", "any"], + }, + "named-imports-order": { + type: "string", + enum: ["case-insensitive", "lowercase-first", "lowercase-last", "any"], + }, }, + additionalProperties: false, }, - additionalProperties: false, - }, - optionExamples: [ - true, - [true, { "import-sources-order": "lowercase-last", "named-imports-order": "lowercase-first" }], - ], - type: "style", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.IMPORT_SOURCES_UNORDERED = "Import sources within a group must be alphabetized."; -Rule.NAMED_IMPORTS_UNORDERED = "Named imports must be alphabetized."; + optionExamples: [ + true, + [true, { "import-sources-order": "lowercase-last", "named-imports-order": "lowercase-first" }], + ], + type: "style", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.IMPORT_SOURCES_UNORDERED = "Import sources within a group must be alphabetized."; + Rule.NAMED_IMPORTS_UNORDERED = "Named imports must be alphabetized."; + return Rule; +}(Lint.Rules.AbstractRule)); exports.Rule = Rule; -// Convert aBcD --> AbCd -function flipCase(x) { - return x.split("").map(function (char) { - if (char >= "a" && char <= "z") { - return char.toUpperCase(); - } - else if (char >= "A" && char <= "Z") { - return char.toLowerCase(); - } - return char; - }).join(""); -} -// After applying a transformation, are the nodes sorted according to the text they contain? -// If not, return the pair of nodes which are out of order. -function findUnsortedPair(xs, transform) { - for (var i = 1; i < xs.length; i++) { - if (transform(xs[i].getText()) < transform(xs[i - 1].getText())) { - return [xs[i - 1], xs[i]]; - } - } - return null; -} -function compare(a, b) { - function isLow(value) { - return value[0] === "." || value[0] === "/"; - } - if (isLow(a) && !isLow(b)) { - return 1; - } - else if (!isLow(a) && isLow(b)) { - return -1; - } - else if (a > b) { - return 1; - } - else if (a < b) { - return -1; - } - return 0; -} -function removeQuotes(value) { - // strip out quotes - if (value.length > 1 && (value[0] === "'" || value[0] === "\"")) { - value = value.substr(1, value.length - 2); - } - return value; -} -function sortByKey(xs, getSortKey) { - return xs.slice().sort(function (a, b) { - return compare(getSortKey(a), getSortKey(b)); - }); +var TRANSFORMS = new Map([ + ["any", function () { return ""; }], + ["case-insensitive", function (x) { return x.toLowerCase(); }], + ["lowercase-first", flipCase], + ["lowercase-last", function (x) { return x; }], +]); +function parseOptions(ruleArguments) { + var optionSet = ruleArguments[0]; + var _a = optionSet === undefined ? {} : optionSet, _b = _a["import-sources-order"], sources = _b === void 0 ? "case-insensitive" : _b, _c = _a["named-imports-order"], named = _c === void 0 ? "case-insensitive" : _c; + return { + importSourcesOrderTransform: TRANSFORMS.get(sources), + namedImportsOrderTransform: TRANSFORMS.get(named), + }; } -// Transformations to apply to produce the desired ordering of imports. -// The imports must be lexicographically sorted after applying the transform. -var TRANSFORMS = { - "any": function () { return ""; }, - "case-insensitive": function (x) { return x.toLowerCase(); }, - "lowercase-first": flipCase, - "lowercase-last": function (x) { return x; }, -}; -var OrderedImportsWalker = (function (_super) { - tslib_1.__extends(OrderedImportsWalker, _super); - function OrderedImportsWalker(sourceFile, options) { - var _this = _super.call(this, sourceFile, options) || this; +var Walker = (function (_super) { + tslib_1.__extends(Walker, _super); + function Walker() { + var _this = _super !== null && _super.apply(this, arguments) || this; _this.currentImportsBlock = new ImportsBlock(); - var optionSet = _this.getOptions()[0]; - var _a = optionSet === undefined ? {} : optionSet, _b = _a["import-sources-order"], sources = _b === void 0 ? "case-insensitive" : _b, _c = _a["named-imports-order"], named = _c === void 0 ? "case-insensitive" : _c; - _this.importSourcesOrderTransform = TRANSFORMS[sources]; - _this.namedImportsOrderTransform = TRANSFORMS[named]; return _this; } - // e.g. "import Foo from "./foo";" - OrderedImportsWalker.prototype.visitImportDeclaration = function (node) { - var source = node.moduleSpecifier.getText(); - source = removeQuotes(source); - source = this.importSourcesOrderTransform(source); + Walker.prototype.walk = function (sourceFile) { + for (var _i = 0, _a = sourceFile.statements; _i < _a.length; _i++) { + var statement = _a[_i]; + this.checkStatement(statement); + } + this.endBlock(); + }; + Walker.prototype.checkStatement = function (statement) { + if (!(tsutils_1.isImportDeclaration(statement) || tsutils_1.isImportEqualsDeclaration(statement)) || + /\r?\n\r?\n/.test(this.sourceFile.text.slice(statement.getFullStart(), statement.getStart(this.sourceFile)))) { + this.endBlock(); + } + if (tsutils_1.isImportDeclaration(statement)) { + this.checkImportDeclaration(statement); + } + else if (tsutils_1.isImportEqualsDeclaration(statement)) { + this.checkImportEqualsDeclaration(statement); + } + else if (tsutils_1.isModuleDeclaration(statement)) { + var body = moduleDeclarationBody(statement); + if (body !== undefined) { + for (var _i = 0, _a = body.statements; _i < _a.length; _i++) { + var subStatement = _a[_i]; + this.checkStatement(subStatement); + } + this.endBlock(); + } + } + }; + Walker.prototype.checkImportDeclaration = function (node) { + if (!tsutils_1.isStringLiteral(node.moduleSpecifier)) { + // Ignore grammar error + return; + } + var source = this.options.importSourcesOrderTransform(removeQuotes(node.moduleSpecifier.text)); + this.checkSource(source, node); + var importClause = node.importClause; + if (importClause !== undefined && importClause.namedBindings !== undefined && tsutils_1.isNamedImports(importClause.namedBindings)) { + this.checkNamedImports(importClause.namedBindings); + } + }; + Walker.prototype.checkImportEqualsDeclaration = function (node) { + // only allowed `import x = require('y');` + var moduleReference = node.moduleReference; + if (!tsutils_1.isExternalModuleReference(moduleReference)) { + return; + } + var expression = moduleReference.expression; + if (expression === undefined || !tsutils_1.isStringLiteral(expression)) { + return; + } + var source = this.options.importSourcesOrderTransform(removeQuotes(expression.text)); + this.checkSource(source, node); + }; + Walker.prototype.checkSource = function (source, node) { var previousSource = this.currentImportsBlock.getLastImportSource(); - this.currentImportsBlock.addImportDeclaration(this.getSourceFile(), node, source); + this.currentImportsBlock.addImportDeclaration(this.sourceFile, node, source); if (previousSource !== null && compare(source, previousSource) === -1) { this.lastFix = []; this.addFailureAtNode(node, Rule.IMPORT_SOURCES_UNORDERED, this.lastFix); } - _super.prototype.visitImportDeclaration.call(this, node); }; - // This is the "{A, B, C}" of "import {A, B, C} from "./foo";". - // We need to make sure they're alphabetized. - OrderedImportsWalker.prototype.visitNamedImports = function (node) { + Walker.prototype.endBlock = function () { + if (this.lastFix !== undefined) { + var replacement = this.currentImportsBlock.getReplacement(); + if (replacement !== undefined) { + this.lastFix.push(replacement); + } + this.lastFix = undefined; + } + this.currentImportsBlock = new ImportsBlock(); + }; + Walker.prototype.checkNamedImports = function (node) { var _this = this; var imports = node.elements; - var pair = findUnsortedPair(imports, this.namedImportsOrderTransform); - if (pair !== null) { + var pair = findUnsortedPair(imports, this.options.namedImportsOrderTransform); + if (pair !== undefined) { var a = pair[0], b = pair[1]; - var sortedDeclarations = sortByKey(imports, function (x) { return _this.namedImportsOrderTransform(x.getText()); }).map(function (x) { return x.getText(); }); + var sortedDeclarations = sortByKey(imports, function (x) { + return _this.options.namedImportsOrderTransform(x.getText()); + }).map(function (x) { return x.getText(); }); // replace in reverse order to preserve earlier offsets for (var i = imports.length - 1; i >= 0; i--) { var start = imports[i].getStart(); @@ -163,34 +172,11 @@ var OrderedImportsWalker = (function (_super) { this.currentImportsBlock.replaceNamedImports(start, length, sortedDeclarations[i]); } this.lastFix = []; - this.addFailureFromStartToEnd(a.getStart(), b.getEnd(), Rule.NAMED_IMPORTS_UNORDERED, this.lastFix); - } - _super.prototype.visitNamedImports.call(this, node); - }; - // keep reading the block of import declarations until the block ends, then replace the entire block - // this allows the reorder of named imports to work well with reordering lines - OrderedImportsWalker.prototype.visitNode = function (node) { - var prefixLength = node.getStart() - node.getFullStart(); - var prefix = node.getFullText().slice(0, prefixLength); - var hasBlankLine = prefix.indexOf("\n\n") >= 0 || prefix.indexOf("\r\n\r\n") >= 0; - var notImportDeclaration = node.parent != null - && node.parent.kind === ts.SyntaxKind.SourceFile - && node.kind !== ts.SyntaxKind.ImportDeclaration; - if (hasBlankLine || notImportDeclaration) { - // end of block - if (this.lastFix != null) { - var replacement = this.currentImportsBlock.getReplacement(); - if (replacement != null) { - this.lastFix.push(replacement); - } - this.lastFix = null; - } - this.currentImportsBlock = new ImportsBlock(); + this.addFailure(a.getStart(), b.getEnd(), Rule.NAMED_IMPORTS_UNORDERED, this.lastFix); } - _super.prototype.visitNode.call(this, node); }; - return OrderedImportsWalker; -}(Lint.RuleWalker)); + return Walker; +}(Lint.AbstractWalker)); var ImportsBlock = (function () { function ImportsBlock() { this.importDeclarations = []; @@ -235,7 +221,7 @@ var ImportsBlock = (function () { // creates a Lint.Replacement object with ordering fixes for the entire block ImportsBlock.prototype.getReplacement = function () { if (this.importDeclarations.length === 0) { - return null; + return undefined; } var sortedDeclarations = sortByKey(this.importDeclarations.slice(), function (x) { return x.sourcePath; }); var fixedText = sortedDeclarations.map(function (x) { return x.text; }).join(""); @@ -252,12 +238,69 @@ var ImportsBlock = (function () { }; // gets the offset of the end of the import's line, including newline, to include comment to the right ImportsBlock.prototype.getEndOffset = function (sourceFile, node) { - var endLineOffset = sourceFile.text.indexOf("\n", node.end) + 1; - return endLineOffset; + return sourceFile.text.indexOf("\n", node.end) + 1; }; ImportsBlock.prototype.getLastImportDeclaration = function () { return this.importDeclarations[this.importDeclarations.length - 1]; }; return ImportsBlock; }()); +// Convert aBcD --> AbCd +function flipCase(str) { + return Array.from(str).map(function (char) { + if (char >= "a" && char <= "z") { + return char.toUpperCase(); + } + else if (char >= "A" && char <= "Z") { + return char.toLowerCase(); + } + return char; + }).join(""); +} +// After applying a transformation, are the nodes sorted according to the text they contain? +// If not, return the pair of nodes which are out of order. +function findUnsortedPair(xs, transform) { + for (var i = 1; i < xs.length; i++) { + if (transform(xs[i].getText()) < transform(xs[i - 1].getText())) { + return [xs[i - 1], xs[i]]; + } + } + return undefined; +} +// tslint:disable-next-line no-unsafe-any (fixed in 5.3) +function compare(a, b) { + function isLow(value) { + return value[0] === "." || value[0] === "/"; + } + if (isLow(a) && !isLow(b)) { + return 1; + } + else if (!isLow(a) && isLow(b)) { + return -1; + } + else if (a > b) { + return 1; + } + else if (a < b) { + return -1; + } + return 0; +} +function removeQuotes(value) { + // strip out quotes + if (value.length > 1 && (value[0] === "'" || value[0] === "\"")) { + value = value.substr(1, value.length - 2); + } + return value; +} +function sortByKey(xs, getSortKey) { + return xs.slice().sort(function (a, b) { return compare(getSortKey(a), getSortKey(b)); }); +} +function moduleDeclarationBody(node) { + var body = node.body; + while (body !== undefined && body.kind === ts.SyntaxKind.ModuleDeclaration) { + body = body.body; + } + return body !== undefined && body.kind === ts.SyntaxKind.ModuleBlock ? body : undefined; +} var _a, _b; diff --git a/node_modules/tslint/lib/rules/preferConditionalExpressionRule.js b/node_modules/tslint/lib/rules/preferConditionalExpressionRule.js index 7be4cbcbe..b8f8693df 100644 --- a/node_modules/tslint/lib/rules/preferConditionalExpressionRule.js +++ b/node_modules/tslint/lib/rules/preferConditionalExpressionRule.js @@ -20,6 +20,7 @@ var tslib_1 = require("tslib"); var tsutils_1 = require("tsutils"); var ts = require("typescript"); var Lint = require("../index"); +var OPTION_CHECK_ELSE_IF = "check-else-if"; var Rule = (function (_super) { tslib_1.__extends(Rule, _super); function Rule() { @@ -30,29 +31,36 @@ var Rule = (function (_super) { return "Use a conditional expression instead of assigning to '" + assigned + "' in multiple places."; }; Rule.prototype.apply = function (sourceFile) { - return this.applyWithFunction(sourceFile, walk); + return this.applyWithFunction(sourceFile, walk, { + checkElseIf: this.ruleArguments.indexOf(OPTION_CHECK_ELSE_IF) !== -1, + }); + }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "prefer-conditional-expression", + description: (_a = ["\n Recommends to use a conditional expression instead of assigning to the same thing in each branch of an if statement."], _a.raw = ["\n Recommends to use a conditional expression instead of assigning to the same thing in each branch of an if statement."], Lint.Utils.dedent(_a)), + rationale: (_b = ["\n This reduces duplication and can eliminate an unnecessary variable declaration."], _b.raw = ["\n This reduces duplication and can eliminate an unnecessary variable declaration."], Lint.Utils.dedent(_b)), + optionsDescription: "If `" + OPTION_CHECK_ELSE_IF + "` is specified, the rule also checks nested if-else-if statements.", + options: { + type: "string", + enum: [OPTION_CHECK_ELSE_IF], + }, + optionExamples: [true, [true, OPTION_CHECK_ELSE_IF]], + type: "functionality", + typescriptOnly: false, }; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "prefer-conditional-expression", - description: (_a = ["\n Recommends to use a conditional expression instead of assigning to the same thing in each branch of an if statement."], _a.raw = ["\n Recommends to use a conditional expression instead of assigning to the same thing in each branch of an if statement."], Lint.Utils.dedent(_a)), - rationale: (_b = ["\n This reduces duplication and can eliminate an unnecessary variable declaration."], _b.raw = ["\n This reduces duplication and can eliminate an unnecessary variable declaration."], Lint.Utils.dedent(_b)), - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "functionality", - typescriptOnly: false, -}; exports.Rule = Rule; function walk(ctx) { - var sourceFile = ctx.sourceFile; + var sourceFile = ctx.sourceFile, checkElseIf = ctx.options.checkElseIf; return ts.forEachChild(sourceFile, function cb(node) { if (tsutils_1.isIfStatement(node)) { - var assigned = detect(node, sourceFile); + var assigned = detect(node, sourceFile, checkElseIf); if (assigned !== undefined) { - ctx.addFailureAtNode(Lint.childOfKind(node, ts.SyntaxKind.IfKeyword), Rule.FAILURE_STRING(assigned.getText(sourceFile))); + ctx.addFailureAtNode(node.getChildAt(0, sourceFile), Rule.FAILURE_STRING(assigned.getText(sourceFile))); + } + if (assigned !== undefined || !checkElseIf) { // Be careful not to fail again for the "else if" ts.forEachChild(node.expression, cb); ts.forEachChild(node.thenStatement, cb); @@ -65,12 +73,12 @@ function walk(ctx) { return ts.forEachChild(node, cb); }); } -function detect(_a, sourceFile) { +function detect(_a, sourceFile, elseIf) { var thenStatement = _a.thenStatement, elseStatement = _a.elseStatement; - if (elseStatement === undefined) { + if (elseStatement === undefined || !elseIf && elseStatement.kind === ts.SyntaxKind.IfStatement) { return undefined; } - var elze = tsutils_1.isIfStatement(elseStatement) ? detect(elseStatement, sourceFile) : getAssigned(elseStatement, sourceFile); + var elze = tsutils_1.isIfStatement(elseStatement) ? detect(elseStatement, sourceFile, elseIf) : getAssigned(elseStatement, sourceFile); if (elze === undefined) { return undefined; } diff --git a/node_modules/tslint/lib/rules/preferConstRule.js b/node_modules/tslint/lib/rules/preferConstRule.js index 674a44755..1efc5b1e0 100644 --- a/node_modules/tslint/lib/rules/preferConstRule.js +++ b/node_modules/tslint/lib/rules/preferConstRule.js @@ -33,37 +33,36 @@ var Rule = (function (_super) { }; Rule.prototype.apply = function (sourceFile) { var options = { - destructuringAll: this.ruleArguments.length !== 0 && - this.ruleArguments[0].destructuring === OPTION_DESTRUCTURING_ALL, + destructuringAll: this.ruleArguments.length !== 0 && this.ruleArguments[0].destructuring === OPTION_DESTRUCTURING_ALL, }; var preferConstWalker = new PreferConstWalker(sourceFile, this.ruleName, options); return this.applyWithWalker(preferConstWalker); }; - return Rule; -}(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "prefer-const", - description: "Requires that variable declarations use `const` instead of `let` and `var` if possible.", - descriptionDetails: (_a = ["\n If a variable is only assigned to once when it is declared, it should be declared using 'const'"], _a.raw = ["\n If a variable is only assigned to once when it is declared, it should be declared using 'const'"], Lint.Utils.dedent(_a)), - hasFix: true, - optionsDescription: (_b = ["\n An optional object containing the property \"destructuring\" with two possible values:\n\n * \"", "\" (default) - If any variable in destructuring can be const, this rule warns for those variables.\n * \"", "\" - Only warns if all variables in destructuring can be const."], _b.raw = ["\n An optional object containing the property \"destructuring\" with two possible values:\n\n * \"", "\" (default) - If any variable in destructuring can be const, this rule warns for those variables.\n * \"", "\" - Only warns if all variables in destructuring can be const."], Lint.Utils.dedent(_b, OPTION_DESTRUCTURING_ANY, OPTION_DESTRUCTURING_ALL)), - options: { - type: "object", - properties: { - destructuring: { - type: "string", - enum: [OPTION_DESTRUCTURING_ALL, OPTION_DESTRUCTURING_ANY], + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "prefer-const", + description: "Requires that variable declarations use `const` instead of `let` and `var` if possible.", + descriptionDetails: (_a = ["\n If a variable is only assigned to once when it is declared, it should be declared using 'const'"], _a.raw = ["\n If a variable is only assigned to once when it is declared, it should be declared using 'const'"], Lint.Utils.dedent(_a)), + hasFix: true, + optionsDescription: (_b = ["\n An optional object containing the property \"destructuring\" with two possible values:\n\n * \"", "\" (default) - If any variable in destructuring can be const, this rule warns for those variables.\n * \"", "\" - Only warns if all variables in destructuring can be const."], _b.raw = ["\n An optional object containing the property \"destructuring\" with two possible values:\n\n * \"", "\" (default) - If any variable in destructuring can be const, this rule warns for those variables.\n * \"", "\" - Only warns if all variables in destructuring can be const."], Lint.Utils.dedent(_b, OPTION_DESTRUCTURING_ANY, OPTION_DESTRUCTURING_ALL)), + options: { + type: "object", + properties: { + destructuring: { + type: "string", + enum: [OPTION_DESTRUCTURING_ALL, OPTION_DESTRUCTURING_ANY], + }, }, }, - }, - optionExamples: [ - true, - [true, { destructuring: OPTION_DESTRUCTURING_ALL }], - ], - type: "maintainability", - typescriptOnly: false, -}; + optionExamples: [ + true, + [true, { destructuring: OPTION_DESTRUCTURING_ALL }], + ], + type: "maintainability", + typescriptOnly: false, + }; + return Rule; +}(Lint.Rules.AbstractRule)); exports.Rule = Rule; var Scope = (function () { function Scope(functionScope) { @@ -215,7 +214,6 @@ var PreferConstWalker = (function (_super) { this.handleExpression(property.initializer); } } - break; } }; PreferConstWalker.prototype.handleBindingName = function (name, declarationInfo) { @@ -248,7 +246,8 @@ var PreferConstWalker = (function (_super) { canBeConst: true, declarationList: declarationList, isBlockScoped: kind === 1 /* Let */, - isForLoop: declarationList.parent.kind === ts.SyntaxKind.ForStatement, + isForLoop: declarationList.parent.kind === ts.SyntaxKind.ForStatement || + declarationList.parent.kind === ts.SyntaxKind.ForOfStatement, reassignedSiblings: false, }; } diff --git a/node_modules/tslint/lib/rules/preferForOfRule.js b/node_modules/tslint/lib/rules/preferForOfRule.js index a9a66dabd..f0fb70d89 100644 --- a/node_modules/tslint/lib/rules/preferForOfRule.js +++ b/node_modules/tslint/lib/rules/preferForOfRule.js @@ -29,76 +29,57 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "prefer-for-of", + description: "Recommends a 'for-of' loop over a standard 'for' loop if the index is only used to access the array being iterated.", + rationale: "A for(... of ...) loop is easier to implement and read when the index is not needed.", + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "typescript", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "Expected a 'for-of' loop instead of a 'for' loop with this simple iteration"; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "prefer-for-of", - description: "Recommends a 'for-of' loop over a standard 'for' loop if the index is only used to access the array being iterated.", - rationale: "A for(... of ...) loop is easier to implement and read when the index is not needed.", - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "typescript", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "Expected a 'for-of' loop instead of a 'for' loop with this simple iteration"; exports.Rule = Rule; function walk(ctx) { var sourceFile = ctx.sourceFile; - var scopes = []; - return ts.forEachChild(sourceFile, cb); - function cb(node) { - switch (node.kind) { - case ts.SyntaxKind.ForStatement: - return visitForStatement(node); - case ts.SyntaxKind.Identifier: - return visitIdentifier(node); - default: - return ts.forEachChild(node, cb); + var variables; + return ts.forEachChild(sourceFile, function cb(node) { + if (utils.isForStatement(node)) { + visitForStatement(node); } - } + return ts.forEachChild(node, cb); + }); function visitForStatement(node) { var arrayNodeInfo = getForLoopHeaderInfo(node); if (arrayNodeInfo === undefined) { - return ts.forEachChild(node, cb); + return; } var indexVariable = arrayNodeInfo.indexVariable, arrayExpr = arrayNodeInfo.arrayExpr; - var indexVariableName = indexVariable.text; - // store `for` loop state - var state = { indexVariableName: indexVariableName, arrayExpr: arrayExpr, onlyArrayReadAccess: true }; - scopes.push(state); - ts.forEachChild(node.statement, cb); - scopes.pop(); - if (state.onlyArrayReadAccess) { - ctx.addFailure(node.getStart(), node.statement.getFullStart(), Rule.FAILURE_STRING); - } - } - function visitIdentifier(node) { - var state = getStateForVariable(node.text); - if (state !== undefined && state.onlyArrayReadAccess && isNonSimpleIncrementorUse(node, state.arrayExpr, sourceFile)) { - state.onlyArrayReadAccess = false; + if (variables === undefined) { + variables = utils.collectVariableUsage(sourceFile); } - } - function getStateForVariable(name) { - for (var i = scopes.length - 1; i >= 0; i--) { - var scope = scopes[i]; - if (scope.indexVariableName === name) { - return scope; + for (var _i = 0, _a = variables.get(indexVariable).uses; _i < _a.length; _i++) { + var location = _a[_i].location; + if (location.pos < node.initializer.end || location.pos >= node.end || + location.pos >= node.statement.pos && + isNonSimpleIncrementorUse(location, arrayExpr, sourceFile)) { + return; } } - return undefined; + ctx.addFailure(node.getStart(sourceFile), node.statement.pos, Rule.FAILURE_STRING); } } function isNonSimpleIncrementorUse(node, arrayExpr, sourceFile) { // check if iterator is used for something other than reading data from array - var elementAccess = node.parent; - var accessParent = elementAccess.parent; - return !utils.isElementAccessExpression(elementAccess) - || utils_1.isAssignment(accessParent) - || accessParent.kind === ts.SyntaxKind.DeleteExpression - || !nodeEquals(arrayExpr, utils_1.unwrapParentheses(elementAccess.expression), sourceFile); + var parent = node.parent; + return !utils.isElementAccessExpression(parent) + || utils.isReassignmentTarget(parent) + || !nodeEquals(arrayExpr, utils_1.unwrapParentheses(parent.expression), sourceFile); } function nodeEquals(a, b, sourceFile) { return a.getText(sourceFile) === b.getText(sourceFile); diff --git a/node_modules/tslint/lib/rules/preferFunctionOverMethodRule.js b/node_modules/tslint/lib/rules/preferFunctionOverMethodRule.js index d703adda3..83daf2363 100644 --- a/node_modules/tslint/lib/rules/preferFunctionOverMethodRule.js +++ b/node_modules/tslint/lib/rules/preferFunctionOverMethodRule.js @@ -33,26 +33,26 @@ var Rule = (function (_super) { allowPublic: this.ruleArguments.indexOf(OPTION_ALLOW_PUBLIC) !== -1, })); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "prefer-function-over-method", + description: "Warns for class methods that do not use 'this'.", + optionsDescription: (_a = ["\n \"", "\" excludes checking of public methods.\n \"", "\" excludes checking of protected methods."], _a.raw = ["\n \"", "\" excludes checking of public methods.\n \"", "\" excludes checking of protected methods."], Lint.Utils.dedent(_a, OPTION_ALLOW_PUBLIC, OPTION_ALLOW_PROTECTED)), + options: { + type: "string", + enum: [OPTION_ALLOW_PUBLIC, OPTION_ALLOW_PROTECTED], + }, + optionExamples: [ + true, + [true, OPTION_ALLOW_PUBLIC, OPTION_ALLOW_PROTECTED], + ], + type: "style", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "Class method does not use 'this'. Use a function instead."; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "prefer-function-over-method", - description: "Warns for class methods that do not use 'this'.", - optionsDescription: (_a = ["\n \"", "\" excludes checking of public methods.\n \"", "\" excludes checking of protected methods."], _a.raw = ["\n \"", "\" excludes checking of public methods.\n \"", "\" excludes checking of protected methods."], Lint.Utils.dedent(_a, OPTION_ALLOW_PUBLIC, OPTION_ALLOW_PROTECTED)), - options: { - type: "string", - enum: [OPTION_ALLOW_PUBLIC, OPTION_ALLOW_PROTECTED], - }, - optionExamples: [ - true, - [true, OPTION_ALLOW_PUBLIC, OPTION_ALLOW_PROTECTED], - ], - type: "style", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "Class method does not use 'this'. Use a function instead."; exports.Rule = Rule; var PreferFunctionOverMethodWalker = (function (_super) { tslib_1.__extends(PreferFunctionOverMethodWalker, _super); diff --git a/node_modules/tslint/lib/rules/preferMethodSignatureRule.js b/node_modules/tslint/lib/rules/preferMethodSignatureRule.js index 1fec5e6cf..1eb800069 100644 --- a/node_modules/tslint/lib/rules/preferMethodSignatureRule.js +++ b/node_modules/tslint/lib/rules/preferMethodSignatureRule.js @@ -28,21 +28,21 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "prefer-method-signature", + description: "Prefer `foo(): void` over `foo: () => void` in interfaces and types.", + hasFix: true, + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "style", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "Use a method signature instead of a property signature of function type."; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "prefer-method-signature", - description: "Prefer `foo(): void` over `foo: () => void` in interfaces and types.", - hasFix: true, - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "style", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "Use a method signature instead of a property signature of function type."; exports.Rule = Rule; function walk(ctx) { return ts.forEachChild(ctx.sourceFile, function cb(node) { diff --git a/node_modules/tslint/lib/rules/preferObjectSpreadRule.js b/node_modules/tslint/lib/rules/preferObjectSpreadRule.js index f08a648ca..c835ed693 100644 --- a/node_modules/tslint/lib/rules/preferObjectSpreadRule.js +++ b/node_modules/tslint/lib/rules/preferObjectSpreadRule.js @@ -28,40 +28,37 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "prefer-object-spread", + description: "Enforces the use of the ES2015 object spread operator over `Object.assign()` where appropriate.", + rationale: "Object spread allows for better type checking and inference.", + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "functionality", + typescriptOnly: false, + hasFix: true, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "Use the object spread operator instead."; + Rule.ASSIGNMENT_FAILURE_STRING = "'Object.assign' returns the first argument. Prefer object spread if you want a new object."; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "prefer-object-spread", - description: "Enforces the use of the ES2015 object spread operator over `Object.assign()` where appropriate.", - rationale: "Object spread allows for better type checking and inference.", - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "functionality", - typescriptOnly: false, - hasFix: true, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "Use the object spread operator instead."; -Rule.ASSIGNMENT_FAILURE_STRING = "'Object.assign' returns the first argument. Prefer object spread if you want a new object."; exports.Rule = Rule; function walk(ctx) { return ts.forEachChild(ctx.sourceFile, function cb(node) { if (tsutils_1.isCallExpression(node) && node.arguments.length !== 0 && tsutils_1.isPropertyAccessExpression(node.expression) && node.expression.name.text === "assign" && tsutils_1.isIdentifier(node.expression.expression) && node.expression.expression.text === "Object" && + !ts.isFunctionLike(node.arguments[0]) && // Object.assign(...someArray) cannot be written as object spread !node.arguments.some(tsutils_1.isSpreadElement)) { if (node.arguments[0].kind === ts.SyntaxKind.ObjectLiteralExpression) { ctx.addFailureAtNode(node, Rule.FAILURE_STRING, createFix(node, ctx.sourceFile)); } - else { - var parent = node.parent; - if (parent.kind === ts.SyntaxKind.VariableDeclaration || - tsutils_1.isBinaryExpression(parent) && parent.operatorToken.kind === ts.SyntaxKind.EqualsToken) { - ctx.addFailureAtNode(node, Rule.ASSIGNMENT_FAILURE_STRING, createFix(node, ctx.sourceFile)); - } + else if (tsutils_1.isExpressionValueUsed(node) && !tsutils_1.hasSideEffects(node.arguments[0], 2 /* Constructor */)) { + ctx.addFailureAtNode(node, Rule.ASSIGNMENT_FAILURE_STRING, createFix(node, ctx.sourceFile)); } } return ts.forEachChild(node, cb); @@ -69,9 +66,10 @@ function walk(ctx) { } function createFix(node, sourceFile) { var args = node.arguments; + var objectNeedsParens = node.parent.kind === ts.SyntaxKind.ArrowFunction; var fix = [ - Lint.Replacement.replaceFromTo(node.getStart(sourceFile), args[0].getStart(sourceFile), "{"), - new Lint.Replacement(node.end - 1, 1, "}"), + Lint.Replacement.replaceFromTo(node.getStart(sourceFile), args[0].getStart(sourceFile), (objectNeedsParens ? "(" : "") + "{"), + new Lint.Replacement(node.end - 1, 1, "}" + (objectNeedsParens ? ")" : "")), ]; for (var i = 0; i < args.length; ++i) { var arg = args[i]; @@ -81,7 +79,7 @@ function createFix(node, sourceFile) { if (i !== args.length - 1) { end = args[i + 1].getStart(sourceFile); } - else if (args.hasTrailingComma === true) { + else if (args.hasTrailingComma) { end = args.end; } // remove empty object iteral and the following comma if exists diff --git a/node_modules/tslint/lib/rules/preferSwitchRule.js b/node_modules/tslint/lib/rules/preferSwitchRule.js index da57daad9..feac8dd80 100644 --- a/node_modules/tslint/lib/rules/preferSwitchRule.js +++ b/node_modules/tslint/lib/rules/preferSwitchRule.js @@ -34,25 +34,25 @@ var Rule = (function (_super) { } return this.applyWithFunction(sourceFile, walk, minCases); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "prefer-switch", + description: "Prefer a `switch` statement to an `if` statement with simple `===` comparisons.", + optionsDescription: (_a = ["\n An optional object with the property '", "'.\n This is the number cases needed before a switch statement is recommended.\n Defaults to 3."], _a.raw = ["\n An optional object with the property '", "'.\n This is the number cases needed before a switch statement is recommended.\n Defaults to 3."], Lint.Utils.dedent(_a, OPTION_MIN_CASES)), + options: { + type: "object", + properties: (_b = {}, + _b[OPTION_MIN_CASES] = { type: "number" }, + _b), + }, + optionExamples: [true, [true, (_c = {}, _c[OPTION_MIN_CASES] = 2, _c)]], + type: "style", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "Use a switch statement instead of using multiple '===' checks."; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "prefer-switch", - description: "Prefer a `switch` statement to an `if` statement with simple `===` comparisons.", - optionsDescription: (_a = ["\n An optional object with the property '", "'.\n This is the number cases needed before a switch statement is recommended.\n Defaults to 3."], _a.raw = ["\n An optional object with the property '", "'.\n This is the number cases needed before a switch statement is recommended.\n Defaults to 3."], Lint.Utils.dedent(_a, OPTION_MIN_CASES)), - options: { - type: "object", - properties: (_b = {}, - _b[OPTION_MIN_CASES] = { type: "number" }, - _b), - }, - optionExamples: [true, [true, (_c = {}, _c[OPTION_MIN_CASES] = 2, _c)]], - type: "style", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "Use a switch statement instead of using multiple '===' checks."; exports.Rule = Rule; function walk(ctx) { var minCases = ctx.options, sourceFile = ctx.sourceFile; diff --git a/node_modules/tslint/lib/rules/preferTemplateRule.js b/node_modules/tslint/lib/rules/preferTemplateRule.js index 1b0ae6f69..66eed83b7 100644 --- a/node_modules/tslint/lib/rules/preferTemplateRule.js +++ b/node_modules/tslint/lib/rules/preferTemplateRule.js @@ -33,24 +33,24 @@ var Rule = (function (_super) { var allowSingleConcat = this.ruleArguments.indexOf(OPTION_SINGLE_CONCAT) !== -1; return this.applyWithFunction(sourceFile, function (ctx) { return walk(ctx, allowSingleConcat); }); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "prefer-template", + description: "Prefer a template expression over string literal concatenation.", + optionsDescription: (_a = ["\n If `", "` is specified, then a single concatenation (`x + y`) is allowed, but not more (`x + y + z`)."], _a.raw = ["\n If \\`", "\\` is specified, then a single concatenation (\\`x + y\\`) is allowed, but not more (\\`x + y + z\\`)."], Lint.Utils.dedent(_a, OPTION_SINGLE_CONCAT)), + options: { + type: "string", + enum: [OPTION_SINGLE_CONCAT], + }, + optionExamples: [true, [true, OPTION_SINGLE_CONCAT]], + type: "style", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "Use a template literal instead of concatenating with a string literal."; + Rule.FAILURE_STRING_MULTILINE = "Use a multiline template literal instead of concatenating string literals with newlines."; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "prefer-template", - description: "Prefer a template expression over string literal concatenation.", - optionsDescription: (_a = ["\n If `", "` is specified, then a single concatenation (`x + y`) is allowed, but not more (`x + y + z`)."], _a.raw = ["\n If \\`", "\\` is specified, then a single concatenation (\\`x + y\\`) is allowed, but not more (\\`x + y + z\\`)."], Lint.Utils.dedent(_a, OPTION_SINGLE_CONCAT)), - options: { - type: "string", - enum: [OPTION_SINGLE_CONCAT], - }, - optionExamples: [true, [true, OPTION_SINGLE_CONCAT]], - type: "style", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "Use a template literal instead of concatenating with a string literal."; -Rule.FAILURE_STRING_MULTILINE = "Use a multiline template literal instead of concatenating string literals with newlines."; exports.Rule = Rule; function walk(ctx, allowSingleConcat) { return ts.forEachChild(ctx.sourceFile, function cb(node) { diff --git a/node_modules/tslint/lib/rules/promiseFunctionAsyncRule.js b/node_modules/tslint/lib/rules/promiseFunctionAsyncRule.js index c035b6095..62f5f0957 100644 --- a/node_modules/tslint/lib/rules/promiseFunctionAsyncRule.js +++ b/node_modules/tslint/lib/rules/promiseFunctionAsyncRule.js @@ -28,22 +28,22 @@ var Rule = (function (_super) { Rule.prototype.applyWithProgram = function (sourceFile, program) { return this.applyWithFunction(sourceFile, function (ctx) { return walk(ctx, program.getTypeChecker()); }); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "promise-function-async", + description: "Requires any function or method that returns a promise to be marked async.", + rationale: (_a = ["\n Ensures that each function is only capable of 1) returning a rejected promise, or 2)\n throwing an Error object. In contrast, non-`async` `Promise`-returning functions\n are technically capable of either. This practice removes a requirement for consuming\n code to handle both cases.\n "], _a.raw = ["\n Ensures that each function is only capable of 1) returning a rejected promise, or 2)\n throwing an Error object. In contrast, non-\\`async\\` \\`Promise\\`-returning functions\n are technically capable of either. This practice removes a requirement for consuming\n code to handle both cases.\n "], Lint.Utils.dedent(_a)), + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "typescript", + typescriptOnly: false, + requiresTypeInfo: true, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "functions that return promises must be async"; return Rule; }(Lint.Rules.TypedRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "promise-function-async", - description: "Requires any function or method that returns a promise to be marked async.", - rationale: (_a = ["\n Ensures that each function is only capable of 1) returning a rejected promise, or 2)\n throwing an Error object. In contrast, non-`async` `Promise`-returning functions\n are technically capable of either. This practice removes a requirement for consuming\n code to handle both cases.\n "], _a.raw = ["\n Ensures that each function is only capable of 1) returning a rejected promise, or 2)\n throwing an Error object. In contrast, non-\\`async\\` \\`Promise\\`-returning functions\n are technically capable of either. This practice removes a requirement for consuming\n code to handle both cases.\n "], Lint.Utils.dedent(_a)), - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "typescript", - typescriptOnly: false, - requiresTypeInfo: true, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "functions that return promises must be async"; exports.Rule = Rule; function walk(ctx, tc) { return ts.forEachChild(ctx.sourceFile, function cb(node) { diff --git a/node_modules/tslint/lib/rules/quotemarkRule.js b/node_modules/tslint/lib/rules/quotemarkRule.js index 4226e8ed1..1f1a76b4c 100644 --- a/node_modules/tslint/lib/rules/quotemarkRule.js +++ b/node_modules/tslint/lib/rules/quotemarkRule.js @@ -19,6 +19,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var tsutils_1 = require("tsutils"); var ts = require("typescript"); +var error_1 = require("../error"); var Lint = require("../index"); var OPTION_SINGLE = "single"; var OPTION_DOUBLE = "double"; @@ -42,7 +43,8 @@ var Rule = (function (_super) { var args = this.ruleArguments; if (args.length > 0) { if (args[0] !== OPTION_SINGLE && args[0] !== OPTION_DOUBLE) { - throw new Error("First argument to 'quotemark' rule should be \"" + OPTION_SINGLE + "\" or \"" + OPTION_DOUBLE + "\""); + error_1.showWarningOnce("Warning: First argument to 'quotemark' rule should be \"" + OPTION_SINGLE + "\" or \"" + OPTION_DOUBLE + "\""); + return []; } } var quoteMark = args[0] === OPTION_SINGLE ? "'" : '"'; @@ -56,30 +58,30 @@ var Rule = (function (_super) { return args.indexOf(name) !== -1; } }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "quotemark", + description: "Requires single or double quotes for string literals.", + hasFix: true, + optionsDescription: (_a = ["\n Five arguments may be optionally provided:\n\n * `\"", "\"` enforces single quotes.\n * `\"", "\"` enforces double quotes.\n * `\"", "\"` enforces single quotes for JSX attributes.\n * `\"", "\"` enforces double quotes for JSX attributes.\n * `\"", "\"` forbids single-line untagged template strings that do not contain string interpolations.\n * `\"", "\"` allows you to use the \"other\" quotemark in cases where escaping would normally be required.\n For example, `[true, \"", "\", \"", "\"]` would not report a failure on the string literal\n `'Hello \"World\"'`."], _a.raw = ["\n Five arguments may be optionally provided:\n\n * \\`\"", "\"\\` enforces single quotes.\n * \\`\"", "\"\\` enforces double quotes.\n * \\`\"", "\"\\` enforces single quotes for JSX attributes.\n * \\`\"", "\"\\` enforces double quotes for JSX attributes.\n * \\`\"", "\"\\` forbids single-line untagged template strings that do not contain string interpolations.\n * \\`\"", "\"\\` allows you to use the \"other\" quotemark in cases where escaping would normally be required.\n For example, \\`[true, \"", "\", \"", "\"]\\` would not report a failure on the string literal\n \\`'Hello \"World\"'\\`."], Lint.Utils.dedent(_a, OPTION_SINGLE, OPTION_DOUBLE, OPTION_JSX_SINGLE, OPTION_JSX_DOUBLE, OPTION_AVOID_TEMPLATE, OPTION_AVOID_ESCAPE, OPTION_DOUBLE, OPTION_AVOID_ESCAPE)), + options: { + type: "array", + items: { + type: "string", + enum: [OPTION_SINGLE, OPTION_DOUBLE, OPTION_JSX_SINGLE, OPTION_JSX_DOUBLE, OPTION_AVOID_ESCAPE], + }, + minLength: 0, + maxLength: 5, + }, + optionExamples: [ + [true, OPTION_SINGLE, OPTION_AVOID_ESCAPE, OPTION_AVOID_TEMPLATE], + [true, OPTION_SINGLE, OPTION_JSX_DOUBLE], + ], + type: "style", + typescriptOnly: false, + }; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "quotemark", - description: "Requires single or double quotes for string literals.", - hasFix: true, - optionsDescription: (_a = ["\n Five arguments may be optionally provided:\n\n * `\"", "\"` enforces single quotes.\n * `\"", "\"` enforces double quotes.\n * `\"", "\"` enforces single quotes for JSX attributes.\n * `\"", "\"` enforces double quotes for JSX attributes.\n * `\"", "\"` forbids single-line untagged template strings that do not contain string interpolations.\n * `\"", "\"` allows you to use the \"other\" quotemark in cases where escaping would normally be required.\n For example, `[true, \"", "\", \"", "\"]` would not report a failure on the string literal\n `'Hello \"World\"'`."], _a.raw = ["\n Five arguments may be optionally provided:\n\n * \\`\"", "\"\\` enforces single quotes.\n * \\`\"", "\"\\` enforces double quotes.\n * \\`\"", "\"\\` enforces single quotes for JSX attributes.\n * \\`\"", "\"\\` enforces double quotes for JSX attributes.\n * \\`\"", "\"\\` forbids single-line untagged template strings that do not contain string interpolations.\n * \\`\"", "\"\\` allows you to use the \"other\" quotemark in cases where escaping would normally be required.\n For example, \\`[true, \"", "\", \"", "\"]\\` would not report a failure on the string literal\n \\`'Hello \"World\"'\\`."], Lint.Utils.dedent(_a, OPTION_SINGLE, OPTION_DOUBLE, OPTION_JSX_SINGLE, OPTION_JSX_DOUBLE, OPTION_AVOID_TEMPLATE, OPTION_AVOID_ESCAPE, OPTION_DOUBLE, OPTION_AVOID_ESCAPE)), - options: { - type: "array", - items: { - type: "string", - enum: [OPTION_SINGLE, OPTION_DOUBLE, OPTION_JSX_SINGLE, OPTION_JSX_DOUBLE, OPTION_AVOID_ESCAPE], - }, - minLength: 0, - maxLength: 5, - }, - optionExamples: [ - [true, OPTION_SINGLE, OPTION_AVOID_ESCAPE, OPTION_AVOID_TEMPLATE], - [true, OPTION_SINGLE, OPTION_JSX_DOUBLE], - ], - type: "style", - typescriptOnly: false, -}; exports.Rule = Rule; function walk(ctx) { var sourceFile = ctx.sourceFile, options = ctx.options; diff --git a/node_modules/tslint/lib/rules/radixRule.js b/node_modules/tslint/lib/rules/radixRule.js index 13daded51..63907bec5 100644 --- a/node_modules/tslint/lib/rules/radixRule.js +++ b/node_modules/tslint/lib/rules/radixRule.js @@ -28,21 +28,21 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "radix", + description: "Requires the radix parameter to be specified when calling `parseInt`.", + rationale: (_a = ["\n From [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt):\n > Always specify this parameter to eliminate reader confusion and to guarantee predictable behavior.\n > Different implementations produce different results when a radix is not specified, usually defaulting the value to 10."], _a.raw = ["\n From [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt):\n > Always specify this parameter to eliminate reader confusion and to guarantee predictable behavior.\n > Different implementations produce different results when a radix is not specified, usually defaulting the value to 10."], Lint.Utils.dedent(_a)), + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "functionality", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "Missing radix parameter"; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "radix", - description: "Requires the radix parameter to be specified when calling `parseInt`.", - rationale: (_a = ["\n From [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt):\n > Always specify this parameter to eliminate reader confusion and to guarantee predictable behavior.\n > Different implementations produce different results when a radix is not specified, usually defaulting the value to 10."], _a.raw = ["\n From [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/parseInt):\n > Always specify this parameter to eliminate reader confusion and to guarantee predictable behavior.\n > Different implementations produce different results when a radix is not specified, usually defaulting the value to 10."], Lint.Utils.dedent(_a)), - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "functionality", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "Missing radix parameter"; exports.Rule = Rule; function walk(ctx) { return ts.forEachChild(ctx.sourceFile, function cb(node) { diff --git a/node_modules/tslint/lib/rules/restrictPlusOperandsRule.js b/node_modules/tslint/lib/rules/restrictPlusOperandsRule.js index 229d170be..930ce2892 100644 --- a/node_modules/tslint/lib/rules/restrictPlusOperandsRule.js +++ b/node_modules/tslint/lib/rules/restrictPlusOperandsRule.js @@ -28,21 +28,21 @@ var Rule = (function (_super) { Rule.prototype.applyWithProgram = function (sourceFile, program) { return this.applyWithFunction(sourceFile, function (ctx) { return walk(ctx, program); }); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "restrict-plus-operands", + description: "When adding two variables, operands must both be of type number or of type string.", + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "functionality", + typescriptOnly: false, + requiresTypeInfo: true, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.INVALID_TYPES_ERROR = "Operands of '+' operation must either be both strings or both numbers"; return Rule; }(Lint.Rules.TypedRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "restrict-plus-operands", - description: "When adding two variables, operands must both be of type number or of type string.", - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "functionality", - typescriptOnly: false, - requiresTypeInfo: true, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.INVALID_TYPES_ERROR = "Operands of '+' operation must either be both strings or both numbers"; exports.Rule = Rule; function walk(ctx, program) { return ts.forEachChild(ctx.sourceFile, function cb(node) { diff --git a/node_modules/tslint/lib/rules/returnUndefinedRule.js b/node_modules/tslint/lib/rules/returnUndefinedRule.js index 313fec4e4..8a5509cf5 100644 --- a/node_modules/tslint/lib/rules/returnUndefinedRule.js +++ b/node_modules/tslint/lib/rules/returnUndefinedRule.js @@ -28,22 +28,22 @@ var Rule = (function (_super) { Rule.prototype.applyWithProgram = function (sourceFile, program) { return this.applyWithFunction(sourceFile, function (ctx) { return walk(ctx, program.getTypeChecker()); }); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "return-undefined", + description: "Prefer `return;` in void functions and `return undefined;` in value-returning functions.", + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "style", + typescriptOnly: false, + requiresTypeInfo: true, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING_VALUE_RETURN = "Value-returning function should use `return undefined;`, not just `return;`."; + Rule.FAILURE_STRING_VOID_RETURN = "`void` function should use `return;`, not `return undefined;`."; return Rule; }(Lint.Rules.TypedRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "return-undefined", - description: "Prefer `return;` in void functions and `return undefined;` in value-returning functions.", - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "style", - typescriptOnly: false, - requiresTypeInfo: true, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING_VALUE_RETURN = "Value-returning function should use `return undefined;`, not just `return;`."; -Rule.FAILURE_STRING_VOID_RETURN = "`void` function should use `return;`, not `return undefined;`."; exports.Rule = Rule; function walk(ctx, checker) { return ts.forEachChild(ctx.sourceFile, function cb(node) { diff --git a/node_modules/tslint/lib/rules/semicolonRule.js b/node_modules/tslint/lib/rules/semicolonRule.js index 747a2acd2..13e3b53f2 100644 --- a/node_modules/tslint/lib/rules/semicolonRule.js +++ b/node_modules/tslint/lib/rules/semicolonRule.js @@ -31,136 +31,119 @@ var Rule = (function (_super) { } Rule.prototype.apply = function (sourceFile) { var options = { - always: this.ruleArguments.indexOf(OPTION_NEVER) === -1, boundClassMethods: this.ruleArguments.indexOf(OPTION_IGNORE_BOUND_CLASS_METHODS) === -1, interfaces: this.ruleArguments.indexOf(OPTION_IGNORE_INTERFACES) === -1, }; - return this.applyWithWalker(new SemicolonWalker(sourceFile, this.ruleName, options)); + var Walker = this.ruleArguments.indexOf(OPTION_NEVER) === -1 ? SemicolonAlwaysWalker : SemicolonNeverWalker; + return this.applyWithWalker(new Walker(sourceFile, this.ruleName, options)); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "semicolon", + description: "Enforces consistent semicolon usage at the end of every statement.", + hasFix: true, + optionsDescription: (_a = ["\n One of the following arguments must be provided:\n\n * `\"", "\"` enforces semicolons at the end of every statement.\n * `\"", "\"` disallows semicolons at the end of every statement except for when they are necessary.\n\n The following arguments may be optionally provided:\n\n * `\"", "\"` skips checking semicolons at the end of interface members.\n * `\"", "\"` skips checking semicolons at the end of bound class methods."], _a.raw = ["\n One of the following arguments must be provided:\n\n * \\`\"", "\"\\` enforces semicolons at the end of every statement.\n * \\`\"", "\"\\` disallows semicolons at the end of every statement except for when they are necessary.\n\n The following arguments may be optionally provided:\n\n * \\`\"", "\"\\` skips checking semicolons at the end of interface members.\n * \\`\"", "\"\\` skips checking semicolons at the end of bound class methods."], Lint.Utils.dedent(_a, OPTION_ALWAYS, OPTION_NEVER, OPTION_IGNORE_INTERFACES, OPTION_IGNORE_BOUND_CLASS_METHODS)), + options: { + type: "array", + items: [ + { + type: "string", + enum: [OPTION_ALWAYS, OPTION_NEVER], + }, + { + type: "string", + enum: [OPTION_IGNORE_INTERFACES], + }, + ], + additionalItems: false, + }, + optionExamples: [ + [true, OPTION_ALWAYS], + [true, OPTION_NEVER], + [true, OPTION_ALWAYS, OPTION_IGNORE_INTERFACES], + [true, OPTION_ALWAYS, OPTION_IGNORE_BOUND_CLASS_METHODS], + ], + type: "style", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING_MISSING = "Missing semicolon"; + Rule.FAILURE_STRING_COMMA = "Properties should be separated by semicolons"; + Rule.FAILURE_STRING_UNNECESSARY = "Unnecessary semicolon"; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "semicolon", - description: "Enforces consistent semicolon usage at the end of every statement.", - hasFix: true, - optionsDescription: (_a = ["\n One of the following arguments must be provided:\n\n * `\"", "\"` enforces semicolons at the end of every statement.\n * `\"", "\"` disallows semicolons at the end of every statement except for when they are necessary.\n\n The following arguments may be optionally provided:\n\n * `\"", "\"` skips checking semicolons at the end of interface members.\n * `\"", "\"` skips checking semicolons at the end of bound class methods."], _a.raw = ["\n One of the following arguments must be provided:\n\n * \\`\"", "\"\\` enforces semicolons at the end of every statement.\n * \\`\"", "\"\\` disallows semicolons at the end of every statement except for when they are necessary.\n\n The following arguments may be optionally provided:\n\n * \\`\"", "\"\\` skips checking semicolons at the end of interface members.\n * \\`\"", "\"\\` skips checking semicolons at the end of bound class methods."], Lint.Utils.dedent(_a, OPTION_ALWAYS, OPTION_NEVER, OPTION_IGNORE_INTERFACES, OPTION_IGNORE_BOUND_CLASS_METHODS)), - options: { - type: "array", - items: [ - { - type: "string", - enum: [OPTION_ALWAYS, OPTION_NEVER], - }, - { - type: "string", - enum: [OPTION_IGNORE_INTERFACES], - }, - ], - additionalItems: false, - }, - optionExamples: [ - [true, OPTION_ALWAYS], - [true, OPTION_NEVER], - [true, OPTION_ALWAYS, OPTION_IGNORE_INTERFACES], - [true, OPTION_ALWAYS, OPTION_IGNORE_BOUND_CLASS_METHODS], - ], - type: "style", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING_MISSING = "Missing semicolon"; -Rule.FAILURE_STRING_COMMA = "Properties should be separated by semicolons"; -Rule.FAILURE_STRING_UNNECESSARY = "Unnecessary semicolon"; exports.Rule = Rule; var SemicolonWalker = (function (_super) { tslib_1.__extends(SemicolonWalker, _super); function SemicolonWalker() { - var _this = _super !== null && _super.apply(this, arguments) || this; - _this.scanner = undefined; - return _this; + return _super !== null && _super.apply(this, arguments) || this; } SemicolonWalker.prototype.walk = function (sourceFile) { var _this = this; var cb = function (node) { - switch (node.kind) { - case ts.SyntaxKind.VariableStatement: - case ts.SyntaxKind.ExpressionStatement: - case ts.SyntaxKind.ReturnStatement: - case ts.SyntaxKind.BreakStatement: - case ts.SyntaxKind.ContinueStatement: - case ts.SyntaxKind.ThrowStatement: - case ts.SyntaxKind.ImportEqualsDeclaration: - case ts.SyntaxKind.DoStatement: - case ts.SyntaxKind.ExportAssignment: - _this.checkSemicolonAt(node); - break; - case ts.SyntaxKind.TypeAliasDeclaration: - case ts.SyntaxKind.ImportDeclaration: - case ts.SyntaxKind.ExportDeclaration: - case ts.SyntaxKind.DebuggerStatement: - _this.checkSemicolonOrLineBreak(node); - break; - case ts.SyntaxKind.ModuleDeclaration: - // shorthand module declaration - if (node.body === undefined) { - _this.checkSemicolonOrLineBreak(node); - } - break; - case ts.SyntaxKind.PropertyDeclaration: - _this.visitPropertyDeclaration(node); - break; - case ts.SyntaxKind.MethodDeclaration: - case ts.SyntaxKind.FunctionDeclaration: - if (node.body === undefined) { - _this.checkSemicolonOrLineBreak(node); - } - break; - case ts.SyntaxKind.InterfaceDeclaration: - if (_this.options.interfaces) { - _this.checkInterface(node); - } - break; - case ts.SyntaxKind.SemicolonClassElement: - return _this.reportUnnecessary(node.end - 1); - case ts.SyntaxKind.EmptyStatement: - return _this.checkEmptyStatement(node); - default: - } + _this.visitNode(node); return ts.forEachChild(node, cb); }; return ts.forEachChild(sourceFile, cb); }; - SemicolonWalker.prototype.visitPropertyDeclaration = function (node) { - // check if this is a multi-line arrow function - if (node.initializer !== undefined && - node.initializer.kind === ts.SyntaxKind.ArrowFunction && - !utils.isSameLine(this.sourceFile, node.getStart(this.sourceFile), node.end)) { - if (this.options.boundClassMethods) { - if (this.sourceFile.text[node.end - 1] === ";" && - this.isFollowedByLineBreak(node.end)) { - this.reportUnnecessary(node.end - 1); - } - } - } - else { - this.checkSemicolonOrLineBreak(node); + SemicolonWalker.prototype.visitNode = function (node) { + switch (node.kind) { + case ts.SyntaxKind.SemicolonClassElement: + return this.reportUnnecessary(node.end); + case ts.SyntaxKind.EmptyStatement: + return this.checkEmptyStatement(node); + case ts.SyntaxKind.PropertyDeclaration: + return this.visitPropertyDeclaration(node); } }; - SemicolonWalker.prototype.isFollowedByLineBreak = function (pos) { - var scanner = this.scanner !== undefined ? this.scanner : - (this.scanner = ts.createScanner(this.sourceFile.languageVersion, true, this.sourceFile.languageVariant, this.sourceFile.text)); - scanner.setTextPos(pos); - return scanner.scan() === ts.SyntaxKind.EndOfFileToken || scanner.hasPrecedingLineBreak(); + SemicolonWalker.prototype.reportUnnecessary = function (pos, noFix) { + this.addFailure(pos - 1, pos, Rule.FAILURE_STRING_UNNECESSARY, noFix ? undefined : Lint.Replacement.deleteText(pos - 1, 1)); }; SemicolonWalker.prototype.checkSemicolonOrLineBreak = function (node) { - var hasSemicolon = this.sourceFile.text[node.end - 1] === ";"; - if (this.options.always && !hasSemicolon) { - this.reportMissing(node.end); + if (this.sourceFile.text[node.end - 1] !== ";") { + return; + } + var nextToken = utils.getNextToken(node, this.sourceFile); + switch (nextToken.kind) { + case ts.SyntaxKind.EndOfFileToken: + case ts.SyntaxKind.CloseBraceToken: + return this.reportUnnecessary(node.end); + default: + if (!utils.isSameLine(this.sourceFile, node.end, nextToken.end)) { + this.reportUnnecessary(node.end); + } + } + }; + SemicolonWalker.prototype.checkUnnecessary = function (node) { + if (this.sourceFile.text[node.end - 1] !== ";") { + return; } - else if (!this.options.always && hasSemicolon && this.isFollowedByLineBreak(node.end)) { - // semicolon can be removed if followed by line break; - this.reportUnnecessary(node.end - 1); + var lastToken = utils.getPreviousToken(node.getLastToken(this.sourceFile), this.sourceFile); + // yield does not continue on the next line if there is no yielded expression + if (lastToken.kind === ts.SyntaxKind.YieldKeyword && lastToken.parent.kind === ts.SyntaxKind.YieldExpression || + // arrow functions with block as body don't continue on the next line + lastToken.kind === ts.SyntaxKind.CloseBraceToken && lastToken.parent.kind === ts.SyntaxKind.Block && + lastToken.parent.parent.kind === ts.SyntaxKind.ArrowFunction) { + return this.checkSemicolonOrLineBreak(node); + } + var nextToken = utils.getNextToken(node, this.sourceFile); + switch (nextToken.kind) { + case ts.SyntaxKind.OpenParenToken: + case ts.SyntaxKind.OpenBracketToken: + case ts.SyntaxKind.PlusToken: + case ts.SyntaxKind.MinusToken: + case ts.SyntaxKind.RegularExpressionLiteral: + case ts.SyntaxKind.LessThanToken: + case ts.SyntaxKind.NoSubstitutionTemplateLiteral: + case ts.SyntaxKind.TemplateHead: + break; + case ts.SyntaxKind.CloseBraceToken: + case ts.SyntaxKind.EndOfFileToken: + return this.reportUnnecessary(node.end); + default: + if (!utils.isSameLine(this.sourceFile, node.end, nextToken.end)) { + this.reportUnnecessary(node.end); + } } }; SemicolonWalker.prototype.checkEmptyStatement = function (node) { @@ -172,61 +155,169 @@ var SemicolonWalker = (function (_super) { var noFix = parentKind === ts.SyntaxKind.IfStatement || parentKind === ts.SyntaxKind.LabeledStatement || parentKind === ts.SyntaxKind.WithStatement; - this.reportUnnecessary(node.end - 1, noFix); + this.reportUnnecessary(node.end, noFix); } }; - SemicolonWalker.prototype.checkInterface = function (node) { - for (var _i = 0, _a = node.members; _i < _a.length; _i++) { - var member = _a[_i]; - var lastChar = this.sourceFile.text[member.end - 1]; - var hasSemicolon = lastChar === ";"; - if (this.options.always && !hasSemicolon) { - if (lastChar === ",") { - this.addFailureAt(member.end - 1, 1, Rule.FAILURE_STRING_COMMA, new Lint.Replacement(member.end - 1, 1, ";")); - } - else { - this.reportMissing(member.end); - } - } - else if (!this.options.always && hasSemicolon && - (member === node.members[node.members.length - 1] || this.isFollowedByLineBreak(member.end))) { - this.reportUnnecessary(member.end - 1); + SemicolonWalker.prototype.visitPropertyDeclaration = function (node) { + // check if this is a multi-line arrow function + if (node.initializer !== undefined && + node.initializer.kind === ts.SyntaxKind.ArrowFunction && + !utils.isSameLine(this.sourceFile, node.getStart(this.sourceFile), node.end)) { + if (this.options.boundClassMethods) { + this.checkUnnecessary(node); } } + else { + this.checkPropertyDeclaration(node); + } }; - SemicolonWalker.prototype.reportMissing = function (pos) { - this.addFailureAt(pos, 0, Rule.FAILURE_STRING_MISSING, Lint.Replacement.appendText(pos, ";")); + return SemicolonWalker; +}(Lint.AbstractWalker)); +var SemicolonAlwaysWalker = (function (_super) { + tslib_1.__extends(SemicolonAlwaysWalker, _super); + function SemicolonAlwaysWalker() { + return _super !== null && _super.apply(this, arguments) || this; + } + SemicolonAlwaysWalker.prototype.visitNode = function (node) { + switch (node.kind) { + case ts.SyntaxKind.VariableStatement: + case ts.SyntaxKind.ExpressionStatement: + case ts.SyntaxKind.ReturnStatement: + case ts.SyntaxKind.BreakStatement: + case ts.SyntaxKind.ContinueStatement: + case ts.SyntaxKind.ThrowStatement: + case ts.SyntaxKind.ImportEqualsDeclaration: + case ts.SyntaxKind.DoStatement: + case ts.SyntaxKind.ExportAssignment: + case ts.SyntaxKind.TypeAliasDeclaration: + case ts.SyntaxKind.ImportDeclaration: + case ts.SyntaxKind.ExportDeclaration: + case ts.SyntaxKind.DebuggerStatement: + return this.checkMissing(node); + case ts.SyntaxKind.ModuleDeclaration: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.FunctionDeclaration: + // check shorthand module declarations and method / function signatures + if (node.body === undefined) { + this.checkMissing(node); + } + break; + case ts.SyntaxKind.InterfaceDeclaration: + if (this.options.interfaces) { + this.checkInterface(node); + } + break; + default: + return _super.prototype.visitNode.call(this, node); + } }; - SemicolonWalker.prototype.reportUnnecessary = function (pos, noFix) { - this.addFailureAt(pos, 1, Rule.FAILURE_STRING_UNNECESSARY, noFix === true ? undefined : Lint.Replacement.deleteText(pos, 1)); + SemicolonAlwaysWalker.prototype.checkPropertyDeclaration = function (node) { + return this.checkMissing(node); }; - SemicolonWalker.prototype.checkSemicolonAt = function (node) { - var hasSemicolon = this.sourceFile.text[node.end - 1] === ";"; - if (this.options.always && !hasSemicolon) { + SemicolonAlwaysWalker.prototype.checkMissing = function (node) { + if (this.sourceFile.text[node.end - 1] !== ";") { this.reportMissing(node.end); } - else if (!this.options.always && hasSemicolon) { - switch (utils.getNextToken(node, this.sourceFile).kind) { - case ts.SyntaxKind.OpenParenToken: - case ts.SyntaxKind.OpenBracketToken: - case ts.SyntaxKind.PlusToken: - case ts.SyntaxKind.MinusToken: - case ts.SyntaxKind.RegularExpressionLiteral: + }; + SemicolonAlwaysWalker.prototype.reportMissing = function (pos) { + this.addFailureAt(pos, 0, Rule.FAILURE_STRING_MISSING, Lint.Replacement.appendText(pos, ";")); + }; + SemicolonAlwaysWalker.prototype.checkInterface = function (node) { + for (var _i = 0, _a = node.members; _i < _a.length; _i++) { + var member = _a[_i]; + switch (this.sourceFile.text[member.end - 1]) { + case ";": break; + case ",": + this.addFailureAt(member.end - 1, 1, Rule.FAILURE_STRING_COMMA, new Lint.Replacement(member.end - 1, 1, ";")); break; default: - if (!this.isFollowedByStatement(node)) { - this.reportUnnecessary(node.end - 1); - } + this.reportMissing(member.end); } } }; - SemicolonWalker.prototype.isFollowedByStatement = function (node) { + return SemicolonAlwaysWalker; +}(SemicolonWalker)); +var SemicolonNeverWalker = (function (_super) { + tslib_1.__extends(SemicolonNeverWalker, _super); + function SemicolonNeverWalker() { + return _super !== null && _super.apply(this, arguments) || this; + } + SemicolonNeverWalker.prototype.visitNode = function (node) { + switch (node.kind) { + case ts.SyntaxKind.ExpressionStatement: + case ts.SyntaxKind.ThrowStatement: + case ts.SyntaxKind.ExportAssignment: + return this.checkUnnecessary(node); + case ts.SyntaxKind.VariableStatement: + return this.checkVariableStatement(node); + case ts.SyntaxKind.ReturnStatement: + if (node.expression === undefined) { + // return does not continue on the next line if the is no returned expression + return this.checkSemicolonOrLineBreak(node); + } + return this.checkUnnecessary(node); + case ts.SyntaxKind.TypeAliasDeclaration: + case ts.SyntaxKind.ImportEqualsDeclaration: + case ts.SyntaxKind.ImportDeclaration: + case ts.SyntaxKind.ExportDeclaration: + case ts.SyntaxKind.DebuggerStatement: + case ts.SyntaxKind.BreakStatement: + case ts.SyntaxKind.ContinueStatement: + case ts.SyntaxKind.DoStatement: + return this.checkSemicolonOrLineBreak(node); + case ts.SyntaxKind.ModuleDeclaration: + // shorthand module declaration + if (node.body === undefined) { + this.checkShorthandModuleDeclaration(node); + } + break; + case ts.SyntaxKind.MethodDeclaration: + // check method signature + if (node.body === undefined) { + this.checkSemicolonOrLineBreak(node); + } + break; + case ts.SyntaxKind.FunctionDeclaration: + // check function signature + if (node.body === undefined) { + this.checkSemicolonOrLineBreak(node); + } + break; + case ts.SyntaxKind.InterfaceDeclaration: + if (this.options.interfaces) { + this.checkInterface(node); + } + break; + default: + return _super.prototype.visitNode.call(this, node); + } + }; + SemicolonNeverWalker.prototype.checkPropertyDeclaration = function (node) { + if (node.initializer === undefined) { + return this.checkSemicolonOrLineBreak(node); + } + return this.checkUnnecessary(node); + }; + SemicolonNeverWalker.prototype.checkVariableStatement = function (node) { + var declarations = node.declarationList.declarations; + if (declarations[declarations.length - 1].initializer === undefined) { + // variable declaration does not continue on the next line if it has no initializer + return this.checkSemicolonOrLineBreak(node); + } + return this.checkUnnecessary(node); + }; + SemicolonNeverWalker.prototype.checkShorthandModuleDeclaration = function (node) { var nextStatement = utils.getNextStatement(node); - if (nextStatement === undefined) { - return false; + if (nextStatement === undefined || nextStatement.kind !== ts.SyntaxKind.Block) { + this.checkSemicolonOrLineBreak(node); } - return utils.isSameLine(this.sourceFile, node.end, nextStatement.getStart(this.sourceFile)); }; - return SemicolonWalker; -}(Lint.AbstractWalker)); + SemicolonNeverWalker.prototype.checkInterface = function (node) { + for (var _i = 0, _a = node.members; _i < _a.length; _i++) { + var member = _a[_i]; + this.checkSemicolonOrLineBreak(member); + } + }; + return SemicolonNeverWalker; +}(SemicolonWalker)); var _a; diff --git a/node_modules/tslint/lib/rules/spaceBeforeFunctionParenRule.js b/node_modules/tslint/lib/rules/spaceBeforeFunctionParenRule.js index cad09c6d3..5188eee1b 100644 --- a/node_modules/tslint/lib/rules/spaceBeforeFunctionParenRule.js +++ b/node_modules/tslint/lib/rules/spaceBeforeFunctionParenRule.js @@ -31,34 +31,34 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk, parseOptions(this.ruleArguments[0])); }; + Rule.metadata = { + description: "Require or disallow a space before function parenthesis", + hasFix: true, + optionExamples: [ + true, + [true, "always"], + [true, "never"], + [true, { anonymous: "always", named: "never", asyncArrow: "always" }], + ], + options: { + properties: { + anonymous: ALWAYS_OR_NEVER, + asyncArrow: ALWAYS_OR_NEVER, + constructor: ALWAYS_OR_NEVER, + method: ALWAYS_OR_NEVER, + named: ALWAYS_OR_NEVER, + }, + type: "object", + }, + optionsDescription: (_a = ["\n One argument which is an object which may contain the keys `anonymous`, `named`, and `asyncArrow`\n These should be set to either `\"always\"` or `\"never\"`.\n\n * `\"anonymous\"` checks before the opening paren in anonymous functions\n * `\"named\"` checks before the opening paren in named functions\n * `\"asyncArrow\"` checks before the opening paren in async arrow functions\n * `\"method\"` checks before the opening paren in class methods\n * `\"constructor\"` checks before the opening paren in class constructors\n "], _a.raw = ["\n One argument which is an object which may contain the keys \\`anonymous\\`, \\`named\\`, and \\`asyncArrow\\`\n These should be set to either \\`\"always\"\\` or \\`\"never\"\\`.\n\n * \\`\"anonymous\"\\` checks before the opening paren in anonymous functions\n * \\`\"named\"\\` checks before the opening paren in named functions\n * \\`\"asyncArrow\"\\` checks before the opening paren in async arrow functions\n * \\`\"method\"\\` checks before the opening paren in class methods\n * \\`\"constructor\"\\` checks before the opening paren in class constructors\n "], Lint.Utils.dedent(_a)), + ruleName: "space-before-function-paren", + type: "style", + typescriptOnly: false, + }; + Rule.INVALID_WHITESPACE_ERROR = "Spaces before function parens are disallowed"; + Rule.MISSING_WHITESPACE_ERROR = "Missing whitespace before function parens"; return Rule; }(Lint.Rules.AbstractRule)); -Rule.metadata = { - description: "Require or disallow a space before function parenthesis", - hasFix: true, - optionExamples: [ - true, - [true, "always"], - [true, "never"], - [true, { anonymous: "always", named: "never", asyncArrow: "always" }], - ], - options: { - properties: { - anonymous: ALWAYS_OR_NEVER, - asyncArrow: ALWAYS_OR_NEVER, - constructor: ALWAYS_OR_NEVER, - method: ALWAYS_OR_NEVER, - named: ALWAYS_OR_NEVER, - }, - type: "object", - }, - optionsDescription: (_a = ["\n One argument which is an object which may contain the keys `anonymous`, `named`, and `asyncArrow`\n These should be set to either `\"always\"` or `\"never\"`.\n\n * `\"anonymous\"` checks before the opening paren in anonymous functions\n * `\"named\"` checks before the opening paren in named functions\n * `\"asyncArrow\"` checks before the opening paren in async arrow functions\n * `\"method\"` checks before the opening paren in class methods\n * `\"constructor\"` checks before the opening paren in class constructors\n "], _a.raw = ["\n One argument which is an object which may contain the keys \\`anonymous\\`, \\`named\\`, and \\`asyncArrow\\`\n These should be set to either \\`\"always\"\\` or \\`\"never\"\\`.\n\n * \\`\"anonymous\"\\` checks before the opening paren in anonymous functions\n * \\`\"named\"\\` checks before the opening paren in named functions\n * \\`\"asyncArrow\"\\` checks before the opening paren in async arrow functions\n * \\`\"method\"\\` checks before the opening paren in class methods\n * \\`\"constructor\"\\` checks before the opening paren in class constructors\n "], Lint.Utils.dedent(_a)), - ruleName: "space-before-function-paren", - type: "style", - typescriptOnly: false, -}; -Rule.INVALID_WHITESPACE_ERROR = "Spaces before function parens are disallowed"; -Rule.MISSING_WHITESPACE_ERROR = "Missing whitespace before function parens"; exports.Rule = Rule; var optionNames = ["anonymous", "asyncArrow", "constructor", "method", "named"]; function parseOptions(json) { @@ -75,19 +75,26 @@ function walk(ctx) { ts.forEachChild(sourceFile, function cb(node) { var option = getOption(node, options); if (option !== undefined) { - var openParen = Lint.childOfKind(node, ts.SyntaxKind.OpenParenToken); - var hasSpace = ts.isWhiteSpaceLike(sourceFile.text.charCodeAt(openParen.end - 2)); - if (hasSpace && option === "never") { - var pos = openParen.getStart() - 1; - ctx.addFailureAt(pos, 1, Rule.INVALID_WHITESPACE_ERROR, Lint.Replacement.deleteText(pos, 1)); - } - else if (!hasSpace && option === "always") { - var pos = openParen.getStart(); - ctx.addFailureAt(pos, 1, Rule.MISSING_WHITESPACE_ERROR, Lint.Replacement.appendText(pos, " ")); - } + check(node, option); } ts.forEachChild(node, cb); }); + function check(node, option) { + var openParen = Lint.childOfKind(node, ts.SyntaxKind.OpenParenToken); + // openParen may be missing for an async arrow function `async x => ...`. + if (openParen === undefined) { + return; + } + var hasSpace = Lint.isWhiteSpace(sourceFile.text.charCodeAt(openParen.end - 2)); + if (hasSpace && option === "never") { + var pos = openParen.getStart() - 1; + ctx.addFailureAt(pos, 1, Rule.INVALID_WHITESPACE_ERROR, Lint.Replacement.deleteText(pos, 1)); + } + else if (!hasSpace && option === "always") { + var pos = openParen.getStart(); + ctx.addFailureAt(pos, 1, Rule.MISSING_WHITESPACE_ERROR, Lint.Replacement.appendText(pos, " ")); + } + } } function getOption(node, options) { switch (node.kind) { @@ -96,7 +103,8 @@ function getOption(node, options) { case ts.SyntaxKind.Constructor: return options.constructor; case ts.SyntaxKind.FunctionDeclaration: - return options.named; + // name is optional for function declaration which is default export (TS will emit error in other cases). + // Can be handled in the same way as function expression. case ts.SyntaxKind.FunctionExpression: return node.name !== undefined ? options.named : options.anonymous; case ts.SyntaxKind.MethodDeclaration: diff --git a/node_modules/tslint/lib/rules/spaceWithinParensRule.d.ts b/node_modules/tslint/lib/rules/spaceWithinParensRule.d.ts new file mode 100644 index 000000000..4ed2047ee --- /dev/null +++ b/node_modules/tslint/lib/rules/spaceWithinParensRule.d.ts @@ -0,0 +1,9 @@ +import * as ts from "typescript"; +import * as Lint from "../index"; +export declare class Rule extends Lint.Rules.AbstractRule { + static metadata: Lint.IRuleMetadata; + static FAILURE_NO_SPACE: string; + static FAILURE_NEEDS_SPACE(count: number): string; + static FAILURE_NO_EXTRA_SPACE(count: number): string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/node_modules/tslint/lib/rules/spaceWithinParensRule.js b/node_modules/tslint/lib/rules/spaceWithinParensRule.js new file mode 100644 index 000000000..1549239a6 --- /dev/null +++ b/node_modules/tslint/lib/rules/spaceWithinParensRule.js @@ -0,0 +1,154 @@ +"use strict"; +/** + * @license + * Copyright 2017 Palantir Technologies, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +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) { + tslib_1.__extends(Rule, _super); + function Rule() { + return _super !== null && _super.apply(this, arguments) || this; + } + Rule.FAILURE_NEEDS_SPACE = function (count) { + return "Needs " + count + " whitespace" + (count > 1 ? "s" : "") + " within parentheses"; + }; + Rule.FAILURE_NO_EXTRA_SPACE = function (count) { + return "No more than " + count + " whitespace" + (count > 1 ? "s" : "") + " within parentheses allowed"; + }; + Rule.prototype.apply = function (sourceFile) { + return this.applyWithWalker(new SpaceWithinParensWalker(sourceFile, this.ruleName, parseOptions(this.ruleArguments[0]))); + }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "space-within-parens", + description: "Enforces spaces within parentheses or disallow them.", + hasFix: true, + optionsDescription: (_a = ["\n You may enforce the amount of whitespace within parentheses.\n "], _a.raw = ["\n You may enforce the amount of whitespace within parentheses.\n "], Lint.Utils.dedent(_a)), + options: { type: "number", min: 0 }, + type: "style", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_NO_SPACE = "Whitespace within parentheses is not allowed"; + return Rule; +}(Lint.Rules.AbstractRule)); +exports.Rule = Rule; +function parseOptions(whitespaceSize) { + var size = 0; + if (typeof whitespaceSize === "number") { + if (whitespaceSize >= 0) { + size = whitespaceSize; + } + } + else if (typeof whitespaceSize === "string") { + var parsedSize = parseInt(whitespaceSize, 10); + if (!Number.isNaN(parsedSize) && parsedSize >= 0) { + size = parsedSize; + } + } + return { + size: size, + }; +} +var SpaceWithinParensWalker = (function (_super) { + tslib_1.__extends(SpaceWithinParensWalker, _super); + function SpaceWithinParensWalker() { + return _super !== null && _super.apply(this, arguments) || this; + } + SpaceWithinParensWalker.prototype.walk = function (sourceFile) { + var _this = this; + tsutils_1.forEachToken(sourceFile, function (token) { + if (token.kind === ts.SyntaxKind.OpenParenToken) { + _this.checkOpenParenToken(token); + } + else if (token.kind === ts.SyntaxKind.CloseParenToken) { + _this.checkCloseParenToken(token); + } + }); + }; + SpaceWithinParensWalker.prototype.checkOpenParenToken = function (tokenNode) { + var currentPos = tokenNode.end; + var currentChar = this.sourceFile.text.charCodeAt(currentPos); + var allowedSpaceCount = this.options.size; + while (ts.isWhiteSpaceSingleLine(currentChar)) { + ++currentPos; + currentChar = this.sourceFile.text.charCodeAt(currentPos); + } + if (!ts.isLineBreak(currentChar)) { + var whitespaceCount = currentPos - tokenNode.end; + if (whitespaceCount !== allowedSpaceCount) { + var length = 0; + var pos = tokenNode.end; + if (whitespaceCount > allowedSpaceCount) { + pos += allowedSpaceCount; + length = whitespaceCount - allowedSpaceCount; + } + else if (whitespaceCount > 0 && whitespaceCount < allowedSpaceCount) { + pos += allowedSpaceCount - whitespaceCount; + } + this.addFailureAtWithFix(pos, length, whitespaceCount); + } + } + }; + SpaceWithinParensWalker.prototype.checkCloseParenToken = function (tokenNode) { + var currentPos = tokenNode.end - 2; + var currentChar = this.sourceFile.text.charCodeAt(currentPos); + var allowedSpaceCount = this.options.size; + while (ts.isWhiteSpaceSingleLine(currentChar)) { + --currentPos; + currentChar = this.sourceFile.text.charCodeAt(currentPos); + } + /** + * Number 40 is open parenthese char code, we skip this cause + * it's already been caught by `checkOpenParenToken` + */ + if (!ts.isLineBreak(currentChar) && currentChar !== 40) { + var whitespaceCount = tokenNode.end - currentPos - 2; + if (whitespaceCount !== allowedSpaceCount) { + var length = 0; + var pos = currentPos + 1; + if (whitespaceCount > allowedSpaceCount) { + length = whitespaceCount - allowedSpaceCount; + } + this.addFailureAtWithFix(pos, length, whitespaceCount); + } + } + }; + SpaceWithinParensWalker.prototype.addFailureAtWithFix = function (position, length, whitespaceCount) { + var lintMsg; + var lintFix; + var allowedSpaceCount = this.options.size; + if (allowedSpaceCount === 0) { + lintMsg = Rule.FAILURE_NO_SPACE; + lintFix = Lint.Replacement.deleteText(position, length); + } + else if (allowedSpaceCount > whitespaceCount) { + lintMsg = Rule.FAILURE_NEEDS_SPACE(allowedSpaceCount - whitespaceCount); + var whitespace = " ".repeat(allowedSpaceCount - whitespaceCount); + lintFix = Lint.Replacement.appendText(position, whitespace); + } + else { + lintMsg = Rule.FAILURE_NO_EXTRA_SPACE(allowedSpaceCount); + lintFix = Lint.Replacement.deleteText(position, whitespaceCount - allowedSpaceCount); + } + this.addFailureAt(position, length, lintMsg, lintFix); + }; + return SpaceWithinParensWalker; +}(Lint.AbstractWalker)); +var _a; diff --git a/node_modules/tslint/lib/rules/strictBooleanExpressionsRule.js b/node_modules/tslint/lib/rules/strictBooleanExpressionsRule.js index a202e2c49..0d1851179 100644 --- a/node_modules/tslint/lib/rules/strictBooleanExpressionsRule.js +++ b/node_modules/tslint/lib/rules/strictBooleanExpressionsRule.js @@ -24,6 +24,7 @@ var OPTION_ALLOW_UNDEFINED_UNION = "allow-undefined-union"; var OPTION_ALLOW_STRING = "allow-string"; var OPTION_ALLOW_NUMBER = "allow-number"; var OPTION_ALLOW_MIX = "allow-mix"; +var OPTION_ALLOW_BOOLEAN_OR_UNDEFINED = "allow-boolean-or-undefined"; // tslint:disable object-literal-sort-keys switch-default var Rule = (function (_super) { tslib_1.__extends(Rule, _super); @@ -31,32 +32,39 @@ var Rule = (function (_super) { return _super !== null && _super.apply(this, arguments) || this; } Rule.prototype.applyWithProgram = function (sourceFile, program) { - var options = parseOptions(this.ruleArguments, program.getCompilerOptions().strictNullChecks === true); + var options = parseOptions(this.ruleArguments, Lint.isStrictNullChecksEnabled(program.getCompilerOptions())); return this.applyWithFunction(sourceFile, function (ctx) { return walk(ctx, program.getTypeChecker()); }, options); }; + Rule.metadata = { + ruleName: "strict-boolean-expressions", + description: (_a = ["\n Restricts the types allowed in boolean expressions. By default only booleans are allowed.\n\n The following nodes are checked:\n\n * Arguments to the `!`, `&&`, and `||` operators\n * The condition in a conditional expression (`cond ? x : y`)\n * Conditions for `if`, `for`, `while`, and `do-while` statements."], _a.raw = ["\n Restricts the types allowed in boolean expressions. By default only booleans are allowed.\n\n The following nodes are checked:\n\n * Arguments to the \\`!\\`, \\`&&\\`, and \\`||\\` operators\n * The condition in a conditional expression (\\`cond ? x : y\\`)\n * Conditions for \\`if\\`, \\`for\\`, \\`while\\`, and \\`do-while\\` statements."], Lint.Utils.dedent(_a)), + optionsDescription: (_b = ["\n These options may be provided:\n\n * `", "` allows union types containing `null`.\n - It does *not* allow `null` itself.\n - Without the '--strictNullChecks' compiler option, this will allow anything other than a string, number, or enum.\n * `", "` allows union types containing `undefined`.\n - It does *not* allow `undefined` itself.\n - Without the '--strictNullChecks' compiler option, this will allow anything other than a string, number, or enum.\n * `", "` allows strings.\n - It does *not* allow unions containing `string`.\n - It does *not* allow string literal types.\n * `", "` allows numbers.\n - It does *not* allow unions containing `number`.\n - It does *not* allow enums or number literal types.\n * `", "` allows multiple of the above to appear together.\n - For example, `string | number` or `RegExp | null | undefined` would normally not be allowed.\n - A type like `\"foo\" | \"bar\" | undefined` is always allowed, because it has only one way to be false.\n * `", "` allows `boolean | undefined`.\n - Also allows `true | false | undefined`.\n - Does not allow `false | undefined`.\n - This option is a subset of `", "`, so you don't need to enable both options at the same time.\n "], _b.raw = ["\n These options may be provided:\n\n * \\`", "\\` allows union types containing \\`null\\`.\n - It does *not* allow \\`null\\` itself.\n - Without the '--strictNullChecks' compiler option, this will allow anything other than a string, number, or enum.\n * \\`", "\\` allows union types containing \\`undefined\\`.\n - It does *not* allow \\`undefined\\` itself.\n - Without the '--strictNullChecks' compiler option, this will allow anything other than a string, number, or enum.\n * \\`", "\\` allows strings.\n - It does *not* allow unions containing \\`string\\`.\n - It does *not* allow string literal types.\n * \\`", "\\` allows numbers.\n - It does *not* allow unions containing \\`number\\`.\n - It does *not* allow enums or number literal types.\n * \\`", "\\` allows multiple of the above to appear together.\n - For example, \\`string | number\\` or \\`RegExp | null | undefined\\` would normally not be allowed.\n - A type like \\`\"foo\" | \"bar\" | undefined\\` is always allowed, because it has only one way to be false.\n * \\`", "\\` allows \\`boolean | undefined\\`.\n - Also allows \\`true | false | undefined\\`.\n - Does not allow \\`false | undefined\\`.\n - This option is a subset of \\`", "\\`, so you don't need to enable both options at the same time.\n "], Lint.Utils.dedent(_b, OPTION_ALLOW_NULL_UNION, OPTION_ALLOW_UNDEFINED_UNION, OPTION_ALLOW_STRING, OPTION_ALLOW_NUMBER, OPTION_ALLOW_MIX, OPTION_ALLOW_BOOLEAN_OR_UNDEFINED, OPTION_ALLOW_UNDEFINED_UNION)), + options: { + type: "array", + items: { + type: "string", + enum: [ + OPTION_ALLOW_NULL_UNION, + OPTION_ALLOW_UNDEFINED_UNION, + OPTION_ALLOW_STRING, + OPTION_ALLOW_NUMBER, + OPTION_ALLOW_BOOLEAN_OR_UNDEFINED, + ], + }, + minLength: 0, + maxLength: 5, + }, + optionExamples: [ + true, + [true, OPTION_ALLOW_NULL_UNION, OPTION_ALLOW_UNDEFINED_UNION, OPTION_ALLOW_STRING, OPTION_ALLOW_NUMBER], + [true, OPTION_ALLOW_BOOLEAN_OR_UNDEFINED], + ], + type: "functionality", + typescriptOnly: true, + requiresTypeInfo: true, + }; return Rule; }(Lint.Rules.TypedRule)); -Rule.metadata = { - ruleName: "strict-boolean-expressions", - description: (_a = ["\n Restricts the types allowed in boolean expressions. By default only booleans are allowed.\n\n The following nodes are checked:\n\n * Arguments to the `!`, `&&`, and `||` operators\n * The condition in a conditional expression (`cond ? x : y`)\n * Conditions for `if`, `for`, `while`, and `do-while` statements."], _a.raw = ["\n Restricts the types allowed in boolean expressions. By default only booleans are allowed.\n\n The following nodes are checked:\n\n * Arguments to the \\`!\\`, \\`&&\\`, and \\`||\\` operators\n * The condition in a conditional expression (\\`cond ? x : y\\`)\n * Conditions for \\`if\\`, \\`for\\`, \\`while\\`, and \\`do-while\\` statements."], Lint.Utils.dedent(_a)), - optionsDescription: (_b = ["\n These options may be provided:\n\n * `", "` allows union types containing `null`.\n - It does *not* allow `null` itself.\n - Without the '--strictNullChecks' compiler option, this will allow anything other than a string, number, or enum.\n * `", "` allows union types containing `undefined`.\n - It does *not* allow `undefined` itself.\n - Without the '--strictNullChecks' compiler option, this will allow anything other than a string, number, or enum.\n * `", "` allows strings.\n - It does *not* allow unions containing `string`.\n - It does *not* allow string literal types.\n * `", "` allows numbers.\n - It does *not* allow unions containing `number`.\n - It does *not* allow enums or number literal types.\n * `", "` allow multiple of the above to appear together.\n - For example, `string | number` or `RegExp | null | undefined` would normally not be allowed.\n - A type like `\"foo\" | \"bar\" | undefined` is always allowed, because it has only one way to be false."], _b.raw = ["\n These options may be provided:\n\n * \\`", "\\` allows union types containing \\`null\\`.\n - It does *not* allow \\`null\\` itself.\n - Without the '--strictNullChecks' compiler option, this will allow anything other than a string, number, or enum.\n * \\`", "\\` allows union types containing \\`undefined\\`.\n - It does *not* allow \\`undefined\\` itself.\n - Without the '--strictNullChecks' compiler option, this will allow anything other than a string, number, or enum.\n * \\`", "\\` allows strings.\n - It does *not* allow unions containing \\`string\\`.\n - It does *not* allow string literal types.\n * \\`", "\\` allows numbers.\n - It does *not* allow unions containing \\`number\\`.\n - It does *not* allow enums or number literal types.\n * \\`", "\\` allow multiple of the above to appear together.\n - For example, \\`string | number\\` or \\`RegExp | null | undefined\\` would normally not be allowed.\n - A type like \\`\"foo\" | \"bar\" | undefined\\` is always allowed, because it has only one way to be false."], Lint.Utils.dedent(_b, OPTION_ALLOW_NULL_UNION, OPTION_ALLOW_UNDEFINED_UNION, OPTION_ALLOW_STRING, OPTION_ALLOW_NUMBER, OPTION_ALLOW_MIX)), - options: { - type: "array", - items: { - type: "string", - enum: [OPTION_ALLOW_NULL_UNION, OPTION_ALLOW_UNDEFINED_UNION, OPTION_ALLOW_STRING, OPTION_ALLOW_NUMBER], - }, - minLength: 0, - maxLength: 5, - }, - optionExamples: [ - true, - [true, OPTION_ALLOW_NULL_UNION, OPTION_ALLOW_UNDEFINED_UNION, OPTION_ALLOW_STRING, OPTION_ALLOW_NUMBER], - ], - type: "functionality", - typescriptOnly: true, - requiresTypeInfo: true, -}; exports.Rule = Rule; function parseOptions(ruleArguments, strictNullChecks) { return { @@ -66,6 +74,7 @@ function parseOptions(ruleArguments, strictNullChecks) { allowString: has(OPTION_ALLOW_STRING), allowNumber: has(OPTION_ALLOW_NUMBER), allowMix: has(OPTION_ALLOW_MIX), + allowBooleanOrUndefined: has(OPTION_ALLOW_BOOLEAN_OR_UNDEFINED), }; function has(name) { return ruleArguments.indexOf(name) !== -1; @@ -115,7 +124,6 @@ function walk(ctx, checker) { if (condition !== undefined) { checkExpression(condition, node); } - break; } } return ts.forEachChild(node, cb); @@ -145,14 +153,41 @@ function getTypeFailure(type, options) { } switch (triState(kind)) { case true: - return 0 /* AlwaysTruthy */; + // Allow 'any'. Allow 'true' itself, but not any other always-truthy type. + // tslint:disable-next-line no-bitwise + return Lint.isTypeFlagSet(type, ts.TypeFlags.Any | ts.TypeFlags.BooleanLiteral) ? undefined : 0 /* AlwaysTruthy */; case false: - return 1 /* AlwaysFalsy */; + // Allow 'false' itself, but not any other always-falsy type + return Lint.isTypeFlagSet(type, ts.TypeFlags.BooleanLiteral) ? undefined : 1 /* AlwaysFalsy */; case undefined: return undefined; } } +function isBooleanUndefined(type) { + var isTruthy = false; + for (var _i = 0, _a = type.types; _i < _a.length; _i++) { + var ty = _a[_i]; + if (Lint.isTypeFlagSet(ty, ts.TypeFlags.Boolean)) { + isTruthy = true; + } + else if (Lint.isTypeFlagSet(ty, ts.TypeFlags.BooleanLiteral)) { + isTruthy = isTruthy || ty.intrinsicName === "true"; + } + else if (!Lint.isTypeFlagSet(ty, ts.TypeFlags.Void | ts.TypeFlags.Undefined)) { + return undefined; + } + } + return isTruthy; +} function handleUnion(type, options) { + if (options.allowBooleanOrUndefined) { + switch (isBooleanUndefined(type)) { + case true: + return undefined; + case false: + return 1 /* AlwaysFalsy */; + } + } // Tracks whether it's possibly truthy. var anyTruthy = false; // Counts falsy kinds to see if there's a mix. Also tracks whether it's possibly falsy. @@ -236,10 +271,11 @@ function getKind(type) { } } function numberLiteralIsZero(type) { - // Uses 'value' in TypeScript>=2.4. + // for compatibility with typescript@<2.4.0 return type.value !== undefined ? type.value === 0 : type.text === "0"; } function stringLiteralIsEmpty(type) { + // for compatibility with typescript@<2.4.0 return (type.value !== undefined ? type.value : type.text) === ""; } /** Matches `&&` and `||` operators. */ @@ -291,12 +327,12 @@ function showLocation(n) { return "operand for the '" + binaryBooleanExpressionKind(n) + "' operator"; } } -function showFailure(location, ty, isUnionType, options) { +function showFailure(location, ty, unionType, options) { var expectedTypes = showExpectedTypes(options); var expected = expectedTypes.length === 1 ? "Only " + expectedTypes[0] + "s are allowed" : "Allowed types are " + stringOr(expectedTypes); - var tyFail = showTypeFailure(ty, isUnionType, options.strictNullChecks); + var tyFail = showTypeFailure(ty, unionType, options.strictNullChecks); return "This type is not allowed in the " + showLocation(location) + " because it " + tyFail + ". " + expected + "."; } function showExpectedTypes(options) { @@ -313,10 +349,13 @@ function showExpectedTypes(options) { if (options.allowNumber) { parts.push("number"); } + if (options.allowBooleanOrUndefined) { + parts.push("boolean-or-undefined"); + } return parts; } -function showTypeFailure(ty, isUnionType, strictNullChecks) { - var is = isUnionType ? "could be" : "is"; +function showTypeFailure(ty, unionType, strictNullChecks) { + var is = unionType ? "could be" : "is"; switch (ty) { case 0 /* AlwaysTruthy */: return strictNullChecks diff --git a/node_modules/tslint/lib/rules/strictTypePredicatesRule.js b/node_modules/tslint/lib/rules/strictTypePredicatesRule.js index 20dd3f9d0..26307b972 100644 --- a/node_modules/tslint/lib/rules/strictTypePredicatesRule.js +++ b/node_modules/tslint/lib/rules/strictTypePredicatesRule.js @@ -19,6 +19,7 @@ Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var tsutils_1 = require("tsutils"); var ts = require("typescript"); +var error_1 = require("../error"); var Lint = require("../index"); // tslint:disable:no-bitwise var Rule = (function (_super) { @@ -33,23 +34,27 @@ var Rule = (function (_super) { return "Use '" + (isPositive ? "===" : "!==") + " " + value + "' instead."; }; Rule.prototype.applyWithProgram = function (sourceFile, program) { + if (!Lint.isStrictNullChecksEnabled(program.getCompilerOptions())) { + error_1.showWarningOnce("strict-type-predicates does not work without --strictNullChecks"); + return []; + } return this.applyWithFunction(sourceFile, function (ctx) { return walk(ctx, program.getTypeChecker()); }); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "strict-type-predicates", + description: (_a = ["\n Warns for type predicates that are always true or always false.\n Works for 'typeof' comparisons to constants (e.g. 'typeof foo === \"string\"'), and equality comparison to 'null'/'undefined'.\n (TypeScript won't let you compare '1 === 2', but it has an exception for '1 === undefined'.)\n Does not yet work for 'instanceof'.\n Does *not* warn for 'if (x.y)' where 'x.y' is always truthy. For that, see strict-boolean-expressions.\n\n This rule requires `strictNullChecks` to work properly."], _a.raw = ["\n Warns for type predicates that are always true or always false.\n Works for 'typeof' comparisons to constants (e.g. 'typeof foo === \"string\"'), and equality comparison to 'null'/'undefined'.\n (TypeScript won't let you compare '1 === 2', but it has an exception for '1 === undefined'.)\n Does not yet work for 'instanceof'.\n Does *not* warn for 'if (x.y)' where 'x.y' is always truthy. For that, see strict-boolean-expressions.\n\n This rule requires \\`strictNullChecks\\` to work properly."], Lint.Utils.dedent(_a)), + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "functionality", + typescriptOnly: true, + requiresTypeInfo: true, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING_BAD_TYPEOF = "Bad comparison for 'typeof'."; return Rule; }(Lint.Rules.TypedRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "strict-type-predicates", - description: (_a = ["\n Warns for type predicates that are always true or always false.\n Works for 'typeof' comparisons to constants (e.g. 'typeof foo === \"string\"'), and equality comparison to 'null'/'undefined'.\n (TypeScript won't let you compare '1 === 2', but it has an exception for '1 === undefined'.)\n Does not yet work for 'instanceof'.\n Does *not* warn for 'if (x.y)' where 'x.y' is always truthy. For that, see strict-boolean-expressions."], _a.raw = ["\n Warns for type predicates that are always true or always false.\n Works for 'typeof' comparisons to constants (e.g. 'typeof foo === \"string\"'), and equality comparison to 'null'/'undefined'.\n (TypeScript won't let you compare '1 === 2', but it has an exception for '1 === undefined'.)\n Does not yet work for 'instanceof'.\n Does *not* warn for 'if (x.y)' where 'x.y' is always truthy. For that, see strict-boolean-expressions."], Lint.Utils.dedent(_a)), - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "functionality", - typescriptOnly: true, - requiresTypeInfo: true, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING_BAD_TYPEOF = "Bad comparison for 'typeof'."; exports.Rule = Rule; function walk(ctx, checker) { return ts.forEachChild(ctx.sourceFile, function cb(node) { @@ -93,7 +98,6 @@ function walk(ctx, checker) { ? Rule.FAILURE_STRING(result === isPositive) : Rule.FAILURE_STRICT_PREFER_STRICT_EQUALS(result, isPositive)); } - break; } } function fail(failure) { diff --git a/node_modules/tslint/lib/rules/switchDefaultRule.js b/node_modules/tslint/lib/rules/switchDefaultRule.js index ac24a8370..5173ae400 100644 --- a/node_modules/tslint/lib/rules/switchDefaultRule.js +++ b/node_modules/tslint/lib/rules/switchDefaultRule.js @@ -28,20 +28,20 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "switch-default", + description: "Require a `default` case in all `switch` statements.", + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "functionality", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "Switch statement should include a 'default' case"; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "switch-default", - description: "Require a `default` case in all `switch` statements.", - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "functionality", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "Switch statement should include a 'default' case"; exports.Rule = Rule; function walk(ctx) { return ts.forEachChild(ctx.sourceFile, function cb(node) { diff --git a/node_modules/tslint/lib/rules/switchFinalBreakRule.d.ts b/node_modules/tslint/lib/rules/switchFinalBreakRule.d.ts new file mode 100644 index 000000000..927ecfb9d --- /dev/null +++ b/node_modules/tslint/lib/rules/switchFinalBreakRule.d.ts @@ -0,0 +1,8 @@ +import * as ts from "typescript"; +import * as Lint from "../index"; +export declare class Rule extends Lint.Rules.AbstractRule { + static metadata: Lint.IRuleMetadata; + static FAILURE_STRING_ALWAYS: string; + static FAILURE_STRING_NEVER: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/node_modules/tslint/lib/rules/switchFinalBreakRule.js b/node_modules/tslint/lib/rules/switchFinalBreakRule.js new file mode 100644 index 000000000..ed5bcc4a7 --- /dev/null +++ b/node_modules/tslint/lib/rules/switchFinalBreakRule.js @@ -0,0 +1,93 @@ +"use strict"; +/** + * @license + * Copyright 2017 Palantir Technologies, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +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 OPTION_ALWAYS = "always"; +var Rule = (function (_super) { + tslib_1.__extends(Rule, _super); + function Rule() { + return _super !== null && _super.apply(this, arguments) || this; + } + Rule.prototype.apply = function (sourceFile) { + return this.applyWithFunction(sourceFile, walk, { always: this.ruleArguments.indexOf(OPTION_ALWAYS) !== -1 }); + }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "switch-final-break", + description: "Checks whether the final clause of a switch statement ends in \`break;\`.", + optionsDescription: (_a = ["\n If no options are passed, a final 'break;' is forbidden.\n If the \"always\" option is passed this will require a 'break;' to always be present\n unless control flow is escaped in some other way."], _a.raw = ["\n If no options are passed, a final 'break;' is forbidden.\n If the \"always\" option is passed this will require a 'break;' to always be present\n unless control flow is escaped in some other way."], Lint.Utils.dedent(_a)), + options: { + type: "string", + enum: [ + OPTION_ALWAYS, + ], + }, + optionExamples: [true, [true, OPTION_ALWAYS]], + type: "style", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING_ALWAYS = "Final clause in 'switch' statement should end with 'break;'."; + Rule.FAILURE_STRING_NEVER = "Final clause in 'switch' statement should not end with 'break;'."; + return Rule; +}(Lint.Rules.AbstractRule)); +exports.Rule = Rule; +function walk(ctx) { + var sourceFile = ctx.sourceFile, always = ctx.options.always; + ts.forEachChild(sourceFile, function cb(node) { + if (tsutils_1.isSwitchStatement(node)) { + check(node); + } + ts.forEachChild(node, cb); + }); + function check(node) { + var clause = last(node.caseBlock.clauses); + if (clause === undefined) { + return; + } + if (always) { + if (!tsutils_1.endsControlFlow(clause)) { + ctx.addFailureAtNode(clause.getChildAt(0), Rule.FAILURE_STRING_ALWAYS); + } + return; + } + if (clause.statements.length === 0) { + return; + } + var block = clause.statements[0]; + var statements = clause.statements.length === 1 && tsutils_1.isBlock(block) ? block.statements : clause.statements; + var lastStatement = last(statements); + if (lastStatement !== undefined && tsutils_1.isBreakStatement(lastStatement)) { + if (lastStatement.label !== undefined) { + var parent = node.parent; + if (!tsutils_1.isLabeledStatement(parent) || parent.label === lastStatement.label) { + // break jumps somewhere else, don't complain + return; + } + } + ctx.addFailureAtNode(lastStatement, Rule.FAILURE_STRING_NEVER); + } + } +} +function last(arr) { + return arr[arr.length - 1]; +} +var _a; diff --git a/node_modules/tslint/lib/rules/trailingCommaRule.js b/node_modules/tslint/lib/rules/trailingCommaRule.js index a91e57fe8..09003f90c 100644 --- a/node_modules/tslint/lib/rules/trailingCommaRule.js +++ b/node_modules/tslint/lib/rules/trailingCommaRule.js @@ -20,7 +20,7 @@ var tslib_1 = require("tslib"); var tsutils_1 = require("tsutils"); var ts = require("typescript"); var Lint = require("../index"); -var defaultOptions = fillOptions("ignore"); +var defaultOptions = fillOptions("ignore"); // tslint:disable-line no-unnecessary-type-assertion function fillOptions(value) { return { arrays: value, @@ -66,42 +66,42 @@ var Rule = (function (_super) { Rule.prototype.isEnabled = function () { return _super.prototype.isEnabled.call(this) && this.ruleArguments.length !== 0; }; - return Rule; -}(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "trailing-comma", - description: (_a = ["\n Requires or disallows trailing commas in array and object literals, destructuring assignments, function typings,\n named imports and exports and function parameters."], _a.raw = ["\n Requires or disallows trailing commas in array and object literals, destructuring assignments, function typings,\n named imports and exports and function parameters."], Lint.Utils.dedent(_a)), - hasFix: true, - optionsDescription: (_b = ["\n One argument which is an object with the keys `multiline` and `singleline`.\n Both can be set to a string (`\"always\"` or `\"never\"`) or an object.\n\n The object can contain any of the following keys: `\"arrays\"`, `\"objects\"`, `\"functions\"`,\n `\"imports\"`, `\"exports\"`, and `\"typeLiterals\"`; each key can have one of the following\n values: `\"always\"`, `\"never\"`, and `\"ignore\"`. Any missing keys will default to `\"ignore\"`.\n\n * `\"multiline\"` checks multi-line object literals.\n * `\"singleline\"` checks single-line object literals.\n\n An array is considered \"multiline\" if its closing bracket is on a line\n after the last array element. The same general logic is followed for\n object literals, function typings, named import statements\n and function parameters."], _b.raw = ["\n One argument which is an object with the keys \\`multiline\\` and \\`singleline\\`.\n Both can be set to a string (\\`\"always\"\\` or \\`\"never\"\\`) or an object.\n\n The object can contain any of the following keys: \\`\"arrays\"\\`, \\`\"objects\"\\`, \\`\"functions\"\\`,\n \\`\"imports\"\\`, \\`\"exports\"\\`, and \\`\"typeLiterals\"\\`; each key can have one of the following\n values: \\`\"always\"\\`, \\`\"never\"\\`, and \\`\"ignore\"\\`. Any missing keys will default to \\`\"ignore\"\\`.\n\n * \\`\"multiline\"\\` checks multi-line object literals.\n * \\`\"singleline\"\\` checks single-line object literals.\n\n An array is considered \"multiline\" if its closing bracket is on a line\n after the last array element. The same general logic is followed for\n object literals, function typings, named import statements\n and function parameters."], Lint.Utils.dedent(_b)), - options: { - type: "object", - properties: { - multiline: metadataOptionShape, - singleline: metadataOptionShape, + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "trailing-comma", + description: (_a = ["\n Requires or disallows trailing commas in array and object literals, destructuring assignments, function typings,\n named imports and exports and function parameters."], _a.raw = ["\n Requires or disallows trailing commas in array and object literals, destructuring assignments, function typings,\n named imports and exports and function parameters."], Lint.Utils.dedent(_a)), + hasFix: true, + optionsDescription: (_b = ["\n One argument which is an object with the keys `multiline` and `singleline`.\n Both can be set to a string (`\"always\"` or `\"never\"`) or an object.\n\n The object can contain any of the following keys: `\"arrays\"`, `\"objects\"`, `\"functions\"`,\n `\"imports\"`, `\"exports\"`, and `\"typeLiterals\"`; each key can have one of the following\n values: `\"always\"`, `\"never\"`, and `\"ignore\"`. Any missing keys will default to `\"ignore\"`.\n\n * `\"multiline\"` checks multi-line object literals.\n * `\"singleline\"` checks single-line object literals.\n\n An array is considered \"multiline\" if its closing bracket is on a line\n after the last array element. The same general logic is followed for\n object literals, function typings, named import statements\n and function parameters."], _b.raw = ["\n One argument which is an object with the keys \\`multiline\\` and \\`singleline\\`.\n Both can be set to a string (\\`\"always\"\\` or \\`\"never\"\\`) or an object.\n\n The object can contain any of the following keys: \\`\"arrays\"\\`, \\`\"objects\"\\`, \\`\"functions\"\\`,\n \\`\"imports\"\\`, \\`\"exports\"\\`, and \\`\"typeLiterals\"\\`; each key can have one of the following\n values: \\`\"always\"\\`, \\`\"never\"\\`, and \\`\"ignore\"\\`. Any missing keys will default to \\`\"ignore\"\\`.\n\n * \\`\"multiline\"\\` checks multi-line object literals.\n * \\`\"singleline\"\\` checks single-line object literals.\n\n An array is considered \"multiline\" if its closing bracket is on a line\n after the last array element. The same general logic is followed for\n object literals, function typings, named import statements\n and function parameters."], Lint.Utils.dedent(_b)), + options: { + type: "object", + properties: { + multiline: metadataOptionShape, + singleline: metadataOptionShape, + }, + additionalProperties: false, }, - additionalProperties: false, - }, - optionExamples: [ - [true, { multiline: "always", singleline: "never" }], - [ - true, - { - multiline: { - objects: "always", - arrays: "always", - functions: "never", - typeLiterals: "ignore", + optionExamples: [ + [true, { multiline: "always", singleline: "never" }], + [ + true, + { + multiline: { + objects: "always", + arrays: "always", + functions: "never", + typeLiterals: "ignore", + }, }, - }, + ], ], - ], - type: "maintainability", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING_NEVER = "Unnecessary trailing comma"; -Rule.FAILURE_STRING_ALWAYS = "Missing trailing comma"; + type: "maintainability", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING_NEVER = "Unnecessary trailing comma"; + Rule.FAILURE_STRING_ALWAYS = "Missing trailing comma"; + return Rule; +}(Lint.Rules.AbstractRule)); exports.Rule = Rule; var TrailingCommaWalker = (function (_super) { tslib_1.__extends(TrailingCommaWalker, _super); @@ -184,14 +184,14 @@ var TrailingCommaWalker = (function (_super) { } var token = tsutils_1.getChildOfKind(node, closeTokenKind, this.sourceFile); if (token !== undefined) { - return this.checkComma(list.hasTrailingComma === true, list, token.end, optionKey); + return this.checkComma(list.hasTrailingComma, list, token.end, optionKey); } }; TrailingCommaWalker.prototype.checkList = function (list, closeElementPos, optionKey) { if (list.length === 0) { return; } - return this.checkComma(list.hasTrailingComma === true, list, closeElementPos, optionKey); + return this.checkComma(list.hasTrailingComma, list, closeElementPos, optionKey); }; /* Expects `list.length !== 0` */ TrailingCommaWalker.prototype.checkComma = function (hasTrailingComma, list, closeTokenPos, optionKey) { diff --git a/node_modules/tslint/lib/rules/tripleEqualsRule.js b/node_modules/tslint/lib/rules/tripleEqualsRule.js index c20d45f18..c93c522e2 100644 --- a/node_modules/tslint/lib/rules/tripleEqualsRule.js +++ b/node_modules/tslint/lib/rules/tripleEqualsRule.js @@ -33,33 +33,33 @@ var Rule = (function (_super) { allowUndefined: this.ruleArguments.indexOf(OPTION_ALLOW_UNDEFINED_CHECK) !== -1, }); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "triple-equals", + description: "Requires `===` and `!==` in place of `==` and `!=`.", + optionsDescription: (_a = ["\n Two arguments may be optionally provided:\n\n * `\"allow-null-check\"` allows `==` and `!=` when comparing to `null`.\n * `\"allow-undefined-check\"` allows `==` and `!=` when comparing to `undefined`."], _a.raw = ["\n Two arguments may be optionally provided:\n\n * \\`\"allow-null-check\"\\` allows \\`==\\` and \\`!=\\` when comparing to \\`null\\`.\n * \\`\"allow-undefined-check\"\\` allows \\`==\\` and \\`!=\\` when comparing to \\`undefined\\`."], Lint.Utils.dedent(_a)), + options: { + type: "array", + items: { + type: "string", + enum: [OPTION_ALLOW_NULL_CHECK, OPTION_ALLOW_UNDEFINED_CHECK], + }, + minLength: 0, + maxLength: 2, + }, + optionExamples: [ + true, + [true, "allow-null-check"], + [true, "allow-undefined-check"], + ], + type: "functionality", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.EQ_FAILURE_STRING = "== should be ==="; + Rule.NEQ_FAILURE_STRING = "!= should be !=="; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "triple-equals", - description: "Requires `===` and `!==` in place of `==` and `!=`.", - optionsDescription: (_a = ["\n Two arguments may be optionally provided:\n\n * `\"allow-null-check\"` allows `==` and `!=` when comparing to `null`.\n * `\"allow-undefined-check\"` allows `==` and `!=` when comparing to `undefined`."], _a.raw = ["\n Two arguments may be optionally provided:\n\n * \\`\"allow-null-check\"\\` allows \\`==\\` and \\`!=\\` when comparing to \\`null\\`.\n * \\`\"allow-undefined-check\"\\` allows \\`==\\` and \\`!=\\` when comparing to \\`undefined\\`."], Lint.Utils.dedent(_a)), - options: { - type: "array", - items: { - type: "string", - enum: [OPTION_ALLOW_NULL_CHECK, OPTION_ALLOW_UNDEFINED_CHECK], - }, - minLength: 0, - maxLength: 2, - }, - optionExamples: [ - true, - [true, "allow-null-check"], - [true, "allow-undefined-check"], - ], - type: "functionality", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.EQ_FAILURE_STRING = "== should be ==="; -Rule.NEQ_FAILURE_STRING = "!= should be !=="; exports.Rule = Rule; function walk(ctx) { return ts.forEachChild(ctx.sourceFile, function cb(node) { diff --git a/node_modules/tslint/lib/rules/typeLiteralDelimiterRule.d.ts b/node_modules/tslint/lib/rules/typeLiteralDelimiterRule.d.ts new file mode 100644 index 000000000..b8b6debd3 --- /dev/null +++ b/node_modules/tslint/lib/rules/typeLiteralDelimiterRule.d.ts @@ -0,0 +1,9 @@ +import * as ts from "typescript"; +import * as Lint from "../index"; +export declare class Rule extends Lint.Rules.AbstractRule { + static metadata: Lint.IRuleMetadata; + static FAILURE_STRING_MISSING: string; + static FAILURE_STRING_COMMA: string; + static FAILURE_STRING_TRAILING: string; + apply(sourceFile: ts.SourceFile): Lint.RuleFailure[]; +} diff --git a/node_modules/tslint/lib/rules/typeLiteralDelimiterRule.js b/node_modules/tslint/lib/rules/typeLiteralDelimiterRule.js new file mode 100644 index 000000000..06c33b0d1 --- /dev/null +++ b/node_modules/tslint/lib/rules/typeLiteralDelimiterRule.js @@ -0,0 +1,82 @@ +"use strict"; +/** + * @license + * Copyright 2017 Palantir Technologies, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +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) { + tslib_1.__extends(Rule, _super); + function Rule() { + return _super !== null && _super.apply(this, arguments) || this; + } + Rule.prototype.apply = function (sourceFile) { + return this.applyWithFunction(sourceFile, walk); + }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "type-literal-delimiter", + description: (_a = ["\n Checks that type literal members are separated by semicolons.\n Enforces a trailing semicolon for multiline type literals."], _a.raw = ["\n Checks that type literal members are separated by semicolons.\n Enforces a trailing semicolon for multiline type literals."], Lint.Utils.dedent(_a)), + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "style", + typescriptOnly: true, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING_MISSING = "Expected type literal to use ';' to separate members."; + Rule.FAILURE_STRING_COMMA = "Expected type literal to use ';' instead of ','."; + Rule.FAILURE_STRING_TRAILING = "Did not expect single-line type literal to have a trailing ';'."; + return Rule; +}(Lint.Rules.AbstractRule)); +exports.Rule = Rule; +function walk(ctx) { + var sourceFile = ctx.sourceFile; + ts.forEachChild(sourceFile, function cb(node) { + if (tsutils_1.isTypeLiteralNode(node)) { + check(node); + } + ts.forEachChild(node, cb); + }); + function check(node) { + node.members.forEach(function (member, idx) { + var end = member.end - 1; + // Trailing delimiter should be ommitted for a single-line type literal. + var shouldOmit = idx === node.members.length - 1 && tsutils_1.isSameLine(sourceFile, node.getStart(sourceFile), node.getEnd()); + var delimiter = sourceFile.text[end]; + switch (delimiter) { + case ";": + if (shouldOmit) { + fail(Rule.FAILURE_STRING_TRAILING); + } + break; + case ",": + fail(Rule.FAILURE_STRING_COMMA); + break; + default: + if (!shouldOmit) { + fail(Rule.FAILURE_STRING_MISSING); + } + } + function fail(failure) { + ctx.addFailureAt(end, 1, failure); + } + }); + } +} +var _a; diff --git a/node_modules/tslint/lib/rules/typedefRule.js b/node_modules/tslint/lib/rules/typedefRule.js index c53358b4f..14789d48e 100644 --- a/node_modules/tslint/lib/rules/typedefRule.js +++ b/node_modules/tslint/lib/rules/typedefRule.js @@ -46,36 +46,36 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithWalker(new TypedefWalker(sourceFile, this.ruleName, parseOptions(this.ruleArguments))); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "typedef", + description: "Requires type definitions to exist.", + optionsDescription: (_a = ["\n Several arguments may be optionally provided:\n\n * `\"", "\"` checks return type of functions.\n * `\"", "\"` checks return type of arrow functions.\n * `\"", "\"` checks type specifier of function parameters for non-arrow functions.\n * `\"", "\"` checks type specifier of function parameters for arrow functions.\n * `\"", "\"` checks return types of interface properties.\n * `\"", "\"` checks non-binding variable declarations.\n * `\"", "\"` checks member variable declarations.\n * `\"", "\"` checks object destructuring declarations.\n * `\"", "\"` checks array destructuring declarations."], _a.raw = ["\n Several arguments may be optionally provided:\n\n * \\`\"", "\"\\` checks return type of functions.\n * \\`\"", "\"\\` checks return type of arrow functions.\n * \\`\"", "\"\\` checks type specifier of function parameters for non-arrow functions.\n * \\`\"", "\"\\` checks type specifier of function parameters for arrow functions.\n * \\`\"", "\"\\` checks return types of interface properties.\n * \\`\"", "\"\\` checks non-binding variable declarations.\n * \\`\"", "\"\\` checks member variable declarations.\n * \\`\"", "\"\\` checks object destructuring declarations.\n * \\`\"", "\"\\` checks array destructuring declarations."], Lint.Utils.dedent(_a, OPTION_CALL_SIGNATURE, OPTION_ARROW_CALL_SIGNATURE, OPTION_PARAMETER, OPTION_ARROW_PARAMETER, OPTION_PROPERTY_DECLARATION, OPTION_VARIABLE_DECLARATION, OPTION_MEMBER_VARIABLE_DECLARATION, OPTION_OBJECT_DESTRUCTURING, OPTION_ARRAY_DESTRUCTURING)), + options: { + type: "array", + items: { + type: "string", + enum: [ + OPTION_CALL_SIGNATURE, + OPTION_ARROW_CALL_SIGNATURE, + OPTION_PARAMETER, + OPTION_ARROW_PARAMETER, + OPTION_PROPERTY_DECLARATION, + OPTION_VARIABLE_DECLARATION, + OPTION_MEMBER_VARIABLE_DECLARATION, + OPTION_OBJECT_DESTRUCTURING, + OPTION_ARRAY_DESTRUCTURING, + ], + }, + minLength: 0, + maxLength: 7, + }, + optionExamples: [[true, OPTION_CALL_SIGNATURE, OPTION_PARAMETER, OPTION_MEMBER_VARIABLE_DECLARATION]], + type: "typescript", + typescriptOnly: true, + }; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "typedef", - description: "Requires type definitions to exist.", - optionsDescription: (_a = ["\n Several arguments may be optionally provided:\n\n * `\"", "\"` checks return type of functions.\n * `\"", "\"` checks return type of arrow functions.\n * `\"", "\"` checks type specifier of function parameters for non-arrow functions.\n * `\"", "\"` checks type specifier of function parameters for arrow functions.\n * `\"", "\"` checks return types of interface properties.\n * `\"", "\"` checks non-binding variable declarations.\n * `\"", "\"` checks member variable declarations.\n * `\"", "\"` checks object destructuring declarations.\n * `\"", "\"` checks array destructuring declarations."], _a.raw = ["\n Several arguments may be optionally provided:\n\n * \\`\"", "\"\\` checks return type of functions.\n * \\`\"", "\"\\` checks return type of arrow functions.\n * \\`\"", "\"\\` checks type specifier of function parameters for non-arrow functions.\n * \\`\"", "\"\\` checks type specifier of function parameters for arrow functions.\n * \\`\"", "\"\\` checks return types of interface properties.\n * \\`\"", "\"\\` checks non-binding variable declarations.\n * \\`\"", "\"\\` checks member variable declarations.\n * \\`\"", "\"\\` checks object destructuring declarations.\n * \\`\"", "\"\\` checks array destructuring declarations."], Lint.Utils.dedent(_a, OPTION_CALL_SIGNATURE, OPTION_ARROW_CALL_SIGNATURE, OPTION_PARAMETER, OPTION_ARROW_PARAMETER, OPTION_PROPERTY_DECLARATION, OPTION_VARIABLE_DECLARATION, OPTION_MEMBER_VARIABLE_DECLARATION, OPTION_OBJECT_DESTRUCTURING, OPTION_ARRAY_DESTRUCTURING)), - options: { - type: "array", - items: { - type: "string", - enum: [ - OPTION_CALL_SIGNATURE, - OPTION_ARROW_CALL_SIGNATURE, - OPTION_PARAMETER, - OPTION_ARROW_PARAMETER, - OPTION_PROPERTY_DECLARATION, - OPTION_VARIABLE_DECLARATION, - OPTION_MEMBER_VARIABLE_DECLARATION, - OPTION_OBJECT_DESTRUCTURING, - OPTION_ARRAY_DESTRUCTURING, - ], - }, - minLength: 0, - maxLength: 7, - }, - optionExamples: [[true, OPTION_CALL_SIGNATURE, OPTION_PARAMETER, OPTION_MEMBER_VARIABLE_DECLARATION]], - type: "typescript", - typescriptOnly: true, -}; exports.Rule = Rule; var TypedefWalker = (function (_super) { tslib_1.__extends(TypedefWalker, _super); @@ -111,7 +111,6 @@ var TypedefWalker = (function (_super) { } case ts.SyntaxKind.VariableDeclaration: _this.checkVariableDeclaration(node); - break; } return ts.forEachChild(node, cb); }; diff --git a/node_modules/tslint/lib/rules/typedefWhitespaceRule.js b/node_modules/tslint/lib/rules/typedefWhitespaceRule.js index 3fc253e6c..e6e14aeec 100644 --- a/node_modules/tslint/lib/rules/typedefWhitespaceRule.js +++ b/node_modules/tslint/lib/rules/typedefWhitespaceRule.js @@ -53,41 +53,41 @@ var Rule = (function (_super) { }; return this.applyWithWalker(new TypedefWhitespaceWalker(sourceFile, this.ruleName, options)); }; + Rule.metadata = { + ruleName: "typedef-whitespace", + description: "Requires or disallows whitespace for type definitions.", + descriptionDetails: "Determines if a space is required or not before the colon in a type specifier.", + optionsDescription: (_a = ["\n Two arguments which are both objects.\n The first argument specifies how much space should be to the _left_ of a typedef colon.\n The second argument specifies how much space should be to the _right_ of a typedef colon.\n Each key should have a value of `\"onespace\"`, `\"space\"` or `\"nospace\"`.\n Possible keys are:\n\n * `\"call-signature\"` checks return type of functions.\n * `\"index-signature\"` checks index type specifier of indexers.\n * `\"parameter\"` checks function parameters.\n * `\"property-declaration\"` checks object property declarations.\n * `\"variable-declaration\"` checks variable declaration."], _a.raw = ["\n Two arguments which are both objects.\n The first argument specifies how much space should be to the _left_ of a typedef colon.\n The second argument specifies how much space should be to the _right_ of a typedef colon.\n Each key should have a value of \\`\"onespace\"\\`, \\`\"space\"\\` or \\`\"nospace\"\\`.\n Possible keys are:\n\n * \\`\"call-signature\"\\` checks return type of functions.\n * \\`\"index-signature\"\\` checks index type specifier of indexers.\n * \\`\"parameter\"\\` checks function parameters.\n * \\`\"property-declaration\"\\` checks object property declarations.\n * \\`\"variable-declaration\"\\` checks variable declaration."], Lint.Utils.dedent(_a)), + options: { + type: "array", + items: [SPACE_OBJECT, SPACE_OBJECT], + additionalItems: false, + }, + optionExamples: [ + [ + true, + { + "call-signature": "nospace", + "index-signature": "nospace", + "parameter": "nospace", + "property-declaration": "nospace", + "variable-declaration": "nospace", + }, + { + "call-signature": "onespace", + "index-signature": "onespace", + "parameter": "onespace", + "property-declaration": "onespace", + "variable-declaration": "onespace", + }, + ], + ], + type: "typescript", + typescriptOnly: true, + hasFix: true, + }; return Rule; }(Lint.Rules.AbstractRule)); -Rule.metadata = { - ruleName: "typedef-whitespace", - description: "Requires or disallows whitespace for type definitions.", - descriptionDetails: "Determines if a space is required or not before the colon in a type specifier.", - optionsDescription: (_a = ["\n Two arguments which are both objects.\n The first argument specifies how much space should be to the _left_ of a typedef colon.\n The second argument specifies how much space should be to the _right_ of a typedef colon.\n Each key should have a value of `\"onespace\"`, `\"space\"` or `\"nospace\"`.\n Possible keys are:\n\n * `\"call-signature\"` checks return type of functions.\n * `\"index-signature\"` checks index type specifier of indexers.\n * `\"parameter\"` checks function parameters.\n * `\"property-declaration\"` checks object property declarations.\n * `\"variable-declaration\"` checks variable declaration."], _a.raw = ["\n Two arguments which are both objects.\n The first argument specifies how much space should be to the _left_ of a typedef colon.\n The second argument specifies how much space should be to the _right_ of a typedef colon.\n Each key should have a value of \\`\"onespace\"\\`, \\`\"space\"\\` or \\`\"nospace\"\\`.\n Possible keys are:\n\n * \\`\"call-signature\"\\` checks return type of functions.\n * \\`\"index-signature\"\\` checks index type specifier of indexers.\n * \\`\"parameter\"\\` checks function parameters.\n * \\`\"property-declaration\"\\` checks object property declarations.\n * \\`\"variable-declaration\"\\` checks variable declaration."], Lint.Utils.dedent(_a)), - options: { - type: "array", - items: [SPACE_OBJECT, SPACE_OBJECT], - additionalItems: false, - }, - optionExamples: [ - [ - true, - { - "call-signature": "nospace", - "index-signature": "nospace", - "parameter": "nospace", - "property-declaration": "nospace", - "variable-declaration": "nospace", - }, - { - "call-signature": "onespace", - "index-signature": "onespace", - "parameter": "onespace", - "property-declaration": "onespace", - "variable-declaration": "onespace", - }, - ], - ], - type: "typescript", - typescriptOnly: true, - hasFix: true, -}; exports.Rule = Rule; var TypedefWhitespaceWalker = (function (_super) { tslib_1.__extends(TypedefWhitespaceWalker, _super); @@ -97,30 +97,9 @@ var TypedefWhitespaceWalker = (function (_super) { TypedefWhitespaceWalker.prototype.walk = function (sourceFile) { var _this = this; var cb = function (node) { - switch (node.kind) { - case ts.SyntaxKind.FunctionDeclaration: - case ts.SyntaxKind.FunctionExpression: - case ts.SyntaxKind.MethodDeclaration: - case ts.SyntaxKind.ArrowFunction: - case ts.SyntaxKind.GetAccessor: - case ts.SyntaxKind.SetAccessor: - case ts.SyntaxKind.MethodSignature: - case ts.SyntaxKind.ConstructSignature: - case ts.SyntaxKind.CallSignature: - _this.checkSpace(node, "call-signature"); - break; - case ts.SyntaxKind.IndexSignature: - _this.checkSpace(node, "index-signature"); - break; - case ts.SyntaxKind.VariableDeclaration: - _this.checkSpace(node, "variable-declaration"); - break; - case ts.SyntaxKind.Parameter: - _this.checkSpace(node, "parameter"); - break; - case ts.SyntaxKind.PropertySignature: - case ts.SyntaxKind.PropertyDeclaration: - _this.checkSpace(node, "property-declaration"); + var optionType = getOptionType(node); + if (optionType !== undefined) { + _this.checkSpace(node, optionType); } return ts.forEachChild(node, cb); }; @@ -191,4 +170,29 @@ var TypedefWhitespaceWalker = (function (_super) { }; return TypedefWhitespaceWalker; }(Lint.AbstractWalker)); +function getOptionType(node) { + switch (node.kind) { + case ts.SyntaxKind.FunctionDeclaration: + case ts.SyntaxKind.FunctionExpression: + case ts.SyntaxKind.MethodDeclaration: + case ts.SyntaxKind.ArrowFunction: + case ts.SyntaxKind.GetAccessor: + case ts.SyntaxKind.SetAccessor: + case ts.SyntaxKind.MethodSignature: + case ts.SyntaxKind.ConstructSignature: + case ts.SyntaxKind.CallSignature: + return "call-signature"; + case ts.SyntaxKind.IndexSignature: + return "index-signature"; + case ts.SyntaxKind.VariableDeclaration: + return "variable-declaration"; + case ts.SyntaxKind.Parameter: + return "parameter"; + case ts.SyntaxKind.PropertySignature: + case ts.SyntaxKind.PropertyDeclaration: + return "property-declaration"; + default: + return undefined; + } +} var _a; diff --git a/node_modules/tslint/lib/rules/typeofCompareRule.js b/node_modules/tslint/lib/rules/typeofCompareRule.js index 4526cd296..3aee80cf1 100644 --- a/node_modules/tslint/lib/rules/typeofCompareRule.js +++ b/node_modules/tslint/lib/rules/typeofCompareRule.js @@ -29,20 +29,20 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "typeof-compare", + description: "Makes sure result of `typeof` is compared to correct string values", + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "functionality", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "'typeof' expression must be compared to one of: " + Array.from(LEGAL_TYPEOF_RESULTS).map(function (x) { return "\"" + x + "\""; }).join(", "); return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "typeof-compare", - description: "Makes sure result of `typeof` is compared to correct string values", - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "functionality", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "'typeof' expression must be compared to one of: " + Array.from(LEGAL_TYPEOF_RESULTS).map(function (x) { return "\"" + x + "\""; }).join(", "); exports.Rule = Rule; function walk(ctx) { ts.forEachChild(ctx.sourceFile, function cb(node) { diff --git a/node_modules/tslint/lib/rules/unifiedSignaturesRule.js b/node_modules/tslint/lib/rules/unifiedSignaturesRule.js index 578dae231..771ef1604 100644 --- a/node_modules/tslint/lib/rules/unifiedSignaturesRule.js +++ b/node_modules/tslint/lib/rules/unifiedSignaturesRule.js @@ -45,18 +45,18 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "unified-signatures", + description: "Warns for any two overloads that could be unified into one by using a union or an optional/rest parameter.", + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "typescript", + typescriptOnly: true, + }; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "unified-signatures", - description: "Warns for any two overloads that could be unified into one by using a union or an optional/rest parameter.", - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "typescript", - typescriptOnly: true, -}; exports.Rule = Rule; function walk(ctx) { var sourceFile = ctx.sourceFile; @@ -74,7 +74,6 @@ function walk(ctx) { } case ts.SyntaxKind.TypeLiteral: checkMembers(node.members); - break; } return ts.forEachChild(node, cb); }); @@ -127,7 +126,6 @@ function walk(ctx) { ctx.addFailureAtNode(extraParameter, extraParameter.dotDotDotToken !== undefined ? Rule.FAILURE_STRING_OMITTING_REST_PARAMETER(lineOfOtherOverload) : Rule.FAILURE_STRING_OMITTING_SINGLE_PARAMETER(lineOfOtherOverload)); - break; } } } @@ -186,7 +184,11 @@ function signaturesDifferBySingleParameter(types1, types2) { } var a = types1[index]; var b = types2[index]; - return parametersHaveEqualSigils(a, b) ? { kind: "single-parameter-difference", p0: a, p1: b } : undefined; + // Can unify `a?: string` and `b?: number`. Can't unify `...args: string[]` and `...args: number[]`. + // See https://github.com/Microsoft/TypeScript/issues/5077 + return parametersHaveEqualSigils(a, b) && a.dotDotDotToken === undefined + ? { kind: "single-parameter-difference", p0: a, p1: b } + : undefined; } /** * Detect `a(): void` and `a(x: number): void`. @@ -228,7 +230,7 @@ function getIsTypeParameter(typeParameters) { } /** True if any of the outer type parameters are used in a signature. */ function signatureUsesTypeParameter(sig, isTypeParameter) { - return sig.parameters.some(function (p) { return p.type !== undefined && typeContainsTypeParameter(p.type); }); + return sig.parameters.some(function (p) { return p.type !== undefined && typeContainsTypeParameter(p.type) === true; }); function typeContainsTypeParameter(type) { if (utils.isTypeReferenceNode(type)) { var typeName = type.typeName; diff --git a/node_modules/tslint/lib/rules/useDefaultTypeParameterRule.d.ts b/node_modules/tslint/lib/rules/useDefaultTypeParameterRule.d.ts new file mode 100644 index 000000000..d2d51d1d1 --- /dev/null +++ b/node_modules/tslint/lib/rules/useDefaultTypeParameterRule.d.ts @@ -0,0 +1,7 @@ +import * as ts from "typescript"; +import * as Lint from "../index"; +export declare class Rule extends Lint.Rules.TypedRule { + static metadata: Lint.IRuleMetadata; + static FAILURE_STRING: string; + applyWithProgram(sourceFile: ts.SourceFile, program: ts.Program): Lint.RuleFailure[]; +} diff --git a/node_modules/tslint/lib/rules/useDefaultTypeParameterRule.js b/node_modules/tslint/lib/rules/useDefaultTypeParameterRule.js new file mode 100644 index 000000000..5d32087fc --- /dev/null +++ b/node_modules/tslint/lib/rules/useDefaultTypeParameterRule.js @@ -0,0 +1,121 @@ +"use strict"; +/** + * @license + * Copyright 2017 Palantir Technologies, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +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 utils_1 = require("../utils"); +var Rule = (function (_super) { + tslib_1.__extends(Rule, _super); + function Rule() { + return _super !== null && _super.apply(this, arguments) || this; + } + Rule.prototype.applyWithProgram = function (sourceFile, program) { + return this.applyWithFunction(sourceFile, function (ctx) { return walk(ctx, program.getTypeChecker()); }); + }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "use-default-type-parameter", + description: "Warns if an explicitly specified type argument is the default for that type parameter.", + optionsDescription: "Not configurable.", + options: null, + optionExamples: ["true"], + type: "functionality", + typescriptOnly: true, + requiresTypeInfo: true, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "This is the default value for this type parameter, so it can be omitted."; + return Rule; +}(Lint.Rules.TypedRule)); +exports.Rule = Rule; +function walk(ctx, checker) { + return ts.forEachChild(ctx.sourceFile, function cb(node) { + var argsAndParams = getArgsAndParameters(node, checker); + if (argsAndParams !== undefined) { + checkArgsAndParameters(node, argsAndParams); + } + return ts.forEachChild(node, cb); + }); + function checkArgsAndParameters(node, _a) { + var typeArguments = _a.typeArguments, typeParameters = _a.typeParameters; + // Just check the last one. Must specify previous type parameters if the last one is specified. + var i = typeArguments.length - 1; + var arg = typeArguments[i]; + var param = typeParameters[i]; + // TODO: would like checker.areTypesEquivalent. https://github.com/Microsoft/TypeScript/issues/13502 + if (param.default !== undefined && param.default.getText() === arg.getText()) { + ctx.addFailureAtNode(arg, Rule.FAILURE_STRING, createFix()); + } + function createFix() { + if (i === 0) { + var lt = Lint.childOfKind(node, ts.SyntaxKind.LessThanToken); + var gt = Lint.childOfKind(node, ts.SyntaxKind.GreaterThanToken); + return Lint.Replacement.deleteFromTo(lt.getStart(), gt.getEnd()); + } + else { + return Lint.Replacement.deleteFromTo(typeArguments[i - 1].getEnd(), arg.getEnd()); + } + } + } +} +function getArgsAndParameters(node, checker) { + switch (node.kind) { + case ts.SyntaxKind.CallExpression: + case ts.SyntaxKind.NewExpression: + case ts.SyntaxKind.TypeReference: + case ts.SyntaxKind.ExpressionWithTypeArguments: + var decl = node; + var typeArguments = decl.typeArguments; + if (typeArguments === undefined) { + return undefined; + } + var typeParameters = decl.kind === ts.SyntaxKind.TypeReference + ? typeParamsFromType(decl.typeName, checker) + : decl.kind === ts.SyntaxKind.ExpressionWithTypeArguments + ? typeParamsFromType(decl.expression, checker) + : typeParamsFromCall(node, checker); + return typeParameters === undefined ? undefined : { typeArguments: typeArguments, typeParameters: typeParameters }; + default: + return undefined; + } +} +function typeParamsFromCall(node, checker) { + var sig = checker.getResolvedSignature(node); + var sigDecl = sig === undefined ? undefined : sig.getDeclaration(); + if (sigDecl === undefined) { + return node.kind === ts.SyntaxKind.NewExpression ? typeParamsFromType(node.expression, checker) : undefined; + } + return sigDecl.typeParameters === undefined ? undefined : sigDecl.typeParameters; +} +function typeParamsFromType(type, checker) { + var sym = getAliasedSymbol(checker.getSymbolAtLocation(type), checker); + if (sym === undefined || sym.declarations === undefined) { + return undefined; + } + return utils_1.find(sym.declarations, function (decl) { + return tsutils_1.isClassLikeDeclaration(decl) || tsutils_1.isTypeAliasDeclaration(decl) || tsutils_1.isInterfaceDeclaration(decl) ? decl.typeParameters : undefined; + }); +} +function getAliasedSymbol(symbol, checker) { + if (symbol === undefined) { + return undefined; + } + return Lint.isSymbolFlagSet(symbol, ts.SymbolFlags.Alias) ? checker.getAliasedSymbol(symbol) : symbol; +} diff --git a/node_modules/tslint/lib/rules/useIsnanRule.js b/node_modules/tslint/lib/rules/useIsnanRule.js index 4b7f3738a..343088e97 100644 --- a/node_modules/tslint/lib/rules/useIsnanRule.js +++ b/node_modules/tslint/lib/rules/useIsnanRule.js @@ -28,21 +28,21 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk); }; + /* tslint:disable:object-literal-sort-keys */ + Rule.metadata = { + ruleName: "use-isnan", + description: "Enforces use of the `isNaN()` function to check for NaN references instead of a comparison to the `NaN` constant.", + rationale: (_a = ["\n Since `NaN !== NaN`, comparisons with regular operators will produce unexpected results.\n So, instead of `if (myVar === NaN)`, do `if (isNaN(myVar))`."], _a.raw = ["\n Since \\`NaN !== NaN\\`, comparisons with regular operators will produce unexpected results.\n So, instead of \\`if (myVar === NaN)\\`, do \\`if (isNaN(myVar))\\`."], Lint.Utils.dedent(_a)), + optionsDescription: "Not configurable.", + options: null, + optionExamples: [true], + type: "functionality", + typescriptOnly: false, + }; + /* tslint:enable:object-literal-sort-keys */ + Rule.FAILURE_STRING = "Found an invalid comparison for NaN: "; return Rule; }(Lint.Rules.AbstractRule)); -/* tslint:disable:object-literal-sort-keys */ -Rule.metadata = { - ruleName: "use-isnan", - description: "Enforces use of the `isNaN()` function to check for NaN references instead of a comparison to the `NaN` constant.", - rationale: (_a = ["\n Since `NaN !== NaN`, comparisons with regular operators will produce unexpected results.\n So, instead of `if (myVar === NaN)`, do `if (isNaN(myVar))`."], _a.raw = ["\n Since \\`NaN !== NaN\\`, comparisons with regular operators will produce unexpected results.\n So, instead of \\`if (myVar === NaN)\\`, do \\`if (isNaN(myVar))\\`."], Lint.Utils.dedent(_a)), - optionsDescription: "Not configurable.", - options: null, - optionExamples: [true], - type: "functionality", - typescriptOnly: false, -}; -/* tslint:enable:object-literal-sort-keys */ -Rule.FAILURE_STRING = "Found an invalid comparison for NaN: "; exports.Rule = Rule; function walk(ctx) { return ts.forEachChild(ctx.sourceFile, function cb(node) { diff --git a/node_modules/tslint/lib/rules/variableNameRule.js b/node_modules/tslint/lib/rules/variableNameRule.js index 23528202b..7e0af2daa 100644 --- a/node_modules/tslint/lib/rules/variableNameRule.js +++ b/node_modules/tslint/lib/rules/variableNameRule.js @@ -38,33 +38,33 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk, parseOptions(this.ruleArguments)); }; + Rule.metadata = { + ruleName: "variable-name", + description: "Checks variable names for various errors.", + optionsDescription: (_a = ["\n Five arguments may be optionally provided:\n\n * `\"", "\"`: allows only lowerCamelCased or UPPER_CASED variable names\n * `\"", "\"` allows underscores at the beginning (only has an effect if \"check-format\" specified)\n * `\"", "\"` allows underscores at the end. (only has an effect if \"check-format\" specified)\n * `\"", "\"` allows PascalCase in addition to lowerCamelCase.\n * `\"", "\"` allows snake_case in addition to lowerCamelCase.\n * `\"", "\"`: disallows the use of certain TypeScript keywords as variable or parameter names.\n * These are: ", ""], _a.raw = ["\n Five arguments may be optionally provided:\n\n * \\`\"", "\"\\`: allows only lowerCamelCased or UPPER_CASED variable names\n * \\`\"", "\"\\` allows underscores at the beginning (only has an effect if \"check-format\" specified)\n * \\`\"", "\"\\` allows underscores at the end. (only has an effect if \"check-format\" specified)\n * \\`\"", "\"\\` allows PascalCase in addition to lowerCamelCase.\n * \\`\"", "\"\\` allows snake_case in addition to lowerCamelCase.\n * \\`\"", "\"\\`: disallows the use of certain TypeScript keywords as variable or parameter names.\n * These are: ", ""], Lint.Utils.dedent(_a, OPTION_CHECK_FORMAT, OPTION_LEADING_UNDERSCORE, OPTION_TRAILING_UNDERSCORE, OPTION_ALLOW_PASCAL_CASE, OPTION_ALLOW_SNAKE_CASE, OPTION_BAN_KEYWORDS, bannedKeywordsStr)), + options: { + type: "array", + items: { + type: "string", + enum: [ + OPTION_CHECK_FORMAT, + OPTION_LEADING_UNDERSCORE, + OPTION_TRAILING_UNDERSCORE, + OPTION_ALLOW_PASCAL_CASE, + OPTION_ALLOW_SNAKE_CASE, + OPTION_BAN_KEYWORDS, + ], + }, + minLength: 0, + maxLength: 5, + }, + optionExamples: [[true, "ban-keywords", "check-format", "allow-leading-underscore"]], + type: "style", + typescriptOnly: false, + }; + Rule.KEYWORD_FAILURE = "variable name clashes with keyword/type"; return Rule; }(Lint.Rules.AbstractRule)); -Rule.metadata = { - ruleName: "variable-name", - description: "Checks variable names for various errors.", - optionsDescription: (_a = ["\n Five arguments may be optionally provided:\n\n * `\"", "\"`: allows only lowerCamelCased or UPPER_CASED variable names\n * `\"", "\"` allows underscores at the beginning (only has an effect if \"check-format\" specified)\n * `\"", "\"` allows underscores at the end. (only has an effect if \"check-format\" specified)\n * `\"", "\"` allows PascalCase in addition to lowerCamelCase.\n * `\"", "\"` allows snake_case in addition to lowerCamelCase.\n * `\"", "\"`: disallows the use of certain TypeScript keywords as variable or parameter names.\n * These are: ", ""], _a.raw = ["\n Five arguments may be optionally provided:\n\n * \\`\"", "\"\\`: allows only lowerCamelCased or UPPER_CASED variable names\n * \\`\"", "\"\\` allows underscores at the beginning (only has an effect if \"check-format\" specified)\n * \\`\"", "\"\\` allows underscores at the end. (only has an effect if \"check-format\" specified)\n * \\`\"", "\"\\` allows PascalCase in addition to lowerCamelCase.\n * \\`\"", "\"\\` allows snake_case in addition to lowerCamelCase.\n * \\`\"", "\"\\`: disallows the use of certain TypeScript keywords as variable or parameter names.\n * These are: ", ""], Lint.Utils.dedent(_a, OPTION_CHECK_FORMAT, OPTION_LEADING_UNDERSCORE, OPTION_TRAILING_UNDERSCORE, OPTION_ALLOW_PASCAL_CASE, OPTION_ALLOW_SNAKE_CASE, OPTION_BAN_KEYWORDS, bannedKeywordsStr)), - options: { - type: "array", - items: { - type: "string", - enum: [ - OPTION_CHECK_FORMAT, - OPTION_LEADING_UNDERSCORE, - OPTION_TRAILING_UNDERSCORE, - OPTION_ALLOW_PASCAL_CASE, - OPTION_ALLOW_SNAKE_CASE, - OPTION_BAN_KEYWORDS, - ], - }, - minLength: 0, - maxLength: 5, - }, - optionExamples: [[true, "ban-keywords", "check-format", "allow-leading-underscore"]], - type: "style", - typescriptOnly: false, -}; -Rule.KEYWORD_FAILURE = "variable name clashes with keyword/type"; exports.Rule = Rule; function parseOptions(ruleArguments) { var banKeywords = hasOption(OPTION_BAN_KEYWORDS); @@ -114,7 +114,6 @@ function walk(ctx) { handleVariableNameKeyword(name); } } - break; } } return ts.forEachChild(node, cb); diff --git a/node_modules/tslint/lib/rules/whitespaceRule.js b/node_modules/tslint/lib/rules/whitespaceRule.js index b92a075e5..4829fa623 100644 --- a/node_modules/tslint/lib/rules/whitespaceRule.js +++ b/node_modules/tslint/lib/rules/whitespaceRule.js @@ -37,28 +37,28 @@ var Rule = (function (_super) { Rule.prototype.apply = function (sourceFile) { return this.applyWithFunction(sourceFile, walk, parseOptions(this.ruleArguments)); }; + Rule.metadata = { + ruleName: "whitespace", + description: "Enforces whitespace style conventions.", + rationale: "Helps maintain a readable, consistent style in your codebase.", + optionsDescription: (_a = ["\n Eight arguments may be optionally provided:\n\n * `\"check-branch\"` checks branching statements (`if`/`else`/`for`/`while`) are followed by whitespace.\n * `\"check-decl\"`checks that variable declarations have whitespace around the equals token.\n * `\"check-operator\"` checks for whitespace around operator tokens.\n * `\"check-module\"` checks for whitespace in import & export statements.\n * `\"check-separator\"` checks for whitespace after separator tokens (`,`/`;`).\n * `\"check-type\"` checks for whitespace before a variable type specification.\n * `\"check-typecast\"` checks for whitespace between a typecast and its target.\n * `\"check-preblock\"` checks for whitespace before the opening brace of a block"], _a.raw = ["\n Eight arguments may be optionally provided:\n\n * \\`\"check-branch\"\\` checks branching statements (\\`if\\`/\\`else\\`/\\`for\\`/\\`while\\`) are followed by whitespace.\n * \\`\"check-decl\"\\`checks that variable declarations have whitespace around the equals token.\n * \\`\"check-operator\"\\` checks for whitespace around operator tokens.\n * \\`\"check-module\"\\` checks for whitespace in import & export statements.\n * \\`\"check-separator\"\\` checks for whitespace after separator tokens (\\`,\\`/\\`;\\`).\n * \\`\"check-type\"\\` checks for whitespace before a variable type specification.\n * \\`\"check-typecast\"\\` checks for whitespace between a typecast and its target.\n * \\`\"check-preblock\"\\` checks for whitespace before the opening brace of a block"], Lint.Utils.dedent(_a)), + options: { + type: "array", + items: { + type: "string", + enum: ["check-branch", "check-decl", "check-operator", "check-module", + "check-separator", "check-type", "check-typecast", "check-preblock"], + }, + minLength: 0, + maxLength: 7, + }, + optionExamples: [[true, "check-branch", "check-operator", "check-typecast"]], + type: "style", + typescriptOnly: false, + }; + Rule.FAILURE_STRING = "missing whitespace"; return Rule; }(Lint.Rules.AbstractRule)); -Rule.metadata = { - ruleName: "whitespace", - description: "Enforces whitespace style conventions.", - rationale: "Helps maintain a readable, consistent style in your codebase.", - optionsDescription: (_a = ["\n Eight arguments may be optionally provided:\n\n * `\"check-branch\"` checks branching statements (`if`/`else`/`for`/`while`) are followed by whitespace.\n * `\"check-decl\"`checks that variable declarations have whitespace around the equals token.\n * `\"check-operator\"` checks for whitespace around operator tokens.\n * `\"check-module\"` checks for whitespace in import & export statements.\n * `\"check-separator\"` checks for whitespace after separator tokens (`,`/`;`).\n * `\"check-type\"` checks for whitespace before a variable type specification.\n * `\"check-typecast\"` checks for whitespace between a typecast and its target.\n * `\"check-preblock\"` checks for whitespace before the opening brace of a block"], _a.raw = ["\n Eight arguments may be optionally provided:\n\n * \\`\"check-branch\"\\` checks branching statements (\\`if\\`/\\`else\\`/\\`for\\`/\\`while\\`) are followed by whitespace.\n * \\`\"check-decl\"\\`checks that variable declarations have whitespace around the equals token.\n * \\`\"check-operator\"\\` checks for whitespace around operator tokens.\n * \\`\"check-module\"\\` checks for whitespace in import & export statements.\n * \\`\"check-separator\"\\` checks for whitespace after separator tokens (\\`,\\`/\\`;\\`).\n * \\`\"check-type\"\\` checks for whitespace before a variable type specification.\n * \\`\"check-typecast\"\\` checks for whitespace between a typecast and its target.\n * \\`\"check-preblock\"\\` checks for whitespace before the opening brace of a block"], Lint.Utils.dedent(_a)), - options: { - type: "array", - items: { - type: "string", - enum: ["check-branch", "check-decl", "check-operator", "check-module", - "check-separator", "check-type", "check-typecast", "check-preblock"], - }, - minLength: 0, - maxLength: 7, - }, - optionExamples: [[true, "check-branch", "check-operator", "check-typecast"]], - type: "style", - typescriptOnly: false, -}; -Rule.FAILURE_STRING = "missing whitespace"; exports.Rule = Rule; function parseOptions(ruleArguments) { return { @@ -124,12 +124,27 @@ function walk(ctx) { // an import clause can have _both_ named bindings and a name (the latter for the default import) // but the named bindings always come last, so we only need to check that for whitespace var position = void 0; - var name_1 = importClause.name, namedBindings = importClause.namedBindings; - if (namedBindings !== undefined) { - position = namedBindings.getEnd(); + var namedBindings_1 = importClause.namedBindings; + if (namedBindings_1 !== undefined) { + if (namedBindings_1.kind !== ts.SyntaxKind.NamespaceImport) { + namedBindings_1.elements.forEach(function (element, idx, arr) { + var internalName = element.name; + if (internalName !== undefined) { + if (idx === arr.length - 1) { + var token = namedBindings_1.getLastToken(); + checkForTrailingWhitespace(token.getFullStart()); + } + if (idx === 0) { + var startPos = internalName.getStart() - 1; + checkForTrailingWhitespace(startPos, startPos + 1); + } + } + }); + } + position = namedBindings_1.getEnd(); } - else if (name_1 !== undefined) { - position = name_1.getEnd(); + else if (importClause.name !== undefined) { + position = importClause.name.getEnd(); } if (position !== undefined) { checkForTrailingWhitespace(position); @@ -154,7 +169,6 @@ function walk(ctx) { if (options.decl && initializer !== undefined) { checkForTrailingWhitespace((type !== undefined ? type : name).getEnd()); } - break; } ts.forEachChild(node, cb); }); @@ -199,14 +213,16 @@ function walk(ctx) { } break; case ts.SyntaxKind.ImportKeyword: + if (parent.kind === ts.SyntaxKind.CallExpression && + parent.expression.kind === ts.SyntaxKind.ImportKeyword) { + return; // Don't check ImportCall + } + // falls through case ts.SyntaxKind.ExportKeyword: case ts.SyntaxKind.FromKeyword: if (options.typecast) { prevTokenShouldBeFollowedByWhitespace = true; } - break; - default: - break; } }); function checkEqualsGreaterThanTokenInNode(node) { @@ -221,9 +237,10 @@ function walk(ctx) { checkForTrailingWhitespace(equalsGreaterThanToken.getFullStart()); checkForTrailingWhitespace(equalsGreaterThanToken.getEnd()); } - function checkForTrailingWhitespace(position) { - if (position !== sourceFile.end && !ts.isWhiteSpaceLike(sourceFile.text.charCodeAt(position))) { - addMissingWhitespaceErrorAt(position); + function checkForTrailingWhitespace(position, whiteSpacePos) { + if (whiteSpacePos === void 0) { whiteSpacePos = position; } + if (position !== sourceFile.end && !Lint.isWhiteSpace(sourceFile.text.charCodeAt(position))) { + addMissingWhitespaceErrorAt(whiteSpacePos); } } function addMissingWhitespaceErrorAt(position) { |