Skip to content

Commit 636cde1

Browse files
author
PreskoIsTheGreatest
committed
update rules to use tslint structure and ng2walker
1 parent 33fb22c commit 636cde1

9 files changed

+128
-206
lines changed
Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,47 @@
11
import * as Lint from 'tslint/lib/lint';
22
import * as ts from 'typescript';
3-
import {decoratorValidator} from "./util/decoratorValidator";
4-
import {ConstructorMetadataWalker} from "./constructorMetadataWalker";
5-
import {RuleBase} from "./util/rulesBase";
3+
import {sprintf} from 'sprintf-js';
64

7-
const FAILURE_STRING = 'In the constructor of class "%s", the parameter "%s" uses the @Attribute decorator, ' +
8-
'which is considered as a bad practice. Please, consider construction of type "@Input() %s: string"';
5+
export class Rule extends Lint.Rules.AbstractRule {
96

10-
const attributeCondition = (name)=> {
11-
return (name == 'Attribute')
12-
};
7+
public apply(sourceFile:ts.SourceFile):Lint.RuleFailure[] {
8+
return this.applyWithWalker(
9+
new ConstructorMetadataWalker(sourceFile,
10+
this.getOptions()));
11+
}
12+
13+
static FAILURE_STRING:string = 'In the constructor of class "%s",' +
14+
' the parameter "%s" uses the @Attribute decorator, ' +
15+
'which is considered as a bad practice. Please,' +
16+
' consider construction of type "@Input() %s: string"';
1317

14-
export class Rule extends RuleBase {
18+
}
1519

16-
constructor(ruleName:string, value:any, disabledIntervals:Lint.IDisabledInterval[]) {
17-
super(ruleName, value, disabledIntervals,
18-
decoratorValidator(attributeCondition),
19-
FAILURE_STRING, ConstructorMetadataWalker);
20+
export class ConstructorMetadataWalker extends Lint.RuleWalker {
21+
22+
visitConstructorDeclaration(node:ts.ConstructorDeclaration) {
23+
let parentName = (<ts.ClassDeclaration>node.parent).name.text;
24+
(node.parameters || []).forEach(this.validateParameter.bind(this, parentName));
25+
super.visitConstructorDeclaration(node);
2026
}
2127

28+
validateParameter(className:string, parameter) {
29+
let parameterName = (<ts.Identifier>parameter.name).text;
30+
if (parameter.decorators) {
31+
parameter.decorators.forEach((decorator)=> {
32+
let baseExpr = <any>decorator.expression || {};
33+
let expr = baseExpr.expression || {};
34+
let name = expr.text;
35+
if (name == 'Attribute') {
36+
let failureConfig:string[] = [className, parameterName, parameterName];
37+
failureConfig.unshift(Rule.FAILURE_STRING);
38+
this.addFailure(
39+
this.createFailure(
40+
parameter.getStart(),
41+
parameter.getWidth(),
42+
sprintf.apply(this, failureConfig)));
43+
}
44+
})
45+
}
46+
}
2247
}

src/callForwardRefRule.ts

Lines changed: 36 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,43 @@
11
import * as Lint from 'tslint/lib/lint';
2-
import {RuleBase} from "./util/rulesBase";
3-
import {ExpressionCallMetadataWalker} from "./expressionCallMetadataWalker";
2+
import * as ts from 'typescript';
3+
import {sprintf} from 'sprintf-js';
44

5-
const forwardRefValidator = (callExpression)=> {
6-
return (callExpression.expression.text === 'forwardRef');
7-
};
5+
export class Rule extends Lint.Rules.AbstractRule {
6+
7+
public apply(sourceFile:ts.SourceFile):Lint.RuleFailure[] {
8+
return this.applyWithWalker(
9+
new ExpressionCallMetadataWalker(sourceFile,
10+
this.getOptions()));
11+
}
12+
13+
static FAILURE_STRING:string = 'In the class "%s" you are calling forwardRef,' +
14+
' which is considered a bad practice ' +
15+
'and indicates either a cyclic dependency or ' +
16+
'inconsistency in the services declaration';
17+
}
818

9-
const FAILURE_STRING:string = 'In the class "%s" you are calling forwardRef, which is considered a bad practice ' +
10-
'and indicates either a cyclic dependency or inconsistency in the services declaration';
1119

12-
export class Rule extends RuleBase {
20+
export class ExpressionCallMetadataWalker extends Lint.RuleWalker {
1321

14-
constructor(ruleName:string, value:any, disabledIntervals:Lint.IDisabledInterval[]) {
15-
super(ruleName, value, disabledIntervals,
16-
forwardRefValidator, FAILURE_STRING,
17-
ExpressionCallMetadataWalker);
22+
visitCallExpression(node:ts.CallExpression) {
23+
this.validateCallExpression(node);
24+
super.visitCallExpression(node);
1825
}
26+
27+
private validateCallExpression(callExpression) {
28+
if (callExpression.expression.text === 'forwardRef') {
29+
let currentNode:any = callExpression;
30+
while (currentNode.parent.parent) {
31+
currentNode = currentNode.parent;
32+
}
33+
let failureConfig:string[] = [currentNode.name.text];
34+
failureConfig.unshift(Rule.FAILURE_STRING);
35+
this.addFailure(
36+
this.createFailure(
37+
callExpression.getStart(),
38+
callExpression.getWidth(),
39+
sprintf.apply(this, failureConfig)));
40+
}
41+
}
42+
1943
}

src/classMetadataWalker.ts

Lines changed: 0 additions & 32 deletions
This file was deleted.

src/constructorMetadataWalker.ts

Lines changed: 0 additions & 34 deletions
This file was deleted.

src/expressionCallMetadataWalker.ts

Lines changed: 0 additions & 35 deletions
This file was deleted.

src/inputPropertyDirectiveRule.ts

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,35 @@
11
import * as Lint from 'tslint/lib/lint';
22
import * as ts from 'typescript';
3-
import {decoratorValidator} from './util/decoratorValidator';
4-
import {RuleBase} from './util/rulesBase';
5-
import {ClassMetadataWalker} from "./classMetadataWalker";
3+
import {sprintf} from 'sprintf-js';
4+
import {Ng2Walker} from "./util/ng2Walker";
65

7-
const FAILURE_STRING = 'In the class "%s", the directive input property "%s" should not be renamed.' +
8-
'Please, consider the following use "@Input() %s: string"';
6+
export class Rule extends Lint.Rules.AbstractRule {
97

10-
const renameInputCondition = (name, arg, element)=> {
11-
let memberName = element.name.text;
12-
return (name === 'Input' && arg && memberName != arg.text);
13-
};
8+
public apply(sourceFile:ts.SourceFile):Lint.RuleFailure[] {
9+
return this.applyWithWalker(
10+
new InputMetadataWalker(sourceFile,
11+
this.getOptions()));
12+
}
1413

15-
export class Rule extends RuleBase {
14+
static FAILURE_STRING:string = 'In the class "%s", the directive input property "%s" should not be renamed.' +
15+
'Please, consider the following use "@Input() %s: string"';
16+
}
1617

17-
constructor(ruleName:string, value:any, disabledIntervals:Lint.IDisabledInterval[]) {
18-
super(ruleName, value, disabledIntervals,
19-
decoratorValidator(renameInputCondition),
20-
FAILURE_STRING, ClassMetadataWalker);
21-
}
2218

19+
export class InputMetadataWalker extends Ng2Walker {
20+
21+
visitNg2Input(property: ts.PropertyDeclaration, input: ts.Decorator, args: string[]){
22+
let className = (<any>property).parent.name.text;
23+
let memberName = (<any>property.name).text;
24+
let name = (<any>input.expression).expression.text;
25+
if (name === 'Input' && args.length!=0 && memberName != args[0]) {
26+
let failureConfig:string[] = [className, memberName, memberName];
27+
failureConfig.unshift(Rule.FAILURE_STRING);
28+
this.addFailure(
29+
this.createFailure(
30+
property.getStart(),
31+
property.getWidth(),
32+
sprintf.apply(this, failureConfig)));
33+
}
34+
}
2335
}

src/outputPropertyDirectiveRule.ts

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,35 @@
11
import * as Lint from 'tslint/lib/lint';
22
import * as ts from 'typescript';
3-
import {decoratorValidator} from './util/decoratorValidator';
4-
import {RuleBase} from "./util/rulesBase";
5-
import {ClassMetadataWalker} from "./classMetadataWalker";
3+
import {sprintf} from 'sprintf-js';
4+
import {Ng2Walker} from "./util/ng2Walker";
65

7-
const FAILURE_STRING = 'In the class "%s", the directive output property "%s" should not be renamed.' +
8-
'Please, consider the following use "@Output() %s = new EventEmitter();"';
6+
export class Rule extends Lint.Rules.AbstractRule {
97

10-
const renameOutputCondition = (name, arg, element)=> {
11-
let memberName = element.name.text;
12-
return (name === 'Output' && arg && memberName !== arg.text);
13-
};
8+
public apply(sourceFile:ts.SourceFile):Lint.RuleFailure[] {
9+
return this.applyWithWalker(
10+
new OutputMetadataWalker(sourceFile,
11+
this.getOptions()));
12+
}
1413

15-
export class Rule extends RuleBase {
14+
static FAILURE_STRING:string = 'In the class "%s", the directive output property "%s" should not be renamed.' +
15+
'Please, consider the following use "@Output() %s = new EventEmitter();"';
16+
}
1617

17-
constructor(ruleName:string, value:any, disabledIntervals:Lint.IDisabledInterval[]) {
18-
super(ruleName, value, disabledIntervals,
19-
decoratorValidator(renameOutputCondition),
20-
FAILURE_STRING, ClassMetadataWalker);
21-
}
2218

19+
export class OutputMetadataWalker extends Ng2Walker {
20+
21+
visitNg2Output(property: ts.PropertyDeclaration, output: ts.Decorator, args: string[]){
22+
let className = (<any>property).parent.name.text;
23+
let memberName = (<any>property.name).text;
24+
let name = (<any>output.expression).expression.text;
25+
if (name === 'Output' && args.length!=0 && memberName != args[0]) {
26+
let failureConfig:string[] = [className, memberName, memberName];
27+
failureConfig.unshift(Rule.FAILURE_STRING);
28+
this.addFailure(
29+
this.createFailure(
30+
property.getStart(),
31+
property.getWidth(),
32+
sprintf.apply(this, failureConfig)));
33+
}
34+
}
2335
}

src/util/decoratorValidator.ts

Lines changed: 0 additions & 18 deletions
This file was deleted.

src/util/rulesBase.ts

Lines changed: 0 additions & 32 deletions
This file was deleted.

0 commit comments

Comments
 (0)