diff options
author | Xianny <8582774+xianny@users.noreply.github.com> | 2019-01-12 02:04:30 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-01-12 02:04:30 +0800 |
commit | 943c378309a84ed142852c6584b53958df7817c8 (patch) | |
tree | 43536b7812b11f3a83db4208bfa5640643cfd6e8 /packages/tslint-config/rules | |
parent | cf3787edbb9e8acf7160ab93b903b54c63bdffda (diff) | |
download | dexon-sol-tools-943c378309a84ed142852c6584b53958df7817c8.tar dexon-sol-tools-943c378309a84ed142852c6584b53958df7817c8.tar.gz dexon-sol-tools-943c378309a84ed142852c6584b53958df7817c8.tar.bz2 dexon-sol-tools-943c378309a84ed142852c6584b53958df7817c8.tar.lz dexon-sol-tools-943c378309a84ed142852c6584b53958df7817c8.tar.xz dexon-sol-tools-943c378309a84ed142852c6584b53958df7817c8.tar.zst dexon-sol-tools-943c378309a84ed142852c6584b53958df7817c8.zip |
Implement tslint enum-naming to enforce PascalCase on enum members (#1474)
Diffstat (limited to 'packages/tslint-config/rules')
-rw-r--r-- | packages/tslint-config/rules/enumNamingRule.ts | 60 |
1 files changed, 60 insertions, 0 deletions
diff --git a/packages/tslint-config/rules/enumNamingRule.ts b/packages/tslint-config/rules/enumNamingRule.ts new file mode 100644 index 000000000..56499618f --- /dev/null +++ b/packages/tslint-config/rules/enumNamingRule.ts @@ -0,0 +1,60 @@ +import * as Lint from 'tslint'; +import * as ts from 'typescript'; + +export class Rule extends Lint.Rules.AbstractRule { + public static FAILURE_STRING = `Enum member names should be PascalCase`; + + public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] { + return this.applyWithFunction(sourceFile, walk); + } +} + +function walk(ctx: Lint.WalkContext<void>): void { + // Recursively walk the AST starting with root node, `ctx.sourceFile`. + // Call the function `cb` (defined below) for each child. + return ts.forEachChild(ctx.sourceFile, cb); + + function cb(node: ts.Node): void { + if (node.kind === ts.SyntaxKind.EnumMember) { + const keyNode = node.getFirstToken(ctx.sourceFile); + if (keyNode !== undefined) { + const keyText = keyNode.getText(ctx.sourceFile); + if (!isPascalCase(keyText)) { + return ctx.addFailureAtNode(node, Rule.FAILURE_STRING, getFix(keyText, node)); + } + } + } + // Continue recursion into the AST by calling function `cb` for every child of the current node. + return ts.forEachChild(node, cb); + } + + function getFix(text: string, node: ts.Node): Lint.Replacement { + let fix = toPascalCase(text); + // check for `member = value` + if (node.getChildCount(ctx.sourceFile) === 3) { + const value = node.getLastToken(ctx.sourceFile); + if (value !== undefined) { + fix += ` = ${value.getText(ctx.sourceFile)}`; + } + } + return new Lint.Replacement(node.getStart(ctx.sourceFile), node.getWidth(ctx.sourceFile), fix); + } +} + +// Modified from: https://github.com/jonschlinkert/pascalcase/ +function toPascalCase(str: string): string { + let result = str.replace(/([a-z0-9\W])([A-Z])/g, '$1 $2'); + if (result.length === 1) { + return result.toUpperCase(); + } + result = result.replace(/^[\W_\.]+|[\W_\.]+$/g, '').toLowerCase(); + result = result.charAt(0).toUpperCase() + result.slice(1); + return result.replace(/[\W_\.]+(\w|$)/g, (_, ch) => { + return ch.toUpperCase(); + }); +} +function isPascalCase(s: string): boolean { + const regex = /^([A-Z0-9]+[a-z0-9]+)+$/g; + const key = s.split('=')[0].trim(); + return regex.test(key); +} |