@@ -0,0 +1,71 @@
1+{-# LANGUAGE LambdaCase #-}
2+{-# LANGUAGE OverloadedStrings #-}
3+{-# LANGUAGE RecordWildCards #-}
4+
5+-- | Type class instance declarations.
6+
7+module Ormolu.Printer.Meat.Declaration.Instance
8+ ( p_clsInstDecl
9+ , FamilyStyle (Associate, Free)
10+ , p_tyFamInstDecl
11+ )
12+where
13+
14+import BasicTypes
15+import Control.Arrow
16+import Data.Foldable
17+import Data.Function
18+import Data.List (sortBy)
19+import GHC
20+import Ormolu.Printer.Combinators
21+import Ormolu.Printer.Meat.Declaration.Signature
22+import Ormolu.Printer.Meat.Declaration.TypeFamily
23+import Ormolu.Printer.Meat.Declaration.Value
24+import Ormolu.Printer.Meat.Type
25+import Ormolu.Utils
26+
27+p_clsInstDecl :: ClsInstDecl GhcPs -> R ()
28+p_clsInstDecl = \case
29+ ClsInstDecl {..} -> do
30+ txt "instance "
31+ case unLoc <$> cid_overlap_mode of
32+ Just Overlappable {} -> txt "{-# OVERLAPPABLE #-} "
33+ Just Overlapping {} -> txt "{-# OVERLAPPING #-} "
34+ Just Overlaps {} -> txt "{-# OVERLAPS #-} "
35+ Just Incoherent {} -> txt "{-# INCOHERENT #-} "
36+ _ -> pure ()
37+ case cid_poly_ty of
38+ HsIB {..} -> sitcc (located hsib_body p_hsType)
39+ XHsImplicitBndrs NoExt -> notImplemented "XHsImplicitBndrs"
40+ -- GHC's AST does not necessarily store each kind of element in source
41+ -- location order. This happens because different declarations are stored in
42+ -- different lists. Consequently, to get all the declarations in proper
43+ -- order, they need to be manually sorted.
44+ let binds = (getLoc &&& located' p_valDecl) <$> cid_binds
45+ sigs = (getLoc &&& located' p_sigDecl) <$> cid_sigs
46+ tyfam_insts =
47+ (getLoc &&& located' (p_tyFamInstDecl Associate)) <$> cid_tyfam_insts
48+ decls =
49+ snd <$>
50+ sortBy (compare `on` fst) (toList binds <> sigs <> tyfam_insts)
51+ if not (null decls)
52+ then do
53+ txt " where"
54+ newline
55+ inci (sequence_ decls)
56+ else do
57+ newline
58+ XClsInstDecl NoExt -> notImplemented "XClsInstDecl"
59+
60+data FamilyStyle
61+ = Associate
62+ | Free
63+
64+p_tyFamInstDecl :: FamilyStyle -> TyFamInstDecl GhcPs -> R ()
65+p_tyFamInstDecl style = \case
66+ TyFamInstDecl {..} -> do
67+ txt $ case style of
68+ Associate -> "type "
69+ Free -> "type instance "
70+ p_tyFamInstEqn tfid_eqn
71+ newline