@@ -171,59 +171,102 @@ func (ctx *parseContext) mapFile(file *ast.File, sourcePath string) *tree.Compil
171171 }
172172}
173173
174- // mapImports maps the import declarations in the file.
174+ // mapImports maps all import declarations in the file into a single Container.
175+ // Go allows multiple import blocks; subsequent blocks are tracked via ImportBlock markers.
175176func (ctx * parseContext ) mapImports (file * ast.File ) * tree.Container [* tree.Import ] {
176- var importDecl * ast.GenDecl
177+ // Collect all import GenDecls in order.
178+ var importDecls []* ast.GenDecl
177179 for _ , decl := range file .Decls {
178180 if gd , ok := decl .(* ast.GenDecl ); ok && gd .Tok == token .IMPORT {
179- importDecl = gd
180- break
181+ importDecls = append (importDecls , gd )
181182 }
182183 }
183- if importDecl == nil {
184+ if len ( importDecls ) == 0 {
184185 return nil
185186 }
186187
187- before := ctx .prefixAndSkip (importDecl .Pos (), len ("import" ))
188-
189188 var elements []tree.RightPadded [* tree.Import ]
190-
191189 var containerMarkers tree.Markers
192- if importDecl .Lparen .IsValid () {
193- openParenPrefix := ctx .prefix (importDecl .Lparen )
194- ctx .skip (1 ) // skip "("
190+ prevGrouped := false
195191
192+ // First import block: captured into Container.Before and Container.Markers
193+ first := importDecls [0 ]
194+ before := ctx .prefixAndSkip (first .Pos (), len ("import" ))
195+
196+ if first .Lparen .IsValid () {
197+ prevGrouped = true
198+ openParenPrefix := ctx .prefix (first .Lparen )
199+ ctx .skip (1 ) // skip "("
196200 containerMarkers = tree.Markers {
197201 ID : uuid .New (),
198202 Entries : []tree.Marker {
199203 tree.GroupedImport {Ident : uuid .New (), Before : openParenPrefix },
200204 },
201205 }
206+ }
202207
203- for _ , spec := range importDecl .Specs {
204- is := spec .(* ast.ImportSpec )
205- imp := ctx .mapImportSpec (is )
206- elements = append (elements , tree.RightPadded [* tree.Import ]{Element : imp })
207- }
208+ for _ , spec := range first .Specs {
209+ is := spec .(* ast.ImportSpec )
210+ imp := ctx .mapImportSpec (is )
211+ elements = append (elements , tree.RightPadded [* tree.Import ]{Element : imp })
212+ }
208213
209- closeParen := ctx .prefix (importDecl .Rparen )
214+ if first .Lparen .IsValid () {
215+ closeParen := ctx .prefix (first .Rparen )
210216 ctx .skip (1 ) // skip ")"
211-
212217 if len (elements ) > 0 {
213218 elements [len (elements )- 1 ].After = closeParen
214219 }
215- } else {
216- for _ , spec := range importDecl .Specs {
217- is := spec .(* ast.ImportSpec )
218- imp := ctx .mapImportSpec (is )
219- elements = append (elements , tree.RightPadded [* tree.Import ]{Element : imp })
220+ }
221+
222+ // Subsequent import blocks: attach ImportBlock marker to first import of each
223+ for _ , importDecl := range importDecls [1 :] {
224+ blockBefore := ctx .prefixAndSkip (importDecl .Pos (), len ("import" ))
225+ grouped := importDecl .Lparen .IsValid ()
226+ var groupedBefore tree.Space
227+ if grouped {
228+ groupedBefore = ctx .prefix (importDecl .Lparen )
229+ ctx .skip (1 ) // skip "("
220230 }
231+
232+ ctx .mapImportBlockSpecs (importDecl , & elements , tree.ImportBlock {
233+ Ident : uuid .New (),
234+ ClosePrevious : prevGrouped ,
235+ Before : blockBefore ,
236+ Grouped : grouped ,
237+ GroupedBefore : groupedBefore ,
238+ })
239+
240+ if grouped {
241+ closeParen := ctx .prefix (importDecl .Rparen )
242+ ctx .skip (1 ) // skip ")"
243+ if len (elements ) > 0 {
244+ elements [len (elements )- 1 ].After = closeParen
245+ }
246+ }
247+ prevGrouped = grouped
221248 }
222249
223250 container := tree.Container [* tree.Import ]{Before : before , Elements : elements , Markers : containerMarkers }
224251 return & container
225252}
226253
254+ // mapImportBlockSpecs maps the specs of a subsequent import block, attaching
255+ // the ImportBlock marker to the first spec's Import node.
256+ func (ctx * parseContext ) mapImportBlockSpecs (decl * ast.GenDecl , elements * []tree.RightPadded [* tree.Import ], marker tree.ImportBlock ) {
257+ for j , spec := range decl .Specs {
258+ is := spec .(* ast.ImportSpec )
259+ imp := ctx .mapImportSpec (is )
260+ if j == 0 {
261+ imp .Markers = tree.Markers {
262+ ID : uuid .New (),
263+ Entries : []tree.Marker {marker },
264+ }
265+ }
266+ * elements = append (* elements , tree.RightPadded [* tree.Import ]{Element : imp })
267+ }
268+ }
269+
227270// mapImportSpec maps a single import spec.
228271func (ctx * parseContext ) mapImportSpec (spec * ast.ImportSpec ) * tree.Import {
229272 prefix := ctx .prefix (spec .Pos ())
@@ -1761,8 +1804,8 @@ func (ctx *parseContext) mapArrayType(expr *ast.ArrayType) tree.Expression {
17611804 length = ctx .mapExpr (expr .Len )
17621805 }
17631806
1764- closePrefix := ctx .prefix (expr .Lbrack + token .Pos (ctx .findNextFrom ('[' , ctx .file .Offset (expr .Lbrack )) - ctx .file .Offset (expr .Lbrack )))
17651807 // Find the `]`
1808+ var closePrefix tree.Space
17661809 rbrackOff := ctx .findNext (']' )
17671810 if rbrackOff >= 0 {
17681811 closePrefix = ctx .prefix (ctx .file .Pos (rbrackOff ))
0 commit comments