@@ -30,6 +30,7 @@ import Language.Haskell.GHC.ExactPrint
30
30
import Language.Haskell.GHC.ExactPrint.Types (DeltaPos (DP ), KeywordId (G ), mkAnnKey )
31
31
import Language.Haskell.LSP.Types
32
32
import OccName
33
+ import Outputable (ppr , showSDocUnsafe )
33
34
34
35
------------------------------------------------------------------------------
35
36
@@ -176,12 +177,26 @@ lastMaybe :: [a] -> Maybe a
176
177
lastMaybe [] = Nothing
177
178
lastMaybe other = Just $ last other
178
179
180
+ liftMaybe :: String -> Maybe a -> TransformT (Either String ) a
181
+ liftMaybe _ (Just x) = return x
182
+ liftMaybe s _ = lift $ Left s
183
+
184
+ -- | Copy anns attached to a into b with modification, then delete anns of a
185
+ transferAnn :: (Data a , Data b ) => Located a -> Located b -> (Annotation -> Annotation ) -> TransformT (Either String ) ()
186
+ transferAnn la lb f = do
187
+ anns <- getAnnsT
188
+ let oldKey = mkAnnKey la
189
+ newKey = mkAnnKey lb
190
+ oldValue <- liftMaybe " Unable to find ann" $ Map. lookup oldKey anns
191
+ putAnnsT $ Map. delete oldKey $ Map. insert newKey (f oldValue) anns
192
+
179
193
------------------------------------------------------------------------------
180
194
extendImport :: Maybe String -> String -> LImportDecl GhcPs -> Rewrite
181
- extendImport mparent identifier lDecl@ (L l _) = Rewrite l $ \ df -> do
182
- case mparent of
183
- Just parent -> extendImportViaParent df parent identifier lDecl
184
- _ -> extendImportTopLevel df identifier lDecl
195
+ extendImport mparent identifier lDecl@ (L l _) =
196
+ Rewrite l $ \ df -> do
197
+ case mparent of
198
+ Just parent -> extendImportViaParent df parent identifier lDecl
199
+ _ -> extendImportTopLevel df identifier lDecl
185
200
186
201
-- | Add an identifier to import list
187
202
--
@@ -201,7 +216,11 @@ extendImportTopLevel df idnetifier (L l it@ImportDecl {..})
201
216
when hasSibling $
202
217
addTrailingCommaT (last lies)
203
218
addSimpleAnnT x (DP (0 , if hasSibling then 1 else 0 )) []
204
- addSimpleAnnT rdr dp00 [(G AnnVal , dp00)]
219
+ addSimpleAnnT rdr dp00 $ unqalDP $ hasParen idnetifier
220
+ -- Parens are attachted to `lies`, so if `lies` was empty previously,
221
+ -- we need change the ann key from `[]` to `:` to keep parens and other anns.
222
+ unless hasSibling $
223
+ transferAnn (L l' lies) (L l' [x]) id
205
224
return $ L l it {ideclHiding = Just (hide, L l' $ lies ++ [x])}
206
225
extendImportTopLevel _ _ _ = lift $ Left " Unable to extend the import list"
207
226
@@ -219,21 +238,18 @@ extendImportViaParent df parent child (L l it@ImportDecl {..})
219
238
where
220
239
go :: Bool -> SrcSpan -> [LIE GhcPs ] -> [LIE GhcPs ] -> TransformT (Either String ) (LImportDecl GhcPs )
221
240
go hide l' pre (lAbs@ (L ll' (IEThingAbs _ absIE@ (L _ ie))) : xs)
222
- -- ThingAbs => ThingWith ie child
241
+ -- ThingAbs ie => ThingWith ie child
223
242
| parent == unIEWrappedName ie = do
224
243
srcChild <- uniqueSrcSpanT
225
244
childRdr <- liftParseAST df child
226
245
let childLIE = L srcChild $ IEName childRdr
227
246
x :: LIE GhcPs = L ll' $ IEThingWith noExtField absIE NoIEWildcard [childLIE] []
228
- modifyAnnsT $ \ anns ->
229
- let oldKey = mkAnnKey lAbs
230
- oldValue = anns Map. ! oldKey
231
- newKey = mkAnnKey x
232
- in Map. insert newKey oldValue {annsDP = annsDP oldValue ++ [(G AnnOpenP , DP (0 , 1 )), (G AnnCloseP , dp00)]} $ Map. delete oldKey anns
247
+ -- take anns from ThingAbs, and attatch parens to it
248
+ transferAnn lAbs x $ \ old -> old {annsDP = annsDP old ++ [(G AnnOpenP , DP (0 , 1 )), (G AnnCloseP , dp00)]}
233
249
addSimpleAnnT childRdr dp00 [(G AnnVal , dp00)]
234
250
return $ L l it {ideclHiding = Just (hide, L l' $ reverse pre ++ [x] ++ xs)}
235
251
go hide l' pre ((L l'' (IEThingWith _ twIE@ (L _ ie) _ lies' _)) : xs)
236
- -- ThingWith ie => ThingWith ie (lies' ++ [child])
252
+ -- ThingWith ie lies' => ThingWith ie (lies' ++ [child])
237
253
| parent == unIEWrappedName ie,
238
254
hasSibling <- not $ null lies' =
239
255
do
@@ -242,7 +258,7 @@ extendImportViaParent df parent child (L l it@ImportDecl {..})
242
258
when hasSibling $
243
259
addTrailingCommaT (last lies')
244
260
let childLIE = L srcChild $ IEName childRdr
245
- addSimpleAnnT childRdr (DP (0 , if hasSibling then 1 else 0 )) [( G AnnVal , dp00)]
261
+ addSimpleAnnT childRdr (DP (0 , if hasSibling then 1 else 0 )) $ unqalDP $ hasParen child
246
262
return $ L l it {ideclHiding = Just (hide, L l' $ reverse pre ++ [L l'' (IEThingWith noExtField twIE NoIEWildcard (lies' ++ [childLIE]) [] )] ++ xs)}
247
263
go hide l' pre (x : xs) = go hide l' (x : pre) xs
248
264
go hide l' pre []
@@ -258,11 +274,27 @@ extendImportViaParent df parent child (L l it@ImportDecl {..})
258
274
let parentLIE = L srcParent $ IEName parentRdr
259
275
childLIE = L srcChild $ IEName childRdr
260
276
x :: LIE GhcPs = L l'' $ IEThingWith noExtField parentLIE NoIEWildcard [childLIE] []
261
- addSimpleAnnT parentRdr (DP (0 , if hasSibling then 1 else 0 )) [( G AnnVal , DP ( 0 , 0 ))]
262
- addSimpleAnnT childRdr (DP (0 , 0 )) [( G AnnVal , DP ( 0 , 0 ))]
277
+ addSimpleAnnT parentRdr (DP (0 , if hasSibling then 1 else 0 )) $ unqalDP $ hasParen parent
278
+ addSimpleAnnT childRdr (DP (0 , 0 )) $ unqalDP $ hasParen child
263
279
addSimpleAnnT x (DP (0 , 0 )) [(G AnnOpenP , DP (0 , 1 )), (G AnnCloseP , DP (0 , 0 ))]
280
+ -- Parens are attachted to `pre`, so if `pre` was empty previously,
281
+ -- we need change the ann key from `[]` to `:` to keep parens and other anns.
282
+ unless hasSibling $
283
+ transferAnn (L l' $ reverse pre) (L l' [x]) id
264
284
return $ L l it {ideclHiding = Just (hide, L l' $ reverse pre ++ [x])}
265
285
extendImportViaParent _ _ _ _ = lift $ Left " Unable to extend the import list via parent"
266
286
267
287
unIEWrappedName :: IEWrappedName (IdP GhcPs ) -> String
268
- unIEWrappedName = occNameString . occName
288
+ unIEWrappedName (occName -> occ) = showSDocUnsafe $ parenSymOcc occ (ppr occ)
289
+
290
+ hasParen :: String -> Bool
291
+ hasParen (' (' : _) = True
292
+ hasParen _ = False
293
+
294
+ unqalDP :: Bool -> [(KeywordId , DeltaPos )]
295
+ unqalDP paren =
296
+ ( if paren
297
+ then \ x -> (G AnnOpenP , dp00) : x : [(G AnnCloseP , dp00)]
298
+ else pure
299
+ )
300
+ (G AnnVal , dp00)
0 commit comments