@@ -9,12 +9,209 @@ const schema = [
99 } ,
1010] ;
1111
12+ function isNeverOption ( context ) {
13+ return ( context . options [ 0 ] || 'never' ) === 'never' ;
14+ }
15+
16+ function isWhitespaceCRLF ( whitespace ) {
17+ return whitespace !== '\n' && whitespace !== '\r' ;
18+ }
19+
20+ function spacesOutside ( node , context ) {
21+ const { callee, typeArguments } = node ;
22+ if ( typeArguments == null ) {
23+ return ;
24+ }
25+
26+ const sourceCode = context . getSourceCode ( ) ;
27+ const { name } = callee ;
28+ const never = isNeverOption ( context ) ;
29+ const parentheses = sourceCode . getTokenAfter ( typeArguments ) ;
30+
31+ const spacesBefore = typeArguments . range [ 0 ] - callee . range [ 1 ] ;
32+ const spacesAfter = parentheses . range [ 0 ] - typeArguments . range [ 1 ] ;
33+
34+ if ( never ) {
35+ if ( spacesBefore ) {
36+ const whiteSpaceBefore = sourceCode . text [ typeArguments . range [ 0 ] ] ;
37+
38+ if ( isWhitespaceCRLF ( whiteSpaceBefore ) ) {
39+ context . report ( {
40+ data : { name } ,
41+ fix : spacingFixers . stripSpacesBefore ( typeArguments , spacesBefore ) ,
42+ message : 'There must be no space before "{{name}}" type annotation' ,
43+ node,
44+ } ) ;
45+ }
46+ }
47+
48+ if ( spacesAfter ) {
49+ const whiteSpaceAfter = sourceCode . text [ typeArguments . range [ 1 ] - 1 ] ;
50+
51+ if ( isWhitespaceCRLF ( whiteSpaceAfter ) ) {
52+ context . report ( {
53+ data : { name } ,
54+ fix : spacingFixers . stripSpacesAfter ( typeArguments , spacesAfter ) ,
55+ message : 'There must be no space after "{{name}}" type annotation' ,
56+ node,
57+ } ) ;
58+ }
59+ }
60+
61+ return ;
62+ }
63+
64+ if ( ! never ) {
65+ if ( spacesBefore > 1 ) {
66+ context . report ( {
67+ data : { name } ,
68+ fix : spacingFixers . stripSpacesBefore ( typeArguments , spacesBefore - 1 ) ,
69+ message : 'There must be one space before "{{name}}" generic type annotation bracket' ,
70+ node,
71+ } ) ;
72+ }
73+
74+ if ( spacesBefore === 0 ) {
75+ context . report ( {
76+ data : { name } ,
77+ fix : spacingFixers . addSpaceBefore ( typeArguments ) ,
78+ message : 'There must be a space before "{{name}}" generic type annotation bracket' ,
79+ node,
80+ } ) ;
81+ }
82+
83+ if ( spacesAfter > 1 ) {
84+ context . report ( {
85+ data : { name } ,
86+ fix : spacingFixers . stripSpacesAfter ( typeArguments , spacesAfter ) ,
87+ message : 'There must be one space before "{{name}}" generic type annotation bracket' ,
88+ node,
89+ } ) ;
90+ }
91+
92+ if ( spacesAfter === 0 ) {
93+ context . report ( {
94+ data : { name } ,
95+ fix : spacingFixers . addSpaceAfter ( typeArguments ) ,
96+ message : 'There must be a space before "{{name}}" generic type annotation bracket' ,
97+ node,
98+ } ) ;
99+ }
100+ }
101+ }
102+
103+ function spacesInside ( node , context ) {
104+ const { callee, typeArguments } = node ;
105+ if ( typeArguments == null ) {
106+ return ;
107+ }
108+
109+ const sourceCode = context . getSourceCode ( ) ;
110+ const { name } = callee ;
111+ const never = isNeverOption ( context ) ;
112+ const isNullable = typeArguments . params [ 0 ] . type === 'NullableTypeAnnotation' ;
113+ const [
114+ opener ,
115+ firstInnerToken ,
116+ secondInnerToken ,
117+ ] = sourceCode . getFirstTokens ( typeArguments , 3 ) ;
118+ const [
119+ lastInnerToken ,
120+ closer ,
121+ ] = sourceCode . getLastTokens ( typeArguments , 2 ) ;
122+
123+ const spacesBefore = firstInnerToken . range [ 0 ] - opener . range [ 1 ] ;
124+ const spaceBetweenNullToken = secondInnerToken . range [ 0 ] - firstInnerToken . range [ 1 ] ;
125+ const spacesAfter = closer . range [ 0 ] - lastInnerToken . range [ 1 ] ;
126+
127+ if ( never ) {
128+ if ( spacesBefore ) {
129+ const whiteSpaceBefore = sourceCode . text [ opener . range [ 1 ] ] ;
130+
131+ if ( whiteSpaceBefore !== '\n' && whiteSpaceBefore !== '\r' ) {
132+ context . report ( {
133+ data : { name } ,
134+ fix : spacingFixers . stripSpacesAfter ( opener , spacesBefore ) ,
135+ message : 'There must be no spaces inside at the start of "{{name}}" type annotation' ,
136+ node,
137+ } ) ;
138+ }
139+ }
140+
141+ if ( isNullable && spaceBetweenNullToken ) {
142+ context . report ( {
143+ data : { name } ,
144+ fix : spacingFixers . stripSpacesAfter ( firstInnerToken , spaceBetweenNullToken ) ,
145+ message : 'There must be no spaces inside "{{name}}" type annotation' ,
146+ node,
147+ } ) ;
148+ }
149+
150+ if ( spacesAfter ) {
151+ const whiteSpaceAfter = sourceCode . text [ closer . range [ 0 ] - 1 ] ;
152+
153+ if ( isWhitespaceCRLF ( whiteSpaceAfter ) ) {
154+ context . report ( {
155+ data : { name } ,
156+ fix : spacingFixers . stripSpacesAfter ( lastInnerToken , spacesAfter ) ,
157+ message : 'There must be no spaces inside at the end of "{{name}}" type annotation' ,
158+ node,
159+ } ) ;
160+ }
161+ }
162+
163+ return ;
164+ }
165+
166+ if ( ! never ) {
167+ if ( spacesBefore > 1 ) {
168+ context . report ( {
169+ data : { name } ,
170+ fix : spacingFixers . stripSpacesBefore ( opener , spacesBefore - 1 ) ,
171+ message : 'There must be one space before "{{name}}" generic type annotation bracket' ,
172+ node,
173+ } ) ;
174+ }
175+
176+ if ( spacesBefore === 0 ) {
177+ context . report ( {
178+ data : { name } ,
179+ fix : spacingFixers . addSpaceBefore ( opener ) ,
180+ message : 'There must be a space before "{{name}}" generic type annotation bracket' ,
181+ node,
182+ } ) ;
183+ }
184+
185+ if ( spacesAfter > 1 ) {
186+ context . report ( {
187+ data : { name } ,
188+ fix : spacingFixers . stripSpacesAfter ( closer , spacesAfter ) ,
189+ message : 'There must be one space before "{{name}}" generic type annotation bracket' ,
190+ node,
191+ } ) ;
192+ }
193+
194+ if ( spacesAfter === 0 ) {
195+ context . report ( {
196+ data : { name } ,
197+ fix : spacingFixers . addSpaceAfter ( closer ) ,
198+ message : 'There must be a space before "{{name}}" generic type annotation bracket' ,
199+ node,
200+ } ) ;
201+ }
202+ }
203+ }
204+
12205const create = ( context ) => {
13206 const sourceCode = context . getSourceCode ( ) ;
14207
15208 const never = ( context . options [ 0 ] || 'never' ) === 'never' ;
16209
17210 return {
211+ CallExpression ( node ) {
212+ spacesOutside ( node , context ) ;
213+ spacesInside ( node , context ) ;
214+ } ,
18215 GenericTypeAnnotation ( node ) {
19216 const types = node . typeParameters ;
20217
0 commit comments