8
8
9
9
import { ProgramAwareRuleWalker , RuleFailure , Rules } from 'tslint' ;
10
10
import * as ts from 'typescript' ;
11
- import { bold , red , green } from 'chalk' ;
12
- import { convertSpeedFactorToDuration } from './ripple-speed-factor' ;
11
+ import { bold , red } from 'chalk' ;
12
+ import {
13
+ convertSpeedFactorToDuration ,
14
+ createSpeedFactorConvertExpression ,
15
+ } from './ripple-speed-factor' ;
16
+
17
+ /**
18
+ * Note that will be added whenever a speed factor expression has been converted to calculate
19
+ * the according duration. This note should encourage people to clean up their code by switching
20
+ * away from the speed factors to explicit durations.
21
+ */
22
+ const removeNote = `TODO: Cleanup duration calculation.` ;
13
23
14
24
/**
15
25
* Rule that walks through property assignment and switches the global `baseSpeedFactor`
@@ -19,7 +29,7 @@ import {convertSpeedFactorToDuration} from './ripple-speed-factor';
19
29
export class Rule extends Rules . TypedRule {
20
30
applyWithProgram ( sourceFile : ts . SourceFile , program : ts . Program ) : RuleFailure [ ] {
21
31
return this . applyWithWalker (
22
- new SwitchRippleSpeedFactorRule ( sourceFile , this . getOptions ( ) , program ) ) ;
32
+ new SwitchRippleSpeedFactorRule ( sourceFile , this . getOptions ( ) , program ) ) ;
23
33
}
24
34
}
25
35
@@ -53,21 +63,32 @@ export class SwitchRippleSpeedFactorRule extends ProgramAwareRuleWalker {
53
63
const propertyNameReplacement = this . createReplacement ( leftExpression . name . getStart ( ) ,
54
64
leftExpression . name . getWidth ( ) , 'animation' ) ;
55
65
66
+ // Replace the value assignment with the new animation config.
56
67
const rightExpressionReplacement = this . createReplacement ( expression . right . getStart ( ) ,
57
68
expression . right . getWidth ( ) , `{enterDuration: ${ newEnterDurationValue } }` ) ;
58
69
59
70
this . addFailureAtNode (
60
71
expression ,
61
- `Found deprecated member assignment for "${ bold ( 'MatRipple' ) } #${ red ( 'speedFactor' ) } "` ,
72
+ `Found deprecated variable assignment for "${ bold ( 'MatRipple' ) } #${ red ( 'speedFactor' ) } "` ,
62
73
[ propertyNameReplacement , rightExpressionReplacement ] ) ;
63
74
} else {
64
- // In case the speed factor is dynamically calculated or passed to the assignment, we just
65
- // print the failure and notify about the breaking change.
75
+ // Handle the right expression differently if the previous speed factor value can't
76
+ // be resolved statically. In that case, we just create a TypeScript expression that
77
+ // calculates the explicit duration based on the non-static speed factor expression.
78
+ const newExpression = createSpeedFactorConvertExpression ( expression . right . getText ( ) ) ;
79
+
80
+ // Replace the `speedFactor` property name with `animation`.
81
+ const propertyNameReplacement = this . createReplacement ( leftExpression . name . getStart ( ) ,
82
+ leftExpression . name . getWidth ( ) , 'animation' ) ;
83
+
84
+ // Replace the value assignment with the new animation config and remove todo.
85
+ const rightExpressionReplacement = this . createReplacement ( expression . right . getStart ( ) ,
86
+ expression . right . getWidth ( ) , `/** ${ removeNote } */ {enterDuration: ${ newExpression } }` ) ;
87
+
66
88
this . addFailureAtNode (
67
- expression , `Found deprecated member assignment for "${ bold ( 'MatRipple' ) } #` +
68
- `${ red ( 'speedFactor' ) } . Please manually switch from "${ red ( 'speedFactor' ) } " to ` +
69
- `"${ green ( 'animation' ) } ". Note that the animation property only accepts explicit ` +
70
- `durations in milliseconds.` ) ;
89
+ expression ,
90
+ `Found deprecated variable assignment for "${ bold ( 'MatRipple' ) } #${ red ( 'speedFactor' ) } "` ,
91
+ [ propertyNameReplacement , rightExpressionReplacement ] ) ;
71
92
}
72
93
}
73
94
}
@@ -94,29 +115,42 @@ export class SwitchRippleSpeedFactorRule extends ProgramAwareRuleWalker {
94
115
// immediately in the provider object (e.g. it can happen that someone just imports the
95
116
// config from a separate file).
96
117
97
- if ( assignment . initializer . kind === ts . SyntaxKind . NumericLiteral ) {
98
- const numericValue = parseFloat ( ( assignment . initializer as ts . NumericLiteral ) . text ) ;
118
+ const { initializer, name} = assignment ;
119
+
120
+ if ( initializer . kind === ts . SyntaxKind . NumericLiteral ) {
121
+ const numericValue = parseFloat ( ( initializer as ts . NumericLiteral ) . text ) ;
99
122
const newEnterDurationValue = convertSpeedFactorToDuration ( numericValue ) ;
100
123
101
- const keyNameReplacement = this . createReplacement ( assignment . name . getStart ( ) ,
124
+ const keyNameReplacement = this . createReplacement ( name . getStart ( ) ,
102
125
assignment . name . getWidth ( ) , `animation` ) ;
103
126
104
- const initializerReplacement = this . createReplacement ( assignment . initializer . getStart ( ) ,
105
- assignment . initializer . getWidth ( ) , `{enterDuration: ${ newEnterDurationValue } }` ) ;
127
+ const initializerReplacement = this . createReplacement ( initializer . getStart ( ) ,
128
+ initializer . getWidth ( ) , `{enterDuration: ${ newEnterDurationValue } }` ) ;
106
129
107
130
this . addFailureAtNode (
108
131
assignment ,
109
- `Found deprecated property assignment for "${ bold ( 'MAT_RIPPLE_GLOBAL_OPTIONS' ) } -> ` +
132
+ `Found deprecated property assignment for "${ bold ( 'MAT_RIPPLE_GLOBAL_OPTIONS' ) } : ` +
110
133
`${ red ( 'baseSpeedFactor' ) } "` ,
111
134
[ keyNameReplacement , initializerReplacement ] ) ;
112
135
} else {
113
- // In case the base speed factor is dynamically calculated and inside of an Angular provider,
114
- // we just print the failure and notify about the breaking change.
136
+ // Handle the right expression differently if the previous speed factor value can't
137
+ // be resolved statically. In that case, we just create a TypeScript expression that
138
+ // calculates the explicit duration based on the non-static speed factor expression.
139
+ const newExpression = createSpeedFactorConvertExpression ( initializer . getText ( ) ) ;
140
+
141
+ // Replace the `baseSpeedFactor` property name with `animation`.
142
+ const propertyNameReplacement = this . createReplacement ( name . getStart ( ) ,
143
+ name . getWidth ( ) , 'animation' ) ;
144
+
145
+ // Replace the value assignment with the new animation config and remove todo.
146
+ const rightExpressionReplacement = this . createReplacement ( initializer . getStart ( ) ,
147
+ initializer . getWidth ( ) , `/** ${ removeNote } */ {enterDuration: ${ newExpression } }` ) ;
148
+
115
149
this . addFailureAtNode (
116
- assignment , `Found a deprecated property assignment for ` +
117
- `"${ bold ( 'MAT_RIPPLE_GLOBAL_OPTIONS' ) } -> ${ red ( 'speedFactor' ) } . Please manually switch ` +
118
- `from " ${ red ( 'baseSpeedFactor' ) } " to " ${ green ( 'animation' ) } ". Note that the animation ` +
119
- `property only accepts explicit durations in milliseconds.` ) ;
150
+ assignment ,
151
+ `Found a deprecated property assignment for "${ bold ( 'MAT_RIPPLE_GLOBAL_OPTIONS' ) } : ` +
152
+ `${ red ( 'baseSpeedFactor' ) } .` ,
153
+ [ propertyNameReplacement , rightExpressionReplacement ] ) ;
120
154
}
121
155
}
122
156
}
0 commit comments