diff --git a/src/rules/banRule.ts b/src/rules/banRule.ts index ec2c6b970b7..877c30499ae 100644 --- a/src/rules/banRule.ts +++ b/src/rules/banRule.ts @@ -23,20 +23,18 @@ export class Rule extends Lint.Rules.AbstractRule { /* tslint:disable:object-literal-sort-keys */ public static metadata: Lint.IRuleMetadata = { ruleName: "ban", - description: "Bans the use of specific functions.", - descriptionDetails: "At this time, there is no way to disable global methods with this rule.", + description: "Bans the use of specific functions or global methods.", optionsDescription: "A list of `['object', 'method']` pairs which ban `object.method()`.", options: { type: "list", listType: { type: "array", - arrayMembers: [ - { type: "string" }, - { type: "string" }, - ], + items: {type: "string"}, + minLength: 1, + maxLength: 2, }, }, - optionExamples: [`[true, ["console", "log"], ["someObject", "someFunction"]]`], + optionExamples: [`[true, ["someGlobalMethod"], ["console", "log"], ["someObject", "someFunction"]]`], type: "functionality", }; /* tslint:enable:object-literal-sort-keys */ @@ -53,17 +51,29 @@ export class Rule extends Lint.Rules.AbstractRule { } export class BanFunctionWalker extends Lint.RuleWalker { + private bannedGlobalFunctions: string[] = []; private bannedFunctions: string[][] = []; public addBannedFunction(bannedFunction: string[]) { - this.bannedFunctions.push(bannedFunction); + if (bannedFunction.length === 1) { + this.bannedGlobalFunctions.push(bannedFunction[0]); + } else if (bannedFunction.length === 2) { + this.bannedFunctions.push(bannedFunction); + } } public visitCallExpression(node: ts.CallExpression) { const expression = node.expression; + this.checkForObjectMethodBan(expression); + this.checkForGlobalBan(expression); + + super.visitCallExpression(node); + } + + private checkForObjectMethodBan(expression: ts.LeftHandSideExpression) { if (expression.kind === ts.SyntaxKind.PropertyAccessExpression - && expression.getChildCount() >= 3) { + && expression.getChildCount() >= 3) { const firstToken = expression.getFirstToken(); const firstChild = expression.getChildAt(0); @@ -93,7 +103,16 @@ export class BanFunctionWalker extends Lint.RuleWalker { } } } + } - super.visitCallExpression(node); + private checkForGlobalBan(expression: ts.LeftHandSideExpression) { + if (expression.kind === ts.SyntaxKind.Identifier) { + const identifierName = ( expression).text; + if (this.bannedGlobalFunctions.indexOf(identifierName) !== -1) { + this.addFailure(this.createFailure(expression.getStart(), expression.getWidth(), + `${Rule.FAILURE_STRING_PART}${identifierName}`)); + } + + } } } diff --git a/test/rules/ban/test.ts.lint b/test/rules/ban/test.ts.lint index c8067440dae..a4aef112dbb 100644 --- a/test/rules/ban/test.ts.lint +++ b/test/rules/ban/test.ts.lint @@ -11,3 +11,13 @@ globals.getDocument().window.toString(); _.keys(obj).forEach(fun); _.forEach(fun); ~~~~~~~~~ [function invocation disallowed: _.forEach] +describe("some text", () => {}); +xdescribe("some text", () => {}); +~~~~~~~~~ [function invocation disallowed: xdescribe] +fdescribe("some text", () => {}); +~~~~~~~~~ [function invocation disallowed: fdescribe] +it("some text", () => {}); +xit("some text", () => {}); +~~~ [function invocation disallowed: xit] +fit("some text", () => {}); +~~~ [function invocation disallowed: fit] diff --git a/test/rules/ban/tslint.json b/test/rules/ban/tslint.json index db8ab1b06b3..4b2e148c579 100644 --- a/test/rules/ban/tslint.json +++ b/test/rules/ban/tslint.json @@ -1,5 +1,5 @@ { "rules": { - "ban": [true, ["window", "toString"], ["_", "forEach"]] + "ban": [true, ["xit"], ["fit"], ["xdescribe"], ["fdescribe"], ["window", "toString"], ["_", "forEach"]] } }