on master help sign in
Improve rendering of "where" in class declarations and such
ac719f3Mark Karpov
CHANGELOG.md+5
@@ -11,6 +11,11 @@
11* More compact rendering of type family injectivity constraints. [Issue
11* More compact rendering of type family injectivity constraints. [Issue
12 482](https://github.com/tweag/ormolu/issues/482).
12 482](https://github.com/tweag/ormolu/issues/482).
13
13
14+* Improved rendering of the keyword `where` in class, data, and type family
15+ declarations. When headers of these declarations are multi-line `where` is
16+ now put on its own line. [Issue
17+ 509](https://github.com/tweag/ormolu/issues/509).
18+
14## Ormolu 0.0.3.1
19## Ormolu 0.0.3.1
15
20
16* Fixed rendering of record updates with the record dot preprocessor syntax
21* Fixed rendering of record updates with the record dot preprocessor syntax
data/examples/declaration/class/dependency-super-classes-out.hs+2−1
@@ -13,7 +13,8 @@ class
13 MonadPlus m -- Potential for failure
13 MonadPlus m -- Potential for failure
14 ) =>
14 ) =>
15 MonadParsec e s m
15 MonadParsec e s m
16+ | m -> e s
16− | m -> e s where
17+ where
17 -- | 'getState' returns state
18 -- | 'getState' returns state
18 getState ::
19 getState ::
19 m s
20 m s
data/examples/declaration/class/functional-dependencies-out.hs+2−1
@@ -14,5 +14,6 @@ class
14 b c -> a d, -- Bar
14 b c -> a d, -- Bar
15 a c -> b d, -- Baz
15 a c -> b d, -- Baz
16 a c d -> b,
16 a c d -> b,
17− a b d -> a b c d where
17+ a b d -> a b c d
18+ where
18 baz :: a -> b
19 baz :: a -> b
data/examples/declaration/class/multi-parameters2-out.hs+2−1
@@ -10,7 +10,8 @@ class
10 c -- Baz bar
10 c -- Baz bar
11 d -- Baz baz
11 d -- Baz baz
12 e -- Rest
12 e -- Rest
13+ f
13− f where
14+ where
14 barbaz ::
15 barbaz ::
15 a -> f
16 a -> f
16 bazbar ::
17 bazbar ::
data/examples/declaration/data/gadt/multiline-where-out.hsnew file+7
@@ -0,0 +1,7 @@
1+data
2+ Foo
3+ a
4+ b
5+ c
6+ where
7+ Foo :: a -> b -> c -> Foo a b c
data/examples/declaration/data/gadt/multiline-where.hsnew file+6
@@ -0,0 +1,6 @@
1+data
2+ Foo
3+ a
4+ b
5+ c where
6+ Foo :: a -> b -> c -> Foo a b c
data/examples/declaration/type-families/closed-type-family/multi-line-out.hs+6−3
@@ -1,6 +1,7 @@
1type family
1type family
2 Id a =
2 Id a =
3− result | result -> a where
3+ result | result -> a
4+ where
4 Id a =
5 Id a =
5 a
6 a
6
7
@@ -9,13 +10,15 @@ type family
9 (a :: k)
10 (a :: k)
10 b
11 b
11 c =
12 c =
12− foo | foo -> k b where
13+ foo | foo -> k b
14+ where
13 G a b c =
15 G a b c =
14 (a, b)
16 (a, b)
15
17
16type family
18type family
17 F a ::
19 F a ::
20+ * -> *
18− * -> * where
21+ where
19 F Int = Double
22 F Int = Double
20 F Bool =
23 F Bool =
21 Char
24 Char
src/Ormolu/Printer/Meat/Declaration/Class.hs+17−16
@@ -38,6 +38,20 @@ p_classDecl ctx name HsQTvs {..} fixity fdeps csigs cdefs cats catdefs cdocs = d
38 signatureSpans = getLoc name : variableSpans
38 signatureSpans = getLoc name : variableSpans
39 dependencySpans = getLoc <$> fdeps
39 dependencySpans = getLoc <$> fdeps
40 combinedSpans = getLoc ctx : (signatureSpans ++ dependencySpans)
40 combinedSpans = getLoc ctx : (signatureSpans ++ dependencySpans)
41+ -- GHC's AST does not necessarily store each kind of element in source
42+ -- location order. This happens because different declarations are stored
43+ -- in different lists. Consequently, to get all the declarations in proper
44+ -- order, they need to be manually sorted.
45+ sigs = (getLoc &&& fmap (SigD NoExt)) <$> csigs
46+ vals = (getLoc &&& fmap (ValD NoExt)) <$> toList cdefs
47+ tyFams = (getLoc &&& fmap (TyClD NoExt . FamDecl NoExt)) <$> cats
48+ docs = (getLoc &&& fmap (DocD NoExt)) <$> cdocs
49+ tyFamDefs =
50+ ( getLoc &&& fmap (InstD NoExt . TyFamInstD NoExt . defltEqnToInstDecl)
51+ )
52+ <$> catdefs
53+ allDecls =
54+ snd <$> sortOn fst (sigs <> vals <> tyFams <> tyFamDefs <> docs)
41 txt "class"
55 txt "class"
42 switchLayout combinedSpans $ do
56 switchLayout combinedSpans $ do
43 breakpoint
57 breakpoint
@@ -50,23 +64,10 @@ p_classDecl ctx name HsQTvs {..} fixity fdeps csigs cdefs cats catdefs cdocs = d
50 (p_rdrName name)
64 (p_rdrName name)
51 (located' p_hsTyVarBndr <$> hsq_explicit)
65 (located' p_hsTyVarBndr <$> hsq_explicit)
52 inci (p_classFundeps fdeps)
66 inci (p_classFundeps fdeps)
53− -- GHC's AST does not necessarily store each kind of element in source
54− -- location order. This happens because different declarations are stored
55− -- in different lists. Consequently, to get all the declarations in proper
56− -- order, they need to be manually sorted.
57− let sigs = (getLoc &&& fmap (SigD NoExt)) <$> csigs
58− vals = (getLoc &&& fmap (ValD NoExt)) <$> toList cdefs
59− tyFams = (getLoc &&& fmap (TyClD NoExt . FamDecl NoExt)) <$> cats
60− docs = (getLoc &&& fmap (DocD NoExt)) <$> cdocs
61− tyFamDefs =
62− ( getLoc &&& fmap (InstD NoExt . TyFamInstD NoExt . defltEqnToInstDecl)
63− )
64− <$> catdefs
65− allDecls =
67+ unless (null allDecls) $ do
66− snd <$> sortOn fst (sigs <> vals <> tyFams <> tyFamDefs <> docs)
68+ breakpoint
69+ txt "where"
67 unless (null allDecls) $ do
70 unless (null allDecls) $ do
68− space
69− txt "where"
70 breakpoint -- Ensure whitespace is added after where clause.
71 breakpoint -- Ensure whitespace is added after where clause.
71 inci (p_hsDeclsRespectGrouping Associated allDecls)
72 inci (p_hsDeclsRespectGrouping Associated allDecls)
72p_classDecl _ _ XLHsQTyVars {} _ _ _ _ _ _ _ = notImplemented "XLHsQTyVars"
73p_classDecl _ _ XLHsQTyVars {} _ _ _ _ _ _ _ = notImplemented "XLHsQTyVars"
src/Ormolu/Printer/Meat/Declaration/Data.hs+7−5
@@ -37,7 +37,8 @@ p_dataDecl style name tpats fixity HsDataDefn {..} = do
37 txt $ case style of
37 txt $ case style of
38 Associated -> mempty
38 Associated -> mempty
39 Free -> " instance"
39 Free -> " instance"
40− switchLayout (getLoc name : fmap getLoc tpats) $ do
40+ let constructorSpans = getLoc name : fmap getLoc tpats
41+ switchLayout constructorSpans $ do
41 breakpoint
42 breakpoint
42 inci $
43 inci $
43 p_infixDefHelper
44 p_infixDefHelper
@@ -55,11 +56,12 @@ p_dataDecl style name tpats fixity HsDataDefn {..} = do
55 let gadt = isJust dd_kindSig || any (isGadt . unLoc) dd_cons
56 let gadt = isJust dd_kindSig || any (isGadt . unLoc) dd_cons
56 unless (null dd_cons) $
57 unless (null dd_cons) $
57 if gadt
58 if gadt
58− then do
59+ then inci $ do
59− space
60+ switchLayout constructorSpans $ do
61+ breakpoint
60− txt "where"
62+ txt "where"
61 breakpoint
63 breakpoint
62− inci $ sepSemi (located' p_conDecl) dd_cons
64+ sepSemi (located' p_conDecl) dd_cons
63 else switchLayout (getLoc name : (getLoc <$> dd_cons))
65 else switchLayout (getLoc name : (getLoc <$> dd_cons))
64 $ inci
66 $ inci
65 $ do
67 $ do
src/Ormolu/Printer/Meat/Declaration/TypeFamily.hs+3−2
@@ -45,8 +45,9 @@ p_famDecl style FamilyDecl {fdTyVars = HsQTvs {..}, ..} = do
45 case mmeqs of
45 case mmeqs of
46 Nothing -> return ()
46 Nothing -> return ()
47 Just meqs -> do
47 Just meqs -> do
48− space
48+ inci $ do
49+ breakpoint
49− txt "where"
50+ txt "where"
50 case meqs of
51 case meqs of
51 Nothing -> do
52 Nothing -> do
52 space
53 space