diff options
Diffstat (limited to 'node_modules/tslint/lib/rules/curlyRule.js')
-rw-r--r-- | node_modules/tslint/lib/rules/curlyRule.js | 80 |
1 files changed, 60 insertions, 20 deletions
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() { |