From 8916b91907833b5aaabd493d4184444383fa0ba5 Mon Sep 17 00:00:00 2001 From: Simon Jakobi Date: Fri, 8 Nov 2019 05:24:38 +0100 Subject: [PATCH 1/2] Add regression test for #91 --- prettyprinter/test/Testsuite/Main.hs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/prettyprinter/test/Testsuite/Main.hs b/prettyprinter/test/Testsuite/Main.hs index 97695e0f..d03e2784 100644 --- a/prettyprinter/test/Testsuite/Main.hs +++ b/prettyprinter/test/Testsuite/Main.hs @@ -80,6 +80,8 @@ tests = testGroup "Tests" , testCase "Preserve leading indentation" removeTrailingWhitespacePreserveIndentation ] + , testCase "Unbounded layout of `group`ed Line fails (#91)" + regressionUnboundedGroupedLine ] ] @@ -296,3 +298,9 @@ removeTrailingWhitespacePreserveIndentation = let sdoc :: SimpleDocStream () sdoc = SLine 2 (SChar 'x' SEmpty) in assertEqual "" sdoc (removeTrailingWhitespace sdoc) + +regressionUnboundedGroupedLine :: Assertion +regressionUnboundedGroupedLine + = let sdoc :: SimpleDocStream () + sdoc = layoutPretty (LayoutOptions Unbounded) (group hardline) + in assertEqual "" (SLine 0 SEmpty) sdoc From a06e0cd97f7da39458553912567965c8f82e93fe Mon Sep 17 00:00:00 2001 From: Simon Jakobi Date: Fri, 8 Nov 2019 04:25:02 +0100 Subject: [PATCH 2/2] Fix #91 by removing the shortcuts from the fitting predicates --- .../src/Data/Text/Prettyprint/Doc/Internal.hs | 37 ++++++++----------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/prettyprinter/src/Data/Text/Prettyprint/Doc/Internal.hs b/prettyprinter/src/Data/Text/Prettyprint/Doc/Internal.hs index 9c966c25..9ee709a2 100755 --- a/prettyprinter/src/Data/Text/Prettyprint/Doc/Internal.hs +++ b/prettyprinter/src/Data/Text/Prettyprint/Doc/Internal.hs @@ -1654,21 +1654,19 @@ layoutPretty -> Doc ann -> SimpleDocStream ann layoutPretty = layoutWadlerLeijen - (FittingPredicate (\_pWidth _minNestingLevel maxWidth sdoc -> case maxWidth of - Nothing -> True - Just w -> fits w sdoc )) + (FittingPredicate (\_pWidth _minNestingLevel maxWidth sdoc -> fits maxWidth sdoc)) where - fits :: Int -- ^ Width in which to fit the first line + fits :: Maybe Int -- ^ Width in which to fit the first line -> SimpleDocStream ann -> Bool - fits w _ | w < 0 = False - fits _ SFail = False - fits _ SEmpty = True - fits w (SChar _ x) = fits (w - 1) x - fits w (SText l _t x) = fits (w - l) x - fits _ SLine{} = True - fits w (SAnnPush _ x) = fits w x - fits w (SAnnPop x) = fits w x + fits (Just w) _ | w < 0 = False + fits _ SFail = False + fits _ SEmpty = True + fits w (SChar _ x) = fits (pred <$> w) x + fits w (SText l _t x) = fits (subtract l <$> w) x + fits _ SLine{} = True + fits w (SAnnPush _ x) = fits w x + fits w (SAnnPop x) = fits w x -- | A layout algorithm with more lookahead than 'layoutPretty', that introduces -- line breaks earlier if the content does not (or will not, rather) fit into @@ -1719,10 +1717,7 @@ layoutSmart :: LayoutOptions -> Doc ann -> SimpleDocStream ann -layoutSmart = layoutWadlerLeijen - (FittingPredicate (\pWidth minNestingLevel maxWidth sdoc -> case maxWidth of - Nothing -> True - Just w -> fits pWidth minNestingLevel w sdoc )) +layoutSmart = layoutWadlerLeijen (FittingPredicate fits) where -- Search with more lookahead: assuming that nesting roughly corresponds to -- syntactic depth, @fits@ checks that not only the current line fits, but @@ -1733,16 +1728,16 @@ layoutSmart = layoutWadlerLeijen -- exponential runtime (and is prohibitively expensive in practice). fits :: PageWidth -> Int -- ^ Minimum nesting level to fit in - -> Int -- ^ Width in which to fit the first line + -> Maybe Int -- ^ Width in which to fit the first line -> SimpleDocStream ann -> Bool - fits _ _ w _ | w < 0 = False + fits _ _ (Just w) _ | w < 0 = False fits _ _ _ SFail = False fits _ _ _ SEmpty = True - fits pw m w (SChar _ x) = fits pw m (w - 1) x - fits pw m w (SText l _t x) = fits pw m (w - l) x + fits pw m w (SChar _ x) = fits pw m (pred <$> w) x + fits pw m w (SText l _t x) = fits pw m (subtract l <$> w) x fits pw m _ (SLine i x) - | m < i, AvailablePerLine cpl _ <- pw = fits pw m (cpl - i) x + | m < i, AvailablePerLine cpl _ <- pw = fits pw m (Just (cpl - i)) x | otherwise = True fits pw m w (SAnnPush _ x) = fits pw m w x fits pw m w (SAnnPop x) = fits pw m w x