@@ -79,27 +79,72 @@ function getNodeRange(
7979 leadingComments ?: Comment [ ] ;
8080 trailingComments ?: Comment [ ] ;
8181 } ,
82+ code : string ,
8283) : [ number , number ] {
83- let start = null ;
84- let end = null ;
84+ const loc =
85+ "range" in node
86+ ? { start : node . range ! [ 0 ] , end : node . range ! [ 1 ] }
87+ : getWithLoc ( node ) ;
88+
89+ let start = loc . start ;
90+ let end = loc . end ;
91+
92+ let openingParenCount = 0 ;
93+ let closingParenCount = 0 ;
8594 if ( node . leadingComments ) {
86- start = getWithLoc ( node . leadingComments [ 0 ] ) . start ;
95+ const commentStart = getWithLoc ( node . leadingComments [ 0 ] ) . start ;
96+ if ( commentStart < start ) {
97+ start = commentStart ;
98+
99+ // Extract the number of parentheses before the node.
100+ let leadingEnd = loc . start ;
101+ for ( let index = node . leadingComments . length - 1 ; index >= 0 ; index -- ) {
102+ const comment = node . leadingComments [ index ] ;
103+ const loc = getWithLoc ( comment ) ;
104+ for ( const c of code . slice ( loc . end , leadingEnd ) . trim ( ) ) {
105+ if ( c === "(" ) openingParenCount ++ ;
106+ }
107+ leadingEnd = loc . start ;
108+ }
109+ }
87110 }
88111 if ( node . trailingComments ) {
89- end = getWithLoc (
112+ const commentEnd = getWithLoc (
90113 node . trailingComments [ node . trailingComments . length - 1 ] ,
91114 ) . end ;
115+ if ( end < commentEnd ) {
116+ end = commentEnd ;
117+
118+ // Extract the number of parentheses after the node.
119+ let trailingStart = loc . end ;
120+ for ( const comment of node . trailingComments ) {
121+ const loc = getWithLoc ( comment ) ;
122+ for ( const c of code . slice ( trailingStart , loc . start ) . trim ( ) ) {
123+ if ( c === ")" ) closingParenCount ++ ;
124+ }
125+ trailingStart = loc . end ;
126+ }
127+ }
92128 }
93129
94- const loc =
95- "range" in node
96- ? { start : node . range ! [ 0 ] , end : node . range ! [ 1 ] }
97- : getWithLoc ( node ) ;
130+ // Adjust the range so that the parentheses match up.
131+ if ( openingParenCount < closingParenCount ) {
132+ for ( ; openingParenCount < closingParenCount && start >= 0 ; start -- ) {
133+ const c = code [ start ] . trim ( ) ;
134+ if ( c ) continue ;
135+ if ( c !== "(" ) break ;
136+ openingParenCount ++ ;
137+ }
138+ } else if ( openingParenCount > closingParenCount ) {
139+ for ( ; openingParenCount > closingParenCount && end < code . length ; end ++ ) {
140+ const c = code [ end ] . trim ( ) ;
141+ if ( c ) continue ;
142+ if ( c !== ")" ) break ;
143+ closingParenCount ++ ;
144+ }
145+ }
98146
99- return [
100- start ? Math . min ( start , loc . start ) : loc . start ,
101- end ? Math . max ( end , loc . end ) : loc . end ,
102- ] ;
147+ return [ start , end ] ;
103148}
104149
105150type StatementNodeType = `${TSESTree . Statement [ "type" ] } `;
@@ -154,7 +199,7 @@ export class ScriptLetContext {
154199 typing ?: string | null ,
155200 ...callbacks : ScriptLetCallback < E > [ ]
156201 ) : ScriptLetCallback < E > [ ] {
157- const range = getNodeRange ( expression ) ;
202+ const range = getNodeRange ( expression , this . ctx . code ) ;
158203 return this . addExpressionFromRange ( range , parent , typing , ...callbacks ) ;
159204 }
160205
@@ -221,7 +266,7 @@ export class ScriptLetContext {
221266 parent : SvelteNode ,
222267 ...callbacks : ScriptLetCallback < ObjectShorthandProperty > [ ]
223268 ) : void {
224- const range = getNodeRange ( identifier ) ;
269+ const range = getNodeRange ( identifier , this . ctx . code ) ;
225270 const part = this . ctx . code . slice ( ...range ) ;
226271 this . appendScript (
227272 `({${ part } });` ,
@@ -260,8 +305,11 @@ export class ScriptLetContext {
260305 const range =
261306 declarator . type === "VariableDeclarator"
262307 ? // As of Svelte v5-next.65, VariableDeclarator nodes do not have location information.
263- [ getNodeRange ( declarator . id ) [ 0 ] , getNodeRange ( declarator . init ! ) [ 1 ] ]
264- : getNodeRange ( declarator ) ;
308+ [
309+ getNodeRange ( declarator . id , this . ctx . code ) [ 0 ] ,
310+ getNodeRange ( declarator . init ! , this . ctx . code ) [ 1 ] ,
311+ ]
312+ : getNodeRange ( declarator , this . ctx . code ) ;
265313 const part = this . ctx . code . slice ( ...range ) ;
266314 this . appendScript (
267315 `const ${ part } ;` ,
@@ -398,7 +446,7 @@ export class ScriptLetContext {
398446 ifBlock : SvelteIfBlock ,
399447 callback : ScriptLetCallback < ESTree . Expression > ,
400448 ) : void {
401- const range = getNodeRange ( expression ) ;
449+ const range = getNodeRange ( expression , this . ctx . code ) ;
402450 const part = this . ctx . code . slice ( ...range ) ;
403451 const restore = this . appendScript (
404452 `if(${ part } ){` ,
@@ -442,8 +490,8 @@ export class ScriptLetContext {
442490 index : ESTree . Identifier | null ,
443491 ) => void ,
444492 ) : void {
445- const exprRange = getNodeRange ( expression ) ;
446- const ctxRange = context && getNodeRange ( context ) ;
493+ const exprRange = getNodeRange ( expression , this . ctx . code ) ;
494+ const ctxRange = context && getNodeRange ( context , this . ctx . code ) ;
447495 let source = "Array.from(" ;
448496 const exprOffset = source . length ;
449497 source += `${ this . ctx . code . slice ( ...exprRange ) } ).forEach((` ;
@@ -563,7 +611,7 @@ export class ScriptLetContext {
563611 callback : ( id : ESTree . Identifier , params : ESTree . Pattern [ ] ) => void ,
564612 ) : void {
565613 const scopeKind = kind || this . currentScriptScopeKind ;
566- const idRange = getNodeRange ( id ) ;
614+ const idRange = getNodeRange ( id , this . ctx . code ) ;
567615 const part = this . ctx . code . slice ( idRange [ 0 ] , closeParentIndex + 1 ) ;
568616 const restore = this . appendScript (
569617 `function ${ part } {` ,
@@ -660,7 +708,7 @@ export class ScriptLetContext {
660708 . map ( ( d ) => {
661709 return {
662710 ...d ,
663- range : getNodeRange ( d . node ) ,
711+ range : getNodeRange ( d . node , this . ctx . code ) ,
664712 } ;
665713 } )
666714 . sort ( ( a , b ) => {
0 commit comments