Skip to content

Commit

Permalink
max-classes-per-file: Convert to function (palantir#2545)
Browse files Browse the repository at this point in the history
  • Loading branch information
andy-hanson authored and adidahiya committed Apr 12, 2017
1 parent ab627d8 commit bdd8e54
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 38 deletions.
55 changes: 20 additions & 35 deletions src/rules/maxClassesPerFileRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* limitations under the License.
*/

import { isClassLikeDeclaration } from "tsutils";
import * as ts from "typescript";
import * as Lint from "../index";

Expand Down Expand Up @@ -47,48 +48,32 @@ export class Rule extends Lint.Rules.AbstractRule {
};
/* tslint:enable:object-literal-sort-keys */

public static FAILURE_STRING_FACTORY = (maxCount: number): string => {
public static FAILURE_STRING(maxCount: number): string {
const maxClassWord = maxCount === 1 ? "class per file is" : "classes per file are";
return `A maximum of ${maxCount} ${maxClassWord} allowed`;
return `A maximum of ${maxCount} ${maxClassWord} allowed.`;
}

public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
return this.applyWithWalker(new MaxClassesPerFileWalker(sourceFile, this.getOptions()));
const argument = this.ruleArguments[0];
const maxClasses = isNaN(argument) || (argument as number) > 0 ? argument : 1;
return this.applyWithFunction(sourceFile, walk, { maxClasses });
}
}

class MaxClassesPerFileWalker extends Lint.RuleWalker {
private classCount = 0;
private maxClassCount: number;

constructor(sourceFile: ts.SourceFile, options: Lint.IOptions) {
super(sourceFile, options);

if (options.ruleArguments[0] === undefined
|| isNaN(options.ruleArguments[0])
|| options.ruleArguments[0] < 1) {

this.maxClassCount = 1;
} else {
this.maxClassCount = options.ruleArguments[0];
}
}

public visitClassDeclaration(node: ts.ClassDeclaration) {
this.increaseClassCount(node);
super.visitClassDeclaration(node);
}

public visitClassExpression(node: ts.ClassExpression) {
this.increaseClassCount(node);
super.visitClassExpression(node);
}
interface Options {
maxClasses: number;
}

private increaseClassCount(node: ts.ClassExpression | ts.ClassDeclaration) {
this.classCount++;
if (this.classCount > this.maxClassCount) {
const msg = Rule.FAILURE_STRING_FACTORY(this.maxClassCount);
this.addFailureAtNode(node, msg);
function walk(ctx: Lint.WalkContext<Options>): void {
const { sourceFile, options: { maxClasses } } = ctx;
let classes = 0;
return ts.forEachChild(sourceFile, function cb(node: ts.Node): void {
if (isClassLikeDeclaration(node)) {
classes++;
if (classes > maxClasses) {
ctx.addFailureAtNode(node, Rule.FAILURE_STRING(maxClasses));
}
}
}
return ts.forEachChild(node, cb);
});
}
6 changes: 4 additions & 2 deletions test/rules/max-classes-per-file/one/test.ts.lint
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ class two {
public theAbovePropertyMakesSense = false;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
}
~ [A maximum of 1 class per file is allowed]
~ [0]

let three = class {
~~~~~~~
public foo = "bar";
~~~~~~~~~~~~~~~~~~~~~~~
}
~ [A maximum of 1 class per file is allowed]
~ [0]

[0]: A maximum of 1 class per file is allowed.
2 changes: 1 addition & 1 deletion test/rules/max-classes-per-file/two/test.ts.lint
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ class four {
}
~ [0]

[0]: A maximum of 2 classes per file are allowed
[0]: A maximum of 2 classes per file are allowed.

0 comments on commit bdd8e54

Please sign in to comment.