@@ -13,7 +13,7 @@ where
13import Bag (bagToList)
13import Bag (bagToList)
14import BasicTypes
14import BasicTypes
15import Control.Monad
15import Control.Monad
16−import Data.Data
16+import Data.Data hiding (Infix, Prefix)
17import Data.List (intersperse, sortOn)
17import Data.List (intersperse, sortOn)
18import Data.Text (Text)
18import Data.Text (Text)
@@ -72,11 +72,20 @@ p_matchGroup
72 :: MatchGroupStyle
72 :: MatchGroupStyle
73 -> MatchGroup GhcPs (LHsExpr GhcPs)
73 -> MatchGroup GhcPs (LHsExpr GhcPs)
75−p_matchGroup style MG {..} =
75+p_matchGroup = p_matchGroup' exprPlacement p_hsExpr
79+ => (body -> Placement)
82+ -> MatchGroup GhcPs (Located body)
84+p_matchGroup' placer pretty style MG {..} =
76 locatedVia Nothing mg_alts $
85 locatedVia Nothing mg_alts $
77 newlineSep (located' (\m@Match {..} ->
86 newlineSep (located' (\m@Match {..} ->
78− p_match style (isInfixMatch m) m_pats m_grhss))
87+ p_match' placer pretty style (isInfixMatch m) m_pats m_grhss))
79−p_matchGroup _ (XMatchGroup NoExt) = notImplemented "XMatchGroup"
88+p_matchGroup' _ _ _ (XMatchGroup NoExt) = notImplemented "XMatchGroup"
82 :: MatchGroupStyle
91 :: MatchGroupStyle
@@ -84,7 +93,18 @@ p_match
84 -> [LPat GhcPs]
93 -> [LPat GhcPs]
85 -> GRHSs GhcPs (LHsExpr GhcPs)
94 -> GRHSs GhcPs (LHsExpr GhcPs)
96+p_match = p_match' exprPlacement p_hsExpr
100+ => (body -> Placement)
103+ -> Bool -- ^ Is this an infix match?
105+ -> GRHSs GhcPs (Located body)
87−p_match style isInfix m_pats m_grhss = do
107+p_match' placer pretty style isInfix m_pats m_grhss = do
88 -- NOTE Normally, since patterns may be placed in a multi-line layout, it
108 -- NOTE Normally, since patterns may be placed in a multi-line layout, it
89 -- is necessary to bump indentation for the pattern group so it's more
109 -- is necessary to bump indentation for the pattern group so it's more
90 -- indented than function name. This in turn means that indentation for
110 -- indented than function name. This in turn means that indentation for
@@ -144,7 +164,7 @@ p_match style isInfix m_pats m_grhss = do
144 let grhssSpan = combineSrcSpans' $
164 let grhssSpan = combineSrcSpans' $
145 getGRHSSpan . unLoc <$> NE.fromList grhssGRHSs
165 getGRHSSpan . unLoc <$> NE.fromList grhssGRHSs
146 patGrhssSpan = maybe grhssSpan (combineSrcSpans grhssSpan) endOfPatsSpan
166 patGrhssSpan = maybe grhssSpan (combineSrcSpans grhssSpan) endOfPatsSpan
147− placement = blockPlacement grhssGRHSs
167+ placement = blockPlacement placer grhssGRHSs
148 inciLocalBinds = case placement of
168 inciLocalBinds = case placement of
149 Normal -> id
169 Normal -> id
150 Hanging -> inci
170 Hanging -> inci
@@ -153,7 +173,7 @@ p_match style isInfix m_pats m_grhss = do
153 if isCase style && hasGuards
173 if isCase style && hasGuards
154 then RightArrow
174 then RightArrow
155 else EqualSign
175 else EqualSign
156− newlineSep (located' (p_grhs groupStyle)) grhssGRHSs
176+ newlineSep (located' (p_grhs' pretty groupStyle)) grhssGRHSs
158 (GHC.isEmptyLocalBindsPR (unLoc grhssLocalBinds))
178 (GHC.isEmptyLocalBindsPR (unLoc grhssLocalBinds))
159 (inciLocalBinds $ do
179 (inciLocalBinds $ do
@@ -168,7 +188,15 @@ p_match style isInfix m_pats m_grhss = do
168 placeHanging placement p_body
188 placeHanging placement p_body
170p_grhs :: GroupStyle -> GRHS GhcPs (LHsExpr GhcPs) -> R ()
190p_grhs :: GroupStyle -> GRHS GhcPs (LHsExpr GhcPs) -> R ()
191+p_grhs = p_grhs' p_hsExpr
197+ -> GRHS GhcPs (Located body)
171−p_grhs style (GRHS NoExt guards body) =
199+p_grhs' pretty style (GRHS NoExt guards body) =
172 case guards of
200 case guards of
173 [] -> p_body
201 [] -> p_body
@@ -181,20 +209,91 @@ p_grhs style (GRHS NoExt guards body) =
181 breakpoint
209 breakpoint
182 inci p_body
210 inci p_body
184− p_body = located body p_hsExpr
212+ p_body = located body pretty
185−p_grhs _ (XGRHS NoExt) = notImplemented "XGRHS"
213+p_grhs' _ _ (XGRHS NoExt) = notImplemented "XGRHS"
215+p_hsCmd :: HsCmd GhcPs -> R ()
217+ HsCmdArrApp NoExt body input arrType _ -> do
218+ located body p_hsExpr
219+ txt $ case arrType of
220+ HsFirstOrderApp -> " -<"
221+ HsHigherOrderApp -> " -<<"
222+ placeHanging (exprPlacement (unLoc input)) $
223+ located input p_hsExpr
224+ HsCmdArrForm NoExt form Prefix _ cmds -> banana $ sitcc $ do
225+ located form p_hsExpr
226+ unless (null cmds) $ do
228+ inci (sequence_ (intersperse breakpoint (located' p_hsCmdTop <$> cmds)))
229+ HsCmdArrForm NoExt form Infix _ [left, right] -> do
230+ located left p_hsCmdTop
232+ located form p_hsExpr
233+ placeHanging (cmdTopPlacement (unLoc right)) $
234+ located right p_hsCmdTop
235+ HsCmdArrForm NoExt _ Infix _ _ -> notImplemented "HsCmdArrForm"
237+ -- XXX Does this ever occur in the syntax tree? It does not seem like it
238+ -- does. Open an issue and ping @yumiova if this ever occurs in output.
239+ notImplemented "HsCmdApp"
240+ HsCmdLam NoExt mgroup -> p_matchGroup' cmdPlacement p_hsCmd Lambda mgroup
241+ HsCmdPar NoExt c -> parens (located c p_hsCmd)
242+ HsCmdCase NoExt e mgroup -> do
247+ inci (p_matchGroup' cmdPlacement p_hsCmd Case mgroup)
248+ HsCmdIf NoExt _ if' then' else' -> do
250+ located if' p_hsExpr
253+ located then' $ \x -> do
258+ located else' $ \x -> do
261+ HsCmdLet NoExt localBinds c -> do
263+ sitcc (located localBinds p_hsLocalBinds)
266+ sitcc (located c p_hsCmd)
267+ HsCmdDo NoExt es -> do
270+ inci (located es (newlineSep (located' (sitcc . p_stmt' p_hsCmd))))
271+ HsCmdWrap {} -> notImplemented "HsCmdWrap"
272+ XCmd {} -> notImplemented "XCmd"
274+p_hsCmdTop :: HsCmdTop GhcPs -> R ()
276+ HsCmdTop NoExt cmd -> located cmd p_hsCmd
277+ XCmdTop {} -> notImplemented "XHsCmdTop"
187p_stmt :: Stmt GhcPs (LHsExpr GhcPs) -> R ()
279p_stmt :: Stmt GhcPs (LHsExpr GhcPs) -> R ()
188−p_stmt = \case
280+p_stmt = p_stmt' p_hsExpr
285+ -> Stmt GhcPs (Located body)
287+p_stmt' pretty = \case
189− LastStmt NoExt body _ _ -> located body p_hsExpr
288+ LastStmt NoExt body _ _ -> located body pretty
190 BindStmt NoExt l f _ _ -> do
289 BindStmt NoExt l f _ _ -> do
191 located l p_pat
290 located l p_pat
194 breakpoint
293 breakpoint
195− inci (located f p_hsExpr)
294+ inci (located f pretty)
196 ApplicativeStmt {} -> notImplemented "ApplicativeStmt"
295 ApplicativeStmt {} -> notImplemented "ApplicativeStmt"
197− BodyStmt NoExt body _ _ -> located body p_hsExpr
296+ BodyStmt NoExt body _ _ -> located body pretty
198 LetStmt NoExt binds -> do
297 LetStmt NoExt binds -> do
199 txt "let "
298 txt "let "
200 sitcc $ located binds p_hsLocalBinds
299 sitcc $ located binds p_hsLocalBinds
@@ -202,7 +301,9 @@ p_stmt = \case
202 sequence_ $ intersperse breakpoint $
301 sequence_ $ intersperse breakpoint $
203 withSep (txt "| ") p_parStmtBlock stmts
302 withSep (txt "| ") p_parStmtBlock stmts
204 TransStmt {} -> notImplemented "TransStmt"
303 TransStmt {} -> notImplemented "TransStmt"
205− RecStmt {} -> notImplemented "RecStmt"
304+ RecStmt {..} -> do
306+ sitcc $ newlineSep (located' (p_stmt' pretty)) recS_stmts
206 XStmtLR {} -> notImplemented "XStmtLR"
307 XStmtLR {} -> notImplemented "XStmtLR"
208p_parStmtBlock :: ParStmtBlock GhcPs GhcPs -> R ()
309p_parStmtBlock :: ParStmtBlock GhcPs GhcPs -> R ()
@@ -434,13 +535,22 @@ p_hsExpr = \case
434 HsRnBracketOut {} -> notImplemented "HsRnBracketOut"
535 HsRnBracketOut {} -> notImplemented "HsRnBracketOut"
435 HsTcBracketOut {} -> notImplemented "HsTcBracketOut"
536 HsTcBracketOut {} -> notImplemented "HsTcBracketOut"
436 HsSpliceE NoExt splice -> p_hsSplice splice
537 HsSpliceE NoExt splice -> p_hsSplice splice
437− HsProc {} -> notImplemented "HsProc"
538+ HsProc NoExt p e -> do
540+ located p $ \x -> do
545+ placeHanging (cmdTopPlacement (unLoc e)) (located e p_hsCmdTop)
438 HsStatic _ e -> do
546 HsStatic _ e -> do
439 txt "static"
547 txt "static"
440 breakpoint
548 breakpoint
441 inci (located e p_hsExpr)
549 inci (located e p_hsExpr)
442− HsArrApp {} -> notImplemented "HsArrApp"
550+ HsArrApp NoExt body input arrType cond ->
443− HsArrForm {} -> notImplemented "HsArrForm"
551+ p_hsCmd (HsCmdArrApp NoExt body input arrType cond)
552+ HsArrForm NoExt form mfixity cmds ->
553+ p_hsCmd (HsCmdArrForm NoExt form Prefix mfixity cmds)
444 HsTick {} -> notImplemented "HsTick"
554 HsTick {} -> notImplemented "HsTick"
445 HsBinTick {} -> notImplemented "HsBinTick"
555 HsBinTick {} -> notImplemented "HsBinTick"
446 HsTickPragma {} -> notImplemented "HsTickPragma"
556 HsTickPragma {} -> notImplemented "HsTickPragma"
@@ -630,7 +740,7 @@ p_hsBracket = \case
630----------------------------------------------------------------------------
740----------------------------------------------------------------------------
631-- Helpers
741-- Helpers
633−getGRHSSpan :: GRHS GhcPs (LHsExpr GhcPs) -> SrcSpan
743+getGRHSSpan :: GRHS GhcPs (Located body) -> SrcSpan
634getGRHSSpan (GRHS NoExt _ body) = getLoc body
744getGRHSSpan (GRHS NoExt _ body) = getLoc body
635getGRHSSpan (XGRHS NoExt) = notImplemented "XGRHS"
745getGRHSSpan (XGRHS NoExt) = notImplemented "XGRHS"
@@ -651,9 +761,26 @@ placeHanging placement m = do
651-- | Check if given block contains single expression which has a hanging
761-- | Check if given block contains single expression which has a hanging
654−blockPlacement :: [LGRHS GhcPs (LHsExpr GhcPs)] -> Placement
764+blockPlacement
765+ :: (body -> Placement)
766+ -> [LGRHS GhcPs (Located body)]
655−blockPlacement [(L _ (GRHS NoExt _ (L _ e)))] = exprPlacement e
768+blockPlacement placer [(L _ (GRHS NoExt _ (L _ x)))] = placer x
656−blockPlacement _ = Normal
769+blockPlacement _ _ = Normal
771+-- | Check if given command has a hanging form.
773+cmdPlacement :: HsCmd GhcPs -> Placement
775+ HsCmdLam NoExt _ -> Hanging
776+ HsCmdCase NoExt _ _ -> Hanging
777+ HsCmdDo NoExt _ -> Hanging
780+cmdTopPlacement :: HsCmdTop GhcPs -> Placement
781+cmdTopPlacement = \case
782+ HsCmdTop NoExt (L _ x) -> cmdPlacement x
783+ XCmdTop {} -> notImplemented "XCmdTop"
658-- | Check if given expression has hinging a form.
785-- | Check if given expression has hinging a form.
@@ -665,11 +792,17 @@ exprPlacement = \case
665 HsDo NoExt DoExpr _ -> Hanging
792 HsDo NoExt DoExpr _ -> Hanging
666 HsDo NoExt MDoExpr _ -> Hanging
793 HsDo NoExt MDoExpr _ -> Hanging
667 RecordCon NoExt _ _ -> Hanging
794 RecordCon NoExt _ _ -> Hanging
795+ HsProc NoExt (L s _) _ ->
796+ -- Indentation breaks if pattern is longer than one line and left hanging.
797+ -- Consequentally, once apply hanging when it is safe.
668 _ -> Normal
801 _ -> Normal
670−withGuards :: [LGRHS GhcPs (LHsExpr GhcPs)] -> Bool
803+withGuards :: [LGRHS GhcPs (Located body)] -> Bool
671withGuards = any (checkOne . unLoc)
804withGuards = any (checkOne . unLoc)
673− checkOne :: GRHS GhcPs (LHsExpr GhcPs) -> Bool
806+ checkOne :: GRHS GhcPs (Located body) -> Bool
674 checkOne (GRHS NoExt [] _) = False
807 checkOne (GRHS NoExt [] _) = False
675 checkOne _ = True
808 checkOne _ = True