@@ -1,4 +1,5 @@
1{-# LANGUAGE LambdaCase #-}
1{-# LANGUAGE LambdaCase #-}
2+{-# LANGUAGE MultiWayIf #-}
2{-# LANGUAGE OverloadedStrings #-}
3{-# LANGUAGE OverloadedStrings #-}
3{-# LANGUAGE RecordWildCards #-}
4{-# LANGUAGE RecordWildCards #-}
4{-# LANGUAGE TypeApplications #-}
5{-# LANGUAGE TypeApplications #-}
@@ -21,12 +22,12 @@ import Data.Char (isPunctuation, isSymbol)
21import Data.Data hiding (Infix, Prefix)
22import Data.Data hiding (Infix, Prefix)
22import Data.Functor ((<&>))
23import Data.Functor ((<&>))
23import Data.List (intersperse, sortOn)
24import Data.List (intersperse, sortOn)
24−import Data.List.NonEmpty ((<|), NonEmpty (..))
25+import Data.List.NonEmpty (NonEmpty (..), (<|))
25import qualified Data.List.NonEmpty as NE
26import qualified Data.List.NonEmpty as NE
26import Data.Text (Text)
27import Data.Text (Text)
27import qualified Data.Text as Text
28import qualified Data.Text as Text
29−import OccName (mkVarOcc)
30+import OccName (occNameString)
30import Ormolu.Printer.Combinators
31import Ormolu.Printer.Combinators
31import Ormolu.Printer.Internal
32import Ormolu.Printer.Internal
32import Ormolu.Printer.Meat.Common
33import Ormolu.Printer.Meat.Common
@@ -60,7 +61,7 @@ data Placement
60 -- should use it and avoid bumping one level
61 -- should use it and avoid bumping one level
61 -- of indentation
62 -- of indentation
63− deriving (Eq)
64+ deriving (Eq, Show)
65p_valDecl :: HsBindLR GhcPs GhcPs -> R ()
66p_valDecl :: HsBindLR GhcPs GhcPs -> R ()
66p_valDecl = \case
67p_valDecl = \case
@@ -179,25 +180,24 @@ p_match' placer render style isInfix strictness m_pats GRHSs {..} = do
179 NoSrcStrict -> return ()
180 NoSrcStrict -> return ()
180 SrcStrict -> txt "!"
181 SrcStrict -> txt "!"
181 SrcLazy -> txt "~"
182 SrcLazy -> txt "~"
182− inci' <- case NE.nonEmpty m_pats of
183+ indentBody <- case NE.nonEmpty m_pats of
183− Nothing -> id <$ case style of
185+ False <$ case style of
184− Function name -> p_rdrName name
186+ Function name -> p_rdrName name
185− _ -> return ()
187+ _ -> return ()
186 Just ne_pats -> do
188 Just ne_pats -> do
187− let combinedSpans =
189+ let combinedSpans = case style of
190+ Function name -> combineSrcSpans (getLoc name) patSpans
188− combineSrcSpans' $
192+ patSpans = combineSrcSpans' (getLoc <$> ne_pats)
191− if isOneLineSpan combinedSpans
193+ indentBody = not (isOneLineSpan combinedSpans)
194 switchLayout [combinedSpans] $ do
194 switchLayout [combinedSpans] $ do
195 let stdCase = sep breakpoint (located' p_pat) m_pats
195 let stdCase = sep breakpoint (located' p_pat) m_pats
196 case style of
196 case style of
197 Function name ->
197 Function name ->
198 p_infixDefHelper
198 p_infixDefHelper
200− inci'
200+ indentBody
201 (p_rdrName name)
201 (p_rdrName name)
202 (located' p_pat <$> m_pats)
202 (located' p_pat <$> m_pats)
203 PatternBind -> stdCase
203 PatternBind -> stdCase
@@ -212,7 +212,7 @@ p_match' placer render style isInfix strictness m_pats GRHSs {..} = do
212 when needsSpace space
212 when needsSpace space
213 sitcc stdCase
213 sitcc stdCase
214 LambdaCase -> stdCase
214 LambdaCase -> stdCase
215− return inci'
215+ return indentBody
216 let -- Calculate position of end of patterns. This is useful when we decide
216 let -- Calculate position of end of patterns. This is useful when we decide
217 -- about putting certain constructions in hanging positions.
217 -- about putting certain constructions in hanging positions.
218 endOfPats = case NE.nonEmpty m_pats of
218 endOfPats = case NE.nonEmpty m_pats of
@@ -224,15 +224,8 @@ p_match' placer render style isInfix strictness m_pats GRHSs {..} = do
224 Case -> True
224 Case -> True
225 LambdaCase -> True
225 LambdaCase -> True
226 _ -> False
226 _ -> False
227− let hasGuards = withGuards grhssGRHSs
227+ hasGuards = withGuards grhssGRHSs
228− unless (length grhssGRHSs > 1) $
230− Function _ | hasGuards -> return ()
231− Function _ -> space >> txt "="
232− PatternBind -> space >> txt "="
233− s | isCase s && hasGuards -> return ()
234− _ -> space >> txt "->"
235− let grhssSpan =
228+ grhssSpan =
236 combineSrcSpans' $
229 combineSrcSpans' $
237 getGRHSSpan . unLoc <$> NE.fromList grhssGRHSs
230 getGRHSSpan . unLoc <$> NE.fromList grhssGRHSs
238 patGrhssSpan =
231 patGrhssSpan =
@@ -260,7 +253,14 @@ p_match' placer render style isInfix strictness m_pats GRHSs {..} = do
260 txt "where"
253 txt "where"
261 unless whereIsEmpty breakpoint
254 unless whereIsEmpty breakpoint
262 inci $ located grhssLocalBinds p_hsLocalBinds
255 inci $ located grhssLocalBinds p_hsLocalBinds
263− inci' $ do
256+ inciIf indentBody $ do
257+ unless (length grhssGRHSs > 1) $
259+ Function _ | hasGuards -> return ()
260+ Function _ -> space >> inci equals
261+ PatternBind -> space >> inci equals
262+ s | isCase s && hasGuards -> return ()
263+ _ -> space >> txt "->"
264 switchLayout [patGrhssSpan] $
264 switchLayout [patGrhssSpan] $
265 placeHanging placement p_body
265 placeHanging placement p_body
266 inci p_where
266 inci p_where
@@ -284,11 +284,11 @@ p_grhs' placer render style (GRHS NoExtField guards body) =
287− sitcc (sep (comma >> breakpoint) (sitcc . located' p_stmt) xs)
287+ sitcc (sep commaDel (sitcc . located' p_stmt) xs)
289− txt $ case style of
289+ inci $ case style of
290− EqualSign -> "="
290+ EqualSign -> equals
291− RightArrow -> "->"
291+ RightArrow -> txt "->"
292 placeHanging placement p_body
292 placeHanging placement p_body
294 placement =
294 placement =
@@ -316,7 +316,7 @@ p_hsCmd = \case
316 HsHigherOrderApp -> txt "-<<"
316 HsHigherOrderApp -> txt "-<<"
317 placeHanging (exprPlacement (unLoc input)) $
317 placeHanging (exprPlacement (unLoc input)) $
318 located input p_hsExpr
318 located input p_hsExpr
319− HsCmdArrForm NoExtField form Prefix _ cmds -> banana $ sitcc $ do
319+ HsCmdArrForm NoExtField form Prefix _ cmds -> banana $ do
320 located form p_hsExpr
320 located form p_hsExpr
321 unless (null cmds) $ do
321 unless (null cmds) $ do
322 breakpoint
322 breakpoint
@@ -353,7 +353,14 @@ p_hsCmdTop = \case
353 HsCmdTop NoExtField cmd -> located cmd p_hsCmd
353 HsCmdTop NoExtField cmd -> located cmd p_hsCmd
354 XCmdTop x -> noExtCon x
354 XCmdTop x -> noExtCon x
356+-- | Render an expression preserving blank lines between such consecutive
357+-- expressions found in the original source code.
356−withSpacing :: Data a => (a -> R ()) -> Located a -> R ()
358+withSpacing ::
359+ -- | Rendering function
361+ -- | Entity to render
357withSpacing f l = located l $ \x -> do
364withSpacing f l = located l $ \x -> do
358 case getLoc l of
365 case getLoc l of
359 UnhelpfulSpan _ -> f x
366 UnhelpfulSpan _ -> f x
@@ -464,37 +471,31 @@ gatherStmtBlock (XParStmtBlock x) = noExtCon x
464p_hsLocalBinds :: HsLocalBindsLR GhcPs GhcPs -> R ()
471p_hsLocalBinds :: HsLocalBindsLR GhcPs GhcPs -> R ()
465p_hsLocalBinds = \case
472p_hsLocalBinds = \case
466 HsValBinds NoExtField (ValBinds NoExtField bag lsigs) -> do
473 HsValBinds NoExtField (ValBinds NoExtField bag lsigs) -> do
469− (srcSpanStart . getLoc)
470− (srcSpanStart . getLoc)
472− (Left <$> bagToList bag) ++ (Right <$> lsigs)
473− p_item (Left x) = located x p_valDecl
474− p_item (Right x) = located x p_sigDecl
475 -- When in a single-line layout, there is a chance that the inner
474 -- When in a single-line layout, there is a chance that the inner
476 -- elements will also contain semicolons and they will confuse the
475 -- elements will also contain semicolons and they will confuse the
477 -- parser. so we request braces around every element except the last.
476 -- parser. so we request braces around every element except the last.
478 br <- layoutToBraces <$> getLayout
477 br <- layoutToBraces <$> getLayout
479− sitcc $
478+ let items =
480− sepSemi
479+ let injectLeft (L l x) = L l (Left x)
481− ( \(p, i) ->
480+ injectRight (L l x) = L l (Right x)
482− ( case p of
481+ in (injectLeft <$> bagToList bag) ++ (injectRight <$> lsigs)
482+ positionToBracing = \case
483− SinglePos -> id
483+ SinglePos -> id
484− FirstPos -> br
484+ FirstPos -> br
485− MiddlePos -> br
485+ MiddlePos -> br
486− LastPos -> id
486+ LastPos -> id
487− )
487+ p_item' (p, item) =
488− (p_item i)
488+ positionToBracing p $
489− )
489+ withSpacing (either p_valDecl p_sigDecl) item
490+ binds = sortOn (srcSpanStart . getLoc) items
490− (attachRelativePos $ sortOn ssStart items)
491+ sitcc $ sepSemi p_item' (attachRelativePos binds)
491 HsValBinds NoExtField _ -> notImplemented "HsValBinds"
492 HsValBinds NoExtField _ -> notImplemented "HsValBinds"
492 HsIPBinds NoExtField (IPBinds NoExtField xs) ->
493 HsIPBinds NoExtField (IPBinds NoExtField xs) ->
493 -- Second argument of IPBind is always Left before type-checking.
494 -- Second argument of IPBind is always Left before type-checking.
494 let p_ipBind (IPBind NoExtField (Left name) expr) = do
495 let p_ipBind (IPBind NoExtField (Left name) expr) = do
495 atom name
496 atom name
498 breakpoint
499 breakpoint
499 useBraces $ inci $ located expr p_hsExpr
500 useBraces $ inci $ located expr p_hsExpr
500 p_ipBind (IPBind NoExtField (Right _) _) =
501 p_ipBind (IPBind NoExtField (Right _) _) =
@@ -513,19 +514,13 @@ p_hsRecField HsRecField {..} = do
513 p_rdrName hsRecFieldLbl
514 p_rdrName hsRecFieldLbl
514 unless hsRecPun $ do
515 unless hsRecPun $ do
517 let placement =
518 let placement =
518 if onTheSameLine (getLoc hsRecFieldLbl) (getLoc hsRecFieldArg)
519 if onTheSameLine (getLoc hsRecFieldLbl) (getLoc hsRecFieldArg)
519 then exprPlacement (unLoc hsRecFieldArg)
520 then exprPlacement (unLoc hsRecFieldArg)
520 else Normal
521 else Normal
521 placeHanging placement (located hsRecFieldArg p_hsExpr)
522 placeHanging placement (located hsRecFieldArg p_hsExpr)
523−p_hsTupArg :: HsTupArg GhcPs -> R ()
525− Present NoExtField x -> located x p_hsExpr
526− Missing NoExtField -> pure ()
527− XTupArg x -> noExtCon x
529p_hsExpr :: HsExpr GhcPs -> R ()
524p_hsExpr :: HsExpr GhcPs -> R ()
530p_hsExpr = p_hsExpr' N
525p_hsExpr = p_hsExpr' N
@@ -589,23 +584,21 @@ p_hsExpr' s = \case
589 -- do-block or case expression it is not a good idea. It seems
584 -- do-block or case expression it is not a good idea. It seems
590 -- to be safe to always bump indentation when the function
585 -- to be safe to always bump indentation when the function
591 -- expression is parenthesised.
586 -- expression is parenthesised.
592− indent =
587+ doIndent =
593 case func of
588 case func of
594− L _ (HsPar NoExtField _) -> inci
589+ L _ (HsPar NoExtField _) -> True
595− L _ (HsAppType NoExtField _ _) -> inci
590+ L _ (HsAppType NoExtField _ _) -> True
596− L _ (HsMultiIf NoExtField _) -> inci
591+ L _ (HsMultiIf NoExtField _) -> True
598− if isOneLineSpan spn
592+ L spn _ -> isOneLineSpan spn
601− ub <- getLayout <&> \case
594+ getLayout <&> \case
602− SingleLine -> useBraces
595+ SingleLine -> useBraces
603− MultiLine -> id
596+ MultiLine -> id
605 located func (p_hsExpr' s)
598 located func (p_hsExpr' s)
606 breakpoint
599 breakpoint
607− indent $ sep breakpoint (located' p_hsExpr) initp
600+ inciIf doIndent $ sep breakpoint (located' p_hsExpr) initp
608− indent $ do
601+ inciIf doIndent $ do
609 unless (null initp) breakpoint
602 unless (null initp) breakpoint
610 located lastp p_hsExpr
603 located lastp p_hsExpr
611 Hanging -> do
604 Hanging -> do
@@ -620,10 +613,15 @@ p_hsExpr' s = \case
620 breakpoint
613 breakpoint
621 inci $ do
614 inci $ do
616+ -- Insert a space when the type is represented as a TH splice to avoid
617+ -- gluing @ and $ together.
618+ case unLoc (hswc_body a) of
619+ HsSpliceTy {} -> space
623 located (hswc_body a) p_hsType
621 located (hswc_body a) p_hsType
624 OpApp NoExtField x op y -> do
622 OpApp NoExtField x op y -> do
625 let opTree = OpBranch (exprOpTree x) op (exprOpTree y)
623 let opTree = OpBranch (exprOpTree x) op (exprOpTree y)
626− p_exprOpTree True s (reassociateOpTree getOpName opTree)
624+ p_exprOpTree s (reassociateOpTree getOpName opTree)
627 NegApp NoExtField e _ -> do
625 NegApp NoExtField e _ -> do
@@ -640,22 +638,27 @@ p_hsExpr' s = \case
640 let isRecordDot' = isRecordDot (unLoc op) (getLoc x)
638 let isRecordDot' = isRecordDot (unLoc op) (getLoc x)
641 unless (useRecordDot' && isRecordDot') breakpoint
639 unless (useRecordDot' && isRecordDot') breakpoint
642 inci (located x p_hsExpr)
640 inci (located x p_hsExpr)
643− ExplicitTuple NoExtField args boxity -> do
641+ ExplicitTuple NoExtField args boxity ->
644 let isSection = any (isMissing . unLoc) args
642 let isSection = any (isMissing . unLoc) args
645 isMissing = \case
643 isMissing = \case
646 Missing NoExtField -> True
644 Missing NoExtField -> True
647 _ -> False
645 _ -> False
647+ Present NoExtField x -> located x p_hsExpr
648+ Missing NoExtField -> pure ()
649+ XTupArg x -> noExtCon x
650+ p_larg = sitcc . located' p_arg
648− let parens' =
651+ parens' =
649 case boxity of
652 case boxity of
650 Boxed -> parens
653 Boxed -> parens
651 Unboxed -> parensHash
654 Unboxed -> parensHash
652− if isSection
655+ in if isSection
654− switchLayout [] . parens' s $
657+ switchLayout [] . parens' s $
655− sep comma (located' p_hsTupArg) args
658+ sep comma p_larg args
657− switchLayout (getLoc <$> args) . parens' s . sitcc $
660+ switchLayout (getLoc <$> args) . parens' s $
658− sep (comma >> breakpoint) (sitcc . located' p_hsTupArg) args
661+ sep commaDel p_larg args
659 ExplicitSum NoExtField tag arity e ->
662 ExplicitSum NoExtField tag arity e ->
660 p_unboxedSum N tag arity (located e p_hsExpr)
663 p_unboxedSum N tag arity (located e p_hsExpr)
661 HsCase NoExtField e mgroup ->
664 HsCase NoExtField e mgroup ->
@@ -663,8 +666,9 @@ p_hsExpr' s = \case
663 HsIf NoExtField _ if' then' else' ->
666 HsIf NoExtField _ if' then' else' ->
664 p_if exprPlacement p_hsExpr if' then' else'
667 p_if exprPlacement p_hsExpr if' then' else'
665 HsMultiIf NoExtField guards -> do
668 HsMultiIf NoExtField guards -> do
666− txt "if "
669+ txt "if"
667− inci . inci . sitcc $ sep newline (located' (p_grhs RightArrow)) guards
671+ inci . inci $ sep newline (located' (p_grhs RightArrow)) guards
668 HsLet NoExtField localBinds e ->
672 HsLet NoExtField localBinds e ->
669 p_let p_hsExpr localBinds e
673 p_let p_hsExpr localBinds e
670 HsDo NoExtField ctx es -> do
674 HsDo NoExtField ctx es -> do
@@ -676,15 +680,15 @@ p_hsExpr' s = \case
677 (ub . withSpacing (p_stmt' exprPlacement (p_hsExpr' S)))
681 (ub . withSpacing (p_stmt' exprPlacement (p_hsExpr' S)))
678 (unLoc es)
682 (unLoc es)
679− compBody = brackets N $ located es $ \xs -> do
683+ compBody = brackets N . located es $ \xs -> do
680 let p_parBody =
684 let p_parBody =
682− (breakpoint >> txt "| ")
686+ (breakpoint >> txt "|" >> space)
683 p_seqBody
687 p_seqBody
684 p_seqBody =
688 p_seqBody =
687− (comma >> breakpoint)
691+ commaDel
688 (located' (sitcc . p_stmt))
692 (located' (sitcc . p_stmt))
689 stmts = init xs
693 stmts = init xs
690 yield = last xs
694 yield = last xs
@@ -705,8 +709,8 @@ p_hsExpr' s = \case
705 ParStmtCtxt _ -> notImplemented "ParStmtCtxt"
709 ParStmtCtxt _ -> notImplemented "ParStmtCtxt"
706 TransStmtCtxt _ -> notImplemented "TransStmtCtxt"
710 TransStmtCtxt _ -> notImplemented "TransStmtCtxt"
707 ExplicitList _ _ xs ->
711 ExplicitList _ _ xs ->
708− brackets s . sitcc $
712+ brackets s $
709− sep (comma >> breakpoint) (sitcc . located' p_hsExpr) xs
713+ sep commaDel (sitcc . located' p_hsExpr) xs
710 RecordCon {..} -> do
714 RecordCon {..} -> do
711 located rcon_con_name atom
715 located rcon_con_name atom
712 breakpoint
716 breakpoint
@@ -722,8 +726,8 @@ p_hsExpr' s = \case
722 case rec_dotdot of
726 case rec_dotdot of
723 Just {} -> [txt ".."]
727 Just {} -> [txt ".."]
724 Nothing -> []
728 Nothing -> []
725− inci . braces N . sitcc $
729+ inci . braces N $
726− sep (comma >> breakpoint) sitcc (fields <> dotdot)
730+ sep commaDel sitcc (fields <> dotdot)
727 RecordUpd {..} -> do
731 RecordUpd {..} -> do
728 located rupd_expr p_hsExpr
732 located rupd_expr p_hsExpr
729 useRecordDot' <- useRecordDot
733 useRecordDot' <- useRecordDot
@@ -741,9 +745,9 @@ p_hsExpr' s = \case
741 Unambiguous _ n -> n
745 Unambiguous _ n -> n
742 XAmbiguousFieldOcc x -> noExtCon x
746 XAmbiguousFieldOcc x -> noExtCon x
744− inci . braces N . sitcc $
748+ inci . braces N $
746− (comma >> breakpoint)
750+ commaDel
747 (sitcc . located' (p_hsRecField . updName))
751 (sitcc . located' (p_hsRecField . updName))
748 rupd_flds
752 rupd_flds
749 ExprWithTySig NoExtField x HsWC {hswc_body = HsIB {..}} -> sitcc $ do
753 ExprWithTySig NoExtField x HsWC {hswc_body = HsIB {..}} -> sitcc $ do
@@ -756,22 +760,22 @@ p_hsExpr' s = \case
756 ExprWithTySig NoExtField _ (XHsWildCardBndrs x) -> noExtCon x
760 ExprWithTySig NoExtField _ (XHsWildCardBndrs x) -> noExtCon x
757 ArithSeq NoExtField _ x ->
761 ArithSeq NoExtField _ x ->
758 case x of
762 case x of
759− From from -> brackets s . sitcc $ do
763+ From from -> brackets s $ do
760 located from p_hsExpr
764 located from p_hsExpr
761 breakpoint
765 breakpoint
763− FromThen from next -> brackets s . sitcc $ do
767+ FromThen from next -> brackets s $ do
764− sitcc $ sep (comma >> breakpoint) (located' p_hsExpr) [from, next]
768+ sep commaDel (located' p_hsExpr) [from, next]
765 breakpoint
769 breakpoint
767− FromTo from to -> brackets s . sitcc $ do
771+ FromTo from to -> brackets s $ do
768 located from p_hsExpr
772 located from p_hsExpr
769 breakpoint
773 breakpoint
772 located to p_hsExpr
776 located to p_hsExpr
773− FromThenTo from next to -> brackets s . sitcc $ do
777+ FromThenTo from next to -> brackets s $ do
774− sitcc $ sep (comma >> breakpoint) (located' p_hsExpr) [from, next]
778+ sep commaDel (located' p_hsExpr) [from, next]
775 breakpoint
779 breakpoint
@@ -821,7 +825,7 @@ p_patSynBind PSB {..} = do
821 breakpoint
825 breakpoint
822 located psb_def p_pat
826 located psb_def p_pat
823 ImplicitBidirectional -> do
827 ImplicitBidirectional -> do
825 breakpoint
829 breakpoint
826 located psb_def p_pat
830 located psb_def p_pat
827 ExplicitBidirectional mgroup -> do
831 ExplicitBidirectional mgroup -> do
@@ -848,8 +852,8 @@ p_patSynBind PSB {..} = do
848 inci $ do
852 inci $ do
849 switchLayout (getLoc . recordPatSynPatVar <$> xs) $ do
853 switchLayout (getLoc . recordPatSynPatVar <$> xs) $ do
850 unless (null xs) breakpoint
854 unless (null xs) breakpoint
851− braces N . sitcc $
855+ braces N $
852− sep (comma >> breakpoint) (p_rdrName . recordPatSynPatVar) xs
856+ sep commaDel (p_rdrName . recordPatSynPatVar) xs
854 InfixCon l r -> do
858 InfixCon l r -> do
855 switchLayout [getLoc l, getLoc r] $ do
859 switchLayout [getLoc l, getLoc r] $ do
@@ -903,10 +907,12 @@ p_if placer render if' then' else' = do
903 breakpoint
907 breakpoint
904 inci $ do
908 inci $ do
905 txt "then"
909 txt "then"
906 located then' $ \x ->
911 located then' $ \x ->
907 placeHanging (placer x) (render x)
912 placeHanging (placer x) (render x)
908 breakpoint
913 breakpoint
909 txt "else"
914 txt "else"
910 located else' $ \x ->
916 located else' $ \x ->
911 placeHanging (placer x) (render x)
917 placeHanging (placer x) (render x)
@@ -943,13 +949,13 @@ p_pat = \case
944 located pat p_pat
950 located pat p_pat
945 ListPat NoExtField pats ->
951 ListPat NoExtField pats ->
946− brackets S . sitcc $ sep (comma >> breakpoint) (located' p_pat) pats
952+ brackets S $ sep commaDel (located' p_pat) pats
947 TuplePat NoExtField pats boxing -> do
953 TuplePat NoExtField pats boxing -> do
948− let f =
954+ let parens' =
949 case boxing of
955 case boxing of
950 Boxed -> parens S
956 Boxed -> parens S
951 Unboxed -> parensHash S
957 Unboxed -> parensHash S
952− f . sitcc $ sep (comma >> breakpoint) (sitcc . located' p_pat) pats
958+ parens' $ sep commaDel (sitcc . located' p_pat) pats
953 SumPat NoExtField pat tag arity ->
959 SumPat NoExtField pat tag arity ->
954 p_unboxedSum S tag arity (located pat p_pat)
960 p_unboxedSum S tag arity (located pat p_pat)
955 ConPatIn pat details ->
961 ConPatIn pat details ->
@@ -965,7 +971,7 @@ p_pat = \case
965 let f = \case
971 let f = \case
966 Nothing -> txt ".."
972 Nothing -> txt ".."
967 Just x -> located x p_pat_hsRecField
973 Just x -> located x p_pat_hsRecField
968− inci . braces N . sitcc . sep (comma >> breakpoint) f $
974+ inci . braces N . sep commaDel f $
969 case dotdot of
975 case dotdot of
970 Nothing -> Just <$> fields
976 Nothing -> Just <$> fields
971 Just (L _ n) -> (Just <$> take n fields) ++ [Nothing]
977 Just (L _ n) -> (Just <$> take n fields) ++ [Nothing]
@@ -1006,7 +1012,7 @@ p_pat_hsRecField HsRecField {..} = do
1006 p_rdrName (rdrNameFieldOcc x)
1012 p_rdrName (rdrNameFieldOcc x)
1007 unless hsRecPun $ do
1013 unless hsRecPun $ do
1009− txt "="
1015+ equals
1010 breakpoint
1016 breakpoint
1011 inci (located hsRecFieldArg p_pat)
1017 inci (located hsRecFieldArg p_pat)
@@ -1015,17 +1021,15 @@ p_unboxedSum s tag arity m = do
1015 let before = tag - 1
1021 let before = tag - 1
1016 after = arity - before - 1
1022 after = arity - before - 1
1017 args = replicate before Nothing <> [Just m] <> replicate after Nothing
1023 args = replicate before Nothing <> [Just m] <> replicate after Nothing
1018− f (x, i) = do
1024+ f x =
1019− let isFirst = i == 0
1020− isLast = i == arity - 1
1021 case x :: Maybe (R ()) of
1025 case x :: Maybe (R ()) of
1022 Nothing ->
1026 Nothing ->
1023− unless (isFirst || isLast) space
1027+ space
1024 Just m' -> do
1028 Just m' -> do
1025− unless isFirst space
1029+ space
1027− unless isLast space
1031+ space
1028− parensHash s $ sep (txt "|") f (zip args [0 ..])
1032+ parensHash s $ sep (txt "|") f args
1030p_hsSplice :: HsSplice GhcPs -> R ()
1034p_hsSplice :: HsSplice GhcPs -> R ()
1031p_hsSplice = \case
1035p_hsSplice = \case
@@ -1227,11 +1231,10 @@ exprPlacement = \case
1227 HsCase NoExtField _ _ -> Hanging
1231 HsCase NoExtField _ _ -> Hanging
1228 HsDo NoExtField DoExpr _ -> Hanging
1232 HsDo NoExtField DoExpr _ -> Hanging
1229 HsDo NoExtField MDoExpr _ -> Hanging
1233 HsDo NoExtField MDoExpr _ -> Hanging
1230− -- If the rightmost expression in an operator chain is hanging, make the
1234+ OpApp NoExtField _ op y ->
1231− -- whole block hanging; so that we can use the common @f = foo $ do@
1235+ case (fmap getOpNameStr . getOpName . unLoc) op of
1233− OpApp NoExtField _ _ y -> exprPlacement (unLoc y)
1236+ Just "$" -> exprPlacement (unLoc y)
1234− -- Same thing for function applications (usually with -XBlockArguments)
1237+ _ -> Normal
1235 HsApp NoExtField _ y -> exprPlacement (unLoc y)
1238 HsApp NoExtField _ y -> exprPlacement (unLoc y)
1236 HsProc NoExtField p _ ->
1239 HsProc NoExtField p _ ->
1237 -- Indentation breaks if pattern is longer than one line and left
1240 -- Indentation breaks if pattern is longer than one line and left
@@ -1257,15 +1260,16 @@ getOpName = \case
1257 HsVar NoExtField (L _ a) -> Just a
1260 HsVar NoExtField (L _ a) -> Just a
1258 _ -> Nothing
1261 _ -> Nothing
1263+getOpNameStr :: RdrName -> String
1264+getOpNameStr = occNameString . rdrNameOcc
1260p_exprOpTree ::
1266p_exprOpTree ::
1261− -- | Can use special handling of dollar?
1263 -- | Bracket style to use
1267 -- | Bracket style to use
1264 BracketStyle ->
1268 BracketStyle ->
1265 OpTree (LHsExpr GhcPs) (LHsExpr GhcPs) ->
1269 OpTree (LHsExpr GhcPs) (LHsExpr GhcPs) ->
1267−p_exprOpTree _ s (OpNode x) = located x (p_hsExpr' s)
1271+p_exprOpTree s (OpNode x) = located x (p_hsExpr' s)
1268−p_exprOpTree isDollarSpecial s (OpBranch x op y) = do
1272+p_exprOpTree s (OpBranch x op y) = do
1269 -- If the beginning of the first argument and the second argument are on
1273 -- If the beginning of the first argument and the second argument are on
1270 -- the same line, and the second argument has a hanging form, use hanging
1274 -- the same line, and the second argument has a hanging form, use hanging
1271 -- placement.
1275 -- placement.
@@ -1287,44 +1291,54 @@ p_exprOpTree isDollarSpecial s (OpBranch x op y) = do
1287 MultiLine -> case placement of
1291 MultiLine -> case placement of
1288 Hanging -> useBraces
1292 Hanging -> useBraces
1289 Normal -> dontUseBraces
1293 Normal -> dontUseBraces
1290− gotDollar = case getOpName (unLoc op) of
1294+ opNameStr = (fmap getOpNameStr . getOpName . unLoc) op
1291− Just rname -> mkVarOcc "$" == rdrNameOcc rname
1295+ gotDollar = opNameStr == Just "$"
1292− _ -> False
1296+ gotColon = opNameStr == Just ":"
1297+ gotRecordDot = isRecordDot (unLoc op) (opTreeLoc y)
1294 switchLayout [opTreeLoc x] $
1299 switchLayout [opTreeLoc x] $
1295− p_exprOpTree (not gotDollar) s x
1300+ p_exprOpTree s x
1296− let p_op = located op (opWrapper . p_hsExpr)
1301+ p_op = located op (opWrapper . p_hsExpr)
1297− p_y = switchLayout [opTreeLoc y] (p_exprOpTree True N y)
1302+ p_y = switchLayout [opTreeLoc y] (p_exprOpTree N y)
1298 isSection = case (opTreeLoc x, getLoc op) of
1303 isSection = case (opTreeLoc x, getLoc op) of
1299 (RealSrcSpan treeSpan, RealSrcSpan opSpan) ->
1304 (RealSrcSpan treeSpan, RealSrcSpan opSpan) ->
1300 srcSpanEndCol treeSpan /= srcSpanStartCol opSpan
1305 srcSpanEndCol treeSpan /= srcSpanStartCol opSpan
1301 _ -> False
1306 _ -> False
1308+ OpNode (L _ HsDo {}) -> True
1302 useRecordDot' <- useRecordDot
1310 useRecordDot' <- useRecordDot
1303− let isRecordDot' = isRecordDot (unLoc op) (opTreeLoc y)
1311+ if
1304− if useRecordDot' && isRecordDot'
1312+ | gotColon -> do
1307− when isSection space
1315− && isOneLineSpan (opTreeLoc x)
1317− useBraces lhs
1313+ lhs
1320− breakpoint
1316+ case placement of
1321− inci p_y
1317+ Hanging -> do
1324− placeHanging placement $ do
1322+ inciIf (isDoBlock y) p_y
1324+ && isOneLineSpan (opTreeLoc x)
1325+ && placement == Normal -> do
1331+ | useRecordDot' && gotRecordDot -> do
1333+ when isSection space
1338+ placeHanging placement $ do
1329-- | Return 'True' if given expression is a record-dot operator expression.
1343-- | Return 'True' if given expression is a record-dot operator expression.
1330isRecordDot ::
1344isRecordDot ::
@@ -1335,14 +1349,10 @@ isRecordDot ::
1336isRecordDot op (RealSrcSpan ySpan) = case op of
1350isRecordDot op (RealSrcSpan ySpan) = case op of
1337 HsVar NoExtField (L (RealSrcSpan opSpan) opName) ->
1351 HsVar NoExtField (L (RealSrcSpan opSpan) opName) ->
1338− isDot opName && (srcSpanEndCol opSpan == srcSpanStartCol ySpan)
1352+ (getOpNameStr opName == ".") && (srcSpanEndCol opSpan == srcSpanStartCol ySpan)
1339 _ -> False
1353 _ -> False
1340isRecordDot _ _ = False
1354isRecordDot _ _ = False
1342−-- | Check whether a given 'RdrName' is the dot operator.
1343−isDot :: RdrName -> Bool
1344−isDot name = rdrNameOcc name == mkVarOcc "."
1346-- | Get annotations for the enclosing element.
1356-- | Get annotations for the enclosing element.
1347getEnclosingAnns :: R [AnnKeywordId]
1357getEnclosingAnns :: R [AnnKeywordId]
1348getEnclosingAnns = do
1358getEnclosingAnns = do