Compare commits

..

No commits in common. "34c8fd93d73dbf4a11f3dffbf314501bb5eb5393" and "2b77142617a35afa0f935b1e9cc49ec0c11e83fe" have entirely different histories.

24 changed files with 544 additions and 771 deletions

View File

@ -170,8 +170,6 @@ test-suite brittany-test-suite
build-depends: build-depends:
, hspec >= 2.8.3 && < 2.10 , hspec >= 2.8.3 && < 2.10
, HUnit >= 1.6.2 && < 1.7
, ansi-terminal >= 0.11.4 && < 0.12
, parsec ^>= 3.1.14 , parsec ^>= 3.1.14
, these ^>= 1.1 , these ^>= 1.1
hs-source-dirs: source/test-suite hs-source-dirs: source/test-suite

View File

@ -329,9 +329,7 @@ func =
foooooooooooooooooooooooooooooooo foooooooooooooooooooooooooooooooo
#test opapp-specialcasing-3 #test opapp-specialcasing-3
func = func = fooooooooooooooooooooooooooooooooo + foooooooooooooooooooooooooooooooo
fooooooooooooooooooooooooooooooooo
+ foooooooooooooooooooooooooooooooo
[ foooooooooooooooooooooooooooooooo [ foooooooooooooooooooooooooooooooo
, foooooooooooooooooooooooooooooooo , foooooooooooooooooooooooooooooooo
, foooooooooooooooooooooooooooooooo , foooooooooooooooooooooooooooooooo
@ -958,43 +956,3 @@ func = other $ meep
[q|hello [q|hello
world|] world|]
(some other very long linnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnne) (some other very long linnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnne)
#test multiline-lambda-whitespace
func =
Text.intercalate
"\n"
( (\(abc, def) ->
abc ++ def ++ "lkajsdljkasdlkjasldjkljkasd" ++ asdasdasdasd
)
<$> mylist
)
#test operator newline behaviour
func =
fromIntegral aaaaaaaaaaaaaaaaaaa
/ fromIntegral (aaaaaaaaaaaaaaaaaaa + bbbbbbbbbbbbbbbbbb)
#test multi-constructor associated data decl
data POtfuggj
instance BMGuwigoc POtfuggj where
data KVeeweknc POtfuggj r
= ILpieakli
| USilcnhkYaraposqu (WeyOoovf (Nubwlhtjd EculdW.QaeopznkAc r))
deriving stock (Lirylfj1, Jexr)
deriving anyclass Qart2.Vrzxuvcf
#test bang-type
data LabeledBool = LabeledBool !Int !Bool
#test block-comment after let
func = do
let cipInuihz = Vuozczdm.yhEfun tuhiuRasohy
let {- CAZEB mecwbd "Caa ||" -}
doeeRbaviceQzymin a b = olivhuwqbaq
iqnz biwomeJhhujy _ _ | biwomeJhhujy < volpoqAsizmHdwpl = pure 0
pure True
#test comment-inside-decl
func False = 0
-- comment
func True = 1

View File

@ -1278,9 +1278,7 @@ func =
foooooooooooooooooooooooooooooooo foooooooooooooooooooooooooooooooo
#test opapp-specialcasing-3 #test opapp-specialcasing-3
func = func = fooooooooooooooooooooooooooooooooo + foooooooooooooooooooooooooooooooo
fooooooooooooooooooooooooooooooooo
+ foooooooooooooooooooooooooooooooo
[ foooooooooooooooooooooooooooooooo [ foooooooooooooooooooooooooooooooo
, foooooooooooooooooooooooooooooooo , foooooooooooooooooooooooooooooooo
, foooooooooooooooooooooooooooooooo , foooooooooooooooooooooooooooooooo

View File

@ -10,8 +10,6 @@ module Language.Haskell.Brittany.Internal
-- re-export from utils: -- re-export from utils:
, extractCommentConfigs , extractCommentConfigs
, TraceFunc(TraceFunc) , TraceFunc(TraceFunc)
, Splitting.splitModuleDecls
, Splitting.extractDeclMap
) )
where where
@ -19,6 +17,7 @@ import Control.Monad.Trans.Except
import Data.CZipWith import Data.CZipWith
import qualified Data.Text as Text import qualified Data.Text as Text
import qualified Data.Text.Lazy as TextL import qualified Data.Text.Lazy as TextL
import qualified GHC hiding ( parseModule )
import qualified GHC.Driver.Session as GHC import qualified GHC.Driver.Session as GHC
import GHC.Hs import GHC.Hs
import qualified GHC.LanguageExtensions.Type as GHC import qualified GHC.LanguageExtensions.Type as GHC
@ -30,8 +29,6 @@ import Language.Haskell.Brittany.Internal.S3_ToBriDocTools
import Language.Haskell.Brittany.Internal.Prelude import Language.Haskell.Brittany.Internal.Prelude
import qualified Language.Haskell.Brittany.Internal.S1_Parsing import qualified Language.Haskell.Brittany.Internal.S1_Parsing
as Parsing as Parsing
import qualified Language.Haskell.Brittany.Internal.S2_SplitModule
as Splitting
import Language.Haskell.Brittany.Internal.StepOrchestrate import Language.Haskell.Brittany.Internal.StepOrchestrate
( processModule ) ( processModule )
import Language.Haskell.Brittany.Internal.Types import Language.Haskell.Brittany.Internal.Types
@ -82,13 +79,9 @@ parsePrintModule traceFunc configWithDebugs inputText = runExceptT $ do
case parseResult of case parseResult of
Left err -> throwE [ErrorInput err] Left err -> throwE [ErrorInput err]
Right x -> pure x Right x -> pure x
let moduleElementList = Splitting.splitModuleDecls parsedSource
(inlineConf, perItemConf) <- (inlineConf, perItemConf) <-
mapExceptT (fmap $ bimap (\(a, b) -> [ErrorMacroConfig a b]) id) mapExceptT (fmap $ bimap (\(a, b) -> [ErrorMacroConfig a b]) id)
$ extractCommentConfigs $ extractCommentConfigs (useTraceFunc traceFunc) parsedSource
(useTraceFunc traceFunc)
(Splitting.extractDeclMap parsedSource)
moduleElementList
let moduleConfig = cZipWith fromOptionIdentity config inlineConf let moduleConfig = cZipWith fromOptionIdentity config inlineConf
let disableFormatting = let disableFormatting =
moduleConfig & _conf_disable_formatting & confUnpack moduleConfig & _conf_disable_formatting & confUnpack
@ -103,12 +96,11 @@ parsePrintModule traceFunc configWithDebugs inputText = runExceptT $ do
& _econf_omit_output_valid_check & _econf_omit_output_valid_check
& confUnpack & confUnpack
(ews, outRaw) <- if hasCPP || omitCheck (ews, outRaw) <- if hasCPP || omitCheck
then lift then lift $ processModule traceFunc moduleConfig perItemConf parsedSource
$ processModule traceFunc moduleConfig perItemConf moduleElementList
else lift $ pPrintModuleAndCheck traceFunc else lift $ pPrintModuleAndCheck traceFunc
moduleConfig moduleConfig
perItemConf perItemConf
moduleElementList parsedSource
let hackF s = fromMaybe s let hackF s = fromMaybe s
$ TextL.stripPrefix (TextL.pack "-- BRITANY_INCLUDE_HACK ") s $ TextL.stripPrefix (TextL.pack "-- BRITANY_INCLUDE_HACK ") s
pure $ if hackAroundIncludes pure $ if hackAroundIncludes
@ -142,17 +134,17 @@ pPrintModuleAndCheck
:: TraceFunc :: TraceFunc
-> Config -> Config
-> PerItemConfig -> PerItemConfig
-> FinalList ModuleElement p -> GHC.ParsedSource
-> IO ([BrittanyError], TextL.Text) -> IO ([BrittanyError], TextL.Text)
pPrintModuleAndCheck traceFunc conf inlineConf moduleElementList = do pPrintModuleAndCheck traceFunc conf inlineConf parsedModule = do
let ghcOptions = conf & _conf_forward & _options_ghc & runIdentity let ghcOptions = conf & _conf_forward & _options_ghc & runIdentity
(errs, output) <- processModule traceFunc conf inlineConf moduleElementList (errs, output) <- processModule traceFunc conf inlineConf parsedModule
parseResult <- Parsing.parseModuleFromString ghcOptions parseResult <- Parsing.parseModuleFromString ghcOptions
"output" "output"
(\_ -> return $ Right ()) (\_ -> return $ Right ())
(TextL.unpack output) (TextL.unpack output)
let errs' = errs ++ case parseResult of let errs' = errs ++ case parseResult of
Left x -> [ErrorOutputCheck x] Left{} -> [ErrorOutputCheck]
Right{} -> [] Right{} -> []
return (errs', output) return (errs', output)
@ -170,14 +162,10 @@ parsePrintModuleTests conf filename input = do
case parseResult of case parseResult of
Left err -> return $ Left err Left err -> return $ Left err
Right (parsedModule, _) -> runExceptT $ do Right (parsedModule, _) -> runExceptT $ do
let moduleElementList = Splitting.splitModuleDecls parsedModule
(inlineConf, perItemConf) <- (inlineConf, perItemConf) <-
mapExceptT mapExceptT
(fmap (bimap (\(a, _) -> "when parsing inline config: " ++ a) id)) (fmap (bimap (\(a, _) -> "when parsing inline config: " ++ a) id))
$ extractCommentConfigs $ extractCommentConfigs (\_ -> pure ()) parsedModule
(\_ -> pure ())
(Splitting.extractDeclMap parsedModule)
moduleElementList
let moduleConf = cZipWith fromOptionIdentity conf inlineConf let moduleConf = cZipWith fromOptionIdentity conf inlineConf
let omitCheck = let omitCheck =
conf conf
@ -188,11 +176,11 @@ parsePrintModuleTests conf filename input = do
then lift $ processModule (TraceFunc $ \_ -> pure ()) then lift $ processModule (TraceFunc $ \_ -> pure ())
moduleConf moduleConf
perItemConf perItemConf
moduleElementList parsedModule
else lift $ pPrintModuleAndCheck (TraceFunc $ \_ -> pure ()) else lift $ pPrintModuleAndCheck (TraceFunc $ \_ -> pure ())
moduleConf moduleConf
perItemConf perItemConf
moduleElementList parsedModule
if null errs if null errs
then pure $ TextL.toStrict $ ltext then pure $ TextL.toStrict $ ltext
else throwE else throwE
@ -207,7 +195,7 @@ parsePrintModuleTests conf filename input = do
LayoutWarning str -> str LayoutWarning str -> str
ErrorUnknownNode str _ -> str ErrorUnknownNode str _ -> str
ErrorMacroConfig str _ -> "when parsing inline config: " ++ str ErrorMacroConfig str _ -> "when parsing inline config: " ++ str
ErrorOutputCheck str -> "Output is not syntactically valid: " ++ str ErrorOutputCheck -> "Output is not syntactically valid."
-- this approach would for if there was a pure GHC.parseDynamicFilePragma. -- this approach would for if there was a pure GHC.parseDynamicFilePragma.
-- Unfortunately that does not exist yet, so we cannot provide a nominally -- Unfortunately that does not exist yet, so we cannot provide a nominally
-- pure interface. -- pure interface.

View File

@ -64,8 +64,6 @@ keywords =
, "proc" , "proc"
, "rec" , "rec"
, "family" , "family"
, "stock"
, "anyclass"
] ]
extraKWs :: [String] extraKWs :: [String]

View File

@ -64,7 +64,6 @@ staticDefaultConfig = Config
, _lconfig_fixityBasedAddAlignParens = coerce False , _lconfig_fixityBasedAddAlignParens = coerce False
, _lconfig_operatorParenthesisRefactorMode = coerce PRMKeep , _lconfig_operatorParenthesisRefactorMode = coerce PRMKeep
, _lconfig_operatorAllowUnqualify = coerce True , _lconfig_operatorAllowUnqualify = coerce True
, _lconfig_allowSinglelineRecord = coerce True
} }
, _conf_errorHandling = ErrorHandlingConfig , _conf_errorHandling = ErrorHandlingConfig
{ _econf_produceOutputOnErrors = coerce False { _econf_produceOutputOnErrors = coerce False
@ -164,7 +163,7 @@ cmdlineConfigParser = do
, _lconfig_allowSingleLineExportList = mempty , _lconfig_allowSingleLineExportList = mempty
, _lconfig_allowHangingQuasiQuotes = mempty , _lconfig_allowHangingQuasiQuotes = mempty
, _lconfig_experimentalSemicolonNewlines = mempty , _lconfig_experimentalSemicolonNewlines = mempty
, _lconfig_allowSinglelineRecord = mempty -- , _lconfig_allowSinglelineRecord = mempty
, _lconfig_fixityAwareOps = mempty , _lconfig_fixityAwareOps = mempty
, _lconfig_fixityAwareTypeOps = mempty , _lconfig_fixityAwareTypeOps = mempty
, _lconfig_fixityBasedAddAlignParens = mempty , _lconfig_fixityBasedAddAlignParens = mempty

View File

@ -26,7 +26,7 @@ import Control.Monad.Trans.Except
import Language.Haskell.Brittany.Internal.Config.Config import Language.Haskell.Brittany.Internal.Config.Config
import Language.Haskell.Brittany.Internal.Config.Types import Language.Haskell.Brittany.Internal.Config.Types
import Language.Haskell.Brittany.Internal.Types import Language.Haskell.Brittany.Internal.Util.AST
import Language.Haskell.Brittany.Internal.Config.Types.Instances1 () import Language.Haskell.Brittany.Internal.Config.Types.Instances1 ()
import Language.Haskell.Brittany.Internal.Config.Types.Instances2 () import Language.Haskell.Brittany.Internal.Config.Types.Instances2 ()
-- import Language.Haskell.Brittany.Internal.Utils -- import Language.Haskell.Brittany.Internal.Utils
@ -44,26 +44,46 @@ data InlineConfigTarget
extractCommentConfigs extractCommentConfigs
:: (String -> IO ()) :: (String -> IO ())
-> Map GHC.RealSrcSpan [String] -> GHC.ParsedSource
-> FinalList ModuleElement a
-> ExceptT (String, String) IO (CConfig Maybe, PerItemConfig) -> ExceptT (String, String) IO (CConfig Maybe, PerItemConfig)
extractCommentConfigs _putErrorLn declMap moduleElementList = do extractCommentConfigs _putErrorLn modul = do
let comments = concatMapFinal (void moduleElementList) $ \case let (L _ (GHC.HsModule modAnn _ _ _ _ decls _ _)) = modul
MEExactModuleHead modul -> case GHC.hsmodAnn $ GHC.unLoc modul of let declMap :: Map GHC.RealSrcSpan [String]
declMap = Map.fromList
[ ( case span of
GHC.RealSrcSpan s _ -> s
GHC.UnhelpfulSpan _ -> error "unexpected UnhelpfulSpan"
, getDeclBindingNames decl
)
| decl <- decls
, let (L (GHC.SrcSpanAnn _ span) _) = decl
]
let epAnnComms = \case
GHC.EpAnn _ _ (GHC.EpaComments prior) -> prior GHC.EpAnn _ _ (GHC.EpaComments prior) -> prior
GHC.EpAnn _ _ (GHC.EpaCommentsBalanced prior following) -> GHC.EpAnn _ _ (GHC.EpaCommentsBalanced prior following) ->
prior ++ following prior ++ following
GHC.EpAnnNotUsed -> [] GHC.EpAnnNotUsed -> []
MEPrettyModuleHead{} -> [] let gatheredComments =
MEImportDecl{} -> [] join
MEDecl{} -> [] $ epAnnComms modAnn
MEComment (_, comment) -> [comment] : [ epAnnComms epAnn | L (GHC.SrcSpanAnn epAnn _) _x <- decls ]
MEWhitespace{} -> [] -- gatheredComments `forM_` \comm@(L anchor _) -> do
-- liftIO $ putErrorLn $ showOutputable comm
-- case Map.lookupLE (GHC.anchor anchor) declMap of
-- Nothing -> pure ()
-- Just (pos, le) -> do
-- liftIO $ putErrorLn $ " le = " ++ show (toConstr le) ++ " at " ++ show
-- (ExactPrint.Utils.ss2deltaEnd pos (GHC.anchor anchor))
-- case Map.lookupGE (GHC.anchor anchor) declMap of
-- Nothing -> pure ()
-- Just (pos, ge) -> do
-- liftIO $ putErrorLn $ " ge = " ++ show (toConstr ge) ++ " at " ++ show
-- (ExactPrint.Utils.ss2deltaStart (GHC.anchor anchor) pos)
lineConfigs <- sequence lineConfigs <- sequence
[ case Butcher.runCmdParserSimpleString line2 parser of [ case Butcher.runCmdParserSimpleString line2 parser of
Left err -> throwE (err, line2) Left err -> throwE (err, line2)
Right (target, conf) -> pure $ (GHC.anchor anchr, target, conf) Right (target, conf) -> pure $ (GHC.anchor anchr, target, conf)
| L anchr (EpaComment comm _) <- comments | L anchr (EpaComment comm _) <- gatheredComments
, Just line1 <- case comm of , Just line1 <- case comm of
EpaLineComment l -> EpaLineComment l ->
[ List.stripPrefix "-- BRITTANY" l [ List.stripPrefix "-- BRITTANY" l

View File

@ -135,14 +135,14 @@ data CLayoutConfig f = LayoutConfig
-- The implementation for this is a bit hacky and not tested; it might -- The implementation for this is a bit hacky and not tested; it might
-- break output syntax or not work properly for every kind of brace. So -- break output syntax or not work properly for every kind of brace. So
-- far I have considered `do` and `case-of`. -- far I have considered `do` and `case-of`.
, _lconfig_allowSinglelineRecord :: f (Last Bool) -- , _lconfig_allowSinglelineRecord :: f (Last Bool)
-- if true, layouts record data decls as a single line when possible, e.g. -- -- if true, layouts record data decls as a single line when possible, e.g.
-- > MyPoint { x :: Double, y :: Double } -- -- > MyPoint { x :: Double, y :: Double }
-- if false, always use the multi-line layout -- -- if false, always use the multi-line layout
-- > MyPoint -- -- > MyPoint
-- > { x :: Double -- -- > { x :: Double
-- > , y :: Double -- -- > , y :: Double
-- > } -- -- > }
, _lconfig_fixityAwareOps :: f (Last Bool) , _lconfig_fixityAwareOps :: f (Last Bool)
-- enables fixity-based layouting, e.g. -- enables fixity-based layouting, e.g.
-- > foo = -- > foo =

View File

@ -3,17 +3,15 @@
-- TODO92 -- TODO92
module Language.Haskell.Brittany.Internal.S2_SplitModule module Language.Haskell.Brittany.Internal.S2_SplitModule
( extractDeclMap ( splitModule
, splitModuleDecls )
, splitModuleStart where
) where
import Language.Haskell.Brittany.Internal.Prelude import Language.Haskell.Brittany.Internal.Prelude
import qualified Data.Generics as SYB import qualified Data.Generics as SYB
import qualified Data.Map as Map
import qualified GHC import qualified GHC
import GHC ( AddEpAnn(AddEpAnn) import GHC ( AddEpAnn(AddEpAnn)
, Anchor(Anchor) , Anchor(Anchor)
@ -58,49 +56,64 @@ import GHC.Parser.Annotation ( DeltaPos
) )
, EpaCommentTok(EpaEofComment) , EpaCommentTok(EpaEofComment)
) )
import GHC.Types.SrcLoc ( realSrcSpanEnd import GHC.Types.SrcLoc ( realSrcSpanEnd )
, realSrcSpanStart
)
import qualified Language.Haskell.GHC.ExactPrint.Types import qualified Language.Haskell.GHC.ExactPrint.Types
as ExactPrint as ExactPrint
import qualified Language.Haskell.GHC.ExactPrint.Utils import qualified Language.Haskell.GHC.ExactPrint.Utils
as ExactPrint as ExactPrint
import Safe ( maximumMay ) import Safe ( maximumMay )
import qualified Control.Monad.Trans.Writer.Strict
as WriterS
import Language.Haskell.Brittany.Internal.Components.BriDoc import Language.Haskell.Brittany.Internal.Components.BriDoc
import Language.Haskell.Brittany.Internal.ToBriDoc.Module import Language.Haskell.Brittany.Internal.ToBriDoc.Module
import Language.Haskell.Brittany.Internal.Types import Language.Haskell.Brittany.Internal.Types
import Language.Haskell.Brittany.Internal.Util.AST
extractDeclMap :: GHC.ParsedSource -> Map GHC.RealSrcSpan [String] splitModule
extractDeclMap modul = :: Bool
Map.fromList -> GHC.ParsedSource
[ ( case span of -> Maybe GHC.RealSrcLoc
GHC.RealSrcSpan s _ -> s -> FinalList ModuleElement ExactPrint.Pos
GHC.UnhelpfulSpan _ -> error "unexpected UnhelpfulSpan" splitModule shouldReformatHead lmod posWhere = do
, getDeclBindingNames decl
)
| decl <- decls
, let (L (GHC.SrcSpanAnn _ span) _) = decl
]
where (L _ (GHC.HsModule _ _ _ _ _ decls _ _)) = modul
splitModuleDecls :: GHC.ParsedSource -> FinalList ModuleElement ExactPrint.Pos
splitModuleDecls lmod = do
let L moduleSpan modl = lmod let L moduleSpan modl = lmod
HsModule _ _layout _name _exports _imports decls _ _ = modl HsModule _ _layout _name _exports imports decls _ _ = modl
(hsModAnn', finalComments) = case GHC.hsmodAnn modl of (hsModAnn', finalComments) = case GHC.hsmodAnn modl of
EpAnn a modAnns (EpaCommentsBalanced prior post) -> EpAnn a modAnns (EpaCommentsBalanced prior post) ->
(EpAnn a modAnns (EpaCommentsBalanced prior []), post) (EpAnn a modAnns (EpaCommentsBalanced prior []), post)
_ -> (GHC.hsmodAnn modl, []) _ -> (GHC.hsmodAnn modl, [])
moduleWithoutComments = L moduleSpan modl { GHC.hsmodAnn = hsModAnn' moduleWithoutComments =
, GHC.hsmodDecls = [] L moduleSpan modl { GHC.hsmodAnn = hsModAnn', GHC.hsmodDecls = [] }
} lastSpan <- if shouldReformatHead
lastSpan <- do then do
finalYield $ MEPrettyModuleHead moduleWithoutComments
let locBeforeImports =
maximumMay
$ [ realSrcSpanEnd $ anchor a
| L a _ <- case hsModAnn' of
EpAnn _ _ (EpaComments cs ) -> cs
EpAnn _ _ (EpaCommentsBalanced cs1 cs2) -> cs1 ++ cs2
EpAnnNotUsed -> error "unexpected EpAnnNotUsed"
]
++ [ pos | Just pos <- [posWhere] ]
let (importLines, lastSpan) = finalToList $ transformToImportLine
( maybe 0 srcLocLine locBeforeImports
, maybe 1 srcLocCol locBeforeImports
)
imports
let commentedImports = groupifyImportLines importLines
sortCommentedImports commentedImports `forM_` \case
EmptyLines n ->
finalYield $ MEWhitespace $ DifferentLine n 1
SamelineComment{} ->
error "brittany internal error: splitModule SamelineComment"
NewlineComment comm -> finalYield $ MEComment comm
ImportStatement record -> do
forM_ (commentsBefore record) $ finalYield . MEComment
finalYield
$ MEImportDecl (importStatement record) (commentsSameline record)
forM_ (commentsAfter record) $ finalYield . MEComment
pure $ lastSpan
else do
finalYield $ MEExactModuleHead moduleWithoutComments finalYield $ MEExactModuleHead moduleWithoutComments
pure pure
$ maybe (1, 1) (ExactPrint.ss2posEnd) $ maybe (1, 1) (ExactPrint.ss2posEnd)
@ -119,43 +132,12 @@ splitModuleDecls lmod = do
EpAnnNotUsed -> [] EpAnnNotUsed -> []
] ]
++ [ span ++ [ span
| L (SrcSpanAnn _ (GHC.RealSrcSpan span _)) _ <- GHC.hsmodImports modl | L (SrcSpanAnn _ (GHC.RealSrcSpan span _)) _ <- GHC.hsmodImports
modl
] ]
spanAfterDecls <- enrichDecls lastSpan decls spanAfterDecls <- enrichDecls lastSpan decls
enrichComms spanAfterDecls finalComments enrichComms spanAfterDecls finalComments
splitModuleStart
:: GHC.ParsedSource
-> Maybe GHC.RealSrcLoc
-> FinalList ModuleElement ExactPrint.Pos
splitModuleStart modul posWhere = do
finalYield $ MEPrettyModuleHead modul
let locBeforeImports =
maximumMay
$ [ realSrcSpanEnd $ anchor a
| L a _ <- case GHC.hsmodAnn $ unLoc modul of
EpAnn _ _ (EpaComments cs ) -> cs
EpAnn _ _ (EpaCommentsBalanced cs1 cs2) -> cs1 ++ cs2
EpAnnNotUsed -> error "unexpected EpAnnNotUsed"
]
++ [ pos | Just pos <- [posWhere] ]
let (importLines, lastSpan) = finalToList $ transformToImportLine
( maybe 0 srcLocLine locBeforeImports
, maybe 1 srcLocCol locBeforeImports
)
(GHC.hsmodImports $ unLoc modul)
let commentedImports = groupifyImportLines importLines
sortCommentedImports commentedImports `forM_` \case
EmptyLines n -> finalYield $ MEWhitespace $ DifferentLine n 1
SamelineComment{} ->
error "brittany internal error: splitModuleStart SamelineComment"
NewlineComment comm -> finalYield $ MEComment comm
ImportStatement record -> do
forM_ (commentsBefore record) $ finalYield . MEComment
finalYield $ MEImportDecl (importStatement record)
(commentsSameline record)
forM_ (commentsAfter record) $ finalYield . MEComment
pure $ lastSpan
enrichComms enrichComms
:: ExactPrint.Pos -> [LEpaComment] -> FinalList ModuleElement ExactPrint.Pos :: ExactPrint.Pos -> [LEpaComment] -> FinalList ModuleElement ExactPrint.Pos
@ -166,57 +148,52 @@ enrichComms lastSpanEnd = \case
SameLine i -> SameLine i SameLine i -> SameLine i
DifferentLine l c -> DifferentLine (l - 1) c DifferentLine l c -> DifferentLine (l - 1) c
enrichComms (ExactPrint.ss2posEnd span) commRest enrichComms (ExactPrint.ss2posEnd span) commRest
lcomm@(L (Anchor span _) _) : commRest -> do (L (Anchor span _) (EpaComment comm _) : commRest) -> do
case ExactPrint.ss2delta lastSpanEnd span of case ExactPrint.ss2delta lastSpanEnd span of
SameLine i -> do SameLine i -> do
finalYield $ MEComment (i, lcomm) finalYield $ MEComment (i, comm)
DifferentLine l c -> do DifferentLine l c -> do
finalYield $ MEWhitespace $ DifferentLine (l - 1) c finalYield $ MEWhitespace $ DifferentLine (l - 1) c
finalYield $ MEComment (0, lcomm) finalYield $ MEComment (0, comm)
enrichComms (ExactPrint.ss2posEnd span) commRest enrichComms (ExactPrint.ss2posEnd span) commRest
enrichDecls enrichDecls
:: ExactPrint.Pos -> [LHsDecl GhcPs] -> FinalList ModuleElement ExactPrint.Pos :: ExactPrint.Pos -> [LHsDecl GhcPs] -> FinalList ModuleElement ExactPrint.Pos
enrichDecls lastSpanEnd = \case enrichDecls lastSpanEnd = \case
[] -> finalPure $ lastSpanEnd [] -> finalPure $ lastSpanEnd
ldecl@(L (SrcSpanAnn dAnn (GHC.RealSrcSpan span _)) _) : declRest -> (L (SrcSpanAnn dAnn rlspan@(GHC.RealSrcSpan span _)) decl : declRest) ->
case dAnn of case dAnn of
EpAnn _dAnchor _items (EpaComments _dComments) -> do EpAnn dAnchor items (EpaComments dComments) -> do
let let
commentExtract withoutComments =
:: [LEpaComment] -> WriterS.Writer [LEpaComment] [LEpaComment] (L (SrcSpanAnn (EpAnn dAnchor items (EpaComments [])) rlspan) decl)
commentExtract comms = do commentExtract = \case
let (innerComments, outerComments) = L (GHC.Anchor anch _) EpaComment{} -> ExactPrint.ss2posEnd anch
partition -- It would be really nice if `ExactPrint.ss2posEnd span` was
(\(L (Anchor anch _) _) -> -- sufficient. But for some reason the comments are not
( realSrcSpanStart anch < realSrcSpanEnd span -- (consistently) included in the length of the anchor. I.e.
&& realSrcSpanEnd anch > realSrcSpanStart span -- there are cases where a syntax tree node has an anchor from
) -- pos A -> pos B. But then somewhere _below_ that node is a
) -- comment that has an anchor pos B -> pos C.
comms -- We simply detect this here.
WriterS.tell outerComments -- We probably do some redundant `SYB.everything` lookups
pure innerComments -- throughout the code now. But optimizing it is not easy, and
(ldecl', extractedComments) = WriterS.runWriter -- at worst it is larger constant factor on the size of the
$ SYB.everywhereM (SYB.mkM commentExtract) ldecl -- input, so it isn't _that_ bad.
fixedSpanEnd = SYB.everything
max
(SYB.mkQ (ExactPrint.ss2posEnd span) commentExtract)
decl
case ExactPrint.ss2delta lastSpanEnd span of case ExactPrint.ss2delta lastSpanEnd span of
SameLine{} -> pure () SameLine{} -> pure ()
DifferentLine n _ -> DifferentLine n _ ->
finalYield $ MEWhitespace $ DifferentLine (n - 1) 1 finalYield $ MEWhitespace $ DifferentLine (n - 1) 1
let fixedSpanEnd = ExactPrint.ss2posEnd span let (afterComms, span2) = finalToList $ enrichComms fixedSpanEnd (reverse dComments)
let (afterComms, span2) = finalToList let (immediate, later) = List.span (\case
$ enrichComms fixedSpanEnd
(List.sortOn (\(L l _) -> l) extractedComments)
let (immediate, later) =
List.span
(\case
MEComment{} -> True MEComment{} -> True
_ -> False _ -> False
) ) afterComms
afterComms finalYield $ MEDecl withoutComments [ comm | MEComment comm <- immediate ]
finalYield
$ MEDecl
ldecl'
[ (ind, GHC.ac_tok comm) | MEComment (ind, L _ comm) <- immediate ]
later `forM_` finalYield later `forM_` finalYield
enrichDecls span2 declRest enrichDecls span2 declRest
EpAnn _anchor _items (EpaCommentsBalanced{}) -> EpAnn _anchor _items (EpaCommentsBalanced{}) ->
@ -230,8 +207,8 @@ enrichDecls lastSpanEnd = \case
data ImportLine data ImportLine
= EmptyLines Int = EmptyLines Int
| SamelineComment (Int, LEpaComment) | SamelineComment (Int, EpaCommentTok)
| NewlineComment (Int, LEpaComment) -- indentation and comment | NewlineComment (Int, EpaCommentTok) -- indentation and comment
| ImportStatement ImportStatementRecord | ImportStatement ImportStatementRecord
instance Show ImportLine where instance Show ImportLine where
@ -244,10 +221,10 @@ instance Show ImportLine where
(length $ commentsAfter r) (length $ commentsAfter r)
data ImportStatementRecord = ImportStatementRecord data ImportStatementRecord = ImportStatementRecord
{ commentsBefore :: [(Int, LEpaComment)] { commentsBefore :: [(Int, EpaCommentTok)]
, importStatement :: LImportDecl GhcPs , importStatement :: LImportDecl GhcPs
, commentsSameline :: [(Int, EpaCommentTok)] , commentsSameline :: [(Int, EpaCommentTok)]
, commentsAfter :: [(Int, LEpaComment)] , commentsAfter :: [(Int, EpaCommentTok)]
} }
instance Show ImportStatementRecord where instance Show ImportStatementRecord where
@ -266,13 +243,13 @@ transformToImportLine startPos is =
:: [LEpaComment] -> ExactPrint.Pos -> FinalList ImportLine ExactPrint.Pos :: [LEpaComment] -> ExactPrint.Pos -> FinalList ImportLine ExactPrint.Pos
flattenComms = \case flattenComms = \case
[] -> finalPure [] -> finalPure
lcomm@(L (Anchor span _) _) : commRest -> \lastSpanEnd -> do (L (Anchor span _) (EpaComment comm _) : commRest) -> \lastSpanEnd -> do
case ExactPrint.ss2delta lastSpanEnd span of case ExactPrint.ss2delta lastSpanEnd span of
SameLine i -> do SameLine i -> do
finalYield $ SamelineComment (i, lcomm) finalYield $ SamelineComment (i, comm)
DifferentLine l c -> do DifferentLine l c -> do
finalYield $ EmptyLines (l - 1) finalYield $ EmptyLines (l - 1)
finalYield $ NewlineComment (c - 1, lcomm) finalYield $ NewlineComment (c - 1, comm)
flattenComms commRest (ExactPrint.ss2posEnd span) flattenComms commRest (ExactPrint.ss2posEnd span)
flattenDecls flattenDecls
:: [LImportDecl GhcPs] :: [LImportDecl GhcPs]
@ -288,12 +265,14 @@ transformToImportLine startPos is =
EpAnn anch s (EpaCommentsBalanced cs1 cs2) -> EpAnn anch s (EpaCommentsBalanced cs1 cs2) ->
(reverse cs1, reverse cs2, EpAnn anch s (EpaComments [])) (reverse cs1, reverse cs2, EpAnn anch s (EpaComments []))
EpAnnNotUsed -> ([], [], EpAnnNotUsed) EpAnnNotUsed -> ([], [], EpAnnNotUsed)
in do in
do
span1 <- flattenComms commsBefore lastSpanEnd span1 <- flattenComms commsBefore lastSpanEnd
let newlines = case ExactPrint.ss2delta span1 declSpan of let newlines = case ExactPrint.ss2delta span1 declSpan of
SameLine _ -> 0 SameLine _ -> 0
DifferentLine i _ -> i - 1 DifferentLine i _ -> i - 1
finalYield $ EmptyLines newlines finalYield
$ EmptyLines newlines
finalYield $ ImportStatement ImportStatementRecord finalYield $ ImportStatement ImportStatementRecord
{ commentsBefore = [] { commentsBefore = []
, importStatement = L (SrcSpanAnn cleanEpAnn srcSpan) decl , importStatement = L (SrcSpanAnn cleanEpAnn srcSpan) decl
@ -307,15 +286,15 @@ transformToImportLine startPos is =
in in
flattenDecls is startPos flattenDecls is startPos
data Partial = PartialCommsOnly [(Int, LEpaComment)] data Partial = PartialCommsOnly [(Int, EpaCommentTok)]
| PartialImport ImportStatementRecord | PartialImport ImportStatementRecord
groupifyImportLines :: [ImportLine] -> [ImportLine] groupifyImportLines :: [ImportLine] -> [ImportLine]
groupifyImportLines ls = finalToList_ $ go (PartialCommsOnly []) ls groupifyImportLines ls = finalToList_ $ go (PartialCommsOnly []) ls
where where
go acc [] = case acc of go acc [] = case acc of
PartialCommsOnly comms -> reverse comms `forM_` \comm -> PartialCommsOnly comms ->
finalYield $ NewlineComment comm reverse comms `forM_` \comm -> finalYield $ NewlineComment comm
PartialImport partialRecord -> PartialImport partialRecord ->
finalYield $ ImportStatement $ unpartial partialRecord finalYield $ ImportStatement $ unpartial partialRecord
go acc (line1 : lineR) = do go acc (line1 : lineR) = do
@ -328,9 +307,8 @@ groupifyImportLines ls = finalToList_ $ go (PartialCommsOnly []) ls
SamelineComment comm -> do SamelineComment comm -> do
pure $ PartialCommsOnly (comm : comms) pure $ PartialCommsOnly (comm : comms)
NewlineComment comm -> pure $ PartialCommsOnly (comm : comms) NewlineComment comm -> pure $ PartialCommsOnly (comm : comms)
ImportStatement record -> pure $ PartialImport $ record ImportStatement record ->
{ commentsBefore = comms pure $ PartialImport $ record { commentsBefore = comms }
}
PartialImport partialRecord -> case line1 of PartialImport partialRecord -> case line1 of
e@EmptyLines{} -> do e@EmptyLines{} -> do
finalYield $ ImportStatement $ unpartial partialRecord finalYield $ ImportStatement $ unpartial partialRecord
@ -339,8 +317,7 @@ groupifyImportLines ls = finalToList_ $ go (PartialCommsOnly []) ls
SamelineComment comm -> do SamelineComment comm -> do
if (null $ commentsAfter partialRecord) if (null $ commentsAfter partialRecord)
then pure $ PartialImport partialRecord then pure $ PartialImport partialRecord
{ commentsSameline = tokenOnly comm { commentsSameline = comm : commentsSameline partialRecord
: commentsSameline partialRecord
} }
else pure $ PartialImport partialRecord else pure $ PartialImport partialRecord
{ commentsAfter = comm : commentsAfter partialRecord { commentsAfter = comm : commentsAfter partialRecord
@ -356,8 +333,6 @@ groupifyImportLines ls = finalToList_ $ go (PartialCommsOnly []) ls
pure $ PartialImport $ record { commentsBefore = contestedComments } pure $ PartialImport $ record { commentsBefore = contestedComments }
-- comments in between will stay connected to the following decl -- comments in between will stay connected to the following decl
go newAcc lineR go newAcc lineR
tokenOnly :: (Int, LEpaComment) -> (Int, EpaCommentTok)
tokenOnly (ind, L _ (EpaComment tok _)) = (ind, tok)
unpartial :: ImportStatementRecord -> ImportStatementRecord unpartial :: ImportStatementRecord -> ImportStatementRecord
unpartial partialRecord = ImportStatementRecord unpartial partialRecord = ImportStatementRecord
{ commentsBefore = reverse (commentsBefore partialRecord) { commentsBefore = reverse (commentsBefore partialRecord)
@ -386,8 +361,8 @@ sortCommentedImports =
Left x -> [x] Left x -> [x]
Right y -> ImportStatement <$> y Right y -> ImportStatement <$> y
sortGroups :: [ImportStatementRecord] -> [ImportStatementRecord] sortGroups :: [ImportStatementRecord] -> [ImportStatementRecord]
sortGroups = List.sortOn sortGroups =
(moduleNameString . unLoc . ideclName . unLoc . importStatement) List.sortOn (moduleNameString . unLoc . ideclName . unLoc . importStatement)
groupify :: [ImportLine] -> [Either ImportLine [ImportStatementRecord]] groupify :: [ImportLine] -> [Either ImportLine [ImportStatementRecord]]
groupify cs = go [] cs groupify cs = go [] cs
where where

View File

@ -389,9 +389,6 @@ docSeq :: [ToBriDocM BriDocNumbered] -> ToBriDocM BriDocNumbered
docSeq [] = docEmpty docSeq [] = docEmpty
docSeq l = allocateNode . BDSeq =<< sequence l docSeq l = allocateNode . BDSeq =<< sequence l
docSeqSep :: [ToBriDocM BriDocNumbered] -> ToBriDocM BriDocNumbered
docSeqSep = docSeq . List.intersperse docSeparator
docLines :: [ToBriDocM BriDocNumbered] -> ToBriDocM BriDocNumbered docLines :: [ToBriDocM BriDocNumbered] -> ToBriDocM BriDocNumbered
docLines l = allocateNode . BDLines =<< sequence l docLines l = allocateNode . BDLines =<< sequence l
@ -723,10 +720,6 @@ instance DocFlushCommsPost (Maybe GHC.RealSrcSpan) (ToBriDocM BriDocNumbered) wh
bd <- bdm bd <- bdm
pure (i1, BDFlushCommentsPost (GHC.realSrcSpanEnd loc) shouldMark bd) pure (i1, BDFlushCommentsPost (GHC.realSrcSpanEnd loc) shouldMark bd)
instance DocFlushCommsPost GHC.EpaLocation (ToBriDocM BriDocNumbered) where
docFlushCommsPost shouldMark epaLocation =
docFlushCommsPost shouldMark (Just $ GHC.epaLocationRealSrcSpan epaLocation)
instance DocFlushCommsPost ann (ToBriDocM BriDocNumbered) instance DocFlushCommsPost ann (ToBriDocM BriDocNumbered)
=> DocFlushCommsPost ann (ToBriDocM [BriDocNumbered]) where => DocFlushCommsPost ann (ToBriDocM [BriDocNumbered]) where
docFlushCommsPost shouldMark loc bdm = do docFlushCommsPost shouldMark loc bdm = do

View File

@ -275,53 +275,21 @@ layoutBriDocM = \case
layoutBriDocM bd layoutBriDocM bd
BDFlushCommentsPrior loc bd -> do BDFlushCommentsPrior loc bd -> do
comms <- takeBefore loc comms <- takeBefore loc
startCurY <- mGet <&> _lstate_curY
printComments comms printComments comms
mModify (\s -> s + CommentCounter (length comms)) mModify (\s -> s + CommentCounter (length comms))
mModify $ \s -> s mModify $ \s -> s
{ _lstate_markerForDelta = Nothing { _lstate_markerForDelta = Nothing
, _lstate_plannedSpace = , _lstate_plannedSpace = case _lstate_markerForDelta s of
case _lstate_markerForDelta s of
Nothing -> _lstate_plannedSpace s Nothing -> _lstate_plannedSpace s
Just m -> Just m ->
let p1 = (srcLocLine m, srcLocCol m) let p1 = (srcLocLine m, srcLocCol m)
p2 = (srcLocLine loc, srcLocCol loc) p2 = (srcLocLine loc, srcLocCol loc)
in -- trace ("_lstate_plannedSpace = " ++ show (_lstate_plannedSpace s) -- traceShow (m, ExactPrint.pos2delta p1 p2) $ pure ()
-- ++ ", _lstate_markerForDelta = " ++ show (_lstate_markerForDelta s) in case ExactPrint.pos2delta p1 p2 of
-- ++ ", _lstate_curY = " ++ show (_lstate_curY s) SameLine{} -> _lstate_plannedSpace s
-- ++ ", p1 = " ++ show p1
-- ++ ", p2 = " ++ show p2
-- ++ ", startCurY = " ++ show startCurY
-- -- ++ ", delta = " ++ show (ExactPrint.pos2delta p1 p2)
-- ) $
case ExactPrint.pos2delta p1 p2 of
SameLine iDelta -> case _lstate_plannedSpace s of
-- There is a delta after a marker. That should only happen
-- after a block-comment. And the marker-delta is SameLine,
-- so if layout doesn't force a newline we respect the marker
-- delta (i.e. respect whitespace immediately after a block
-- comment) or we just use the plan.
PlannedNone -> PlannedSameline iDelta
PlannedSameline i -> PlannedSameline (max (iDelta - 0) i)
p@PlannedNewline{} -> p
p@PlannedDelta{} -> p
DifferentLine n _ -> case _lstate_plannedSpace s of DifferentLine n _ -> case _lstate_plannedSpace s of
-- Marker with DifferentLine delta means that we want to PlannedNone -> PlannedNone
-- reproduce the newlines that were present in the input. PlannedSameline i -> PlannedDelta n (_lstate_curY s + i)
-- These will be emptylines in cases where it makes sense to
-- reproduce them, e.g. between statements in a do-block.
PlannedNone -> PlannedDelta n startCurY
-- ^^^^^^^^^
--
-- after a block-comment, _lstate_curY
-- matches the end of the comment.
-- But to not break layout we need to
-- restore the original.
-- E.g. consider > let {-comm-}
-- > x = 13
--
-- vvvvvvvvvvvvvvv
PlannedSameline i -> PlannedDelta n (startCurY + i)
PlannedNewline{} -> PlannedNewline n PlannedNewline{} -> PlannedNewline n
PlannedDelta _ i -> PlannedDelta n i PlannedDelta _ i -> PlannedDelta n i
} }

View File

@ -1,9 +1,9 @@
{-# LANGUAGE NoImplicitPrelude #-} {-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE DataKinds #-}
module Language.Haskell.Brittany.Internal.StepOrchestrate module Language.Haskell.Brittany.Internal.StepOrchestrate
( processModule ( processModule
) where )
where
import Language.Haskell.Brittany.Internal.Prelude import Language.Haskell.Brittany.Internal.Prelude
@ -15,8 +15,7 @@ import qualified Data.Text.Lazy as TextL
import qualified Data.Text.Lazy.Builder as TextL.Builder import qualified Data.Text.Lazy.Builder as TextL.Builder
import qualified Data.Text.Lazy.Builder as Text.Builder import qualified Data.Text.Lazy.Builder as Text.Builder
import qualified GHC import qualified GHC
import GHC ( EpaComment(EpaComment) import GHC ( EpaCommentTok
, EpaCommentTok
( EpaBlockComment ( EpaBlockComment
, EpaEofComment , EpaEofComment
, EpaLineComment , EpaLineComment
@ -37,7 +36,7 @@ import Language.Haskell.Brittany.Internal.Config.Types
import Language.Haskell.Brittany.Internal.Config.Types.Instances2 import Language.Haskell.Brittany.Internal.Config.Types.Instances2
( ) ( )
import Language.Haskell.Brittany.Internal.S2_SplitModule import Language.Haskell.Brittany.Internal.S2_SplitModule
( splitModuleStart ) ( splitModule )
import Language.Haskell.Brittany.Internal.S3_ToBriDocTools import Language.Haskell.Brittany.Internal.S3_ToBriDocTools
import Language.Haskell.Brittany.Internal.S4_WriteBriDoc import Language.Haskell.Brittany.Internal.S4_WriteBriDoc
( ppBriDoc ) ( ppBriDoc )
@ -47,8 +46,7 @@ import Language.Haskell.Brittany.Internal.ToBriDoc.Module
import Language.Haskell.Brittany.Internal.Types import Language.Haskell.Brittany.Internal.Types
import Language.Haskell.Brittany.Internal.Util.AST import Language.Haskell.Brittany.Internal.Util.AST
import Language.Haskell.Brittany.Internal.Utils import Language.Haskell.Brittany.Internal.Utils
import Language.Haskell.Brittany.Internal.ToBriDoc import Language.Haskell.Brittany.Internal.ToBriDoc (layouters)
( layouters )
@ -60,10 +58,18 @@ processModule
:: TraceFunc :: TraceFunc
-> Config -> Config
-> PerItemConfig -> PerItemConfig
-> FinalList ModuleElement p -> GHC.ParsedSource
-> IO ([BrittanyError], TextL.Text) -> IO ([BrittanyError], TextL.Text)
processModule traceFunc conf inlineConf moduleElems = do processModule traceFunc conf inlineConf parsedModule = do
let FinalList moduleElementsStream = moduleElems let shouldReformatHead =
conf & _conf_layout & _lconfig_reformatModulePreamble & confUnpack
let
wrapNonDeclToBriDoc = MultiRWSS.withMultiReader conf
. MultiRWSS.withMultiState_ (CommentCounter 0)
FinalList moduleElementsStream = splitModule
shouldReformatHead
parsedModule
(fmap GHC.realSrcSpanStart $ obtainAnnPos (GHC.hsmodAnn $ GHC.unLoc parsedModule) GHC.AnnWhere)
((out, errs), debugStrings) = ((out, errs), debugStrings) =
runIdentity runIdentity
$ MultiRWSS.runMultiRWSTNil $ MultiRWSS.runMultiRWSTNil
@ -73,7 +79,59 @@ processModule traceFunc conf inlineConf moduleElems = do
$ MultiRWSS.withMultiReader traceFunc $ MultiRWSS.withMultiReader traceFunc
$ moduleElementsStream $ moduleElementsStream
(\modElem cont -> do (\modElem cont -> do
processModuleElement modElem case modElem of
MEExactModuleHead modHead -> wrapNonDeclToBriDoc $ do
bdMay <- ppModuleHead modHead
case bdMay of
Nothing -> pure ()
Just bd -> ppBriDoc bd True
MEPrettyModuleHead (L loc modHead) -> wrapNonDeclToBriDoc $ do
case modHead of
HsModule epAnn _layoutInfo Nothing Nothing _ _ _ _ -> do
(bd, _) <-
briDocMToPPM layouters
$ maybe id
docFlushRemaining
(srcSpanFileName_maybe loc)
$ docHandleComms epAnn docSeparator
ppBriDoc bd True
HsModule _ _layoutInfo Nothing Just{} _ _ _ _ -> error
"brittany internal error: exports without module name"
HsModule epAnn _layoutInfo (Just n) les _ _ _ _ -> do
(bd, _) <-
briDocMToPPM layouters
$ maybe id
docFlushRemaining
(srcSpanFileName_maybe loc)
$ moduleNameExportBridoc epAnn n les
ppBriDoc bd True
MEImportDecl importDecl immediateAfterComms ->
wrapNonDeclToBriDoc $ do
(bd, _) <-
briDocMToPPM layouters
$ docSeq
( layoutImport importDecl
: map commentToDoc immediateAfterComms
)
ppBriDoc bd False
MEDecl decl immediateAfterComms -> do
let declConfig = getDeclConfig conf inlineConf decl
MultiRWSS.withMultiReader declConfig
$ MultiRWSS.withMultiState_ (CommentCounter 0)
$ ppToplevelDecl decl immediateAfterComms
MEComment (ind, EpaLineComment str) -> do
mTell $ TextL.Builder.fromString (replicate ind ' ' ++ str)
mTell $ TextL.Builder.fromString "\n"
MEComment (ind, EpaBlockComment str) -> do
mTell $ TextL.Builder.fromString (replicate ind ' ' ++ str)
mTell $ TextL.Builder.fromString "\n"
MEComment (_, EpaEofComment) -> pure ()
MEComment _ ->
mTell $ TextL.Builder.fromString "some other comment"
MEWhitespace dp -> do
-- mTell $ TextL.Builder.fromString "B"
-- mTell $ TextL.Builder.fromString ("whitespace " ++ show dp)
ppmMoveToExactLoc dp
cont cont
) )
(\x -> do (\x -> do
@ -93,94 +151,13 @@ processModule traceFunc conf inlineConf moduleElems = do
-- MEExactModuleHead{} -> useTraceFunc traceFunc "MEExactModuleHead" -- MEExactModuleHead{} -> useTraceFunc traceFunc "MEExactModuleHead"
-- MEPrettyModuleHead{} -> useTraceFunc traceFunc "MEPrettyModuleHead" -- MEPrettyModuleHead{} -> useTraceFunc traceFunc "MEPrettyModuleHead"
-- MEImportDecl{} -> useTraceFunc traceFunc "MEImportDecl" -- MEImportDecl{} -> useTraceFunc traceFunc "MEImportDecl"
-- MEDecl decl _ -> -- MEDecl{} -> useTraceFunc traceFunc "MEDecl"
-- useTraceFunc -- MEComment{} -> useTraceFunc traceFunc "MEComment"
-- traceFunc
-- ("MEDecl " ++ intercalate "," (getDeclBindingNames decl))
-- MEComment (y, L _ (EpaComment (EpaLineComment str) _)) ->
-- useTraceFunc traceFunc ("MEComment " ++ show y ++ " " ++ str)
-- MEComment (y, L _ (EpaComment (EpaBlockComment str) _)) ->
-- useTraceFunc traceFunc ("MEComment " ++ show y ++ " " ++ take 5 str)
-- MEComment (y, _) ->
-- useTraceFunc traceFunc ("MEComment " ++ show y ++ " _")
-- MEWhitespace dp -> useTraceFunc traceFunc ("MEWhitespace " ++ show dp) -- MEWhitespace dp -> useTraceFunc traceFunc ("MEWhitespace " ++ show dp)
-- rest -- rest
-- ) -- )
-- (\_ -> pure ()) -- (\_ -> pure ())
pure (errs, TextL.Builder.toLazyText out) pure (errs, TextL.Builder.toLazyText out)
where
shouldReformatHead =
conf & _conf_layout & _lconfig_reformatModulePreamble & confUnpack
wrapNonDeclToBriDoc =
MultiRWSS.withMultiReader conf . MultiRWSS.withMultiState_
(CommentCounter 0)
processModuleElement
:: ModuleElement
-> MultiRWSS.MultiRWST
'[TraceFunc]
'[Text.Builder.Builder , [BrittanyError] , Seq String]
'[]
Identity
()
processModuleElement = \case
MEExactModuleHead modHead -> if shouldReformatHead
then do
let FinalList startElems =
splitModuleStart
modHead
( fmap GHC.realSrcSpanStart
$ obtainAnnPos (GHC.hsmodAnn $ GHC.unLoc modHead) GHC.AnnWhere
)
startElems
(\modElem cont -> do
processModuleElement modElem
cont
)
(\_ -> pure ())
else wrapNonDeclToBriDoc $ do
bdMay <- ppModuleHead modHead
case bdMay of
Nothing -> pure ()
Just bd -> do
ppBriDoc bd True
mTell $ Text.Builder.fromString "\n"
MEPrettyModuleHead (L loc modHead) -> wrapNonDeclToBriDoc $ do
case modHead of
HsModule epAnn _layoutInfo Nothing Nothing _ _ _ _ -> do
(bd, _) <-
briDocMToPPM layouters
$ maybe id docFlushRemaining (srcSpanFileName_maybe loc)
$ docHandleComms epAnn docSeparator
ppBriDoc bd True
HsModule _ _layoutInfo Nothing Just{} _ _ _ _ ->
error "brittany internal error: exports without module name"
HsModule epAnn _layoutInfo (Just n) les _ _ _ _ -> do
(bd, _) <-
briDocMToPPM layouters
$ maybe id docFlushRemaining (srcSpanFileName_maybe loc)
$ moduleNameExportBridoc epAnn n les
ppBriDoc bd True
MEImportDecl importDecl immediateAfterComms -> wrapNonDeclToBriDoc $ do
(bd, _) <- briDocMToPPM layouters $ docSeq
(layoutImport importDecl : map commentToDoc immediateAfterComms)
ppBriDoc bd False
MEDecl decl immediateAfterComms -> do
let declConfig = getDeclConfig conf inlineConf decl
MultiRWSS.withMultiReader declConfig
$ MultiRWSS.withMultiState_ (CommentCounter 0)
$ ppToplevelDecl decl immediateAfterComms
MEComment (ind, L _ (EpaComment (EpaLineComment str) _)) -> do
mTell $ TextL.Builder.fromString (replicate ind ' ' ++ str)
mTell $ TextL.Builder.fromString "\n"
MEComment (ind, L _ (EpaComment (EpaBlockComment str) _)) -> do
mTell $ TextL.Builder.fromString (replicate ind ' ' ++ str)
mTell $ TextL.Builder.fromString "\n"
MEComment (_, L _ (EpaComment EpaEofComment _)) -> pure ()
MEComment _ -> mTell $ TextL.Builder.fromString "some other comment"
MEWhitespace dp -> do
-- mTell $ TextL.Builder.fromString "B"
-- mTell $ TextL.Builder.fromString ("whitespace " ++ show dp)
ppmMoveToExactLoc dp
commentToDoc :: (Int, EpaCommentTok) -> ToBriDocM BriDocNumbered commentToDoc :: (Int, EpaCommentTok) -> ToBriDocM BriDocNumbered
commentToDoc (indent, c) = case c of commentToDoc (indent, c) = case c of
@ -220,13 +197,17 @@ processDefault x = do
_ -> mTell $ Text.Builder.fromString $ List.dropWhileEnd ((==) '\n') str _ -> mTell $ Text.Builder.fromString $ List.dropWhileEnd ((==) '\n') str
getDeclConfig :: Config -> PerItemConfig -> GHC.LHsDecl GhcPs -> Config getDeclConfig
:: Config
-> PerItemConfig
-> GHC.LHsDecl GhcPs
-> Config
getDeclConfig config inlineConf decl = cZipWith fromOptionIdentity config getDeclConfig config inlineConf decl = cZipWith fromOptionIdentity config
$ mconcat (catMaybes (mBindingConfs ++ [mDeclConf])) $ mconcat (catMaybes (mBindingConfs ++ [mDeclConf]))
where where
declBindingNames = getDeclBindingNames decl declBindingNames = getDeclBindingNames decl
mBindingConfs = declBindingNames <&> \n -> mBindingConfs =
Map.lookup n $ _icd_perBinding inlineConf declBindingNames <&> \n -> Map.lookup n $ _icd_perBinding inlineConf
mDeclConf = case GHC.locA $ GHC.getLoc decl of mDeclConf = case GHC.locA $ GHC.getLoc decl of
GHC.RealSrcSpan x _ -> Map.lookup x $ _icd_perAnchor inlineConf GHC.RealSrcSpan x _ -> Map.lookup x $ _icd_perAnchor inlineConf
GHC.UnhelpfulSpan{} -> Nothing GHC.UnhelpfulSpan{} -> Nothing
@ -236,15 +217,16 @@ ppToplevelDecl decl immediateAfterComms = do
exactprintOnly <- mAsk <&> \declConfig -> exactprintOnly <- mAsk <&> \declConfig ->
declConfig & _conf_roundtrip_exactprint_only & confUnpack declConfig & _conf_roundtrip_exactprint_only & confUnpack
bd <- fmap fst $ if exactprintOnly bd <- fmap fst $ if exactprintOnly
then briDocMToPPM layouters $ docSeq then briDocMToPPM layouters
$ docSeq
(briDocByExactNoComment decl : map commentToDoc immediateAfterComms) (briDocByExactNoComment decl : map commentToDoc immediateAfterComms)
else do else do
let innerDoc = case decl of let innerDoc = case decl of
L (SrcSpanAnn _ (GHC.RealSrcSpan s _)) _ -> L (SrcSpanAnn _ (GHC.RealSrcSpan s _)) _ ->
docFlushRemaining (GHC.srcSpanFile s) $ layoutDecl decl docFlushRemaining (GHC.srcSpanFile s) $ layoutDecl decl
_ -> layoutDecl decl _ -> layoutDecl decl
(r, errorCount) <- briDocMToPPM layouters $ docSeq (r, errorCount) <- briDocMToPPM layouters
(innerDoc : map commentToDoc immediateAfterComms) $ docSeq (innerDoc : map commentToDoc immediateAfterComms)
if errorCount == 0 if errorCount == 0
then pure (r, 0) then pure (r, 0)
else briDocMToPPM layouters $ briDocByExactNoComment decl else briDocMToPPM layouters $ briDocByExactNoComment decl

View File

@ -15,7 +15,7 @@ import Language.Haskell.Brittany.Internal.Components.BriDoc
layoutDataDecl layoutDataDecl
:: Maybe (LTyClDecl GhcPs) :: LTyClDecl GhcPs
-> EpAnn [AddEpAnn] -> EpAnn [AddEpAnn]
-> LIdP GhcPs -> LIdP GhcPs
-> LHsQTyVars GhcPs -> LHsQTyVars GhcPs
@ -35,7 +35,7 @@ layoutDataDecl ltycl declEpAnn name (HsQTvs _ bndrs) pats defn = case defn of
then do then do
nameStr <- lrdrNameToTextAnn name nameStr <- lrdrNameToTextAnn name
consNameStr <- lrdrNameToTextAnn consName consNameStr <- lrdrNameToTextAnn consName
tyVars <- mapM shareDoc $ createBndrDoc bndrs tyVarLine <- shareDoc $ createBndrDoc bndrs
patDocs <- mapM shareDoc $ layoutHsTyPats pats patDocs <- mapM shareDoc $ layoutHsTyPats pats
-- headDoc <- fmap return $ docSeq -- headDoc <- fmap return $ docSeq
-- [ appSep $ docLitS "newtype") -- [ appSep $ docLitS "newtype")
@ -43,111 +43,29 @@ layoutDataDecl ltycl declEpAnn name (HsQTvs _ bndrs) pats defn = case defn of
-- , appSep tyVarLine -- , appSep tyVarLine
-- ] -- ]
rhsDoc <- return <$> createDetailsDoc consNameStr details rhsDoc <- return <$> createDetailsDoc consNameStr details
docHandleComms declEpAnn $ createDerivingPar mDerivs $ docAlt docHandleComms declEpAnn $ createDerivingPar mDerivs $ docSeq
[ -- newtype Tagged s b = Tagged { unTagged :: b }
docSeq
[ appSep $ docLitS "newtype" [ appSep $ docLitS "newtype"
, appSep $ docLit nameStr , appSep $ docLit nameStr
, appSep (docSeqSep tyVars) , appSep tyVarLine
, docSeq $ [x | p <- patDocs, x <- [p, docSeparator]] , docSeq $ [x | p <- patDocs, x <- [p, docSeparator]]
, docSeparator , docSeparator
, docLitS "=" , docLitS "="
, docSeparator , docSeparator
, docForceParSpacing $ docHandleComms epAnn $ rhsDoc
]
, -- newtype Tagged s b
-- = Tagged { unTagged :: b }
-- newtype Tagged s
-- b
-- = Tagged { unTagged :: b }
docAddBaseY BrIndentRegular $ docPar
( docSeq
[ appSep $ docLitS "newtype"
, appSep $ docLit nameStr
, docAlt
[ docForceSingleline $ docSeq
[ appSep (docSeqSep tyVars)
, docSeq $ [x | p <- patDocs, x <- [p, docSeparator]]
]
, docSetBaseY $ docLines
$ map docForceSingleline $ tyVars ++ patDocs
]
]
)
( docSeq
[ docLitS "="
, docSeparator
, docHandleComms epAnn $ rhsDoc , docHandleComms epAnn $ rhsDoc
] ]
) else briDocByExactNoComment ltycl
, -- newtype Tagged _ -> briDocByExactNoComment ltycl
-- s
-- b
-- = Tagged { unTagged :: b }
docAddBaseY BrIndentRegular $ docPar
( docSeq
[ appSep $ docLitS "newtype"
, appSep $ docLit nameStr
-- , appSep tyVarLine
-- , docSeq $ [x | p <- patDocs, x <- [p, docSeparator]]
]
)
( docLines
$ map (docEnsureIndent BrIndentRegular) tyVars
++ map (docEnsureIndent BrIndentRegular) patDocs
++ [ docSeq
[ docLitS "="
, docSeparator
, docHandleComms epAnn $ rhsDoc
]
]
)
]
else maybe
(error
$ "Unsupported form of DataFamInstDecl:"
++ " ConDeclH98 with context"
)
briDocByExactNoComment
ltycl
_ -> maybe
(error
$ "Unsupported form of DataFamInstDecl:"
++ " ConDeclH98 with forall"
)
briDocByExactNoComment
ltycl
HsDataDefn NoExtField NewType _ _ Just{} _ _ -> maybe
(error $ "Unsupported form of DataFamInstDecl: NewType _ _ Just _ _")
briDocByExactNoComment
ltycl
HsDataDefn NoExtField NewType _ _ Nothing _ _ -> maybe
(error $ "Unsupported form of DataFamInstDecl: NewType _ _ Nothing _ _")
briDocByExactNoComment
ltycl
-- data MyData = MyData ..
-- data MyData = MyData { .. } -- data MyData a b
HsDataDefn NoExtField DataType ctxMay _ctype Nothing conss mDerivs -> do -- (zero constructors)
HsDataDefn NoExtField DataType ctxMay _ctype Nothing [] mDerivs -> do
lhsContextDoc <- case ctxMay of lhsContextDoc <- case ctxMay of
Just (L _ lhsContext) -> shareDoc $ createContextDoc lhsContext Just (L _ lhsContext) -> shareDoc $ createContextDoc lhsContext
Nothing -> pure docEmpty Nothing -> pure docEmpty
nameStr <- lrdrNameToTextAnn name nameStr <- lrdrNameToTextAnn name
tyVarLine <- shareDoc $ docSeqSep $ createBndrDoc bndrs tyVarLine <- return <$> createBndrDoc bndrs
patDocs <- mapM shareDoc $ layoutHsTyPats pats patDocs <- mapM shareDoc $ layoutHsTyPats pats
lhsDoc <- shareDoc $ docSeq
[ -- TOOD92 docNodeAnnKW ltycl (Just GHC.AnnData) $
appSep $ docLitS "data"
, docForceSingleline $ lhsContextDoc
, appSep $ docLit nameStr
, appSep tyVarLine
, docSeq $ [x | p <- patDocs, x <- [p, docSeparator]]
]
let prefixes = "=" : repeat "|"
layoutConssResult <- mapM layoutConDecl (zip prefixes conss)
case sequence layoutConssResult of
Left err -> maybe (error err) briDocByExactNoComment ltycl
Right [] -> do
docHandleComms declEpAnn $ createDerivingPar mDerivs $ docSeq docHandleComms declEpAnn $ createDerivingPar mDerivs $ docSeq
[ appSep $ docLitS "data" [ appSep $ docLitS "data"
, lhsContextDoc , lhsContextDoc
@ -155,140 +73,151 @@ layoutDataDecl ltycl declEpAnn name (HsQTvs _ bndrs) pats defn = case defn of
, appSep tyVarLine , appSep tyVarLine
, docSeq $ [x | p <- patDocs, x <- [p, docSeparator]] , docSeq $ [x | p <- patDocs, x <- [p, docSeparator]]
] ]
Right [(consDocSl, consDocMl)] -> do
docHandleComms declEpAnn $ createDerivingPar mDerivs $ docAlt
[ -- data D = forall a . Show a => D a
docSeq [lhsDoc, consDocSl]
, -- data D
-- = forall a . Show a => D a
-- data D
-- = forall a
-- . Show a =>
-- D a
docAddBaseY BrIndentRegular
$ docPar lhsDoc
(docNonBottomSpacing $ docAlt [consDocSl, consDocMl])
, -- data
-- Show a =>
-- D
-- = rhsDoc
-- This alternative is only for -XDatatypeContexts.
-- But I think it is rather unlikely this will trigger without
-- -XDataTypeContexts, especially with the `docNonBottomSpacing`
-- above, so while not strictly necessary, this should not
-- hurt.
docAddBaseY BrIndentRegular $ docPar
(-- TODO92 docNodeAnnKW ltycl (Just GHC.AnnData) $
docLitS "data")
(docLines
[ lhsContextDoc
, docSeq
[ appSep $ docLit nameStr
, tyVarLine
, docSeq $ [x | p <- patDocs, x <- [p, docSeparator]]
]
, consDocMl
]
)
]
Right consDocTuples -> do
docHandleComms declEpAnn
$ createDerivingPar mDerivs
$ docAddBaseY BrIndentRegular
$ docPar
(docAlt
[ -- data Show a => D a
lhsDoc
, -- data
-- Show a =>
-- D
-- This alternative is only for -XDatatypeContexts.
-- But I think it is rather unlikely this will trigger without
-- -XDataTypeContexts, especially with the `docNonBottomSpacing`
-- above, so while not strictly necessary, this should not
-- hurt.
docAddBaseY BrIndentRegular $ docPar
(-- TODO92 docNodeAnnKW ltycl (Just GHC.AnnData) $
docLitS "data")
(docLines
[ lhsContextDoc
, docSeq
[ appSep $ docLit nameStr
, tyVarLine
, docSeq $ [x | p <- patDocs, x <- [p, docSeparator]]
]
]
)
]
)
(docLines $ [docAlt [sl, ml] | (sl, ml) <- consDocTuples])
HsDataDefn NoExtField DataType _ _ Just{} _ _ -> maybe -- data MyData = MyData ..
(error $ "Unsupported form of DataFamInstDecl: DataType _ _ Just _ _") -- data MyData = MyData { .. }
briDocByExactNoComment HsDataDefn NoExtField DataType ctxMay _ctype Nothing [cons] mDerivs ->
ltycl case cons of
(L _ (ConDeclH98 epAnn consName _hasExt qvars mRhsContext details _conDoc))
layoutConDecl -> do
:: (String, LConDecl GhcPs) lhsContextDoc <- case ctxMay of
-> ToBriDocM Just (L _ lhsContext) -> shareDoc $ createContextDoc lhsContext
(Either String (ToBriDocM BriDocNumbered, ToBriDocM BriDocNumbered)) Nothing -> pure docEmpty
layoutConDecl (prefix, L _ con) = case con of nameStr <- lrdrNameToTextAnn name
ConDeclH98 epAnn consName _hasExt qvars mRhsContext details _conDoc -> do
consNameStr <- lrdrNameToTextAnn consName consNameStr <- lrdrNameToTextAnn consName
tyVarLine <- return <$> createBndrDoc bndrs
patDocs <- mapM shareDoc $ layoutHsTyPats pats
forallDocMay <- case createForallDoc qvars of forallDocMay <- case createForallDoc qvars of
Nothing -> pure Nothing Nothing -> pure Nothing
Just x -> Just . pure <$> x Just x -> Just . pure <$> x
rhsContextDocMay <- case mRhsContext of rhsContextDocMay <- case mRhsContext of
Nothing -> pure Nothing Nothing -> pure Nothing
Just (L _ ctxt) -> Just . pure <$> createContextDoc ctxt Just (L _ ctxt) -> Just . pure <$> createContextDoc ctxt
detailsDoc <- shareDoc $ createDetailsDoc consNameStr details rhsDoc <- return <$> createDetailsDoc consNameStr details
let posEqual = obtainAnnPos epAnn AnnEqual let posEqual = obtainAnnPos epAnn AnnEqual
pure $ Right consDoc <-
( docSeq shareDoc
[ docHandleComms epAnn $ docHandleComms posEqual $ docLitS prefix $ docHandleComms epAnn
$ docHandleComms posEqual
$ docNonBottomSpacing
$ case (forallDocMay, rhsContextDocMay) of
(Just forallDoc, Just rhsContextDoc) -> docLines
[ docSeq
[docLitS "=", docSeparator, docForceSingleline forallDoc]
, docSeq
[ docLitS "."
, docSeparator
, docSetBaseY $ docLines [rhsContextDoc, docSetBaseY rhsDoc]
]
]
(Just forallDoc, Nothing) -> docLines
[ docSeq
[docLitS "=", docSeparator, docForceSingleline forallDoc]
, docSeq [docLitS ".", docSeparator, rhsDoc]
]
(Nothing, Just rhsContextDoc) -> docSeq
[ docLitS "="
, docSeparator
, docSetBaseY $ docLines [rhsContextDoc, docSetBaseY rhsDoc]
]
(Nothing, Nothing) ->
docSeq [docLitS "=", docSeparator, rhsDoc]
docHandleComms declEpAnn $ createDerivingPar mDerivs $ docAlt
[ -- data D = forall a . Show a => D a
docSeq
[ -- TOOD92 docNodeAnnKW ltycl (Just GHC.AnnData) $
docSeq
[ appSep $ docLitS "data"
, docForceSingleline $ lhsContextDoc
, appSep $ docLit nameStr
, appSep tyVarLine
, docSeq $ [x | p <- patDocs, x <- [p, docSeparator]]
]
, docHandleComms epAnn $ docHandleComms posEqual $ docLitS "="
, docSeparator , docSeparator
, docSetIndentLevel $ docSeq , docSetIndentLevel $ docSeq
[ case forallDocMay of [ case forallDocMay of
Nothing -> docEmpty Nothing -> docEmpty
Just forallDoc -> docSeq Just forallDoc ->
docSeq
[ docForceSingleline forallDoc [ docForceSingleline forallDoc
, docSeparator , docSeparator
, docLitS "." , docLitS "."
, docSeparator , docSeparator
] ]
, maybe docEmpty docForceSingleline rhsContextDocMay , maybe docEmpty docForceSingleline rhsContextDocMay
, detailsDoc , rhsDoc
] ]
] ]
, docHandleComms epAnn , -- data D
$ docHandleComms posEqual -- = forall a . Show a => D a
$ docNonBottomSpacing docAddBaseY BrIndentRegular $ docPar
$ case (forallDocMay, rhsContextDocMay) of ( -- TODO92 docNodeAnnKW ltycl (Just GHC.AnnData) $
(Just forallDoc, Just rhsContextDoc) -> docLines docSeq
[ docSeq [ appSep $ docLitS "data"
[docLitS prefix, docSeparator, docForceSingleline forallDoc] , docForceSingleline lhsContextDoc
, docSeq , appSep $ docLit nameStr
[ docLitS "." , tyVarLine
, docSeparator , docSeq $ [x | p <- patDocs, x <- [p, docSeparator]]
, docSetBaseY $ docLines [rhsContextDoc, docSetBaseY detailsDoc]
] ]
]
(Just forallDoc, Nothing) -> docLines
[ docSeq
[docLitS prefix, docSeparator, docForceSingleline forallDoc]
, docSeq [docLitS ".", docSeparator, detailsDoc]
]
(Nothing, Just rhsContextDoc) -> docSeq
[ docLitS prefix
, docSeparator
, docSetBaseY $ docLines [rhsContextDoc, docSetBaseY detailsDoc]
]
(Nothing, Nothing) -> docSeq
[docLitS prefix, docSeparator, detailsDoc]
) )
ConDeclGADT{} -> pure (docSeq
$ Left "Unsupported: ConDeclGADT inside DataFamInstDecl" [ docHandleComms epAnn $ docHandleComms posEqual $ docLitS "="
, docSeparator
, docSetIndentLevel $ docSeq
[ case forallDocMay of
Nothing -> docEmpty
Just forallDoc ->
docSeq
[ docForceSingleline forallDoc
, docSeparator
, docLitS "."
, docSeparator
]
, maybe docEmpty docForceSingleline rhsContextDocMay
, rhsDoc
]
]
)
, -- data D
-- = forall a
-- . Show a =>
-- D a
docAddBaseY BrIndentRegular $ docPar
( -- TODO92 docNodeAnnKW ltycl (Just GHC.AnnData) $
docSeq
[ appSep $ docLitS "data"
, docForceSingleline lhsContextDoc
, appSep $ docLit nameStr
, tyVarLine
, docSeq $ [x | p <- patDocs, x <- [p, docSeparator]]
]
)
consDoc
, -- data
-- Show a =>
-- D
-- = forall a
-- . Show a =>
-- D a
-- This alternative is only for -XDatatypeContexts.
-- But I think it is rather unlikely this will trigger without
-- -XDataTypeContexts, especially with the `docNonBottomSpacing`
-- above, so while not strictly necessary, this should not
-- hurt.
docAddBaseY BrIndentRegular $ docPar
(docLitS "data")
(docLines
[ lhsContextDoc
, -- TODO92 docNodeAnnKW ltycl (Just GHC.AnnData) $
docSeq [appSep $ docLit nameStr, tyVarLine, docSeq $ [x | p <- patDocs, x <- [p, docSeparator]]]
, consDoc
]
)
]
_ -> briDocByExactNoComment ltycl
_ -> briDocByExactNoComment ltycl
layoutHsTyPats layoutHsTyPats
:: [LHsTypeArg GhcPs] -> [ToBriDocM BriDocNumbered] :: [LHsTypeArg GhcPs] -> [ToBriDocM BriDocNumbered]
@ -324,13 +253,14 @@ createContextDoc (t1 : tR) = do
] ]
] ]
createBndrDoc :: [LHsTyVarBndr flag GhcPs] -> [ToBriDocM BriDocNumbered] createBndrDoc :: [LHsTyVarBndr flag GhcPs] -> ToBriDocM BriDocNumbered
createBndrDoc = map $ \x -> do createBndrDoc bs = do
(vname, mKind) <- case x of tyVarDocs <- bs `forM` \case
(L _ (UserTyVar _ _ext vname)) -> return $ (lrdrNameToText vname, Nothing) (L _ (UserTyVar _ _ext vname)) -> return $ (lrdrNameToText vname, Nothing)
(L _ (KindedTyVar _ _ext lrdrName kind)) -> do (L _ (KindedTyVar _ _ext lrdrName kind)) -> do
d <- shareDoc $ callLayouter layout_type kind d <- shareDoc $ callLayouter layout_type kind
return $ (lrdrNameToText lrdrName, Just $ d) return $ (lrdrNameToText lrdrName, Just $ d)
docSeq $ List.intersperse docSeparator $ tyVarDocs <&> \(vname, mKind) ->
case mKind of case mKind of
Nothing -> docLit vname Nothing -> docLit vname
Just kind -> docSeq Just kind -> docSeq
@ -455,7 +385,8 @@ createDetailsDoc consNameStr details = case details of
let ((fName1, fType1), fDocR) = case mkFieldDocs fields of let ((fName1, fType1), fDocR) = case mkFieldDocs fields of
(doc1:docR) -> (doc1, docR) (doc1:docR) -> (doc1, docR)
_ -> error "cannot happen (TM)" _ -> error "cannot happen (TM)"
allowSingleline <- mAsk <&> _conf_layout .> _lconfig_allowSinglelineRecord .> confUnpack -- allowSingleline <- mAsk <&> _conf_layout .> _lconfig_allowSinglelineRecord .> confUnpack
let allowSingleline = False
docAddBaseY BrIndentRegular $ runFilteredAlternative $ do docAddBaseY BrIndentRegular $ runFilteredAlternative $ do
-- single-line: { i :: Int, b :: Bool } -- single-line: { i :: Int, b :: Bool }
addAlternativeCond allowSingleline $ docSeq addAlternativeCond allowSingleline $ docSeq
@ -481,7 +412,7 @@ createDetailsDoc consNameStr details = case details of
, docSeparator , docSeparator
, docHandleComms posClose $ docLitS "}" , docHandleComms posClose $ docLitS "}"
] ]
addAlternative $ docSetParSpacing $ docPar addAlternative $ docPar
(docLit consNameStr) (docLit consNameStr)
(docNonBottomSpacingS $ docLines (docNonBottomSpacingS $ docLines
[ docAlt [ docAlt
@ -537,7 +468,7 @@ createForallDoc
:: [LHsTyVarBndr flag GhcPs] -> Maybe (ToBriDocM BriDocNumbered) :: [LHsTyVarBndr flag GhcPs] -> Maybe (ToBriDocM BriDocNumbered)
createForallDoc [] = Nothing createForallDoc [] = Nothing
createForallDoc lhsTyVarBndrs = createForallDoc lhsTyVarBndrs =
Just $ docSeq [docLitS "forall ", docSeqSep $ createBndrDoc lhsTyVarBndrs] Just $ docSeq [docLitS "forall ", createBndrDoc lhsTyVarBndrs]
createNamesAndTypeDoc createNamesAndTypeDoc
:: LConDeclField GhcPs :: LConDeclField GhcPs

View File

@ -238,10 +238,7 @@ layoutGrhs (L _ (GRHS epAnn guards body)) = do
guardDocs <- case guards of guardDocs <- case guards of
[] -> pure [] [] -> pure []
_ -> docFlushCommsPost False posArrow $ callLayouter layout_stmt `mapM` guards _ -> docFlushCommsPost False posArrow $ callLayouter layout_stmt `mapM` guards
let bodyEndPos = case locA $ getLoc body of bodyDoc <- callLayouter layout_expr body
GHC.RealSrcSpan s _ -> Just s
GHC.UnhelpfulSpan{} -> Nothing
bodyDoc <- docFlushCommsPost True bodyEndPos $ callLayouter layout_expr body
return (Just epAnn, guardDocs, bodyDoc) return (Just epAnn, guardDocs, bodyDoc)
layoutPatternBind layoutPatternBind
@ -263,7 +260,7 @@ layoutPatternBind funId binderDoc lmatch@(L _ match) = do
let t' = fixPatternBindIdentifier match t let t' = fixPatternBindIdentifier match t
docLit t' docLit t'
_ -> pure Nothing _ -> pure Nothing
patDoc <- case (mIdDoc, patDocs) of patDoc <- docHandleComms lmatch $ case (mIdDoc, patDocs) of -- TODO92 we use lmatch twice here!
(Just idDoc, p1 : p2 : pr) | isInfix -> if null pr (Just idDoc, p1 : p2 : pr) | isInfix -> if null pr
then docCols then docCols
ColPatternsFuncInfix ColPatternsFuncInfix
@ -808,7 +805,7 @@ layoutTyCl ltycl@(L _loc tycl) = case tycl of
typeDoc typeDoc
DataDecl epAnn name tyVars _ dataDefn -> do DataDecl epAnn name tyVars _ dataDefn -> do
layouters <- mAsk layouters <- mAsk
layout_dataDecl layouters (Just ltycl) epAnn name tyVars [] dataDefn layout_dataDecl layouters ltycl epAnn name tyVars [] dataDefn
_ -> briDocByExactNoComment ltycl _ -> briDocByExactNoComment ltycl
layoutTyVarBndr :: Bool -> ToBriDoc (HsTyVarBndr ()) layoutTyVarBndr :: Bool -> ToBriDoc (HsTyVarBndr ())
@ -976,7 +973,7 @@ layoutClsInst (L declLoc _) cid = do
layouters <- mAsk layouters <- mAsk
layout_dataDecl layout_dataDecl
layouters layouters
Nothing (error "Unsupported form of DataFamInstDecl")
epAnn epAnn
tycon tycon
(case bndrs of (case bndrs of

View File

@ -556,10 +556,7 @@ layoutExpr lexpr@(L _ expr) = do
-- to making brittany idempotent, even though the result is non-optimal -- to making brittany idempotent, even though the result is non-optimal
-- if "let" is moved horizontally as part of the transformation, as the -- if "let" is moved horizontally as part of the transformation, as the
-- comments before the first let item are moved horizontally with it. -- comments before the first let item are moved horizontally with it.
letDoc <- shareDoc letDoc <- shareDoc $ wrapLet $ docLit $ Text.pack "let"
$ docFlushCommsPost True spanLet
$ wrapLet
$ docLitS "let"
inDoc <- shareDoc $ wrapIn $ docLit $ Text.pack "in" inDoc <- shareDoc $ wrapIn $ docLit $ Text.pack "in"
docSetBaseAndIndent $ case fmap snd mBindDocs of docSetBaseAndIndent $ case fmap snd mBindDocs of
Just [bindDoc] -> runFilteredAlternative $ do Just [bindDoc] -> runFilteredAlternative $ do

View File

@ -198,9 +198,6 @@ layoutOpTree allowSinglelinePar = \case
pure (pure op, subDoc) pure (pure op, subDoc)
sharedOpsFlat <- flattenList docOps sharedOpsFlat <- flattenList docOps
sharedOps <- simpleTransform docOps sharedOps <- simpleTransform docOps
let lastWrap = if getPrec fixity <= 1
then docForceParSpacing
else docForceSingleline
coreAlternative hasParen coreAlternative hasParen
locO locO
locC locC
@ -208,12 +205,11 @@ layoutOpTree allowSinglelinePar = \case
docL docL
sharedOps sharedOps
sharedOpsFlat sharedOpsFlat
lastWrap docForceParSpacing
OpLeaf l -> pure l OpLeaf l -> pure l
where where
isPrec0 x = getPrec x == 0 isPrec0 = \case
getPrec = \case Fixity _ prec _ -> prec == 0
Fixity _ prec _ -> prec
coreAlternative coreAlternative
:: Bool :: Bool
-> Maybe GHC.RealSrcLoc -> Maybe GHC.RealSrcLoc
@ -227,10 +223,7 @@ layoutOpTree allowSinglelinePar = \case
coreAlternative hasParen locO locC fixity docL sharedOps sharedOpsFlat lastWrap coreAlternative hasParen locO locC fixity docL sharedOps sharedOpsFlat lastWrap
= do = do
indentPolicy <- askLayoutConf _lconfig_indentPolicy indentPolicy <- askLayoutConf _lconfig_indentPolicy
let zeroOps = null sharedOps let wrapParenIfSl x inner = if x then wrapParenSl inner else docSetParSpacing inner
wrapParenIfSl x inner = if x
then wrapParenSl inner
else docSetParSpacing inner
wrapParenSl inner = docAlt wrapParenSl inner = docAlt
[ docSeq [ docSeq
[ docLit $ Text.pack "(" [ docLit $ Text.pack "("
@ -248,7 +241,7 @@ layoutOpTree allowSinglelinePar = \case
wrapParenMl innerHead innerLines = docSetBaseY $ docLines wrapParenMl innerHead innerLines = docSetBaseY $ docLines
( [ docCols ( [ docCols
ColOpPrefix ColOpPrefix
[ (if zeroOps then id else appSep) $ docLit $ Text.pack "(" [ appSep $ docLit $ Text.pack "("
, docHandleComms locO $ innerHead , docHandleComms locO $ innerHead
] ]
] ]
@ -275,11 +268,7 @@ layoutOpTree allowSinglelinePar = \case
([docForceSingleline docL] ++ case splitFirstLast sharedOpsFlat of ([docForceSingleline docL] ++ case splitFirstLast sharedOpsFlat of
FirstLastEmpty -> [] FirstLastEmpty -> []
FirstLastSingleton (od, ed) -> FirstLastSingleton (od, ed) ->
[ docSeparator [docSeparator, docForceSingleline od, docSeparator, lastWrap ed]
, docForceSingleline od
, docSeparator
, lastWrap ed
]
FirstLast (od1, ed1) ems (odN, edN) -> FirstLast (od1, ed1) ems (odN, edN) ->
( [ docSeparator ( [ docSeparator
, docForceSingleline od1 , docForceSingleline od1
@ -301,6 +290,8 @@ layoutOpTree allowSinglelinePar = \case
] ]
) )
) )
-- this case rather leads to some unfortunate layouting than to anything
-- useful; disabling for now. (it interfers with cols stuff.)
-- one -- one
-- + two -- + two
-- + three -- + three
@ -320,7 +311,8 @@ layoutOpTree allowSinglelinePar = \case
[(od, ed)] | curIsPrec0 -> [(od, ed)] | curIsPrec0 ->
addAlternativeCond (not hasParen && isSingleOp) addAlternativeCond (not hasParen && isSingleOp)
$ docSetParSpacing $ docSetParSpacing
$ docPar (docHandleComms locO $ docForceSingleline $ docL) $ docPar
(docHandleComms locO $ docForceSingleline $ docL)
(docSeq [od, docSeparator, singlelineUnlessFree ed]) (docSeq [od, docSeparator, singlelineUnlessFree ed])
_ -> pure () _ -> pure ()
-- > ( one -- > ( one

View File

@ -47,20 +47,18 @@ layoutStmt lstmt@(L _ stmt) = do
] ]
] ]
LetStmt epAnn binds -> docHandleComms epAnn $ do LetStmt epAnn binds -> docHandleComms epAnn $ do
let spanLet = obtainAnnPos epAnn AnnLet
letDoc <- shareDoc $ docFlushCommsPost True spanLet $ docLitS "let"
let isFree = indentPolicy == IndentPolicyFree let isFree = indentPolicy == IndentPolicyFree
let indentFourPlus = indentAmount >= 4 let indentFourPlus = indentAmount >= 4
(wrapBinds, bindrDocsMay) <- callLayouter layout_localBinds binds (wrapBinds, bindrDocsMay) <- callLayouter layout_localBinds binds
case bindrDocsMay of case bindrDocsMay of
Nothing -> letDoc Nothing -> docLit $ Text.pack "let"
-- i just tested the above, and it is indeed allowed. heh. -- i just tested the above, and it is indeed allowed. heh.
Just (_, []) -> letDoc -- this probably never happens Just (_, []) -> docLit $ Text.pack "let" -- this probably never happens
Just (_, [bindDoc]) -> docAlt Just (_, [bindDoc]) -> docAlt
[ -- let bind = expr [ -- let bind = expr
docCols docCols
ColDoLet ColDoLet
[ appSep $ letDoc [ appSep $ docLit $ Text.pack "let"
, let , let
f = case indentPolicy of f = case indentPolicy of
IndentPolicyFree -> docSetBaseAndIndent IndentPolicyFree -> docSetBaseAndIndent
@ -73,7 +71,7 @@ layoutStmt lstmt@(L _ stmt) = do
, -- let , -- let
-- bind = expr -- bind = expr
docAddBaseY BrIndentRegular $ docPar docAddBaseY BrIndentRegular $ docPar
letDoc (docLit $ Text.pack "let")
(wrapBinds $ docSetBaseAndIndent $ return bindDoc) (wrapBinds $ docSetBaseAndIndent $ return bindDoc)
] ]
Just (_, bindDocs) -> runFilteredAlternative $ do Just (_, bindDocs) -> runFilteredAlternative $ do
@ -81,7 +79,7 @@ layoutStmt lstmt@(L _ stmt) = do
-- bbb = exprb -- bbb = exprb
-- ccc = exprc -- ccc = exprc
addAlternativeCond (isFree || indentFourPlus) $ docSeq addAlternativeCond (isFree || indentFourPlus) $ docSeq
[ appSep $ letDoc [ appSep $ docLit $ Text.pack "let"
, let , let
f = if indentFourPlus f = if indentFourPlus
then docEnsureIndent BrIndentRegular then docEnsureIndent BrIndentRegular
@ -95,7 +93,7 @@ layoutStmt lstmt@(L _ stmt) = do
addAlternativeCond (not indentFourPlus) addAlternativeCond (not indentFourPlus)
$ docAddBaseY BrIndentRegular $ docAddBaseY BrIndentRegular
$ docPar $ docPar
letDoc (docLit $ Text.pack "let")
(wrapBinds $ docSetBaseAndIndent $ docLines $ return <$> bindDocs) (wrapBinds $ docSetBaseAndIndent $ docLines $ return <$> bindDocs)
RecStmt epAnn (L _ stmts) _ _ _ _ _ -> RecStmt epAnn (L _ stmts) _ _ _ _ _ ->
docHandleComms epAnn $ runFilteredAlternative $ do docHandleComms epAnn $ runFilteredAlternative $ do

View File

@ -370,9 +370,7 @@ layoutType ltype@(L _ typ) = docHandleComms ltype $ case typ of
] ]
) )
] ]
HsBangTy epAnn (HsSrcBang NoSourceText NoSrcUnpack SrcStrict) innerTy -> do HsBangTy{} -> -- TODO
docHandleComms epAnn $ docSeq [docLitS "!", layoutType innerTy]
HsBangTy {} ->
briDocByExactInlineOnly "HsBangTy{}" ltype briDocByExactInlineOnly "HsBangTy{}" ltype
-- HsBangTy bang typ1 -> do -- HsBangTy bang typ1 -> do
-- let bangStr = case bang of -- let bangStr = case bang of

View File

@ -24,7 +24,6 @@ import GHC ( Anno
, ParsedSource , ParsedSource
, XRec , XRec
, LImportDecl , LImportDecl
, LEpaComment
) )
import GHC.Utils.Outputable(Outputable) import GHC.Utils.Outputable(Outputable)
import Language.Haskell.Brittany.Internal.Config.Types import Language.Haskell.Brittany.Internal.Config.Types
@ -53,7 +52,7 @@ data BrittanyError
| forall ast . (Data.Data.Data (XRec GhcPs ast), Outputable (Anno ast)) => ErrorUnknownNode String (XRec GhcPs ast) | forall ast . (Data.Data.Data (XRec GhcPs ast), Outputable (Anno ast)) => ErrorUnknownNode String (XRec GhcPs ast)
-- ^ internal error: pretty-printing is not implemented for type of node -- ^ internal error: pretty-printing is not implemented for type of node
-- in the syntax-tree -- in the syntax-tree
| ErrorOutputCheck String | ErrorOutputCheck
-- ^ checking the output for syntactic validity failed -- ^ checking the output for syntactic validity failed
@ -90,8 +89,6 @@ finalToList_ :: FinalList a () -> [a]
finalToList_ (FinalList l) = l (:) (\() -> []) finalToList_ (FinalList l) = l (:) (\() -> [])
finalToList :: FinalList a b -> ([a], b) finalToList :: FinalList a b -> ([a], b)
finalToList (FinalList l) = l (\x (a, b) -> (x:a, b)) (\b -> ([], b)) finalToList (FinalList l) = l (\x (a, b) -> (x:a, b)) (\b -> ([], b))
concatMapFinal :: FinalList a () -> (a -> [b]) -> [b]
concatMapFinal (FinalList l) f = l (\x rest -> f x ++ rest) (\() -> [])
instance Functor (FinalList a) where instance Functor (FinalList a) where
fmap = _finalRMap fmap = _finalRMap
@ -122,7 +119,7 @@ data ModuleElement
-- ^ an import decl, only occurs if pretty-printing the module head. -- ^ an import decl, only occurs if pretty-printing the module head.
| MEDecl (LHsDecl GhcPs) [(Int, EpaCommentTok)] | MEDecl (LHsDecl GhcPs) [(Int, EpaCommentTok)]
-- ^ a top-level declaration -- ^ a top-level declaration
| MEComment (Int, LEpaComment) | MEComment (Int, EpaCommentTok)
-- ^ a top-level comment, i.e. a comment located between top-level elements -- ^ a top-level comment, i.e. a comment located between top-level elements
-- (and not associated to some nested node, which might in theory happen). -- (and not associated to some nested node, which might in theory happen).
-- The Int carries the indentation of the comment. -- The Int carries the indentation of the comment.
@ -239,7 +236,7 @@ data Layouters = Layouters
) )
) )
, layout_dataDecl , layout_dataDecl
:: Maybe (GHC.LTyClDecl GhcPs) :: GHC.LTyClDecl GhcPs
-> GHC.EpAnn [GHC.AddEpAnn] -> GHC.EpAnn [GHC.AddEpAnn]
-> GHC.LIdP GhcPs -> GHC.LIdP GhcPs
-> GHC.LHsQTyVars GhcPs -> GHC.LHsQTyVars GhcPs

View File

@ -152,7 +152,7 @@ layoutWriteComment absolute isBlock dp commentLines s = do -- TODO92 we don't mo
mSet state mSet state
{ _lstate_plannedSpace = if isBlock { _lstate_plannedSpace = if isBlock
then case _lstate_plannedSpace state of then case _lstate_plannedSpace state of
p@PlannedNone -> p PlannedNone -> PlannedSameline 1
p@PlannedSameline{} -> p p@PlannedSameline{} -> p
PlannedNewline l -> PlannedNewline l ->
if l <= y then PlannedSameline 1 else PlannedNewline (l - y) if l <= y then PlannedSameline 1 else PlannedNewline (l - y)

View File

@ -381,15 +381,9 @@ coreIO putErrorLnIO config suppressOutput checkMode inputPathM outputPathM =
putErrorLn left putErrorLn left
ExceptT.throwE 60 ExceptT.throwE 60
Right (parsedSource, hasCPP) -> do Right (parsedSource, hasCPP) -> do
let moduleElementList = splitModuleDecls parsedSource
(inlineConf, perItemConf) <- do (inlineConf, perItemConf) <- do
resE <- resE <-
liftIO liftIO $ ExceptT.runExceptT $ extractCommentConfigs putErrorLnIO parsedSource
$ ExceptT.runExceptT
$ extractCommentConfigs
putErrorLnIO
(extractDeclMap parsedSource)
moduleElementList
case resE of case resE of
Left (err, input) -> do Left (err, input) -> do
putErrorLn $ "Error: parse error in inline configuration:" putErrorLn $ "Error: parse error in inline configuration:"
@ -420,9 +414,9 @@ coreIO putErrorLnIO config suppressOutput checkMode inputPathM outputPathM =
.> _econf_omit_output_valid_check .> _econf_omit_output_valid_check
.> confUnpack .> confUnpack
(ews, outRaw) <- if hasCPP || omitCheck (ews, outRaw) <- if hasCPP || omitCheck
then liftIO $ processModule (TraceFunc putErrorLnIO) moduleConf perItemConf moduleElementList then liftIO $ processModule (TraceFunc putErrorLnIO) moduleConf perItemConf parsedSource
else liftIO else liftIO
$ pPrintModuleAndCheck (TraceFunc putErrorLnIO) moduleConf perItemConf moduleElementList $ pPrintModuleAndCheck (TraceFunc putErrorLnIO) moduleConf perItemConf parsedSource
let let
hackF s = fromMaybe s $ TextL.stripPrefix hackF s = fromMaybe s $ TextL.stripPrefix
(TextL.pack "-- BRITANY_INCLUDE_HACK ") (TextL.pack "-- BRITANY_INCLUDE_HACK ")

View File

@ -15,7 +15,6 @@ import Language.Haskell.Brittany.Internal
import Language.Haskell.Brittany.Internal.Config.Config import Language.Haskell.Brittany.Internal.Config.Config
import Language.Haskell.Brittany.Internal.Config.Types import Language.Haskell.Brittany.Internal.Config.Types
import Language.Haskell.Brittany.Internal.Prelude import Language.Haskell.Brittany.Internal.Prelude
import Test.HUnit (assertEqual)
import qualified System.Directory import qualified System.Directory
import System.FilePath ((</>)) import System.FilePath ((</>))
import System.Timeout (timeout) import System.Timeout (timeout)
@ -23,7 +22,6 @@ import Test.Hspec
import qualified Text.Parsec as Parsec import qualified Text.Parsec as Parsec
import Text.Parsec.Text (Parser) import Text.Parsec.Text (Parser)
import qualified Data.List.Extra import qualified Data.List.Extra
import qualified System.Console.ANSI as ANSI
hush :: Either a b -> Maybe b hush :: Either a b -> Maybe b
hush = either (const Nothing) Just hush = either (const Nothing) Just
@ -284,15 +282,9 @@ roundTripEqual c t =
`shouldReturn` Right (PPTextWrapper t) `shouldReturn` Right (PPTextWrapper t)
goldenTest :: Config -> Text -> Text -> Expectation goldenTest :: Config -> Text -> Text -> Expectation
goldenTest c input expected = do goldenTest c input expected =
result <- parsePrintModuleTests c "TestFakeFileName.hs" input fmap (fmap PPTextWrapper) (parsePrintModuleTests c "TestFakeFileName.hs" input)
assertEqual `shouldReturn` Right (PPTextWrapper expected)
( ANSI.setSGRCode [ANSI.SetColor ANSI.Foreground ANSI.Dull ANSI.Red]
++ "golden input: see test source!"
++ ANSI.setSGRCode [ANSI.Reset]
)
(Right (PPTextWrapper expected))
(fmap PPTextWrapper result)
newtype PPTextWrapper = PPTextWrapper Text newtype PPTextWrapper = PPTextWrapper Text
deriving Eq deriving Eq
@ -323,7 +315,7 @@ defaultTestConfig = Config
, _lconfig_allowSingleLineExportList = coerce True , _lconfig_allowSingleLineExportList = coerce True
, _lconfig_allowHangingQuasiQuotes = coerce True , _lconfig_allowHangingQuasiQuotes = coerce True
, _lconfig_experimentalSemicolonNewlines = coerce False , _lconfig_experimentalSemicolonNewlines = coerce False
, _lconfig_allowSinglelineRecord = coerce False -- , _lconfig_allowSinglelineRecord = coerce False
, _lconfig_fixityAwareOps = coerce True , _lconfig_fixityAwareOps = coerce True
, _lconfig_fixityAwareTypeOps = coerce True , _lconfig_fixityAwareTypeOps = coerce True
, _lconfig_fixityBasedAddAlignParens = coerce False , _lconfig_fixityBasedAddAlignParens = coerce False