From c69c5ffafa5c394c29ca45336ddad6bacf9e0bb8 Mon Sep 17 00:00:00 2001 From: Alexander Schrab Date: Fri, 22 May 2015 09:55:28 +0200 Subject: [PATCH] New rule: classMemberNoDefaultAccess. Disallows public access modifiers that are not explicit in the class --- src/rules/classMemberNoDefaultAccessRule.ts | 69 +++++++++++++++++++ .../rules/classmembernodefaultaccess.test.ts | 18 +++++ test/rules/classMemberNoDefaultAccessTest.ts | 32 +++++++++ 3 files changed, 119 insertions(+) create mode 100644 src/rules/classMemberNoDefaultAccessRule.ts create mode 100644 test/files/rules/classmembernodefaultaccess.test.ts create mode 100644 test/rules/classMemberNoDefaultAccessTest.ts diff --git a/src/rules/classMemberNoDefaultAccessRule.ts b/src/rules/classMemberNoDefaultAccessRule.ts new file mode 100644 index 00000000000..f3ff8e60787 --- /dev/null +++ b/src/rules/classMemberNoDefaultAccessRule.ts @@ -0,0 +1,69 @@ +/* + * 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. +*/ + +export class Rule extends Lint.Rules.AbstractRule { + public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] { + return this.applyWithWalker(new MemberAccessWalker(sourceFile, this.getOptions())); + } +} + +interface IModifiers { + hasAccessModifier: boolean; +} + +function getModifiers(modifiers?: ts.ModifiersArray): IModifiers { + var modifierStrings: string[] = []; + if (modifiers != null) { + modifierStrings = modifiers.map((x) => { + return x.getText(); + }); + } + + var hasAccessModifier = modifierStrings.indexOf("public") !== -1; + hasAccessModifier = hasAccessModifier || modifierStrings.indexOf("private") !== -1; + hasAccessModifier = hasAccessModifier || modifierStrings.indexOf("protected") !== -1; + + return { + hasAccessModifier: hasAccessModifier + }; +} + +export class MemberAccessWalker extends Lint.RuleWalker { + constructor(sourceFile: ts.SourceFile, options: Lint.IOptions) { + super(sourceFile, options); + } + + public visitMethodDeclaration(node: ts.MethodDeclaration): void { + this.checkModifiers(node, getModifiers(node.modifiers)); + super.visitMethodDeclaration(node); + } + + public visitPropertyDeclaration(node: ts.PropertyDeclaration): void { + this.checkModifiers(node, getModifiers(node.modifiers)); + super.visitPropertyDeclaration(node); + } + + private checkModifiers(node: ts.Node, current: IModifiers): void { + if (!this.followsRules(current)) { + var message = "Default access modifier on member/method not allowed"; + this.addFailure(this.createFailure(node.getStart(), node.getWidth(), message)); + } + } + + private followsRules(current: IModifiers): boolean { + return current.hasAccessModifier; + } +} diff --git a/test/files/rules/classmembernodefaultaccess.test.ts b/test/files/rules/classmembernodefaultaccess.test.ts new file mode 100644 index 00000000000..ec05e491b31 --- /dev/null +++ b/test/files/rules/classmembernodefaultaccess.test.ts @@ -0,0 +1,18 @@ +class Foo { + constructor() { + } + + public w: number; + private x: number; + protected y: number; + z: number; + + public barW(): any { + } + private barX(): any { + } + protected barY(): any { + } + barZ(): any { + } +} diff --git a/test/rules/classMemberNoDefaultAccessTest.ts b/test/rules/classMemberNoDefaultAccessTest.ts new file mode 100644 index 00000000000..690ac3e7c7c --- /dev/null +++ b/test/rules/classMemberNoDefaultAccessTest.ts @@ -0,0 +1,32 @@ +/* + * 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. + */ + +/// + +describe("", () => { + it("disallow default access on member", () => { + var fileName = "rules/classmembernodefaultaccess.test.ts"; + var ClassMemberNoDefaultAccess = Lint.Test.getRule("class-member-no-default-access"); + var actualFailures = Lint.Test.applyRuleOnFile(fileName, ClassMemberNoDefaultAccess, []); + + Lint.Test.assertFailuresEqual(actualFailures, [ + Lint.Test.createFailure(fileName, [8, 5], [8, 15], + "Default access modifier on member/method not allowed"), + Lint.Test.createFailure(fileName, [16, 5], [17, 6], + "Default access modifier on member/method not allowed") + ]); + }); +});