/
noOutputOnPrefixRule.ts
45 lines (37 loc) · 1.61 KB
/
noOutputOnPrefixRule.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import { sprintf } from 'sprintf-js';
import * as Lint from 'tslint';
import * as ts from 'typescript';
import { NgWalker } from './angular/ngWalker';
import { getClassName } from './util/utils';
export class Rule extends Lint.Rules.AbstractRule {
static readonly metadata: Lint.IRuleMetadata = {
description: 'Name events without the prefix on.',
descriptionDetails: 'See more at https://angular.io/guide/styleguide#dont-prefix-output-properties.',
options: null,
optionsDescription: 'Not configurable.',
rationale:
'Angular allows for an alternative syntax on-*. If the event itself was prefixed with on this would result in an on-onEvent binding expression.',
ruleName: 'no-output-on-prefix',
type: 'maintainability',
typescriptOnly: true
};
static readonly FAILURE_STRING = 'In the class "%s", the output property "%s" should not be prefixed with on';
apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
return this.applyWithWalker(new OutputWalker(sourceFile, this.getOptions()));
}
}
class OutputWalker extends NgWalker {
protected visitNgOutput(property: ts.PropertyDeclaration, output: ts.Decorator, args: string[]) {
this.validateOutput(property);
super.visitNgOutput(property, output, args);
}
private validateOutput(property: ts.PropertyDeclaration): void {
const className = getClassName(property);
const memberName = property.name.getText();
if (!memberName || !/^on((?![a-z])|(?=$))/.test(memberName)) {
return;
}
const failure = sprintf(Rule.FAILURE_STRING, className, memberName);
this.addFailureAtNode(property, failure);
}
}