1
- import { walk } from 'estree-walker' ;
1
+ import { BaseNode , walk } from 'estree-walker' ;
2
2
import { EOL } from 'os' ;
3
3
// @ts -ignore
4
4
import { TemplateNode } from 'svelte/types/compiler/interfaces' ;
@@ -25,6 +25,8 @@ import ts from 'typescript';
25
25
// but the AST returned by svelte/compiler does. Type as any as a workaround.
26
26
type Node = any ;
27
27
28
+ type Ast = Awaited < ReturnType < SvelteDocument [ 'getCompiled' ] > > [ 'ast' ] ;
29
+
28
30
/**
29
31
* Get applicable quick fixes.
30
32
*/
@@ -41,7 +43,6 @@ export async function getQuickfixActions(
41
43
const transpiled = await svelteDoc . getTranspiled ( ) ;
42
44
const content = transpiled . getText ( ) ;
43
45
const lineOffsets = getLineOffsets ( content ) ;
44
- const { html } = ast ;
45
46
46
47
const codeActions : CodeAction [ ] = [ ] ;
47
48
@@ -52,7 +53,7 @@ export async function getQuickfixActions(
52
53
transpiled ,
53
54
content ,
54
55
lineOffsets ,
55
- html ,
56
+ ast ,
56
57
diagnostic
57
58
) )
58
59
) ;
@@ -66,7 +67,7 @@ async function createQuickfixActions(
66
67
transpiled : ITranspiledSvelteDocument ,
67
68
content : string ,
68
69
lineOffsets : number [ ] ,
69
- html : TemplateNode ,
70
+ ast : Ast ,
70
71
diagnostic : Diagnostic
71
72
) : Promise < CodeAction [ ] > {
72
73
const {
@@ -80,7 +81,21 @@ async function createQuickfixActions(
80
81
pos : diagnosticStartOffset ,
81
82
end : diagnosticEndOffset
82
83
} ;
83
- const node = findTagForRange ( html , offsetRange ) ;
84
+ const { html, instance, module } = ast ;
85
+ const tree = [ html , instance , module ] . find ( ( part ) => {
86
+ return (
87
+ part ?. start != null &&
88
+ offsetRange . pos >= part . start &&
89
+ part ?. end != null &&
90
+ offsetRange . pos <= part . end &&
91
+ part ?. end != null &&
92
+ offsetRange . end <= part . end &&
93
+ part ?. start != null &&
94
+ offsetRange . end >= part . start
95
+ ) ;
96
+ } ) ;
97
+
98
+ const node = findTagForRange ( tree ! , offsetRange , tree === html ) ;
84
99
85
100
const codeActions : CodeAction [ ] = [ ] ;
86
101
@@ -103,7 +118,8 @@ async function createQuickfixActions(
103
118
content ,
104
119
lineOffsets ,
105
120
node ,
106
- diagnostic
121
+ diagnostic ,
122
+ tree === html
107
123
)
108
124
) ;
109
125
@@ -146,14 +162,15 @@ function createSvelteIgnoreQuickfixAction(
146
162
content : string ,
147
163
lineOffsets : number [ ] ,
148
164
node : Node ,
149
- diagnostic : Diagnostic
165
+ diagnostic : Diagnostic ,
166
+ isHtml : boolean
150
167
) : CodeAction {
151
168
return CodeAction . create (
152
169
getCodeActionTitle ( diagnostic ) ,
153
170
{
154
171
documentChanges : [
155
172
TextDocumentEdit . create ( textDocument , [
156
- getSvelteIgnoreEdit ( transpiled , content , lineOffsets , node , diagnostic )
173
+ getSvelteIgnoreEdit ( transpiled , content , lineOffsets , node , diagnostic , isHtml )
157
174
] )
158
175
]
159
176
} ,
@@ -190,7 +207,8 @@ function getSvelteIgnoreEdit(
190
207
content : string ,
191
208
lineOffsets : number [ ] ,
192
209
node : Node ,
193
- diagnostic : Diagnostic
210
+ diagnostic : Diagnostic ,
211
+ isHtml : boolean
194
212
) {
195
213
const { code } = diagnostic ;
196
214
@@ -207,26 +225,31 @@ function getSvelteIgnoreEdit(
207
225
const indent = getIndent ( afterStartLineStart ) ;
208
226
209
227
// TODO: Make all code action's new line consistent
210
- const ignore = `${ indent } <!-- svelte-ignore ${ code } -->${ EOL } ` ;
228
+ let ignore = `${ indent } // svelte-ignore ${ code } ${ EOL } ${ indent } ` ;
229
+ if ( isHtml ) {
230
+ ignore = `${ indent } <!-- svelte-ignore ${ code } -->${ EOL } ` ;
231
+ }
211
232
const position = Position . create ( nodeStartPosition . line , 0 ) ;
212
233
213
234
return mapObjWithRangeToOriginal ( transpiled , TextEdit . insert ( position , ignore ) ) ;
214
235
}
215
236
216
237
const elementOrComponent = [ 'Component' , 'Element' , 'InlineComponent' ] ;
217
238
218
- function findTagForRange ( html : Node , range : ts . TextRange ) {
219
- let nearest = html ;
239
+ function findTagForRange ( ast : BaseNode , range : ts . TextRange , isHtml : boolean ) {
240
+ let nearest : BaseNode = ast ;
220
241
221
- walk ( html , {
242
+ walk ( ast , {
222
243
enter ( node , parent ) {
223
- const { type } = node ;
224
- const isBlock = 'block' in node || node . type . toLowerCase ( ) . includes ( 'block' ) ;
225
- const isFragment = type === 'Fragment' ;
226
- const keepLooking = isFragment || elementOrComponent . includes ( type ) || isBlock ;
227
- if ( ! keepLooking ) {
228
- this . skip ( ) ;
229
- return ;
244
+ if ( isHtml ) {
245
+ const { type } = node ;
246
+ const isBlock = 'block' in node || node . type . toLowerCase ( ) . includes ( 'block' ) ;
247
+ const isFragment = type === 'Fragment' ;
248
+ const keepLooking = isFragment || elementOrComponent . includes ( type ) || isBlock ;
249
+ if ( ! keepLooking ) {
250
+ this . skip ( ) ;
251
+ return ;
252
+ }
230
253
}
231
254
232
255
if ( within ( node , range ) && parent === nearest ) {
0 commit comments