Skip to content

Commit

Permalink
class-name: Refactor and check class expressions (palantir#2553)
Browse files Browse the repository at this point in the history
[enhancement] `class-name` now also checks class expressions
  • Loading branch information
ajafff authored and adidahiya committed Apr 12, 2017
1 parent bdd8e54 commit 33e672f
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 28 deletions.
42 changes: 14 additions & 28 deletions src/rules/classNameRule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
* limitations under the License.
*/

import { isClassLikeDeclaration, isInterfaceDeclaration } from "tsutils";
import * as ts from "typescript";

import * as Lint from "../index";
Expand All @@ -36,38 +37,23 @@ export class Rule extends Lint.Rules.AbstractRule {
public static FAILURE_STRING = "Class name must be in pascal case";

public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
return this.applyWithWalker(new NameWalker(sourceFile, this.getOptions()));
return this.applyWithFunction(sourceFile, walk);
}
}

class NameWalker extends Lint.RuleWalker {
public visitClassDeclaration(node: ts.ClassDeclaration) {
// classes declared as default exports will be unnamed
if (node.name != null) {
const className = node.name.getText();
if (!this.isPascalCased(className)) {
this.addFailureAtNode(node.name, Rule.FAILURE_STRING);
function walk(ctx: Lint.WalkContext<void>) {
return ts.forEachChild(ctx.sourceFile, function cb(node: ts.Node): void {
if (isClassLikeDeclaration(node) && node.name !== undefined ||
isInterfaceDeclaration(node)) {
if (!isPascalCased(node.name!.text)) {
ctx.addFailureAtNode(node.name!, Rule.FAILURE_STRING);
}
}
return ts.forEachChild(node, cb);
});
}

super.visitClassDeclaration(node);
}

public visitInterfaceDeclaration(node: ts.InterfaceDeclaration) {
const interfaceName = node.name.getText();
if (!this.isPascalCased(interfaceName)) {
this.addFailureAtNode(node.name, Rule.FAILURE_STRING);
}

super.visitInterfaceDeclaration(node);
}

private isPascalCased(name: string) {
if (name.length <= 0) {
return true;
}

const firstCharacter = name.charAt(0);
return ((firstCharacter === firstCharacter.toUpperCase()) && name.indexOf("_") === -1);
}
function isPascalCased(name: string) {
const firstCharacter = name[0];
return ((firstCharacter === firstCharacter.toUpperCase()) && !name.includes("_"));
}
9 changes: 9 additions & 0 deletions test/rules/class-name/test.ts.lint
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,13 @@ export default class {
// should not fail
}

// anonymous class expression
var foo = class {};
var bar = class invalidName {}
~~~~~~~~~~~ [0]

interface someInterface {}
~~~~~~~~~~~~~ [0]
interface SomeInterface {}

[0]: Class name must be in pascal case

0 comments on commit 33e672f

Please sign in to comment.