Skip to content

Instantly share code, notes, and snippets.

@okunokentaro
Created April 21, 2017 03:32
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save okunokentaro/1e1cde0764a3201c01adfed7ab5cf866 to your computer and use it in GitHub Desktop.
Save okunokentaro/1e1cde0764a3201c01adfed7ab5cf866 to your computer and use it in GitHub Desktop.
enforceNamingBase.ts
import * as ts from 'typescript';
import * as Lint from 'tslint';
import { EnforceNamingWalker } from './enforceNamingBase';
export class Rule extends Lint.Rules.AbstractRule {
static FAILURE_STRING = `It is a method that returns Observable, use '*$' suffix`;
apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
const walker = new EnforceNamingWalker(
sourceFile,
this.getOptions(),
'Observable',
/\$$/,
Rule.FAILURE_STRING,
);
return this.applyWithWalker(walker);
}
}
import * as ts from 'typescript';
import * as Lint from 'tslint';
import { IOptions } from 'tslint';
export class EnforceNamingWalker extends Lint.RuleWalker {
private SERVICE_NAMES = [
// something
];
constructor(
sourceFile: ts.SourceFile,
options: IOptions,
private targetTypeName: string,
private targetNamingRegex: RegExp,
private failureString: string,
) {
super(sourceFile, options);
}
walk(node: ts.SourceFile) {
if (!this.SERVICE_NAMES.some(name => node.text.includes(name))) {
this.skip(node);
return;
}
super.walk(node);
}
protected visitClassDeclaration(node: ts.ClassDeclaration) {
if (!node.heritageClauses) {
super.visitClassDeclaration(node);
return;
}
node.heritageClauses.forEach((heritageClauseNode: ts.HeritageClause) => {
heritageClauseNode.types.forEach((exprNode: ts.ExpressionWithTypeArguments) => {
const text = exprNode.expression.getText();
if (this.SERVICE_NAMES.some(name => text.includes(name))) {
this.validateEnforceAsPromise(node);
}
});
});
super.visitClassDeclaration(node);
}
private validateEnforceAsPromise(node: ts.ClassDeclaration) {
node.members.forEach((member: ts.PropertyDeclaration) => {
let typeName: string;
if (member.type && (member.type as ts.TypeReferenceNode).typeName as ts.Identifier) {
typeName = (member.type as ts.TypeReferenceNode).typeName.getText();
}
let methodName: string;
if (member.name) {
methodName = member.name.getText();
}
if (member.modifiers) {
const isRestricted = Array.from(member.modifiers).some(modifier => {
return modifier.kind === ts.SyntaxKind.ProtectedKeyword ||
modifier.kind === ts.SyntaxKind.PrivateKeyword;
});
if (isRestricted) {
return;
}
}
if (typeName === this.targetTypeName && !this.targetNamingRegex.test(methodName)) {
this.addFailureAtNode(member, this.failureString);
}
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment