@@ -30,6 +30,7 @@ import Language.Haskell.GHC.ExactPrint
3030import Language.Haskell.GHC.ExactPrint.Types (DeltaPos (DP ), KeywordId (G ), mkAnnKey )
3131import Language.Haskell.LSP.Types
3232import OccName
33+ import Outputable (ppr , showSDocUnsafe )
3334
3435------------------------------------------------------------------------------
3536
@@ -176,12 +177,26 @@ lastMaybe :: [a] -> Maybe a
176177lastMaybe [] = Nothing
177178lastMaybe other = Just $ last other
178179
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+
179193------------------------------------------------------------------------------
180194extendImport :: 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
185200
186201-- | Add an identifier to import list
187202--
@@ -201,7 +216,11 @@ extendImportTopLevel df idnetifier (L l it@ImportDecl {..})
201216 when hasSibling $
202217 addTrailingCommaT (last lies)
203218 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
205224 return $ L l it {ideclHiding = Just (hide, L l' $ lies ++ [x])}
206225extendImportTopLevel _ _ _ = lift $ Left " Unable to extend the import list"
207226
@@ -219,21 +238,18 @@ extendImportViaParent df parent child (L l it@ImportDecl {..})
219238 where
220239 go :: Bool -> SrcSpan -> [LIE GhcPs ] -> [LIE GhcPs ] -> TransformT (Either String ) (LImportDecl GhcPs )
221240 go hide l' pre (lAbs@ (L ll' (IEThingAbs _ absIE@ (L _ ie))) : xs)
222- -- ThingAbs => ThingWith ie child
241+ -- ThingAbs ie => ThingWith ie child
223242 | parent == unIEWrappedName ie = do
224243 srcChild <- uniqueSrcSpanT
225244 childRdr <- liftParseAST df child
226245 let childLIE = L srcChild $ IEName childRdr
227246 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)]}
233249 addSimpleAnnT childRdr dp00 [(G AnnVal , dp00)]
234250 return $ L l it {ideclHiding = Just (hide, L l' $ reverse pre ++ [x] ++ xs)}
235251 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])
237253 | parent == unIEWrappedName ie,
238254 hasSibling <- not $ null lies' =
239255 do
@@ -242,7 +258,7 @@ extendImportViaParent df parent child (L l it@ImportDecl {..})
242258 when hasSibling $
243259 addTrailingCommaT (last lies')
244260 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
246262 return $ L l it {ideclHiding = Just (hide, L l' $ reverse pre ++ [L l'' (IEThingWith noExtField twIE NoIEWildcard (lies' ++ [childLIE]) [] )] ++ xs)}
247263 go hide l' pre (x : xs) = go hide l' (x : pre) xs
248264 go hide l' pre []
@@ -258,11 +274,27 @@ extendImportViaParent df parent child (L l it@ImportDecl {..})
258274 let parentLIE = L srcParent $ IEName parentRdr
259275 childLIE = L srcChild $ IEName childRdr
260276 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
263279 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
264284 return $ L l it {ideclHiding = Just (hide, L l' $ reverse pre ++ [x])}
265285extendImportViaParent _ _ _ _ = lift $ Left " Unable to extend the import list via parent"
266286
267287unIEWrappedName :: 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