-
Notifications
You must be signed in to change notification settings - Fork 232
Expand file tree
/
Copy pathpreferOnPushComponentChangeDetectionRule.ts
More file actions
56 lines (46 loc) · 2.35 KB
/
Copy pathpreferOnPushComponentChangeDetectionRule.ts
File metadata and controls
56 lines (46 loc) · 2.35 KB
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
46
47
48
49
50
51
52
53
54
55
56
import { IRuleMetadata, RuleFailure } from 'tslint/lib';
import { AbstractRule } from 'tslint/lib/rules';
import { dedent } from 'tslint/lib/utils';
import { isPropertyAccessExpression, SourceFile } from 'typescript/lib/typescript';
import { ComponentMetadata } from './angular/metadata';
import { NgWalker } from './angular/ngWalker';
import { getDecoratorPropertyInitializer } from './util/utils';
const ON_PUSH = 'OnPush';
export class Rule extends AbstractRule {
static readonly metadata: IRuleMetadata = {
description: `Enforces component's change detection to ChangeDetectionStrategy.${ON_PUSH}.`,
options: null,
optionsDescription: 'Not configurable.',
rationale: dedent`
By default Angular uses the ChangeDetectionStrategy.Default.
This strategy doesn’t assume anything about the application, therefore every time something changes in our application, as a result of various user events, timers, XHR, promises, etc., a change detection will run on all components.
By using ChangeDetectionStrategy.${ON_PUSH}, Angular will only run the change detection cycle in the following cases:
* Inputs references change.
* An event originated from the component or one of its children.
* If manually called.
`,
ruleName: 'prefer-on-push-component-change-detection',
type: 'functionality',
typescriptOnly: true,
};
static readonly FAILURE_STRING = `The changeDetection value of a component should be set to ChangeDetectionStrategy.${ON_PUSH}`;
apply(sourceFile: SourceFile): RuleFailure[] {
const walker = new Walker(sourceFile, this.getOptions());
return this.applyWithWalker(walker);
}
}
class Walker extends NgWalker {
protected visitNgComponent(metadata: ComponentMetadata): void {
this.validateComponent(metadata);
super.visitNgComponent(metadata);
}
private validateComponent(metadata: ComponentMetadata): void {
const { decorator: metadataDecorator } = metadata;
const changeDetectionExpression = getDecoratorPropertyInitializer(metadataDecorator, 'changeDetection');
if (!changeDetectionExpression) {
this.addFailureAtNode(metadataDecorator, Rule.FAILURE_STRING);
} else if (isPropertyAccessExpression(changeDetectionExpression) && changeDetectionExpression.name.text !== ON_PUSH) {
this.addFailureAtNode(changeDetectionExpression, Rule.FAILURE_STRING);
}
}
}