mirror of
https://github.com/google/ormolu.git
synced 2024-11-23 14:16:24 +03:00
Make function arguments look more consistent
This change modifies the ‘HsApp’ printer to handle all function parameters at once instead of following the AST order. This allows us to consistently put each function argument on separate lines. Previously, when printing the function f a b c, the AST would look like (((f a) b) c), which would cause inconsistencies regarding to newlines (imagine f a\n b). Otherwise I tried to preserve the same behaviour as the previous printer, and added a few tests. This only changes the ‘p_hsExpr’ function, rest of the changes are caused by the formatting change.
This commit is contained in:
parent
1d3eeba701
commit
3abadaefa5
@ -10,7 +10,8 @@
|
||||
|
||||
{-# RULES
|
||||
"map/map"
|
||||
map f
|
||||
map
|
||||
f
|
||||
(map g xs) =
|
||||
map
|
||||
(f . g)
|
||||
|
@ -1,6 +1,7 @@
|
||||
{-# RULES
|
||||
"map/map" [2]
|
||||
map f
|
||||
map
|
||||
f
|
||||
(map g xs) =
|
||||
map
|
||||
(f . g)
|
||||
@ -9,7 +10,8 @@
|
||||
|
||||
{-# RULES
|
||||
"map/map" [1] forall x y z.
|
||||
map f
|
||||
map
|
||||
f
|
||||
(map g xs) =
|
||||
map
|
||||
(f . g)
|
||||
|
17
data/examples/declaration/value/function/application-out.hs
Normal file
17
data/examples/declaration/value/function/application-out.hs
Normal file
@ -0,0 +1,17 @@
|
||||
foo =
|
||||
f1
|
||||
p1
|
||||
p2
|
||||
p3
|
||||
|
||||
foo' =
|
||||
f2
|
||||
p1
|
||||
p2
|
||||
p3
|
||||
|
||||
foo'' =
|
||||
f3
|
||||
p1
|
||||
p2
|
||||
p3
|
12
data/examples/declaration/value/function/application.hs
Normal file
12
data/examples/declaration/value/function/application.hs
Normal file
@ -0,0 +1,12 @@
|
||||
foo =
|
||||
f1
|
||||
p1
|
||||
p2 p3
|
||||
|
||||
foo' = f2 p1
|
||||
p2
|
||||
p3
|
||||
|
||||
foo'' =
|
||||
f3 p1 p2
|
||||
p3
|
@ -25,3 +25,5 @@ f7 = foo \x -> y
|
||||
|
||||
f8 = foo \x ->
|
||||
y
|
||||
|
||||
f9 = foo do { bar } baz
|
||||
|
@ -21,3 +21,5 @@ f7 = foo \x -> y
|
||||
|
||||
f8 = foo \x ->
|
||||
y
|
||||
|
||||
f9 = foo do { bar } baz
|
||||
|
@ -14,6 +14,7 @@ bar =
|
||||
baz :: StaticPtr Bool
|
||||
baz =
|
||||
static
|
||||
( fun 1
|
||||
( fun
|
||||
1
|
||||
2
|
||||
)
|
||||
|
@ -51,7 +51,9 @@ instance Exception OrmoluException where
|
||||
)
|
||||
++ ["Please, consider reporting the bug."]
|
||||
OrmoluNonIdempotentOutput loc left right ->
|
||||
showParsingErr "Formatting is not idempotent:" loc
|
||||
showParsingErr
|
||||
"Formatting is not idempotent:"
|
||||
loc
|
||||
["before: " ++ show left, "after: " ++ show right]
|
||||
++ "Please, consider reporting the bug.\n"
|
||||
|
||||
|
@ -62,7 +62,8 @@ mkCommentStream extraComments pstate =
|
||||
mapMaybe toRealSpan $
|
||||
extraComments
|
||||
++ mapMaybe (liftMaybe . fmap unAnnotationComment) (GHC.comment_q pstate)
|
||||
++ concatMap (mapMaybe (liftMaybe . fmap unAnnotationComment) . snd)
|
||||
++ concatMap
|
||||
(mapMaybe (liftMaybe . fmap unAnnotationComment) . snd)
|
||||
(GHC.annotations_comments pstate)
|
||||
|
||||
-- | Test whether a 'Comment' looks like a Haddock following a definition,
|
||||
|
@ -21,7 +21,8 @@ printModule ::
|
||||
-- | Resulting rendition
|
||||
Text
|
||||
printModule ParseResult {..} =
|
||||
runR (p_hsModule prExtensions prParsedSource)
|
||||
runR
|
||||
(p_hsModule prExtensions prParsedSource)
|
||||
(mkSpanStream prParsedSource)
|
||||
prCommentStream
|
||||
prAnns
|
||||
|
@ -19,7 +19,7 @@ import Data.Bool (bool)
|
||||
import Data.Char (isPunctuation, isSymbol)
|
||||
import Data.Data hiding (Infix, Prefix)
|
||||
import Data.List (intersperse, sortOn)
|
||||
import Data.List.NonEmpty (NonEmpty ((:|)))
|
||||
import Data.List.NonEmpty ((<|), NonEmpty ((:|)))
|
||||
import qualified Data.List.NonEmpty as NE
|
||||
import Data.Text (Text)
|
||||
import qualified Data.Text as Text
|
||||
@ -237,7 +237,8 @@ p_match' placer render style isInfix strictness m_pats m_grhss = do
|
||||
combineSrcSpans' $
|
||||
getGRHSSpan . unLoc <$> NE.fromList grhssGRHSs
|
||||
patGrhssSpan =
|
||||
maybe grhssSpan
|
||||
maybe
|
||||
grhssSpan
|
||||
(combineSrcSpans grhssSpan . srcLocSpan)
|
||||
endOfPats
|
||||
placement =
|
||||
@ -525,25 +526,44 @@ p_hsExpr' s = \case
|
||||
breakpoint
|
||||
inci (p_matchGroup LambdaCase mgroup)
|
||||
HsApp NoExt f x -> do
|
||||
-- We hang only the last function argument. In order to do this, we only
|
||||
-- call 'placeHanging' on the topmost 'HsApp', and then use
|
||||
-- 'p_withoutHanging' for the descendants.
|
||||
let p_withoutHanging (HsApp NoExt f' x') = do
|
||||
let -- In order to format function applications with multiple parameters
|
||||
-- nicer, traverse the AST to gather the function and all the
|
||||
-- parameters together.
|
||||
gatherArgs f' knownArgs =
|
||||
case f' of
|
||||
L _ (HsApp _ _ _) -> located f' p_withoutHanging
|
||||
_ -> located f' (p_hsExpr' s)
|
||||
breakpoint
|
||||
inci $ located x' p_hsExpr
|
||||
p_withoutHanging e = p_hsExpr e
|
||||
-- Only use the hanging placement if the function spans a single
|
||||
L _ (HsApp _ l r) -> gatherArgs l (r <| knownArgs)
|
||||
_ -> (f', knownArgs)
|
||||
(func, args) = gatherArgs f (x :| [])
|
||||
-- We need to handle the last argument specially if it is a
|
||||
-- hanging construct, so separate it from the rest.
|
||||
(initp, lastp) = (NE.init args, NE.last args)
|
||||
initSpan = combineSrcSpans' $ getLoc f :| map getLoc initp
|
||||
-- Hang the last argument only if the initial arguments spans one
|
||||
-- line.
|
||||
placement =
|
||||
if isOneLineSpan (getLoc f)
|
||||
then exprPlacement (unLoc x)
|
||||
if isOneLineSpan initSpan
|
||||
then exprPlacement (unLoc lastp)
|
||||
else Normal
|
||||
useBraces (located f p_withoutHanging)
|
||||
placeHanging placement $
|
||||
located x p_hsExpr
|
||||
-- If the last argument is not hanging, just separate every argument as
|
||||
-- usual. If it is hanging, print the initial arguments and hang the
|
||||
-- last one. Also, use braces around the every argument except the last
|
||||
-- one.
|
||||
case placement of
|
||||
Normal -> do
|
||||
useBraces $ do
|
||||
located func (p_hsExpr' s)
|
||||
breakpoint
|
||||
inci $ sep breakpoint (located' p_hsExpr) initp
|
||||
inci $ do
|
||||
unless (null initp) breakpoint
|
||||
located lastp p_hsExpr
|
||||
Hanging -> do
|
||||
useBraces . switchLayout [initSpan] $ do
|
||||
located func (p_hsExpr' s)
|
||||
breakpoint
|
||||
sep breakpoint (located' p_hsExpr) initp
|
||||
placeHanging placement $
|
||||
located lastp p_hsExpr
|
||||
HsAppType a e -> do
|
||||
located e p_hsExpr
|
||||
breakpoint
|
||||
@ -1089,7 +1109,8 @@ p_stringLit src =
|
||||
zipPrevNext :: [a] -> [(Maybe a, a, Maybe a)]
|
||||
zipPrevNext xs =
|
||||
let z =
|
||||
zip (zip (Nothing : map Just xs) xs)
|
||||
zip
|
||||
(zip (Nothing : map Just xs) xs)
|
||||
(map Just (tail xs) ++ repeat Nothing)
|
||||
in map (\((p, x), n) -> (p, x, n)) z
|
||||
orig (_, x, _) = x
|
||||
|
@ -191,7 +191,8 @@ p_conDeclField :: ConDeclField GhcPs -> R ()
|
||||
p_conDeclField ConDeclField {..} = do
|
||||
mapM_ (p_hsDocString Pipe True) cd_fld_doc
|
||||
sitcc $
|
||||
sep (comma >> breakpoint)
|
||||
sep
|
||||
(comma >> breakpoint)
|
||||
(located' (p_rdrName . rdrNameFieldOcc))
|
||||
cd_fld_names
|
||||
space
|
||||
|
Loading…
Reference in New Issue
Block a user