1- import { walk } from 'estree-walker' ;
1+ import { BaseNode , walk } from 'estree-walker' ;
22import { EOL } from 'os' ;
33// @ts -ignore
44import { TemplateNode } from 'svelte/types/compiler/interfaces' ;
@@ -25,6 +25,8 @@ import ts from 'typescript';
2525// but the AST returned by svelte/compiler does. Type as any as a workaround.
2626type Node = any ;
2727
28+ type Ast = Awaited < ReturnType < SvelteDocument [ 'getCompiled' ] > > [ 'ast' ] ;
29+
2830/**
2931 * Get applicable quick fixes.
3032 */
@@ -41,7 +43,6 @@ export async function getQuickfixActions(
4143 const transpiled = await svelteDoc . getTranspiled ( ) ;
4244 const content = transpiled . getText ( ) ;
4345 const lineOffsets = getLineOffsets ( content ) ;
44- const { html } = ast ;
4546
4647 const codeActions : CodeAction [ ] = [ ] ;
4748
@@ -52,7 +53,7 @@ export async function getQuickfixActions(
5253 transpiled ,
5354 content ,
5455 lineOffsets ,
55- html ,
56+ ast ,
5657 diagnostic
5758 ) )
5859 ) ;
@@ -66,7 +67,7 @@ async function createQuickfixActions(
6667 transpiled : ITranspiledSvelteDocument ,
6768 content : string ,
6869 lineOffsets : number [ ] ,
69- html : TemplateNode ,
70+ ast : Ast ,
7071 diagnostic : Diagnostic
7172) : Promise < CodeAction [ ] > {
7273 const {
@@ -80,7 +81,21 @@ async function createQuickfixActions(
8081 pos : diagnosticStartOffset ,
8182 end : diagnosticEndOffset
8283 } ;
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 ) ;
8499
85100 const codeActions : CodeAction [ ] = [ ] ;
86101
@@ -103,7 +118,8 @@ async function createQuickfixActions(
103118 content ,
104119 lineOffsets ,
105120 node ,
106- diagnostic
121+ diagnostic ,
122+ tree === html
107123 )
108124 ) ;
109125
@@ -146,14 +162,15 @@ function createSvelteIgnoreQuickfixAction(
146162 content : string ,
147163 lineOffsets : number [ ] ,
148164 node : Node ,
149- diagnostic : Diagnostic
165+ diagnostic : Diagnostic ,
166+ isHtml : boolean
150167) : CodeAction {
151168 return CodeAction . create (
152169 getCodeActionTitle ( diagnostic ) ,
153170 {
154171 documentChanges : [
155172 TextDocumentEdit . create ( textDocument , [
156- getSvelteIgnoreEdit ( transpiled , content , lineOffsets , node , diagnostic )
173+ getSvelteIgnoreEdit ( transpiled , content , lineOffsets , node , diagnostic , isHtml )
157174 ] )
158175 ]
159176 } ,
@@ -190,7 +207,8 @@ function getSvelteIgnoreEdit(
190207 content : string ,
191208 lineOffsets : number [ ] ,
192209 node : Node ,
193- diagnostic : Diagnostic
210+ diagnostic : Diagnostic ,
211+ isHtml : boolean
194212) {
195213 const { code } = diagnostic ;
196214
@@ -207,26 +225,31 @@ function getSvelteIgnoreEdit(
207225 const indent = getIndent ( afterStartLineStart ) ;
208226
209227 // 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+ }
211232 const position = Position . create ( nodeStartPosition . line , 0 ) ;
212233
213234 return mapObjWithRangeToOriginal ( transpiled , TextEdit . insert ( position , ignore ) ) ;
214235}
215236
216237const elementOrComponent = [ 'Component' , 'Element' , 'InlineComponent' ] ;
217238
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 ;
220241
221- walk ( html , {
242+ walk ( ast , {
222243 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+ }
230253 }
231254
232255 if ( within ( node , range ) && parent === nearest ) {
0 commit comments