@@ -25,11 +25,23 @@ import {GeneratedSource} from '../HIR';
25
25
* The enable comment can be missing in the case where only a disable block is present, ie the rest
26
26
* of the file has potential React violations.
27
27
*/
28
- export type SuppressionRange = {
29
- disableComment : t . Comment ;
30
- enableComment : t . Comment | null ;
31
- source : SuppressionSource ;
32
- } ;
28
+ export type SuppressionRange =
29
+ | {
30
+ kind : 'single-line' ;
31
+ source : SuppressionSource ;
32
+ comment : t . Comment ;
33
+ }
34
+ | {
35
+ kind : 'multi-line' ;
36
+ source : SuppressionSource ;
37
+ disableComment : t . Comment ;
38
+ enableComment : t . Comment | null ;
39
+ } ;
40
+
41
+ export type SingleLineSuppressionRange = Extract <
42
+ SuppressionRange ,
43
+ { kind : 'single-line' }
44
+ > ;
33
45
34
46
type SuppressionSource = 'Eslint' | 'Flow' ;
35
47
@@ -38,38 +50,44 @@ type SuppressionSource = 'Eslint' | 'Flow';
38
50
* 1. The suppression is within the function's body; or
39
51
* 2. The suppression wraps the function
40
52
*/
41
- export function filterSuppressionsThatAffectFunction (
42
- suppressionRanges : Array < SuppressionRange > ,
43
- fn : NodePath < t . Function > ,
44
- ) : Array < SuppressionRange > {
45
- const suppressionsInScope : Array < SuppressionRange > = [ ] ;
46
- const fnNode = fn . node ;
53
+ export function filterSuppressionsThatAffectNode < T extends SuppressionRange > (
54
+ suppressionRanges : Array < T > ,
55
+ node : NodePath ,
56
+ ) : Array < T > {
57
+ const suppressionsInScope : Array < T > = [ ] ;
58
+ const fnNode = node . node ;
47
59
for ( const suppressionRange of suppressionRanges ) {
60
+ const enableComment =
61
+ suppressionRange . kind === 'single-line'
62
+ ? suppressionRange . comment
63
+ : suppressionRange . enableComment ;
64
+ const disableComment =
65
+ suppressionRange . kind === 'single-line'
66
+ ? suppressionRange . comment
67
+ : suppressionRange . disableComment ;
48
68
if (
49
- suppressionRange . disableComment . start == null ||
69
+ disableComment . start == null ||
50
70
fnNode . start == null ||
51
71
fnNode . end == null
52
72
) {
53
73
continue ;
54
74
}
55
75
// The suppression is within the function
56
76
if (
57
- suppressionRange . disableComment . start > fnNode . start &&
77
+ disableComment . start > fnNode . start &&
58
78
// If there is no matching enable, the rest of the file has potential violations
59
- ( suppressionRange . enableComment === null ||
60
- ( suppressionRange . enableComment . end != null &&
61
- suppressionRange . enableComment . end < fnNode . end ) )
79
+ ( enableComment === null ||
80
+ ( enableComment . end != null && enableComment . end < fnNode . end ) )
62
81
) {
63
82
suppressionsInScope . push ( suppressionRange ) ;
64
83
}
65
84
66
85
// The suppression wraps the function
67
86
if (
68
- suppressionRange . disableComment . start < fnNode . start &&
87
+ disableComment . start < fnNode . start &&
69
88
// If there is no matching enable, the rest of the file has potential violations
70
- ( suppressionRange . enableComment === null ||
71
- ( suppressionRange . enableComment . end != null &&
72
- suppressionRange . enableComment . end > fnNode . end ) )
89
+ ( enableComment === null ||
90
+ ( enableComment . end != null && enableComment . end > fnNode . end ) )
73
91
) {
74
92
suppressionsInScope . push ( suppressionRange ) ;
75
93
}
@@ -83,9 +101,7 @@ export function findProgramSuppressions(
83
101
flowSuppressions : boolean ,
84
102
) : Array < SuppressionRange > {
85
103
const suppressionRanges : Array < SuppressionRange > = [ ] ;
86
- let disableComment : t . Comment | null = null ;
87
- let enableComment : t . Comment | null = null ;
88
- let source : SuppressionSource | null = null ;
104
+ let suppression : SuppressionRange | null = null ;
89
105
90
106
const rulePattern = `(${ ruleNames . join ( '|' ) } )` ;
91
107
const disableNextLinePattern = new RegExp (
@@ -107,42 +123,49 @@ export function findProgramSuppressions(
107
123
* If we're already within a CommentBlock, we should not restart the range prematurely for a
108
124
* CommentLine within the block.
109
125
*/
110
- disableComment == null &&
126
+ suppression == null &&
111
127
disableNextLinePattern . test ( comment . value )
112
128
) {
113
- disableComment = comment ;
114
- enableComment = comment ;
115
- source = 'Eslint' ;
129
+ suppression = {
130
+ kind : 'single-line' ,
131
+ comment,
132
+ source : 'Eslint' ,
133
+ } ;
116
134
}
117
135
118
136
if (
119
137
flowSuppressions &&
120
- disableComment == null &&
138
+ suppression == null &&
121
139
flowSuppressionPattern . test ( comment . value )
122
140
) {
123
- disableComment = comment ;
124
- enableComment = comment ;
125
- source = 'Flow' ;
141
+ suppression = {
142
+ kind : 'single-line' ,
143
+ comment,
144
+ source : 'Flow' ,
145
+ } ;
126
146
}
127
147
128
148
if ( disablePattern . test ( comment . value ) ) {
129
- disableComment = comment ;
130
- source = 'Eslint' ;
149
+ suppression = {
150
+ kind : 'multi-line' ,
151
+ disableComment : comment ,
152
+ enableComment : null ,
153
+ source : 'Eslint' ,
154
+ } ;
131
155
}
132
156
133
- if ( enablePattern . test ( comment . value ) && source === 'Eslint' ) {
134
- enableComment = comment ;
157
+ if (
158
+ enablePattern . test ( comment . value ) &&
159
+ suppression != null &&
160
+ suppression . kind === 'multi-line' &&
161
+ suppression . source === 'Eslint'
162
+ ) {
163
+ suppression . enableComment = comment ;
135
164
}
136
165
137
- if ( disableComment != null && source != null ) {
138
- suppressionRanges . push ( {
139
- disableComment : disableComment ,
140
- enableComment : enableComment ,
141
- source,
142
- } ) ;
143
- disableComment = null ;
144
- enableComment = null ;
145
- source = null ;
166
+ if ( suppression != null ) {
167
+ suppressionRanges . push ( suppression ) ;
168
+ suppression = null ;
146
169
}
147
170
}
148
171
return suppressionRanges ;
@@ -157,10 +180,11 @@ export function suppressionsToCompilerError(
157
180
} ) ;
158
181
const error = new CompilerError ( ) ;
159
182
for ( const suppressionRange of suppressionRanges ) {
160
- if (
161
- suppressionRange . disableComment . start == null ||
162
- suppressionRange . disableComment . end == null
163
- ) {
183
+ const disableComment =
184
+ suppressionRange . kind === 'single-line'
185
+ ? suppressionRange . comment
186
+ : suppressionRange . disableComment ;
187
+ if ( disableComment . start == null || disableComment . end == null ) {
164
188
continue ;
165
189
}
166
190
let reason , suggestion ;
@@ -185,22 +209,19 @@ export function suppressionsToCompilerError(
185
209
error . pushDiagnostic (
186
210
CompilerDiagnostic . create ( {
187
211
reason : reason ,
188
- description : `React Compiler only works when your components follow all the rules of React, disabling them may result in unexpected or incorrect behavior. Found suppression \`${ suppressionRange . disableComment . value . trim ( ) } \`` ,
212
+ description : `React Compiler only works when your components follow all the rules of React, disabling them may result in unexpected or incorrect behavior. Found suppression \`${ disableComment . value . trim ( ) } \`` ,
189
213
severity : ErrorSeverity . InvalidReact ,
190
214
category : ErrorCategory . Suppression ,
191
215
suggestions : [
192
216
{
193
217
description : suggestion ,
194
- range : [
195
- suppressionRange . disableComment . start ,
196
- suppressionRange . disableComment . end ,
197
- ] ,
218
+ range : [ disableComment . start , disableComment . end ] ,
198
219
op : CompilerSuggestionOperation . Remove ,
199
220
} ,
200
221
] ,
201
222
} ) . withDetail ( {
202
223
kind : 'error' ,
203
- loc : suppressionRange . disableComment . loc ?? null ,
224
+ loc : disableComment . loc ?? null ,
204
225
message : 'Found React rule suppression' ,
205
226
} ) ,
206
227
) ;
0 commit comments