diff --git a/CHANGELOG.md b/CHANGELOG.md index 5ad16e729..77818e137 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ * Support the (deprecated) `DatatypeContexts` extension to avoid surprises. [Issue 1012](https://github.com/tweag/ormolu/issues/1012). +* Don't let comments escape from empty export lists. [Issue + 906](https://github.com/tweag/ormolu/issues/906). + ## Ormolu 0.6.0.1 * Fix false positives in AST diffing related to `UnicodeSyntax`. [PR diff --git a/data/examples/module-header/multiline-empty-comment-out.hs b/data/examples/module-header/multiline-empty-comment-out.hs new file mode 100644 index 000000000..83579f6e5 --- /dev/null +++ b/data/examples/module-header/multiline-empty-comment-out.hs @@ -0,0 +1,4 @@ +module Foo + ( -- test + ) +where diff --git a/data/examples/module-header/multiline-empty-comment.hs b/data/examples/module-header/multiline-empty-comment.hs new file mode 100644 index 000000000..fa29986a1 --- /dev/null +++ b/data/examples/module-header/multiline-empty-comment.hs @@ -0,0 +1,2 @@ +module Foo ( -- test + ) where diff --git a/src/Ormolu/Printer/Combinators.hs b/src/Ormolu/Printer/Combinators.hs index 19e23d20b..9b4142d99 100644 --- a/src/Ormolu/Printer/Combinators.hs +++ b/src/Ormolu/Printer/Combinators.hs @@ -23,6 +23,7 @@ module Ormolu.Printer.Combinators inciIf, askSourceType, askFixityOverrides, + encloseLocated, askFixityMap, located, located', @@ -77,7 +78,7 @@ import GHC.Data.Strict qualified as Strict import GHC.Types.SrcLoc import Ormolu.Printer.Comments import Ormolu.Printer.Internal -import Ormolu.Utils (HasSrcSpan (..)) +import Ormolu.Utils (HasSrcSpan (..), getLoc') ---------------------------------------------------------------------------- -- Basic @@ -111,6 +112,23 @@ located (L l' a) f = case loc' l' of switchLayout [RealSrcSpan l Strict.Nothing] (f a) spitFollowingComments l +-- | Similar to 'located', but when the "payload" is an empty list, print +-- virtual elements at the start and end of the source span to prevent comments +-- from "floating out". +encloseLocated :: + (HasSrcSpan l) => + GenLocated l [a] -> + ([a] -> R ()) -> + R () +encloseLocated la f = located la $ \a -> do + when (null a) $ located (L startSpan ()) pure + f a + when (null a) $ located (L endSpan ()) pure + where + l = getLoc' la + (startLoc, endLoc) = (srcSpanStart l, srcSpanEnd l) + (startSpan, endSpan) = (mkSrcSpan startLoc startLoc, mkSrcSpan endLoc endLoc) + -- | A version of 'located' with arguments flipped. located' :: (HasSrcSpan l) => diff --git a/src/Ormolu/Printer/Meat/Module.hs b/src/Ormolu/Printer/Meat/Module.hs index 999226b87..d0315d7b1 100644 --- a/src/Ormolu/Printer/Meat/Module.hs +++ b/src/Ormolu/Printer/Meat/Module.hs @@ -54,7 +54,7 @@ p_hsModule mstackHeader pragmas HsModule {..} = do case hsmodExports of Nothing -> return () Just l -> do - located l $ \exports -> do + encloseLocated l $ \exports -> do inci (p_hsmodExports exports) breakpoint txt "where"