Skip to content

Commit 37c454f

Browse files
committed
Create tslint rule to allow @HostListener and @HostBinding in abstract classes.
1 parent 0ea4370 commit 37c454f

File tree

2 files changed

+42
-3
lines changed

2 files changed

+42
-3
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import * as ts from 'typescript';
2+
import * as Lint from 'tslint';
3+
4+
export class Rule extends Lint.Rules.AbstractRule {
5+
apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
6+
return this.applyWithWalker(new Walker(sourceFile, this.getOptions()));
7+
}
8+
}
9+
10+
class Walker extends Lint.RuleWalker {
11+
visitClassDeclaration(node: ts.ClassDeclaration) {
12+
if (!node.modifiers || !this.getOptions().length) { return; }
13+
14+
// Do not check the class if its abstract.
15+
if (!!node.modifiers.find(modifier => modifier.kind === ts.SyntaxKind.AbstractKeyword)) {
16+
return;
17+
}
18+
19+
node.members.forEach(el => {
20+
if (el.decorators) {
21+
el.decorators.forEach(decorator => {
22+
const decoratorText: string = decorator.getChildAt(1).getText();
23+
const matchedDecorator: string = this.getOptions().find(
24+
(item: string) => decoratorText.startsWith(item));
25+
if (!!matchedDecorator) {
26+
this.addFailureFromStartToEnd(decorator.getChildAt(1).pos - 1, decorator.end,
27+
`The @${matchedDecorator} decorator may only be used in abstract classes. In
28+
concrete classes use \`host\` in the component definition instead.`);
29+
}
30+
});
31+
}
32+
});
33+
34+
super.visitClassDeclaration(node);
35+
}
36+
}

tslint.json

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,9 +75,7 @@
7575
["fit"],
7676
["fdescribe"],
7777
["xit"],
78-
["xdescribe"],
79-
{ "name": "HostBinding", "message": "Use `host` in the component definition instead." },
80-
{ "name": "HostListener", "message": "Use `host` in the component definition instead." }
78+
["xdescribe"]
8179
],
8280
// Disallows importing the whole RxJS library. Submodules can be still imported.
8381
"import-blacklist": [true, "rxjs"],
@@ -87,6 +85,11 @@
8785
// Custom Rules
8886
"ts-loader": true,
8987
"no-exposed-todo": true,
88+
"no-host-decorator-in-concrete": [
89+
true,
90+
"HostBinding",
91+
"HostListener"
92+
],
9093
"validate-decorators": [true, {
9194
"Component": {
9295
"encapsulation": "\\.None$",

0 commit comments

Comments
 (0)