Skip to content
This repository has been archived by the owner on Mar 25, 2021. It is now read-only.

Fix #612 #801

Merged
merged 3 commits into from
Nov 18, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,8 @@ A sample configuration file with all options is available [here](https://github.
* `label-undefined` checks that labels are defined before usage.
* `max-line-length` sets the maximum length of a line.
* `member-access` enforces using explicit visibility on class members
* `"check-accessor"` enforces explicit visibility on get/set accessors (can only be public)
* `"check-constructor"` enforces explicit visibility on constructors (can only be public)
* `member-ordering` enforces member ordering. Rule options:
* `public-before-private` All public members must be declared before private members
* `static-before-instance` All static members must be declared before instance members
Expand Down
29 changes: 29 additions & 0 deletions src/rules/memberAccessRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,44 @@ export class MemberAccessWalker extends Lint.RuleWalker {
super(sourceFile, options);
}

public visitConstructorDeclaration(node: ts.ConstructorDeclaration) {
if (this.hasOption("check-constructor")) {
// constructor is only allowed to have public or nothing, but the compiler will catch this
this.validateVisibilityModifiers(node);
}

super.visitConstructorDeclaration(node);
}

public visitMethodDeclaration(node: ts.MethodDeclaration) {
this.validateVisibilityModifiers(node);
super.visitMethodDeclaration(node);
}

public visitPropertyDeclaration(node: ts.PropertyDeclaration) {
this.validateVisibilityModifiers(node);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this method should also get a super call

super.visitPropertyDeclaration(node);
}

public visitGetAccessor(node: ts.AccessorDeclaration) {
if (this.hasOption("check-accessor")) {
this.validateVisibilityModifiers(node);
}
super.visitGetAccessor(node);
}

public visitSetAccessor(node: ts.AccessorDeclaration) {
if (this.hasOption("check-accessor")) {
this.validateVisibilityModifiers(node);
}
super.visitSetAccessor(node);
}

private validateVisibilityModifiers(node: ts.Node) {
if (node.parent.kind === ts.SyntaxKind.ObjectLiteralExpression) {
return;
}

const hasAnyVisibilityModifiers = Lint.hasModifier(
node.modifiers,
ts.SyntaxKind.PublicKeyword,
Expand Down
17 changes: 17 additions & 0 deletions test/files/rules/memberaccess-accessor.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
class Members {
get g() {
return 1;
}
set s(o: any) {}

public get publicG() {
return 1;
}
public set publicS(o: any) {}
}

const obj = {
get g() {
return 1;
}
};
9 changes: 9 additions & 0 deletions test/files/rules/memberaccess-constructor.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class ContructorsNoAccess {
constructor(i: number);
constructor(o: any) {}
}

class ContructorsAccess {
public constructor(i: number);
public constructor(o: any) {}
}
42 changes: 28 additions & 14 deletions test/files/rules/memberaccess.test.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,32 @@
class Foo {
constructor() {
}
declare class AmbientNoAccess {
a(): number;
}

public w: number;
private x: number;
protected y: number;
z: number;
declare class AmbientAccess {
public a(): number;
}

public barW(): any {
}
private barX(): any {
}
protected barY(): any {
}
barZ(): any {
class Members {
i: number;

public nPublic: number;
protected nProtected: number;
private nPrivate: number;

noAccess(x: number): number;
noAccess(o: any): any {}

public access(x: number): number;
public access(o: any): any {}
}

const obj = {
func() {}
};

function main() {
class A {
i: number;
public n: number;
}
}
51 changes: 42 additions & 9 deletions test/rules/memberAccessTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,47 @@
import * as Lint from "../lint";

describe("<member-access>", () => {
it("enforces using explicit visibility on class members", () => {
let fileName = "rules/memberaccess.test.ts";
let MemberAccessRule = Lint.Test.getRule("member-access");
let actualFailures = Lint.Test.applyRuleOnFile(fileName, MemberAccessRule);

Lint.Test.assertFailuresEqual(actualFailures, [
Lint.Test.createFailure(fileName, [8, 5], [8, 15], MemberAccessRule.FAILURE_STRING),
Lint.Test.createFailure(fileName, [16, 5], [17, 6], MemberAccessRule.FAILURE_STRING)
]);
it("ensures that class properties have access modifiers", () => {
const fileName = "rules/memberaccess.test.ts";
const expectedFailures = [
[[2, 5], [2, 17]],
[[10, 5], [10, 15]],
[[16, 5], [16, 33]],
[[17, 5], [17, 29]],
[[29, 9], [29, 19]]
];

assertFailuresInFile(fileName, expectedFailures);
});

it("ensures that constructors have access modifiers", () => {
const fileName = "rules/memberaccess-constructor.test.ts";
const expectedFailures = [
[[2, 5], [2, 28]],
[[3, 5], [3, 27]]
];
const options = [true, "check-constructor"];

assertFailuresInFile(fileName, expectedFailures, options);
});

it("ensures that accessors have access modifiers", () => {
const fileName = "rules/memberaccess-accessor.test.ts";
const expectedFailures = [
[[2, 5], [4, 6]],
[[5, 5], [5, 21]]
];
const options = [true, "check-accessor"];

assertFailuresInFile(fileName, expectedFailures, options);
});

function assertFailuresInFile(fileName: string, expectedFailures: number[][][], options: any[] = [true]) {
const MemberAccessRule = Lint.Test.getRule("member-access");
const createFailure = Lint.Test.createFailuresOnFile(fileName, MemberAccessRule.FAILURE_STRING);
const expectedFileFailures = expectedFailures.map(failure => createFailure(failure[0], failure[1]));

const actualFailures = Lint.Test.applyRuleOnFile(fileName, MemberAccessRule, options);
Lint.Test.assertFailuresEqual(actualFailures, expectedFileFailures);
}
});