@@ -0,0 +1,235 @@
1+{-# LANGUAGE LambdaCase #-}
2+{-# LANGUAGE OverloadedStrings #-}
3+{-# LANGUAGE RecordWildCards #-}
5+module Ormolu.Printer.Meat.Declaration.Value
10+import Bag (bagToList)
12+import Data.List (sortOn)
14+import Ormolu.Printer.Combinators
15+import Ormolu.Printer.Meat.Common
16+import Ormolu.Printer.Meat.Declaration.Pat
17+import Ormolu.Printer.Meat.Declaration.Signature
19+import SrcLoc (isOneLineSpan)
20+import qualified Data.List.NonEmpty as NE
22+p_valDecl :: HsBindLR GhcPs GhcPs -> R ()
23+p_valDecl = line . p_valDecl'
25+p_valDecl' :: HsBindLR GhcPs GhcPs -> R ()
27+ FunBind funId funMatches _ _ _ -> p_funBind funId funMatches
28+ _ -> notImplemented "certain kinds of binding declarations"
31+ :: Located RdrName -- ^
32+ -> MatchGroup GhcPs (LHsExpr GhcPs) -- ^
34+p_funBind name mgroup =
35+ p_matchGroup (Function (unL name)) mgroup
45+ -> MatchGroup GhcPs (LHsExpr GhcPs)
47+p_matchGroup style MG {..} =
48+ locatedVia Nothing mg_alts $
49+ newlineSep (located' (p_match style))
53+ -> Match GhcPs (LHsExpr GhcPs)
55+p_match style Match {..} = do
57+ Function name -> p_rdrName name
59+ -- NOTE Normally, since patterns may be placed in a multi-line layout, it
60+ -- is necessary to bump indentation for the pattern group so it's more
61+ -- indented than function name. This in turn means that indentation for
62+ -- the body should also be bumped. Normally this would mean that bodies
63+ -- would start with two indentation steps applied, which is ugly, so we
64+ -- need to be a bit more clever here and bump indentation level only when
65+ -- pattern group is multiline.
66+ inci' <- case NE.nonEmpty m_pats of
69+ let combinedSpans = combineSrcSpans' $
71+ inci' = if isOneLineSpan combinedSpans
74+ switchLayout combinedSpans $ do
76+ Function _ -> breakpoint
79+ LambdaCase -> return ()
80+ inci' (velt' (located' p_pat <$> m_pats))
84+ let GRHSs {..} = m_grhss
85+ unless (length grhssGRHSs > 1) . txt $
89+ let combinedSpans = combineSrcSpans' $
90+ getGRHSSpan . unL <$> NE.fromList grhssGRHSs
94+ switchLayout combinedSpans . inci $ do
98+ newlineSep (located' p_grhs) grhssGRHSs
99+ unless (GHC.isEmptyLocalBinds (unL grhssLocalBinds)) $ do
102+ inci (located grhssLocalBinds p_hsLocalBinds)
104+getGRHSSpan :: GRHS GhcPs (LHsExpr GhcPs) -> SrcSpan
105+getGRHSSpan (GRHS _ body) = getSpan body
107+p_grhs :: GRHS GhcPs (LHsExpr GhcPs) -> R ()
108+p_grhs (GRHS guards body) =
113+ velt $ withSep comma (located' p_stmt) xs
118+ p_body = located body p_hsExpr
120+p_stmt :: Stmt GhcPs (LHsExpr GhcPs) -> R ()
122+ LastStmt {} -> notImplemented "do notation"
123+ BindStmt {} -> notImplemented "do notation"
124+ ApplicativeStmt {} -> notImplemented "applicative stmt"
125+ BodyStmt body _ _ _ -> located body p_hsExpr
126+ LetStmt binds -> located binds p_hsLocalBinds
127+ ParStmt {} -> notImplemented "ParStmt"
128+ TransStmt {} -> notImplemented "TransStmt"
129+ RecStmt {} -> notImplemented "RecStmt"
131+p_hsLocalBinds :: HsLocalBindsLR GhcPs GhcPs -> R ()
132+p_hsLocalBinds = \case
133+ HsValBinds (ValBindsIn bag lsigs) -> do
134+ let ssStart = either
135+ (srcSpanStart . getSpan)
136+ (srcSpanStart . getSpan)
138+ (Left <$> bagToList bag) ++ (Right <$> lsigs)
139+ p_item (Left x) = located x p_valDecl'
140+ p_item (Right x) = located x p_sigDecl'
141+ newlineSep p_item (sortOn ssStart items)
142+ HsValBinds _ -> notImplemented "HsValBinds"
143+ HsIPBinds _ -> notImplemented "HsIPBinds"
144+ EmptyLocalBinds -> return ()
146+p_hsExpr :: HsExpr GhcPs -> R ()
148+ HsVar name -> located name p_rdrName'
149+ HsUnboundVar _ -> notImplemented "HsUnboundVar"
150+ HsConLikeOut _ -> notImplemented "HsConLikeOut"
153+ Unambiguous name _ -> located name p_rdrName'
154+ Ambiguous name _ -> located name p_rdrName'
155+ HsOverLabel _ _ -> notImplemented "HsOverLabel"
156+ HsIPVar (HsIPName name) -> atom name
157+ HsOverLit v -> atom (ol_val v)
158+ HsLit lit -> atom lit
160+ p_matchGroup Lambda mgroup
161+ HsLamCase mgroup -> do
164+ inci (p_matchGroup LambdaCase mgroup)
168+ inci (located x p_hsExpr)
169+ HsAppType {} -> notImplemented "HsAppType"
170+ HsAppTypeOut {} -> notImplemented "HsAppTypeOut"
171+ OpApp x op _ y -> do
181+ HsPar e -> parens (located e p_hsExpr)
182+ SectionL {} -> notImplemented "SectionL"
183+ SectionR {} -> notImplemented "SectionR"
184+ ExplicitTuple {} -> notImplemented "ExplicitTuple"
185+ ExplicitSum {} -> notImplemented "ExplicitSum"
186+ HsCase e mgroup -> do
191+ inci (p_matchGroup Case mgroup)
192+ HsIf _ if' then' else' -> do
194+ located if' p_hsExpr
197+ located then' p_hsExpr
200+ located else' p_hsExpr
201+ HsMultiIf {} -> notImplemented "MulitiIf"
202+ HsLet localBinds e -> do
204+ inci (located localBinds p_hsLocalBinds)
208+ HsDo {} -> notImplemented "HsDo"
209+ ExplicitList _ _ xs -> do
210+ brackets $ velt (withSep comma (located' p_hsExpr) xs)
211+ ExplicitPArr {} -> notImplemented "ExplicitPArr"
212+ RecordCon {} -> notImplemented "RecordCon"
213+ RecordUpd {} -> notImplemented "RecordUpd"
214+ ExprWithTySig {} -> notImplemented "ExprWithTySig"
215+ ExprWithTySigOut {} -> notImplemented "ExprWithTySigOut"
216+ ArithSeq {} -> notImplemented "ArithSeq"
217+ PArrSeq {} -> notImplemented "PArrSeq"
218+ HsSCC {} -> notImplemented "HsSCC"
219+ HsCoreAnn {} -> notImplemented "HsCoreAnn"
220+ HsBracket {} -> notImplemented "HsBracket"
221+ HsRnBracketOut {} -> notImplemented "HsRnBracketOut"
222+ HsTcBracketOut {} -> notImplemented "HsTcBracketOut"
223+ HsSpliceE {} -> notImplemented "HsSpliceE"
224+ HsProc {} -> notImplemented "HsProc"
225+ HsStatic {} -> notImplemented "HsStatic"
226+ HsArrApp {} -> notImplemented "HsArrApp"
227+ HsArrForm {} -> notImplemented "HsArrForm"
228+ HsTick {} -> notImplemented "HsTick"
229+ HsBinTick {} -> notImplemented "HsBinTick"
230+ HsTickPragma {} -> notImplemented "HsTickPragma"
231+ EWildPat -> notImplemented "EWildPat"
232+ EAsPat {} -> notImplemented "EAsPat"
233+ EViewPat {} -> notImplemented "EViewPat"
234+ ELazyPat {} -> notImplemented "ELazyPat"
235+ HsWrap {} -> notImplemented "HsWrap"