@@ -79,27 +79,72 @@ function getNodeRange(
79
79
leadingComments ?: Comment [ ] ;
80
80
trailingComments ?: Comment [ ] ;
81
81
} ,
82
+ code : string ,
82
83
) : [ 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 ;
85
94
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
+ }
87
110
}
88
111
if ( node . trailingComments ) {
89
- end = getWithLoc (
112
+ const commentEnd = getWithLoc (
90
113
node . trailingComments [ node . trailingComments . length - 1 ] ,
91
114
) . 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
+ }
92
128
}
93
129
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
+ }
98
146
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 ] ;
103
148
}
104
149
105
150
type StatementNodeType = `${TSESTree . Statement [ "type" ] } `;
@@ -154,7 +199,7 @@ export class ScriptLetContext {
154
199
typing ?: string | null ,
155
200
...callbacks : ScriptLetCallback < E > [ ]
156
201
) : ScriptLetCallback < E > [ ] {
157
- const range = getNodeRange ( expression ) ;
202
+ const range = getNodeRange ( expression , this . ctx . code ) ;
158
203
return this . addExpressionFromRange ( range , parent , typing , ...callbacks ) ;
159
204
}
160
205
@@ -221,7 +266,7 @@ export class ScriptLetContext {
221
266
parent : SvelteNode ,
222
267
...callbacks : ScriptLetCallback < ObjectShorthandProperty > [ ]
223
268
) : void {
224
- const range = getNodeRange ( identifier ) ;
269
+ const range = getNodeRange ( identifier , this . ctx . code ) ;
225
270
const part = this . ctx . code . slice ( ...range ) ;
226
271
this . appendScript (
227
272
`({${ part } });` ,
@@ -260,8 +305,11 @@ export class ScriptLetContext {
260
305
const range =
261
306
declarator . type === "VariableDeclarator"
262
307
? // 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 ) ;
265
313
const part = this . ctx . code . slice ( ...range ) ;
266
314
this . appendScript (
267
315
`const ${ part } ;` ,
@@ -398,7 +446,7 @@ export class ScriptLetContext {
398
446
ifBlock : SvelteIfBlock ,
399
447
callback : ScriptLetCallback < ESTree . Expression > ,
400
448
) : void {
401
- const range = getNodeRange ( expression ) ;
449
+ const range = getNodeRange ( expression , this . ctx . code ) ;
402
450
const part = this . ctx . code . slice ( ...range ) ;
403
451
const restore = this . appendScript (
404
452
`if(${ part } ){` ,
@@ -442,8 +490,8 @@ export class ScriptLetContext {
442
490
index : ESTree . Identifier | null ,
443
491
) => void ,
444
492
) : 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 ) ;
447
495
let source = "Array.from(" ;
448
496
const exprOffset = source . length ;
449
497
source += `${ this . ctx . code . slice ( ...exprRange ) } ).forEach((` ;
@@ -563,7 +611,7 @@ export class ScriptLetContext {
563
611
callback : ( id : ESTree . Identifier , params : ESTree . Pattern [ ] ) => void ,
564
612
) : void {
565
613
const scopeKind = kind || this . currentScriptScopeKind ;
566
- const idRange = getNodeRange ( id ) ;
614
+ const idRange = getNodeRange ( id , this . ctx . code ) ;
567
615
const part = this . ctx . code . slice ( idRange [ 0 ] , closeParentIndex + 1 ) ;
568
616
const restore = this . appendScript (
569
617
`function ${ part } {` ,
@@ -660,7 +708,7 @@ export class ScriptLetContext {
660
708
. map ( ( d ) => {
661
709
return {
662
710
...d ,
663
- range : getNodeRange ( d . node ) ,
711
+ range : getNodeRange ( d . node , this . ctx . code ) ,
664
712
} ;
665
713
} )
666
714
. sort ( ( a , b ) => {
0 commit comments