brittany 0.8.0.2 → 0.8.0.3
raw patch · 24 files changed
+2222/−1175 lines, 24 filesdep ~basedep ~extradep ~ghcPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependency ranges changed: base, extra, ghc, ghc-boot-th, syb
API changes (from Hackage documentation)
- Language.Haskell.Brittany.Internal.Config.Types: (.:?=) :: FromJSON a => Object -> Text -> Parser a
- Language.Haskell.Brittany.Internal.Config.Types: aesonDecodeOptionsBrittany :: Options
- Language.Haskell.Brittany.Internal.Config.Types: instance Data.Aeson.Types.FromJSON.FromJSON (Language.Haskell.Brittany.Internal.Config.Types.CConfig Data.Semigroup.Option)
- Language.Haskell.Brittany.Internal.Config.Types: instance Data.Aeson.Types.FromJSON.FromJSON (Language.Haskell.Brittany.Internal.Config.Types.CConfig GHC.Base.Maybe)
- Language.Haskell.Brittany.Internal.Config.Types: instance Data.Aeson.Types.FromJSON.FromJSON (Language.Haskell.Brittany.Internal.Config.Types.CDebugConfig Data.Semigroup.Option)
- Language.Haskell.Brittany.Internal.Config.Types: instance Data.Aeson.Types.FromJSON.FromJSON (Language.Haskell.Brittany.Internal.Config.Types.CDebugConfig GHC.Base.Maybe)
- Language.Haskell.Brittany.Internal.Config.Types: instance Data.Aeson.Types.FromJSON.FromJSON (Language.Haskell.Brittany.Internal.Config.Types.CErrorHandlingConfig Data.Semigroup.Option)
- Language.Haskell.Brittany.Internal.Config.Types: instance Data.Aeson.Types.FromJSON.FromJSON (Language.Haskell.Brittany.Internal.Config.Types.CErrorHandlingConfig GHC.Base.Maybe)
- Language.Haskell.Brittany.Internal.Config.Types: instance Data.Aeson.Types.FromJSON.FromJSON (Language.Haskell.Brittany.Internal.Config.Types.CForwardOptions Data.Semigroup.Option)
- Language.Haskell.Brittany.Internal.Config.Types: instance Data.Aeson.Types.FromJSON.FromJSON (Language.Haskell.Brittany.Internal.Config.Types.CForwardOptions GHC.Base.Maybe)
- Language.Haskell.Brittany.Internal.Config.Types: instance Data.Aeson.Types.FromJSON.FromJSON (Language.Haskell.Brittany.Internal.Config.Types.CLayoutConfig Data.Semigroup.Option)
- Language.Haskell.Brittany.Internal.Config.Types: instance Data.Aeson.Types.FromJSON.FromJSON (Language.Haskell.Brittany.Internal.Config.Types.CLayoutConfig GHC.Base.Maybe)
- Language.Haskell.Brittany.Internal.Config.Types: instance Data.Aeson.Types.FromJSON.FromJSON (Language.Haskell.Brittany.Internal.Config.Types.CPreProcessorConfig Data.Semigroup.Option)
- Language.Haskell.Brittany.Internal.Config.Types: instance Data.Aeson.Types.FromJSON.FromJSON (Language.Haskell.Brittany.Internal.Config.Types.CPreProcessorConfig GHC.Base.Maybe)
- Language.Haskell.Brittany.Internal.Config.Types: instance Data.Aeson.Types.FromJSON.FromJSON Language.Haskell.Brittany.Internal.Config.Types.AltChooser
- Language.Haskell.Brittany.Internal.Config.Types: instance Data.Aeson.Types.FromJSON.FromJSON Language.Haskell.Brittany.Internal.Config.Types.CPPMode
- Language.Haskell.Brittany.Internal.Config.Types: instance Data.Aeson.Types.FromJSON.FromJSON Language.Haskell.Brittany.Internal.Config.Types.ColumnAlignMode
- Language.Haskell.Brittany.Internal.Config.Types: instance Data.Aeson.Types.FromJSON.FromJSON Language.Haskell.Brittany.Internal.Config.Types.ExactPrintFallbackMode
- Language.Haskell.Brittany.Internal.Config.Types: instance Data.Aeson.Types.FromJSON.FromJSON Language.Haskell.Brittany.Internal.Config.Types.IndentPolicy
- Language.Haskell.Brittany.Internal.Config.Types: instance Data.Aeson.Types.ToJSON.ToJSON (Language.Haskell.Brittany.Internal.Config.Types.CConfig Data.Semigroup.Option)
- Language.Haskell.Brittany.Internal.Config.Types: instance Data.Aeson.Types.ToJSON.ToJSON (Language.Haskell.Brittany.Internal.Config.Types.CConfig GHC.Base.Maybe)
- Language.Haskell.Brittany.Internal.Config.Types: instance Data.Aeson.Types.ToJSON.ToJSON (Language.Haskell.Brittany.Internal.Config.Types.CDebugConfig Data.Semigroup.Option)
- Language.Haskell.Brittany.Internal.Config.Types: instance Data.Aeson.Types.ToJSON.ToJSON (Language.Haskell.Brittany.Internal.Config.Types.CDebugConfig GHC.Base.Maybe)
- Language.Haskell.Brittany.Internal.Config.Types: instance Data.Aeson.Types.ToJSON.ToJSON (Language.Haskell.Brittany.Internal.Config.Types.CErrorHandlingConfig Data.Semigroup.Option)
- Language.Haskell.Brittany.Internal.Config.Types: instance Data.Aeson.Types.ToJSON.ToJSON (Language.Haskell.Brittany.Internal.Config.Types.CErrorHandlingConfig GHC.Base.Maybe)
- Language.Haskell.Brittany.Internal.Config.Types: instance Data.Aeson.Types.ToJSON.ToJSON (Language.Haskell.Brittany.Internal.Config.Types.CForwardOptions Data.Semigroup.Option)
- Language.Haskell.Brittany.Internal.Config.Types: instance Data.Aeson.Types.ToJSON.ToJSON (Language.Haskell.Brittany.Internal.Config.Types.CForwardOptions GHC.Base.Maybe)
- Language.Haskell.Brittany.Internal.Config.Types: instance Data.Aeson.Types.ToJSON.ToJSON (Language.Haskell.Brittany.Internal.Config.Types.CLayoutConfig Data.Semigroup.Option)
- Language.Haskell.Brittany.Internal.Config.Types: instance Data.Aeson.Types.ToJSON.ToJSON (Language.Haskell.Brittany.Internal.Config.Types.CLayoutConfig GHC.Base.Maybe)
- Language.Haskell.Brittany.Internal.Config.Types: instance Data.Aeson.Types.ToJSON.ToJSON (Language.Haskell.Brittany.Internal.Config.Types.CPreProcessorConfig Data.Semigroup.Option)
- Language.Haskell.Brittany.Internal.Config.Types: instance Data.Aeson.Types.ToJSON.ToJSON (Language.Haskell.Brittany.Internal.Config.Types.CPreProcessorConfig GHC.Base.Maybe)
- Language.Haskell.Brittany.Internal.Config.Types: instance Data.Aeson.Types.ToJSON.ToJSON Language.Haskell.Brittany.Internal.Config.Types.AltChooser
- Language.Haskell.Brittany.Internal.Config.Types: instance Data.Aeson.Types.ToJSON.ToJSON Language.Haskell.Brittany.Internal.Config.Types.CPPMode
- Language.Haskell.Brittany.Internal.Config.Types: instance Data.Aeson.Types.ToJSON.ToJSON Language.Haskell.Brittany.Internal.Config.Types.ColumnAlignMode
- Language.Haskell.Brittany.Internal.Config.Types: instance Data.Aeson.Types.ToJSON.ToJSON Language.Haskell.Brittany.Internal.Config.Types.ExactPrintFallbackMode
- Language.Haskell.Brittany.Internal.Config.Types: instance Data.Aeson.Types.ToJSON.ToJSON Language.Haskell.Brittany.Internal.Config.Types.IndentPolicy
- Language.Haskell.Brittany.Internal.Prelude: (.>) :: (a -> b) -> (b -> c) -> (a -> c)
- Language.Haskell.Brittany.Internal.Prelude: (<&!>) :: Monad m => m a -> (a -> b) -> m b
- Language.Haskell.Brittany.Internal.Prelude: (<&>) :: Functor f => f a -> (a -> b) -> f b
- Language.Haskell.Brittany.Internal.Prelude: errorIf :: Bool -> a -> a
- Language.Haskell.Brittany.Internal.Prelude: errorIfNote :: Maybe String -> a -> a
- Language.Haskell.Brittany.Internal.Prelude: evaluateDeep :: NFData a => a -> IO a
- Language.Haskell.Brittany.Internal.Prelude: infixl 4 <&>
- Language.Haskell.Brittany.Internal.Prelude: infixl 9 .>
- Language.Haskell.Brittany.Internal.Prelude: instance GHC.Base.Alternative Data.Strict.Maybe.Maybe
- Language.Haskell.Brittany.Internal.Prelude: instance GHC.Base.Applicative Data.Strict.Maybe.Maybe
- Language.Haskell.Brittany.Internal.Prelude: instance GHC.Base.Monad Data.Strict.Maybe.Maybe
- Language.Haskell.Brittany.Internal.Prelude: printErr :: Show a => a -> IO ()
- Language.Haskell.Brittany.Internal.Prelude: putStrErrLn :: String -> IO ()
- Language.Haskell.Brittany.Internal.Prelude: traceFunctionWith :: String -> (a -> String) -> (b -> String) -> (a -> b) -> (a -> b)
- Language.Haskell.Brittany.Internal.Types: BDFProhibitMTEL :: (f (BriDocF f)) -> BriDocF f
- Language.Haskell.Brittany.Internal.Types: BDProhibitMTEL :: BriDoc -> BriDoc
- Language.Haskell.Brittany.Internal.Types: [_lstate_inhibitMTEL] :: LayoutState -> Bool
+ Language.Haskell.Brittany.Internal.Config.Types.Instances: (.:?=) :: FromJSON a => Object -> Text -> Parser a
+ Language.Haskell.Brittany.Internal.Config.Types.Instances: aesonDecodeOptionsBrittany :: Options
+ Language.Haskell.Brittany.Internal.Config.Types.Instances: instance Data.Aeson.Types.FromJSON.FromJSON (Language.Haskell.Brittany.Internal.Config.Types.CConfig Data.Semigroup.Option)
+ Language.Haskell.Brittany.Internal.Config.Types.Instances: instance Data.Aeson.Types.FromJSON.FromJSON (Language.Haskell.Brittany.Internal.Config.Types.CConfig GHC.Base.Maybe)
+ Language.Haskell.Brittany.Internal.Config.Types.Instances: instance Data.Aeson.Types.FromJSON.FromJSON (Language.Haskell.Brittany.Internal.Config.Types.CDebugConfig Data.Semigroup.Option)
+ Language.Haskell.Brittany.Internal.Config.Types.Instances: instance Data.Aeson.Types.FromJSON.FromJSON (Language.Haskell.Brittany.Internal.Config.Types.CDebugConfig GHC.Base.Maybe)
+ Language.Haskell.Brittany.Internal.Config.Types.Instances: instance Data.Aeson.Types.FromJSON.FromJSON (Language.Haskell.Brittany.Internal.Config.Types.CErrorHandlingConfig Data.Semigroup.Option)
+ Language.Haskell.Brittany.Internal.Config.Types.Instances: instance Data.Aeson.Types.FromJSON.FromJSON (Language.Haskell.Brittany.Internal.Config.Types.CErrorHandlingConfig GHC.Base.Maybe)
+ Language.Haskell.Brittany.Internal.Config.Types.Instances: instance Data.Aeson.Types.FromJSON.FromJSON (Language.Haskell.Brittany.Internal.Config.Types.CForwardOptions Data.Semigroup.Option)
+ Language.Haskell.Brittany.Internal.Config.Types.Instances: instance Data.Aeson.Types.FromJSON.FromJSON (Language.Haskell.Brittany.Internal.Config.Types.CForwardOptions GHC.Base.Maybe)
+ Language.Haskell.Brittany.Internal.Config.Types.Instances: instance Data.Aeson.Types.FromJSON.FromJSON (Language.Haskell.Brittany.Internal.Config.Types.CLayoutConfig Data.Semigroup.Option)
+ Language.Haskell.Brittany.Internal.Config.Types.Instances: instance Data.Aeson.Types.FromJSON.FromJSON (Language.Haskell.Brittany.Internal.Config.Types.CLayoutConfig GHC.Base.Maybe)
+ Language.Haskell.Brittany.Internal.Config.Types.Instances: instance Data.Aeson.Types.FromJSON.FromJSON (Language.Haskell.Brittany.Internal.Config.Types.CPreProcessorConfig Data.Semigroup.Option)
+ Language.Haskell.Brittany.Internal.Config.Types.Instances: instance Data.Aeson.Types.FromJSON.FromJSON (Language.Haskell.Brittany.Internal.Config.Types.CPreProcessorConfig GHC.Base.Maybe)
+ Language.Haskell.Brittany.Internal.Config.Types.Instances: instance Data.Aeson.Types.FromJSON.FromJSON Language.Haskell.Brittany.Internal.Config.Types.AltChooser
+ Language.Haskell.Brittany.Internal.Config.Types.Instances: instance Data.Aeson.Types.FromJSON.FromJSON Language.Haskell.Brittany.Internal.Config.Types.CPPMode
+ Language.Haskell.Brittany.Internal.Config.Types.Instances: instance Data.Aeson.Types.FromJSON.FromJSON Language.Haskell.Brittany.Internal.Config.Types.ColumnAlignMode
+ Language.Haskell.Brittany.Internal.Config.Types.Instances: instance Data.Aeson.Types.FromJSON.FromJSON Language.Haskell.Brittany.Internal.Config.Types.ExactPrintFallbackMode
+ Language.Haskell.Brittany.Internal.Config.Types.Instances: instance Data.Aeson.Types.FromJSON.FromJSON Language.Haskell.Brittany.Internal.Config.Types.IndentPolicy
+ Language.Haskell.Brittany.Internal.Config.Types.Instances: instance Data.Aeson.Types.ToJSON.ToJSON (Language.Haskell.Brittany.Internal.Config.Types.CConfig Data.Semigroup.Option)
+ Language.Haskell.Brittany.Internal.Config.Types.Instances: instance Data.Aeson.Types.ToJSON.ToJSON (Language.Haskell.Brittany.Internal.Config.Types.CConfig GHC.Base.Maybe)
+ Language.Haskell.Brittany.Internal.Config.Types.Instances: instance Data.Aeson.Types.ToJSON.ToJSON (Language.Haskell.Brittany.Internal.Config.Types.CDebugConfig Data.Semigroup.Option)
+ Language.Haskell.Brittany.Internal.Config.Types.Instances: instance Data.Aeson.Types.ToJSON.ToJSON (Language.Haskell.Brittany.Internal.Config.Types.CDebugConfig GHC.Base.Maybe)
+ Language.Haskell.Brittany.Internal.Config.Types.Instances: instance Data.Aeson.Types.ToJSON.ToJSON (Language.Haskell.Brittany.Internal.Config.Types.CErrorHandlingConfig Data.Semigroup.Option)
+ Language.Haskell.Brittany.Internal.Config.Types.Instances: instance Data.Aeson.Types.ToJSON.ToJSON (Language.Haskell.Brittany.Internal.Config.Types.CErrorHandlingConfig GHC.Base.Maybe)
+ Language.Haskell.Brittany.Internal.Config.Types.Instances: instance Data.Aeson.Types.ToJSON.ToJSON (Language.Haskell.Brittany.Internal.Config.Types.CForwardOptions Data.Semigroup.Option)
+ Language.Haskell.Brittany.Internal.Config.Types.Instances: instance Data.Aeson.Types.ToJSON.ToJSON (Language.Haskell.Brittany.Internal.Config.Types.CForwardOptions GHC.Base.Maybe)
+ Language.Haskell.Brittany.Internal.Config.Types.Instances: instance Data.Aeson.Types.ToJSON.ToJSON (Language.Haskell.Brittany.Internal.Config.Types.CLayoutConfig Data.Semigroup.Option)
+ Language.Haskell.Brittany.Internal.Config.Types.Instances: instance Data.Aeson.Types.ToJSON.ToJSON (Language.Haskell.Brittany.Internal.Config.Types.CLayoutConfig GHC.Base.Maybe)
+ Language.Haskell.Brittany.Internal.Config.Types.Instances: instance Data.Aeson.Types.ToJSON.ToJSON (Language.Haskell.Brittany.Internal.Config.Types.CPreProcessorConfig Data.Semigroup.Option)
+ Language.Haskell.Brittany.Internal.Config.Types.Instances: instance Data.Aeson.Types.ToJSON.ToJSON (Language.Haskell.Brittany.Internal.Config.Types.CPreProcessorConfig GHC.Base.Maybe)
+ Language.Haskell.Brittany.Internal.Config.Types.Instances: instance Data.Aeson.Types.ToJSON.ToJSON Language.Haskell.Brittany.Internal.Config.Types.AltChooser
+ Language.Haskell.Brittany.Internal.Config.Types.Instances: instance Data.Aeson.Types.ToJSON.ToJSON Language.Haskell.Brittany.Internal.Config.Types.CPPMode
+ Language.Haskell.Brittany.Internal.Config.Types.Instances: instance Data.Aeson.Types.ToJSON.ToJSON Language.Haskell.Brittany.Internal.Config.Types.ColumnAlignMode
+ Language.Haskell.Brittany.Internal.Config.Types.Instances: instance Data.Aeson.Types.ToJSON.ToJSON Language.Haskell.Brittany.Internal.Config.Types.ExactPrintFallbackMode
+ Language.Haskell.Brittany.Internal.Config.Types.Instances: instance Data.Aeson.Types.ToJSON.ToJSON Language.Haskell.Brittany.Internal.Config.Types.IndentPolicy
+ Language.Haskell.Brittany.Internal.PreludeUtils: (.>) :: (a -> b) -> (b -> c) -> (a -> c)
+ Language.Haskell.Brittany.Internal.PreludeUtils: (<&!>) :: Monad m => m a -> (a -> b) -> m b
+ Language.Haskell.Brittany.Internal.PreludeUtils: (<&>) :: Functor f => f a -> (a -> b) -> f b
+ Language.Haskell.Brittany.Internal.PreludeUtils: errorIf :: Bool -> a -> a
+ Language.Haskell.Brittany.Internal.PreludeUtils: errorIfNote :: Maybe String -> a -> a
+ Language.Haskell.Brittany.Internal.PreludeUtils: evaluateDeep :: NFData a => a -> IO a
+ Language.Haskell.Brittany.Internal.PreludeUtils: infixl 4 <&>
+ Language.Haskell.Brittany.Internal.PreludeUtils: infixl 9 .>
+ Language.Haskell.Brittany.Internal.PreludeUtils: instance GHC.Base.Alternative Data.Strict.Maybe.Maybe
+ Language.Haskell.Brittany.Internal.PreludeUtils: instance GHC.Base.Applicative Data.Strict.Maybe.Maybe
+ Language.Haskell.Brittany.Internal.PreludeUtils: instance GHC.Base.Monad Data.Strict.Maybe.Maybe
+ Language.Haskell.Brittany.Internal.PreludeUtils: printErr :: Show a => a -> IO ()
+ Language.Haskell.Brittany.Internal.PreludeUtils: putStrErrLn :: String -> IO ()
+ Language.Haskell.Brittany.Internal.PreludeUtils: traceFunctionWith :: String -> (a -> String) -> (b -> String) -> (a -> b) -> (a -> b)
+ Language.Haskell.Brittany.Internal.Types: type PPMLocal = MultiRWS '[Config, Anns] '[Builder, [BrittanyError], Seq String] '[]
+ Language.Haskell.Brittany.Internal.Utils: lines' :: String -> [String]
- Language.Haskell.Brittany.Internal.Types: LayoutState :: [Int] -> Either Int Int -> [Int] -> Int -> Anns -> Maybe Int -> Maybe Int -> Bool -> LayoutState
+ Language.Haskell.Brittany.Internal.Types: LayoutState :: [Int] -> Either Int Int -> [Int] -> Int -> Anns -> Maybe Int -> Maybe Int -> LayoutState
- Language.Haskell.Brittany.Internal.Types: type PPM a = MultiRWS '[Config, Anns] '[Builder, [BrittanyError], Seq String] '[] a
+ Language.Haskell.Brittany.Internal.Types: type PPM = MultiRWS '[Map AnnKey Anns, Config, Anns] '[Builder, [BrittanyError], Seq String] '[]
Files
- ChangeLog.md +13/−0
- README.md +41/−41
- brittany.cabal +14/−14
- src-brittany/Main.hs +135/−114
- src-literatetests/tests.blt +1080/−0
- src/Language/Haskell/Brittany/Internal.hs +30/−17
- src/Language/Haskell/Brittany/Internal/Backend.hs +75/−36
- src/Language/Haskell/Brittany/Internal/BackendUtils.hs +18/−24
- src/Language/Haskell/Brittany/Internal/Config.hs +1/−0
- src/Language/Haskell/Brittany/Internal/Config/Types.hs +0/−86
- src/Language/Haskell/Brittany/Internal/Config/Types/Instances.hs +127/−0
- src/Language/Haskell/Brittany/Internal/ExactPrintUtils.hs +43/−6
- src/Language/Haskell/Brittany/Internal/LayouterBasics.hs +4/−15
- src/Language/Haskell/Brittany/Internal/Layouters/Decl.hs +13/−3
- src/Language/Haskell/Brittany/Internal/Layouters/Expr.hs +52/−3
- src/Language/Haskell/Brittany/Internal/Layouters/Pattern.hs +10/−2
- src/Language/Haskell/Brittany/Internal/Layouters/Type.hs +34/−7
- src/Language/Haskell/Brittany/Internal/Prelude.hs +358/−48
- src/Language/Haskell/Brittany/Internal/PreludeUtils.hs +69/−0
- src/Language/Haskell/Brittany/Internal/Transformations/Alt.hs +3/−7
- src/Language/Haskell/Brittany/Internal/Transformations/Columns.hs +0/−1
- src/Language/Haskell/Brittany/Internal/Types.hs +11/−24
- src/Language/Haskell/Brittany/Internal/Utils.hs +9/−0
- srcinc/prelude.inc +82/−727
ChangeLog.md view
@@ -1,5 +1,18 @@ # Revision history for brittany +## 0.8.0.3 -- September 2017++* Support for ghc-8.2.1+* Bugfixes:+ - Fix quadratic performance issue+ - Fix special "where" indentation with indentAmount /= 2+ - Fix negative literals in patterns+ - Support type applications+* Accept `-h` for `--help` and improve help layouting (via butcher-1.1.0.2)+* Add continuous integration via travis (cabal, cabal-new, stack)+ (brittle due compilation time limit)+* Reduce compilation memory usage a bit+ ## 0.8.0.2 -- August 2017 * Add library interface, to be used by `haskell-ide-engine`.
README.md view
@@ -1,4 +1,4 @@-# brittany+# brittany [](https://hackage.haskell.org/package/brittany) [](https://www.stackage.org/package/brittany) [](http://travis-ci.org/lspitzner/brittany) haskell source code formatter @@ -39,13 +39,13 @@ be detected and the user will get an error); there are other cases where comments are moved slightly; there are also cases where comments result in wonky newline insertion (although this should be a purely aesthetic issue.)-- There is an **open performance issue on large inputs** (due to an- accidentally quadratic sub-algorithm); noticable for inputs with >1k loc.+- ~~There is an **open performance issue on large inputs** (due to an+ accidentally quadratic sub-algorithm); noticable for inputs with >1k loc.~~+ (fixed in `0.8.0.3`) # Other usage notes -- Requires `GHC-8.0.*`; support for 8.2 is on the list, but I haven't even- looked at how much the `GHC` API changes.+- Supports GHC versions `8.0.*` and `8.2.*`. - config (file) documentation is lacking. - some config values can not be configured via commandline yet. - uses/creates user config file in `~/.brittany/config.yaml`;@@ -55,32 +55,32 @@ - via `cabal` "old-build" - ~~~~.sh- # optionally:- # mkdir brittany- # cd brittany- # cabal sandbox init- cabal install brittany --bindir=$HOME/.cabal/bin # -w $PATH_TO_GHC_8_0- ~~~~+ ~~~~.sh+ # optionally:+ # mkdir brittany+ # cd brittany+ # cabal sandbox init+ cabal install brittany --bindir=$HOME/.cabal/bin # -w $PATH_TO_GHC_8_0+ ~~~~ - via `cabal new-build` - ~~~~.sh- cabal unpack brittany- cd brittany-0.8.0.2- # cabal new-configure -w $PATH_TO_GHC_8_0- cabal new-build exe:brittany- # and it should be safe to just copy the executable, e.g.- cp `./find dist-newstyle/build/ -type f -name brittany` $HOME/.cabal/bin/- ~~~~+ ~~~~.sh+ cabal unpack brittany+ cd brittany-0.8.0.2+ # cabal new-configure -w $PATH_TO_GHC_8_0+ cabal new-build exe:brittany+ # and it should be safe to just copy the executable, e.g.+ cp `./find dist-newstyle/build/ -type f -name brittany` $HOME/.cabal/bin/+ ~~~~ - via `stack` - ~~~~.sh- git clone https://github.com/lspitzner/brittany.git- cd brittany- stack install- ~~~~+ ~~~~.sh+ git clone https://github.com/lspitzner/brittany.git+ cd brittany+ stack install+ ~~~~ # Usage@@ -92,22 +92,22 @@ by default, i.e. to add something like this to your `~/.brittany/config.yaml` (execute `brittany` once to create default): - ~~~~- conf_forward:- options_ghc:- - -XLambdaCase- - -XMultiWayIf- - -XGADTs- - -XPatternGuards- - -XViewPatterns- - -XRecursiveDo- - -XTupleSections- - -XExplicitForAll- - -XImplicitParams- - -XQuasiQuotes- - -XTemplateHaskell- - -XBangPatterns- ~~~~+ ~~~~+ conf_forward:+ options_ghc:+ - -XLambdaCase+ - -XMultiWayIf+ - -XGADTs+ - -XPatternGuards+ - -XViewPatterns+ - -XRecursiveDo+ - -XTupleSections+ - -XExplicitForAll+ - -XImplicitParams+ - -XQuasiQuotes+ - -XTemplateHaskell+ - -XBangPatterns+ ~~~~ # Implementation/High-level Documentation
brittany.cabal view
@@ -1,11 +1,11 @@ name: brittany-version: 0.8.0.2+version: 0.8.0.3 synopsis: Haskell source code formatter description: {- See <https://github.com/lspitzner/brittany/blob/master/README.md the README>-+ See <https://github.com/lspitzner/brittany/blob/master/README.md the README>.+ . If you are interested in the implementation, have a look at <https://github.com/lspitzner/brittany/blob/master/doc/implementation/theory.md this document>;-+ . The implementation is documented in more detail <https://github.com/lspitzner/brittany/blob/master/doc/implementation/index.md here>. } license: AGPL-3@@ -23,6 +23,9 @@ README.md doc/implementation/*.md }+extra-source-files: {+ src-literatetests/tests.blt+} source-repository head { type: git@@ -51,10 +54,12 @@ Language.Haskell.Brittany Language.Haskell.Brittany.Internal Language.Haskell.Brittany.Internal.Prelude+ Language.Haskell.Brittany.Internal.PreludeUtils Language.Haskell.Brittany.Internal.Types Language.Haskell.Brittany.Internal.Utils Language.Haskell.Brittany.Internal.Config Language.Haskell.Brittany.Internal.Config.Types+ Language.Haskell.Brittany.Internal.Config.Types.Instances Paths_brittany } other-modules: {@@ -77,15 +82,14 @@ -Wall -j -fno-warn-unused-imports- -fno-warn-orphans -fno-warn-redundant-constraints } if flag(brittany-dev) { ghc-options: -O0 -Werror -fobject-code } build-depends:- { base >=4.9 && <4.10- , ghc >=8.0.1 && <8.1+ { base >=4.9 && <4.11+ , ghc >=8.0.1 && <8.3 , ghc-paths >=0.1.0.9 && <0.2 , ghc-exactprint >=0.5.3.0 && <0.6 , transformers >=0.5.2.0 && <0.6@@ -93,7 +97,7 @@ , mtl >=2.2.1 && <2.3 , text >=1.2 && <1.3 , multistate >=0.7.1.1 && <0.8- , syb >=0.6 && <0.7+ , syb >=0.6 && <0.8 , neat-interpolation >=0.3.2 && <0.4 , data-tree-print , pretty >=1.1.3.3 && <1.2@@ -102,7 +106,7 @@ , butcher >=1.1.0.0 && <1.2 , yaml >=0.8.18 && <0.9 , aeson >=1.0.1.0 && <1.3- , extra >=1.4.10 && <1.6+ , extra >=1.4.10 && <1.7 , uniplate >=1.6.12 && <1.7 , strict >=0.3.2 && <0.4 , monad-memo >=0.4.1 && <0.5@@ -113,7 +117,7 @@ , semigroups >=0.18.2 && <0.19 , cmdargs >=0.10.14 && <0.11 , czipwith >=1.0.0.0 && <1.1- , ghc-boot-th >=8.0.1 && <8.1+ , ghc-boot-th >=8.0.1 && <8.3 } default-extensions: { CPP@@ -202,7 +206,6 @@ -j -fno-spec-constr -fno-warn-unused-imports- -fno-warn-orphans -fno-warn-redundant-constraints -rtsopts -with-rtsopts "-M2G"@@ -282,7 +285,6 @@ -Wall -j -fno-warn-unused-imports- -fno-warn-orphans -rtsopts -with-rtsopts "-M2G" }@@ -356,7 +358,6 @@ -Wall -j -fno-warn-unused-imports- -fno-warn-orphans -rtsopts -with-rtsopts "-M2G" }@@ -396,7 +397,6 @@ -Wall -j -fno-warn-unused-imports- -fno-warn-orphans -rtsopts -with-rtsopts "-M2G" }
src-brittany/Main.hs view
@@ -90,6 +90,7 @@ ] ] + mainCmdParser :: CommandDesc () -> CmdParser Identity (IO ()) () mainCmdParser helpDesc = do addCmdSynopsis "haskell source pretty printer"@@ -99,7 +100,7 @@ addCmd "license" $ addCmdImpl $ print $ licenseDoc -- addButcherDebugCommand reorderStart- printHelp <- addSimpleBoolFlag "" ["help"] mempty+ printHelp <- addSimpleBoolFlag "h" ["help"] mempty printVersion <- addSimpleBoolFlag "" ["version"] mempty printLicense <- addSimpleBoolFlag "" ["license"] mempty inputPaths <- addFlagStringParams "i" ["input"] "PATH" (flagHelpStr "path to input haskell source file")@@ -116,10 +117,10 @@ desc <- peekCmdDesc addCmdImpl $ void $ do when printLicense $ do- liftIO $ print licenseDoc+ print licenseDoc System.Exit.exitSuccess when printVersion $ do- liftIO $ do+ do putStrLn $ "brittany version " ++ showVersion version putStrLn $ "Copyright (C) 2016-2017 Lennart Spitzner" putStrLn $ "There is NO WARRANTY, to the extent permitted by law."@@ -132,127 +133,146 @@ return Nothing [x] -> return $ Just x _ -> do- liftIO $ putStrErrLn $ "more than one input, aborting"- System.Exit.exitWith (System.Exit.ExitFailure 50)- outputPath <- case outputPaths of+ putStrErrLn $ "more than one input, aborting"+ System.Exit.exitWith (System.Exit.ExitFailure 51)+ outputPathM <- case outputPaths of [] -> do return Nothing [x] -> return $ Just x _ -> do- liftIO $ putStrErrLn $ "more than one output, aborting"- System.Exit.exitWith (System.Exit.ExitFailure 50)+ putStrErrLn $ "more than one output, aborting"+ System.Exit.exitWith (System.Exit.ExitFailure 52) config <- runMaybeT (readConfigs cmdlineConfig configPaths) >>= \case- Nothing -> System.Exit.exitWith (System.Exit.ExitFailure 50)+ Nothing -> System.Exit.exitWith (System.Exit.ExitFailure 53) Just x -> return x when (confUnpack $ _dconf_dump_config $ _conf_debug $ config) $ do trace (showConfigYaml config) $ return ()- let ghcOptions = config & _conf_forward & _options_ghc & runIdentity- liftIO $ do- -- there is a good of code duplication between the following code and the- -- `pureModuleTransform` function. Unfortunately, there are also a good- -- amount of slight differences: This module is a bit more verbose, and- -- it tries to use the full-blown `parseModule` function which supports- -- CPP (but requires the input to be a file..).- let cppMode = config & _conf_preprocessor & _ppconf_CPPMode & confUnpack- -- the flag will do the following: insert a marker string- -- ("-- BRITTANY_INCLUDE_HACK ") right before any lines starting with- -- "#include" before processing (parsing) input; and remove that marker- -- string from the transformation output.- let hackAroundIncludes = config & _conf_preprocessor & _ppconf_hackAroundIncludes & confUnpack- let exactprintOnly = config & _conf_debug & _dconf_roundtrip_exactprint_only & confUnpack- let cppCheckFunc dynFlags = if GHC.xopt GHC.Cpp dynFlags- then case cppMode of- CPPModeAbort -> do- return $ Left "Encountered -XCPP. Aborting."- CPPModeWarn -> do- putStrErrLn- $ "Warning: Encountered -XCPP."- ++ " Be warned that -XCPP is not supported and that"- ++ " brittany cannot check that its output is syntactically"- ++ " valid in its presence."- return $ Right True- CPPModeNowarn -> return $ Right True- else return $ Right False- parseResult <- case inputPathM of- Nothing -> do- -- TODO: refactor this hack to not be mixed into parsing logic- let hackF s = if "#include" `isPrefixOf` s then "-- BRITTANY_INCLUDE_HACK " ++ s else s- let hackTransform =- if hackAroundIncludes && not exactprintOnly then List.unlines . fmap hackF . List.lines else id- inputString <- System.IO.hGetContents System.IO.stdin- parseModuleFromString ghcOptions "stdin" cppCheckFunc (hackTransform inputString)- Just p -> parseModule ghcOptions p cppCheckFunc- case parseResult of- Left left -> do- putStrErrLn "parse error:"- printErr left- System.Exit.exitWith (System.Exit.ExitFailure 60)- Right (anns, parsedSource, hasCPP) -> do- when (config & _conf_debug .> _dconf_dump_ast_full .> confUnpack) $ do- let val = printTreeWithCustom 100 (customLayouterF anns) parsedSource- trace ("---- ast ----\n" ++ show val) $ return ()- (errsWarns, outLText) <- do- if exactprintOnly- then do- pure ([], TextL.pack $ ExactPrint.exactPrint parsedSource anns)- else do- let omitCheck = config & _conf_errorHandling .> _econf_omit_output_valid_check .> confUnpack- (ews, outRaw) <- if hasCPP || omitCheck- then return $ pPrintModule config anns parsedSource- else pPrintModuleAndCheck config anns parsedSource- let hackF s = fromMaybe s $ TextL.stripPrefix (TextL.pack "-- BRITTANY_INCLUDE_HACK ") s- pure $ if hackAroundIncludes- then (ews, TextL.unlines $ fmap hackF $ TextL.lines outRaw)- else (ews, outRaw)- let customErrOrder ErrorInput{} = 4- customErrOrder LayoutWarning{} = 0 :: Int- customErrOrder ErrorOutputCheck{} = 1- customErrOrder ErrorUnusedComment{} = 2- customErrOrder ErrorUnknownNode{} = 3- when (not $ null errsWarns) $ do- let groupedErrsWarns = Data.List.Extra.groupOn customErrOrder $ List.sortOn customErrOrder $ errsWarns- groupedErrsWarns `forM_` \case- (ErrorOutputCheck{}:_) -> do- putStrErrLn $ "ERROR: brittany pretty printer" ++ " returned syntactically invalid result."- (ErrorInput str:_) -> do- putStrErrLn $ "ERROR: parse error: " ++ str- uns@(ErrorUnknownNode{}:_) -> do- putStrErrLn $ "ERROR: encountered unknown syntactical constructs:"- uns `forM_` \case- ErrorUnknownNode str ast -> do- putStrErrLn str- when (config & _conf_debug & _dconf_dump_ast_unknown & confUnpack) $ do- putStrErrLn $ " " ++ show (astToDoc ast)- _ -> error "cannot happen (TM)"- warns@(LayoutWarning{}:_) -> do- putStrErrLn $ "WARNINGS:"- warns `forM_` \case- LayoutWarning str -> putStrErrLn str- _ -> error "cannot happen (TM)"- unused@(ErrorUnusedComment{}:_) -> do- putStrErrLn- $ "Error: detected unprocessed comments."- ++ " The transformation output will most likely"- ++ " not contain certain of the comments"- ++ " present in the input haskell source file."- putStrErrLn $ "Affected are the following comments:"- unused `forM_` \case- ErrorUnusedComment str -> putStrErrLn str- _ -> error "cannot happen (TM)"- [] -> error "cannot happen"- -- TODO: don't output anything when there are errors unless user- -- adds some override?- let hasErrors = case config & _conf_errorHandling & _econf_Werror & confUnpack of- False -> 0 < maximum (-1 : fmap customErrOrder errsWarns)- True -> not $ null errsWarns- outputOnErrs = config & _conf_errorHandling & _econf_produceOutputOnErrors & confUnpack- shouldOutput = not suppressOutput && (not hasErrors || outputOnErrs)+ eitherErrSucc <- coreIO putStrErrLn config suppressOutput inputPathM outputPathM+ case eitherErrSucc of+ Left errNo -> System.Exit.exitWith (System.Exit.ExitFailure errNo)+ Right () -> pure () - when shouldOutput $ addTraceSep (_conf_debug config) $ case outputPath of- Nothing -> TextL.IO.putStr $ outLText- Just p -> TextL.IO.writeFile p $ outLText - when hasErrors $ System.Exit.exitWith (System.Exit.ExitFailure 70)+-- | The main IO parts for the default mode of operation, and after commandline+-- and config stuff is processed.+coreIO+ :: (String -> IO ()) -- ^ error output function. In parallel operation, you+ -- may want serialize the different outputs and+ -- consequently not directly print to stderr.+ -> Config -- ^ global program config.+ -> Bool -- ^ whether to supress output (to stdout). Purely IO flag, so+ -- currently not part of program config.+ -> Maybe FilePath.FilePath -- ^ input filepath; stdin if Nothing.+ -> Maybe FilePath.FilePath -- ^ output filepath; stdout if Nothing.+ -> IO (Either Int ()) -- ^ Either an errorNo, or success.+coreIO putErrorLnIO config suppressOutput inputPathM outputPathM = EitherT.runEitherT $ do+ let putErrorLn = liftIO . putErrorLnIO :: String -> EitherT.EitherT e IO ()+ let ghcOptions = config & _conf_forward & _options_ghc & runIdentity+ -- there is a good of code duplication between the following code and the+ -- `pureModuleTransform` function. Unfortunately, there are also a good+ -- amount of slight differences: This module is a bit more verbose, and+ -- it tries to use the full-blown `parseModule` function which supports+ -- CPP (but requires the input to be a file..).+ let cppMode = config & _conf_preprocessor & _ppconf_CPPMode & confUnpack+ -- the flag will do the following: insert a marker string+ -- ("-- BRITTANY_INCLUDE_HACK ") right before any lines starting with+ -- "#include" before processing (parsing) input; and remove that marker+ -- string from the transformation output.+ let hackAroundIncludes = config & _conf_preprocessor & _ppconf_hackAroundIncludes & confUnpack+ let exactprintOnly = config & _conf_debug & _dconf_roundtrip_exactprint_only & confUnpack+ let cppCheckFunc dynFlags = if GHC.xopt GHC.Cpp dynFlags+ then case cppMode of+ CPPModeAbort -> do+ return $ Left "Encountered -XCPP. Aborting."+ CPPModeWarn -> do+ putErrorLnIO+ $ "Warning: Encountered -XCPP."+ ++ " Be warned that -XCPP is not supported and that"+ ++ " brittany cannot check that its output is syntactically"+ ++ " valid in its presence."+ return $ Right True+ CPPModeNowarn -> return $ Right True+ else return $ Right False+ parseResult <- case inputPathM of+ Nothing -> do+ -- TODO: refactor this hack to not be mixed into parsing logic+ let hackF s = if "#include" `isPrefixOf` s then "-- BRITTANY_INCLUDE_HACK " ++ s else s+ let hackTransform =+ if hackAroundIncludes && not exactprintOnly then List.intercalate "\n" . fmap hackF . lines' else id+ inputString <- liftIO $ System.IO.hGetContents System.IO.stdin+ liftIO $ parseModuleFromString ghcOptions "stdin" cppCheckFunc (hackTransform inputString)+ Just p -> liftIO $ parseModule ghcOptions p cppCheckFunc+ case parseResult of+ Left left -> do+ putErrorLn "parse error:"+ putErrorLn $ show left+ EitherT.left 60+ Right (anns, parsedSource, hasCPP) -> do+ when (config & _conf_debug .> _dconf_dump_ast_full .> confUnpack) $ do+ let val = printTreeWithCustom 100 (customLayouterF anns) parsedSource+ trace ("---- ast ----\n" ++ show val) $ return ()+ (errsWarns, outLText) <- do+ if exactprintOnly+ then do+ pure ([], TextL.pack $ ExactPrint.exactPrint parsedSource anns)+ else do+ let omitCheck = config & _conf_errorHandling .> _econf_omit_output_valid_check .> confUnpack+ (ews, outRaw) <- if hasCPP || omitCheck+ then return $ pPrintModule config anns parsedSource+ else liftIO $ pPrintModuleAndCheck config anns parsedSource+ let hackF s = fromMaybe s $ TextL.stripPrefix (TextL.pack "-- BRITTANY_INCLUDE_HACK ") s+ pure $ if hackAroundIncludes+ then (ews, TextL.intercalate (TextL.pack "\n") $ fmap hackF $ TextL.splitOn (TextL.pack "\n") outRaw)+ else (ews, outRaw)+ let customErrOrder ErrorInput{} = 4+ customErrOrder LayoutWarning{} = 0 :: Int+ customErrOrder ErrorOutputCheck{} = 1+ customErrOrder ErrorUnusedComment{} = 2+ customErrOrder ErrorUnknownNode{} = 3+ when (not $ null errsWarns) $ do+ let groupedErrsWarns = Data.List.Extra.groupOn customErrOrder $ List.sortOn customErrOrder $ errsWarns+ groupedErrsWarns `forM_` \case+ (ErrorOutputCheck{}:_) -> do+ putErrorLn $ "ERROR: brittany pretty printer" ++ " returned syntactically invalid result."+ (ErrorInput str:_) -> do+ putErrorLn $ "ERROR: parse error: " ++ str+ uns@(ErrorUnknownNode{}:_) -> do+ putErrorLn $ "ERROR: encountered unknown syntactical constructs:"+ uns `forM_` \case+ ErrorUnknownNode str ast -> do+ putErrorLn str+ when (config & _conf_debug & _dconf_dump_ast_unknown & confUnpack) $ do+ putErrorLn $ " " ++ show (astToDoc ast)+ _ -> error "cannot happen (TM)"+ warns@(LayoutWarning{}:_) -> do+ putErrorLn $ "WARNINGS:"+ warns `forM_` \case+ LayoutWarning str -> putErrorLn str+ _ -> error "cannot happen (TM)"+ unused@(ErrorUnusedComment{}:_) -> do+ putErrorLn+ $ "Error: detected unprocessed comments."+ ++ " The transformation output will most likely"+ ++ " not contain certain of the comments"+ ++ " present in the input haskell source file."+ putErrorLn $ "Affected are the following comments:"+ unused `forM_` \case+ ErrorUnusedComment str -> putErrorLn str+ _ -> error "cannot happen (TM)"+ [] -> error "cannot happen"+ -- TODO: don't output anything when there are errors unless user+ -- adds some override?+ let hasErrors = case config & _conf_errorHandling & _econf_Werror & confUnpack of+ False -> 0 < maximum (-1 : fmap customErrOrder errsWarns)+ True -> not $ null errsWarns+ outputOnErrs = config & _conf_errorHandling & _econf_produceOutputOnErrors & confUnpack+ shouldOutput = not suppressOutput && (not hasErrors || outputOnErrs)++ when shouldOutput $ addTraceSep (_conf_debug config) $ case outputPathM of+ Nothing -> liftIO $ TextL.IO.putStr $ outLText+ Just p -> liftIO $ TextL.IO.writeFile p $ outLText++ when hasErrors $ EitherT.left 70 where addTraceSep conf = if or@@ -268,6 +288,7 @@ ] then trace "----" else id+ readConfigs :: CConfig Option -> [System.IO.FilePath] -> MaybeT IO Config readConfigs cmdlineConfig configPaths = do
+ src-literatetests/tests.blt view
@@ -0,0 +1,1080 @@++###############################################################################+###############################################################################+###############################################################################+#group type signatures+###############################################################################+###############################################################################+###############################################################################++#test simple001+func :: a -> a++#test long typeVar+func+ :: lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ -> lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd++#test keep linebreak mode+func+ :: lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ -> lakjsdlkjasldkj+ -> lakjsdlkjasldkj++#test simple parens 1+func :: ((a))++#test simple parens 2+func :: (a -> a) -> a++#test simple parens 3+func :: a -> (a -> a)++#test did anyone say parentheses?+func :: (((((((((())))))))))++-- current output is.. funny. wonder if that can/needs to be improved..+#test give me more!+#pending+func :: ((((((((((((((((((((((((((((((((((((((((((()))))))))))))))))))))))))))))))))))))))))))++#test unit+func :: ()+++###############################################################################++#test paren'd func 1+func+ :: ( lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ -> lakjsdlkjasldkj+ -> lakjsdlkjasldkj+ )++#test paren'd func 2+func+ :: lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ -> (lakjsdlkjasldkj -> lakjsdlkjasldkj)++#test paren'd func 3+func+ :: (lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd -> lakjsdlkjasldkj)+ -> lakjsdlkjasldkj++#test paren'd func 4+func+ :: ( lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ -> lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ )+ -> lakjsdlkjasldkj++#test paren'd func 5+func+ :: ( ( lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ -> lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ )+ )++###############################################################################++#test type application 1+func :: asd -> Either a b++#test type application 2+func+ :: asd+ -> Either+ lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd++#test type application 3+func+ :: asd+ -> Trither+ lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd++#test type application 4+func+ :: Trither+ lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ -> asd++#test type application 5+func+ :: Trither+ lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ (lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd -> asd)++#test type application 6+func+ :: Trither+ asd+ lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ ( lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ -> lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ )++#test type application paren 1+func+ :: asd+ -> ( Trither+ lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ )++#test type application paren 2+func+ :: asd+ -> ( Trither+ lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ )+ lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd++#test type application paren 3+func+ :: ( Trither+ lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ )+ lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ -> asd++###############################################################################++#test list simple+func :: [a -> b]++#test list func+func+ :: [ lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ -> lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ ]++#test list paren+func+ :: [ ( lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ -> lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ )+ ]++################################################################## -- #############++#test tuple type 1+func :: (a, b, c)++#test tuple type 2+func :: ((a, b, c), (a, b, c), (a, b, c))++#test tuple type long+func+ :: ( lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ , lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ , lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ )++#test tuple type nested+func+ :: ( ( lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ , (lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd)+ , lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ )+ )++#test tuple type function+func+ :: [ ( lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ , lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ , lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ )+ ]+###############################################################################+#test type operator stuff+#pending+test050 :: a :+: b+test051 :: lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ :+: lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+test052 :: lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ -> lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ :+: lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ -> lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd++###############################################################################++#test forall oneliner+{-# LANGUAGE ScopedTypeVariables #-}+func :: forall (a :: *) b . a -> b++#test forall context multiline+{-# LANGUAGE ScopedTypeVariables #-}+func+ :: forall m+ . Foo+ => ColMap2+ -> ColInfo+ -> ColInfo+ -> ColInfo+ -> ColInfo+ -> m ()++#test forall no-context multiline+{-# LANGUAGE ScopedTypeVariables #-}+func+ :: forall m+ . ColMap2+ -> ColInfo+ -> ColInfo+ -> ColInfo+ -> ColInfo+ -> ColInfo+ -> m ()++#test language pragma issue+{-# LANGUAGE ScopedTypeVariables #-}+func :: forall (a :: *) b . a -> b++#test comments 1+func :: a -> b -- comment++#test comments 2+funcA :: a -> b -- comment A+funcB :: a -> b -- comment B++#test comments all+#pending+-- a+func -- b+ :: -- c+ a -- d+ -> -- e+ ( -- f+ c -- g+ , -- h+ d -- i+ ) -- j+-- k++###############################################################################++#test ImplicitParams 1+{-# LANGUAGE ImplicitParams #-}+func :: (?asd::Int) -> ()++#test ImplicitParams 2+{-# LANGUAGE ImplicitParams #-}+func+ :: ( ?asd+ :: lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ -> lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ )+ -> ()+++###############################################################################+###############################################################################+###############################################################################+#group type signatures pragmas+###############################################################################+###############################################################################+###############################################################################++#test inline pragma 1+func = f+ where+ {-# INLINE f #-}+ f = id++#test inline pragma 2+func = ($)+ where+ {-# INLINE ($) #-}+ ($) = id++#test inline pragma 3+func = f+ where+ {-# INLINE CONLIKE [1] f #-}+ f = id++#test inline pragma 4+#pending this does not work with the compiler version we currently use yet (i think). should work with ghc-8.0.2.+func = f+ where+ {-# INLINE [~] f #-}+ f = id+++###############################################################################+###############################################################################+###############################################################################+#group equation.basic+###############################################################################+###############################################################################+###############################################################################+## some basic testing of different kinds of equations.+## some focus on column layouting for multiple-equation definitions.+## (that part probably is not implemented in any way yet.)++#test basic 1+func x = x++#test infix 1+x *** y = x++#test symbol prefix+(***) x y = x+++###############################################################################+###############################################################################+###############################################################################+#group equation.patterns+###############################################################################+###############################################################################+###############################################################################++#test wildcard+func _ = x++#test simple long pattern+#pending+func reallyreallyreallyreallyreallyreallyreallyreallyreallyreallylongvariable+ = x++#test simple multiline pattern+#pending+func reallyreallyreallyreallyreallyreallyreallyreallyreallyreallylongvariable+ reallyreallyreallyreallyreallyreallyreallyreallyreallyreallylongvariable+ = x++#test another multiline pattern+#pending+func reallyreallyreallyreallyreallyreallyreallyreallyreallyreallylongvariable+ a+ b+ = x++#test simple constructor+func (A a) = a++#test list constructor+func (x:xr) = x++#test some other constructor symbol+#pending+func (x:+:xr) = x+++###############################################################################+###############################################################################+###############################################################################+#group equation.guards+###############################################################################+###############################################################################+###############################################################################+#test simple guard+func | True = x++#test multiple-clauses-1+func x | x = simple expression+ | otherwise = 0++#test multiple-clauses-2+func x+ | a somewhat longer guard x = "and a somewhat longer expession that does not"+ | otherwise = "fit without putting the guards in new lines"++#test multiple-clauses-3+func x+ | very long guard, another rather long guard that refers to x = nontrivial+ expression+ foo+ bar+ alsdkjlasdjlasj+ | otherwise = 0++#test multiple-clauses-4+func x+ | very long guard, another rather long guard that refers to x+ = nontrivialexpression foo bar alsdkjlasdjlasj+ | otherwise+ = 0++#test multiple-clauses-5+func x+ | very loooooooooooooooooooooooooooooong guard+ , another rather long guard that refers to x+ = nontrivial expression foo bar alsdkjlasdjlasj+ | otherwise+ = 0+++###############################################################################+###############################################################################+###############################################################################+#group expression.basic+###############################################################################+###############################################################################+###############################################################################++#test var+func = x++describe "infix op" $ do+#test 1+func = x + x++#test long+#pending+func = mweroiuxlskdfjlksjdflkjsdfljksldkjflkjsdflkj+ + mweroiuxlskdfjlksjdflkjsdfljksldkjflkjsdflkj++#test long keep linemode 1+#pending+func = mweroiuxlskdfjlksjdflkjsdfljksldkjflkjsdflkj+ + mweroiuxlskdfjlksj+ + mweroiuxlskdfjlksj++#test long keep linemode 2+#pending+func = mweroiuxlskdfjlksj+ + mweroiuxlskdfjlksj+ + mweroiuxlskdfjlksjdflkjsdfljksldkjflkjsdflkj++#test literals+func = 1+func = "abc"+func = 1.1e5+func = 'x'+func = 981409823458910394810928414192837123987123987123++#test lambdacase+{-# LANGUAGE LambdaCase #-}+func = \case+ FooBar -> x+ Baz -> y++#test lambda+func = \x -> abc++describe "app" $ do+#test 1+func = klajsdas klajsdas klajsdas++#test 2+func = lakjsdlajsdljasdlkjasldjasldjasldjalsdjlaskjd+ lakjsdlajsdljasdlkjasldjasldjasldjalsdjlaskjd+ lakjsdlajsdljasdlkjasldjasldjasldjalsdjlaskjd++#test 3+func = lakjsdlajsdljasdlkjasldjasldjasldjalsdjlaskjd lakjsdlajsdljas+ lakjsdlajsdljas+ lakjsdlajsdljas++###+#group expression.basic.sections+###++#test left+func = (1+)++#test right+func = (+1)++#test left inf+## TODO: this could be improved..+func = (1`abc`)++#test right inf+func = (`abc`1)++###+#group tuples+###++#test 1+func = (abc, def)++#test 2+#pending+func = (lakjsdlajsdljasdlkjasldjasldjasldjalsdjlaskjd+ , lakjsdlajsdljasdlkjasldjasldjasldjalsdjlaskjd)++++###############################################################################+###############################################################################+###############################################################################+#group expression.do statements+###############################################################################+###############################################################################+###############################################################################++#test simple+func = do+ stmt+ stmt++#test bind+func = do+ x <- stmt+ stmt x++#test let+func = do+ let x = 13+ stmt x+++###############################################################################+###############################################################################+###############################################################################+#group expression.lists+###############################################################################+###############################################################################+###############################################################################++#test monad-comprehension-case-of+func =+ foooooo+ $ [ case+ foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo+ of+ _ -> True+ ]+++###############################################################################+###############################################################################+###############################################################################+#group expression.multiwayif+###############################################################################+###############################################################################+###############################################################################++#test simple+{-# LANGUAGE MultiWayIf #-}+func = if+ | cond1 -> loooooooooooooooooooooooooooooong expr1+ | cond2 -> loooooooooooooooooooooooooooooong expr2++#test simplenested+{-# LANGUAGE MultiWayIf #-}+func = do+ foo+ bar $ if+ | cond1 -> loooooooooooooooooooooooooooooong expr1+ | cond2 -> loooooooooooooooooooooooooooooong expr2+++###############################################################################+###############################################################################+###############################################################################+#group stylisticspecialcases+###############################################################################+###############################################################################+###############################################################################++#test operatorprefixalignment-even-with-multiline-alignbreak+func =+ foo+ $ [ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+ , bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb+ ]+ ++ [ccccccccccccccccccccccccccccccccccccccccccccccccccccccccc]+++###############################################################################+###############################################################################+###############################################################################+#group regression+###############################################################################+###############################################################################+###############################################################################++#test newlines-comment+func = do+ abc <- foo++--abc+return ()++#test parenthesis-around-unit+func = (())++#test let-defs indentation+func = do+ let foo True = True+ foo _ = False+ return ()++#test record update indentation 1+func = do+ s <- mGet+ mSet $ s { _lstate_indent = _lstate_indent state }++#test record update indentation 2+func = do+ s <- mGet+ mSet $ s { _lstate_indent = _lstate_indent state+ , _lstate_indent = _lstate_indent state+ }++#test record update indentation 3+func = do+ s <- mGet+ mSet $ s+ { _lstate_indent = _lstate_indent lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ , _lstate_indent = _lstate_indent lkasdlkjalsdjlakjsdlkjasldkjalskdjlkajsd+ }++#test post-indent comment+func = do+-- abc+ -- def+ return ()++#test post-unindent comment+func = do+ do+ return ()+ -- abc+ -- def+ return ()++#test CPP empty comment case+#pending CPP parsing needs fixing for roundTripEqual+{-# LANGUAGE CPP #-}+module Test where+func = do+#if FOO+ let x = 13+#endif+ stmt x++## really, the following should be handled by forcing the Alt to multiline+## because there are comments. as long as this is not implemented though,+## we should ensure the trivial solution works.+#test comment inline placement (temporary)+func+ :: Int -- basic indentation amount+ -> Int -- currently used width in current line (after indent)+ -- used to accurately calc placing of the current-line+ -> LayoutDesc+ -> Int++#test some indentation thingy+func =+ ( lkjadljasldjalskdjaldjalsdjkalsdjlaksdjlasjdlajsaldskj+ $ abc+ $ def+ $ ghi+ $ jkl+ )++#test parenthesized operator+buildG bounds0 edges0 = accumArray (flip (:)) [] bounds0 (map reassoc edges0)+ where reassoc (v, e, w) = (v, (e, w))++#test record pattern matching stuff+downloadRepoPackage = case repo of+ RepoLocal {..} -> return ()+ RepoLocal { abc } -> return ()+ RepoLocal{} -> return ()++#test do let comment indentation level problem+func = do+ let (primaryPkg, otherPkgs) = selectPrimaryLocalPackage pwd pkgs'+ (bproblems, x) = resolveBuildTargets primaryPkg otherPkgs utargets''+ -- default local dir target if there's no given target+ utargets'' = "foo"+ return ()++#test list comprehension comment placement+func =+ [ (thing, take 10 alts) --TODO: select best ones+ | (thing, _got, alts@(_:_)) <- nosuchFooThing+ , gast <- award+ ]++#test if-then-else comment placement+func = if x+ then if y -- y is important+ then foo+ else bar+ else Nothing++#test qualified infix pattern+#pending "TODO"+wrapPatPrepend pat prepElem = do+ patDocs <- layoutPat pat+ case Seq.viewl patDocs of+ Seq.EmptyL -> return $ Seq.empty+ x1 Seq.:< xR -> do+ x1' <- docSeq [prepElem, return x1]+ return $ x1' Seq.<| xR++#test type signature multiline forcing issue+layoutWriteNewlineBlock+ :: ( MonadMultiWriter Text.Builder.Builder m+ , MonadMultiState LayoutState m+ , MonadMultiWriter (Seq String) m+ )+ => m ()++#test multiwayif proper indentation+{-# LANGUAGE MultiWayIf #-}+readMergePersConfig path shouldCreate conf = do+ exists <- liftIO $ System.Directory.doesFileExist path+ if+ | exists -> do+ contents <- liftIO $ ByteString.readFile path -- no lazy IO, tyvm.+ fileConf <- case Data.Yaml.decodeEither contents of+ Left e -> do+ liftIO+ $ putStrErrLn+ $ "error reading in brittany config from "+ ++ path+ ++ ":"+ liftIO $ putStrErrLn e+ mzero+ Right x -> return x+ return $ fileConf Semigroup.<> conf+ | shouldCreate -> do+ liftIO $ ByteString.writeFile path $ Data.Yaml.encode $ cMap+ (Option . Just . runIdentity)+ staticDefaultConfig+ return $ conf+ | otherwise -> do+ return conf++#test nested pattern alignment issue"+func = BuildReport+ where+ convertInstallOutcome = case result of+ Left BR.PlanningFailed -> PlanningFailed+ Left (BR.DependentFailed p) -> DependencyFailed p+ Left (BR.DownloadFailed _) -> DownloadFailed+ Left (BR.UnpackFailed _) -> UnpackFailed+ Left (BR.ConfigureFailed _) -> ConfigureFailed+ Left (BR.BuildFailed _) -> BuildFailed+ Left (BR.TestsFailed _) -> TestsFailed+ Left (BR.InstallFailed _) -> InstallFailed+ Right (BR.BuildOk _ _ _ ) -> InstallOk++#test nested pattern alignment issue"+func = BuildReport+ where+ convertInstallOutcome = case result of+ Left BR.PlanningFailed -> PlanningFailed+ Left (BR.DependentFailed p) -> DependencyFailed p+ Left (BR.DownloadFailed _) -> DownloadFailed+ Left (BR.UnpackFailed _) -> UnpackFailed+ Left (BR.ConfigureFailed _) -> ConfigureFailed+ Left (BR.BuildFailed _) -> BuildFailed+ Left (BR.TestsFailed _) -> TestsFailed+ Left (BR.InstallFailed _) -> InstallFailed+ Right (BR.BuildOk _ _ _ ) -> InstallOk++#test partially overflowing alignment issue"+showPackageDetailedInfo pkginfo =+ renderStyle (style { lineLength = 80, ribbonsPerLine = 1 })+ $ char '*'+ $+$ something+ [ entry "Synopsis" synopsis hideIfNull reflowParagraphs+ , entry "Versions available"+ sourceVersions+ (altText null "[ Not available from server ]")+ (dispTopVersions 9 (preferredVersions pkginfo))+ , entry+ "Versions installed"+ installedVersions+ ( altText+ null+ (if hasLib pkginfo then "[ Not installed ]" else "[ Unknown ]")+ )+ (dispTopVersions 4 (preferredVersions pkginfo))+ , entry "Homepage" homepage orNotSpecified text+ , entry "Bug reports" bugReports orNotSpecified text+ , entry "Description" description hideIfNull reflowParagraphs+ , entry "Category" category hideIfNull text+ , entry "License" license alwaysShow disp+ , entry "Author" author hideIfNull reflowLines+ , entry "Maintainer" maintainer hideIfNull reflowLines+ , entry "Source repo" sourceRepo orNotSpecified text+ , entry "Executables" executables hideIfNull (commaSep text)+ , entry "Flags" flags hideIfNull (commaSep dispFlag)+ , entry "Dependencies" dependencies hideIfNull (commaSep dispExtDep)+ , entry "Documentation" haddockHtml showIfInstalled text+ , entry "Cached" haveTarball alwaysShow dispYesNo+ , if not (hasLib pkginfo)+ then empty+ else text "Modules:"+ $+$ nest 4 (vcat (map disp . sort . modules $ pkginfo))+ ]++#test issue 7a+isValidPosition position | validX && validY = Just position+ | otherwise = Nothing++#test issue-6-pattern-linebreak-validity+## this is ugly, but at least syntactically valid.+foo = Reflex.runSpiderHost $ ReflexHost.hostApp $ do+ (inputEvent :: Reflex.Event Reflex.Spider String, inputFire :: String+ -> IO Bool ) <-+ ReflexHost.newExternalEvent+ liftIO . forkIO . forever $ getLine >>= inputFire+ ReflexHost.performEvent_ $ fmap (liftIO . putStrLn) inputEvent++#test issue 16+foldrDesc f z = unSwitchQueue $ \q ->+ switch (Min.foldrDesc (f unTaggedF) z q) (Min.foldrAsc (f unTaggedF) z q)++#test issue 18+autocheckCases =+ [ ("Never Deadlocks" , representative deadlocksNever)+ , ("No Exceptions" , representative exceptionsNever)+ , ("Consistent Result", alwaysSame) -- already representative+ ]++#test issue 18b+autocheckCases =+ [ ("Never Deadlocks", representative deadlocksNever)+ , ("No Exceptions" , representative exceptionsNever)+ , ( "Consistent Result"+ , alwaysSame -- already representative+ )+ ]++#test issue 18c+func =+ [ (abc, (1111, 1111))+ , (def, (2, 2))+ , foo -- comment+ ]++#test issue 26+foo a b = g a b -- fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo+ where g a b = b + b * a++#test issue 26b+foo a b = g a b where g a b = b + b * a -- fooooooooooooooooooooooooooooooooooo++#test aggressive alignment 1+func = do+ abc <- expr+ abcccccccccccccccccc <- expr+ abcccccccccccccccccccccccccccccccccccccccccc <- expr+ abccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc <- expr++#test example alignment 1+func (MyLongFoo abc def) = 1+func (Bar a d ) = 2+func _ = 3++#test listcomprehension-case-of+parserCompactLocation =+ [ try+ $ [ ParseRelAbs (Text.Read.read digits) _ _+ | digits <- many1 digit+ , rel1 :: Maybe (Either Int (Ratio Int)) <- optionMaybe+ [ case divPart of+ Nothing -> Left $ Text.Read.read digits+ Just ddigits ->+ Right $ Text.Read.read digits % Text.Read.read ddigits+ | digits <- many1 digit+ , divPart <- optionMaybe (string "/" *> many1 digit)+ ]+ ]+ ]++#test opapp-specialcasing-1+func = fooooooooooooooooooooooooooooooooo $ foooooooooooooooooooooooooooooooo+ foooooooooooooooooooooooooooooooo+ foooooooooooooooooooooooooooooooo++#test opapp-specialcasing-2+func =+ fooooooooooooooooooooooooooooooooo+ + foooooooooooooooooooooooooooooooo foooooooooooooooooooooooooooooooo+ foooooooooooooooooooooooooooooooo++#test opapp-specialcasing-3+func = fooooooooooooooooooooooooooooooooo + foooooooooooooooooooooooooooooooo+ [ foooooooooooooooooooooooooooooooo+ , foooooooooooooooooooooooooooooooo+ , foooooooooooooooooooooooooooooooo+ ]++#test opapp-indenting+parserPrim =+ [ r+ | r <-+ [ SGPPrimFloat $ bool id (0-) minus $ readGnok "parserPrim"+ (d1 ++ d2 ++ d3 ++ d4)+ | d2 <- string "."+ , d3 <- many1 (oneOf "0123456789")+ , _ <- string "f"+ ]+ <|> [ SGPPrimFloat $ bool id (0-) minus $ fromIntegral+ (readGnok "parserPrim" d1 :: Integer)+ | _ <- string "f"+ ]+ <|> [ SGPPrimInt $ bool id (0-) minus $ fromIntegral+ (readGnok "parserPrim" d1 :: Integer)+ | _ <- string "i"+ ]+ ]++#test another-parspacing-testcase++samples = (SV.unpackaaaaadat) <&> \f ->+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa++#test recordupd-singleline-bug++runBrittany tabSize text = do+ let+ config' = staticDefaultConfig+ config = config'+ { _conf_layout = (_conf_layout config') { _lconfig_indentAmount = coerce+ tabSize+ }+ , _conf_forward = forwardOptionsSyntaxExtsEnabled+ }+ parsePrintModule config text++#test issue 38++{-# LANGUAGE TypeApplications #-}+foo = bar @Baz++#test comment-before-BDCols+{-# LANGUAGE TypeApplications #-}+layoutPatternBindFinal alignmentToken binderDoc mPatDoc clauseDocs = do+ docAlt+ $ -- one-line solution+ [ docCols+ (ColBindingLine alignmentToken)+ [ docSeq (patPartInline ++ [guardPart])+ , docSeq+ [ appSep $ return binderDoc+ , docForceSingleline $ return body+ , wherePart+ ]+ ]+ | not hasComments+ , [(guards, body, _bodyRaw)] <- [clauseDocs]+ , let guardPart = singleLineGuardsDoc guards+ , wherePart <- case mWhereDocs of+ Nothing -> return @[] $ docEmpty+ Just [w] -> return @[] $ docSeq+ [ docSeparator+ , appSep $ docLit $ Text.pack "where"+ , docSetIndentLevel $ docForceSingleline $ return w+ ]+ _ -> []+ ]+ ++ -- one-line solution + where in next line(s)+ [ docLines+ $ [ docCols+ (ColBindingLine alignmentToken)+ [ docSeq (patPartInline ++ [guardPart])+ , docSeq+ [appSep $ return binderDoc, docForceParSpacing $ return body]+ ]+ ]+ ++ wherePartMultiLine+ | [(guards, body, _bodyRaw)] <- [clauseDocs]+ , let guardPart = singleLineGuardsDoc guards+ , Data.Maybe.isJust mWhereDocs+ ]+ ++ -- two-line solution + where in next line(s)+ [ docLines+ $ [ docForceSingleline+ $ docSeq (patPartInline ++ [guardPart, return binderDoc])+ , docEnsureIndent BrIndentRegular $ docForceSingleline $ return+ body+ ]+ ++ wherePartMultiLine+ | [(guards, body, _bodyRaw)] <- [clauseDocs]+ , let guardPart = singleLineGuardsDoc guards+ ]++#test comment-testcase-17+{-# LANGUAGE MultiWayIf #-}+func = do+ let foo = if+ | Constuctoooooooooooooooooooooooooooooooooooor `elem` artics -- TODO+ -> max+ (defLen - 0.2) -- TODO+ (defLen * 0.8)+ | otherwise -> max (defLen - 0.05) (defLen * 0.95) -- TODO+ return True++#test issue 49++foo n = case n of+ 1 -> True+ -1 -> False++bar n = case n of+ (-2, -2) -> (-2, -2)++#test issue 48 a++foo =+ let a = b@1+ cccc = ()+ in foo++#test issue 48 b++{-# LANGUAGE TypeApplications #-}+foo =+ let a = b @1+ cccc = ()+ in foo+++###############################################################################+###############################################################################+###############################################################################+#group pending+###############################################################################+###############################################################################+###############################################################################++++## this testcase is not about idempotency, but about _how_ the output differs+## from the input; i cannot really express this yet with the current+## test-suite.+## #test ayaz+## +## myManageHook =+## composeOne [isFullscreen -?> doFullFloat, isDialog -?> doFloat, transience]+## <+> composeAll+## [ className =? "Pidgin" --> doFloat+## , className =? "XCalc" --> doFloat+## -- plan9port's acme+## , className =? "acme" --> doFloat+## -- Acme with Vi bindings editor+## , title =? "ED" --> doFloat+## , title =? "wlc-x11" --> doFloat+## , className =? "Skype" --> doFloat+## , className =? "ffplay" --> doFloat+## , className =? "mpv" --> doFloat+## , className =? "Plugin-container" --> doFloat -- Firefox flash, etc.+## -- Firefox works well tiled, but it has dialog windows we want to float.+## , appName =? "Browser" --> doFloat+## ]+## where+## role = stringProperty "WM_WINDOW_ROLE"+
src/Language/Haskell/Brittany/Internal.hs view
@@ -73,7 +73,7 @@ then "-- BRITTANY_INCLUDE_HACK " ++ s else s let hackTransform = if hackAroundIncludes- then List.unlines . fmap hackF . List.lines+ then List.intercalate "\n" . fmap hackF . lines' else id let cppCheckFunc dynFlags = if GHC.xopt GHC.Cpp dynFlags then case cppMode of@@ -101,7 +101,12 @@ let hackF s = fromMaybe s $ TextL.stripPrefix (TextL.pack "-- BRITTANY_INCLUDE_HACK ") s pure $ if hackAroundIncludes- then (ews, TextL.unlines $ fmap hackF $ TextL.lines outRaw)+ then+ ( ews+ , TextL.intercalate (TextL.pack "\n") $ fmap hackF $ TextL.splitOn+ (TextL.pack "\n")+ outRaw+ ) else (ews, outRaw) let customErrOrder ErrorInput{} = 4 customErrOrder LayoutWarning{} = 0 :: Int@@ -115,6 +120,7 @@ if hasErrors then left $ errsWarns else pure $ TextL.toStrict outputTextL + -- BrittanyErrors can be non-fatal warnings, thus both are returned instead -- of an Either. -- This should be cleaned up once it is clear what kinds of errors really@@ -134,6 +140,7 @@ $ MultiRWSS.withMultiWriterW $ MultiRWSS.withMultiReader anns $ MultiRWSS.withMultiReader conf+ $ MultiRWSS.withMultiReader (extractToplevelAnns parsedModule anns) $ do traceIfDumpConf "bridoc annotations raw" _dconf_dump_annotations $ annsDoc anns@@ -260,7 +267,19 @@ anns' = Map.insert (ExactPrint.Types.mkAnnKey lmod) mAnn' anns in (anns', post) MultiRWSS.withMultiReader anns' $ processDefault emptyModule- decls `forM_` ppDecl+ decls `forM_` \decl -> do+ filteredAnns <- mAsk <&> \annMap ->+ Map.findWithDefault Map.empty (ExactPrint.Types.mkAnnKey decl) annMap++ traceIfDumpConf "bridoc annotations filtered/transformed"+ _dconf_dump_annotations+ $ annsDoc filteredAnns++ config <- mAsk++ MultiRWSS.withoutMultiReader $ do+ MultiRWSS.mPutRawR $ config :+: filteredAnns :+: HNil+ ppDecl decl let finalComments = filter ( fst .> \case ExactPrint.Types.AnnComment{} -> True@@ -285,7 +304,7 @@ ppmMoveToExactLoc $ ExactPrint.Types.DP (eofX - cmX, eofY - cmY) _ -> return () -withTransformedAnns :: Data ast => ast -> PPM () -> PPM ()+withTransformedAnns :: Data ast => ast -> PPMLocal () -> PPMLocal () withTransformedAnns ast m = do -- TODO: implement `local` for MultiReader/MultiRWS readers@(conf :+: anns :+: HNil) <- MultiRWSS.mGetRawR@@ -299,13 +318,13 @@ in annsBalanced -ppDecl :: LHsDecl RdrName -> PPM ()+ppDecl :: LHsDecl RdrName -> PPMLocal () ppDecl d@(L loc decl) = case decl of SigD sig -> -- trace (_sigHead sig) $ withTransformedAnns d $ do -- runLayouter $ Old.layoutSig (L loc sig) briDoc <- briDocMToPPM $ layoutSig (L loc sig)- layoutBriDoc d briDoc+ layoutBriDoc briDoc ValD bind -> -- trace (_bindHead bind) $ withTransformedAnns d $ do -- Old.layoutBind (L loc bind)@@ -314,8 +333,8 @@ case eitherNode of Left ns -> docLines $ return <$> ns Right n -> return n- layoutBriDoc d briDoc- _ -> briDocMToPPM (briDocByExactNoComment d) >>= layoutBriDoc d+ layoutBriDoc briDoc+ _ -> briDocMToPPM (briDocByExactNoComment d) >>= layoutBriDoc _sigHead :: Sig RdrName -> String _sigHead = \case@@ -331,8 +350,8 @@ -layoutBriDoc :: Data.Data.Data ast => ast -> BriDocNumbered -> PPM ()-layoutBriDoc ast briDoc = do+layoutBriDoc :: BriDocNumbered -> PPMLocal ()+layoutBriDoc briDoc = do -- first step: transform the briDoc. briDoc' <- MultiRWSS.withMultiStateS BDEmpty $ do -- Note that briDoc is BriDocNumbered, but state type is BriDoc.@@ -368,12 +387,7 @@ -- return simpl anns :: ExactPrint.Types.Anns <- mAsk- let filteredAnns = filterAnns ast anns - traceIfDumpConf "bridoc annotations filtered/transformed"- _dconf_dump_annotations- $ annsDoc filteredAnns- let state = LayoutState { _lstate_baseYs = [0] , _lstate_curYOrAddNewline = Right 0 -- important that we use left here@@ -382,10 +396,9 @@ -- thing properly. , _lstate_indLevels = [0] , _lstate_indLevelLinger = 0- , _lstate_comments = filteredAnns+ , _lstate_comments = anns , _lstate_commentCol = Nothing , _lstate_addSepSpace = Nothing- , _lstate_inhibitMTEL = False } state' <- MultiRWSS.withMultiStateS state $ layoutBriDocM briDoc'
src/Language/Haskell/Brittany/Internal/Backend.hs view
@@ -152,8 +152,7 @@ BDAnnotationPrior annKey bd -> do state <- mGet let m = _lstate_comments state- let allowMTEL = not (_lstate_inhibitMTEL state)- && Data.Either.isRight (_lstate_curYOrAddNewline state)+ let allowMTEL = Data.Either.isRight (_lstate_curYOrAddNewline state) mAnn <- do let mAnn = ExactPrint.annPriorComments <$> Map.lookup annKey m mSet $ state@@ -184,7 +183,7 @@ layoutBriDocM bd BDAnnotationKW annKey keyword bd -> do layoutBriDocM bd- mAnn <- do+ mComments <- do state <- mGet let m = _lstate_comments state let mAnn = ExactPrint.annsDP <$> Map.lookup annKey m@@ -204,11 +203,12 @@ annKey m }- return $ [ comments | not $ null comments ]+ return $ nonEmpty comments _ -> return Nothing- forM_ mAnn- $ mapM_- $ \(ExactPrint.Types.Comment comment _ _, ExactPrint.Types.DP (y, x)) ->+ case mComments of+ Nothing -> pure ()+ Just comments -> do+ comments `forM_` \(ExactPrint.Types.Comment comment _ _, ExactPrint.Types.DP (y, x)) -> do -- evil hack for CPP: case comment of@@ -221,10 +221,10 @@ -- mModify $ \s -> s { _lstate_curYOrAddNewline = Right 0 } BDAnnotationRest annKey bd -> do layoutBriDocM bd- mAnn <- do+ mComments <- do state <- mGet let m = _lstate_comments state- let mAnn = extractAllComments <$> Map.lookup annKey m+ let mComments = nonEmpty =<< extractAllComments <$> Map.lookup annKey m mSet $ state { _lstate_comments = Map.adjust ( \ann -> ann { ExactPrint.annFollowingComments = []@@ -235,10 +235,11 @@ annKey m }- return mAnn- forM_ mAnn- $ mapM_- $ \(ExactPrint.Types.Comment comment _ _, ExactPrint.Types.DP (y, x)) ->+ return mComments+ case mComments of+ Nothing -> pure ()+ Just comments -> do+ comments `forM_` \(ExactPrint.Types.Comment comment _ _, ExactPrint.Types.DP (y, x)) -> do -- evil hack for CPP: case comment of@@ -252,22 +253,6 @@ BDNonBottomSpacing bd -> layoutBriDocM bd BDSetParSpacing bd -> layoutBriDocM bd BDForceParSpacing bd -> layoutBriDocM bd- BDProhibitMTEL bd -> do- -- set flag to True for this child, but disable afterwards.- -- two hard aspects- -- 1) nesting should be allowed. this means that resetting at the end must- -- not indiscriminantely set to False, but take into account the- -- previous value- -- 2) nonetheless, newlines cancel inhibition. this means that if we ever- -- find the flag set to False afterwards, we must not return it to- -- the previous value, which might be True in the case of testing; it- -- must remain False.- state <- mGet- mSet $ state { _lstate_inhibitMTEL = True }- layoutBriDocM bd- state' <- mGet- when (_lstate_inhibitMTEL state') $ do- mSet $ state' { _lstate_inhibitMTEL = _lstate_inhibitMTEL state } BDDebug s bd -> do mTell $ Text.Builder.fromText $ Text.pack $ "{-" ++ s ++ "-}" layoutBriDocM bd@@ -302,7 +287,6 @@ return $ maximum $ ls <&> \l -> StateS.evalState (rec l) x BDLines [] -> error "briDocLineLength BDLines []" BDEnsureIndent _ bd -> rec bd- BDProhibitMTEL bd -> rec bd BDSetParSpacing bd -> rec bd BDForceParSpacing bd -> rec bd BDNonBottomSpacing bd -> rec bd@@ -328,6 +312,7 @@ BDForceMultiline _ -> True BDForceSingleline bd -> rec bd BDForwardLineMode bd -> rec bd+ BDExternal _ _ _ t | [_] <- Text.lines t -> False BDExternal _ _ _ _ -> True BDAnnotationPrior _ bd -> rec bd BDAnnotationKW _ _ bd -> rec bd@@ -336,7 +321,6 @@ BDLines [_ ] -> False BDLines [] -> error "briDocIsMultiLine BDLines []" BDEnsureIndent _ bd -> rec bd- BDProhibitMTEL bd -> rec bd BDSetParSpacing bd -> rec bd BDForceParSpacing bd -> rec bd BDNonBottomSpacing bd -> rec bd@@ -344,6 +328,7 @@ alignColsLines :: LayoutConstraints m => [BriDoc] -> m () alignColsLines bridocs = do -- colInfos `forM_` \colInfo -> do+ -- tellDebugMess ("alignColsLines: at " ++ take 100 (show $ briDocToDoc $ head bridocs)) curX <- do state <- mGet return $ either id (const 0) (_lstate_curYOrAddNewline state) + fromMaybe@@ -385,7 +370,9 @@ Nothing -> 0 Just (_, maxs, _) -> sum maxs maxCols = {-Foldable.foldl1 maxZipper-}- fmap colAggregation $ transpose $ Foldable.toList colss+ fmap colAggregation $ transpose $ Foldable.toList+ -- $ trace ("colss=" ++ show colss ++ " for" ++ take 100 (show $ briDocToDoc $ head bridocs))+ colss (_, posXs) = mapAccumL (\acc x -> (acc + x, acc)) curX maxCols counter count l = if List.last posXs + List.last l <= colMax then count + 1@@ -404,10 +391,54 @@ mergeBriDocsW lastInfo (bd:bdr) = do info <- mergeInfoBriDoc True lastInfo bd infor <- mergeBriDocsW- (if alignBreak && briDocIsMultiLine bd then ColInfoStart else info)+ -- (if alignBreak && briDocIsMultiLine bd then ColInfoStart else info)+ (if shouldBreakAfter bd then ColInfoStart else info) bdr return $ info : infor + -- even with alignBreak config flag, we don't stop aligning for certain+ -- ColSigs - the ones with "False" below. The main reason is that+ -- there are uses of BDCols where they provide the alignment of several+ -- consecutive full larger code segments, for example ColOpPrefix.+ -- Motivating example is+ -- > foo+ -- > $ [ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa+ -- > , bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb+ -- > ]+ -- > ++ [ ccccccccccccccccccccccccccccccccccccccccccccccccccccccccc ]+ -- If we break the alignment here, then all three lines for the first+ -- list move left by one, which is horrible. We really don't want to+ -- break whole-block alignments.+ -- For list, listcomp, tuple and tuples the reasoning is much simpler:+ -- alignment should not have much effect anyways, so i simply make the+ -- choice here that enabling alignment is the safer route for preventing+ -- potential glitches, and it should never have a negative effect.+ -- For RecUpdate the argument is much less clear - it is mostly a+ -- personal preference to not break alignment for those, even if+ -- multiline. Really, this should be configurable.. (TODO)+ shouldBreakAfter :: BriDoc -> Bool+ shouldBreakAfter bd = if alignBreak+ then briDocIsMultiLine bd && case bd of+ (BDCols ColTyOpPrefix _) -> False+ (BDCols ColPatternsFuncPrefix _) -> True+ (BDCols ColPatternsFuncInfix _) -> True+ (BDCols ColPatterns _) -> True+ (BDCols ColCasePattern _) -> True+ (BDCols ColBindingLine{} _) -> True+ (BDCols ColGuard _) -> True+ (BDCols ColGuardedBody _) -> True+ (BDCols ColBindStmt _) -> True+ (BDCols ColDoLet _) -> True+ (BDCols ColRecUpdate _) -> False+ (BDCols ColListComp _) -> False+ (BDCols ColList _) -> False+ (BDCols ColApp _) -> True+ (BDCols ColTuple _) -> False+ (BDCols ColTuples _) -> False+ (BDCols ColOpPrefix _) -> False+ _ -> True+ else False+ mergeInfoBriDoc :: Bool -> ColInfo@@ -483,9 +514,15 @@ alignMode <- mAsk <&> _conf_layout .> _lconfig_columnAlignMode .> confUnpack curX <- do state <- mGet- return $ either id (const 0) (_lstate_curYOrAddNewline state) + fromMaybe- 0- (_lstate_addSepSpace state)+ -- tellDebugMess ("processInfo: " ++ show (_lstate_curYOrAddNewline state) ++ " - " ++ show ((_lstate_addSepSpace state)))+ let spaceAdd = case _lstate_addSepSpace state of+ Nothing -> 0+ Just i -> i+ return $ case _lstate_curYOrAddNewline state of+ Left i -> case _lstate_commentCol state of+ Nothing -> spaceAdd + i+ Just c -> c+ Right{} -> spaceAdd -- tellDebugMess $ show curX let Just (ratio, maxCols, _colss) = IntMapS.lookup ind m let (maxX, posXs) = mapAccumL (\acc x -> (acc + x, acc)) curX maxCols@@ -508,6 +545,8 @@ offsets = (subtract curX) <$> posXs fixed = offsets <&> fromIntegral .> (*factor) .> truncate _ -> posXs+ -- tellDebugMess $ "maxCols = " ++ show maxCols+ -- tellDebugMess $ "fixedPosXs = " ++ show fixedPosXs let alignAct = zip fixedPosXs list `forM_` \(destX, x) -> do layoutWriteEnsureAbsoluteN destX processInfo m (snd x)
src/Language/Haskell/Brittany/Internal/BackendUtils.hs view
@@ -146,7 +146,6 @@ state <- mGet mSet $ state { _lstate_curYOrAddNewline = Right 1 , _lstate_addSepSpace = Just $ lstate_baseY state- , _lstate_inhibitMTEL = False } -- layoutMoveToIndentCol :: ( MonadMultiState LayoutState m@@ -185,28 +184,23 @@ layoutMoveToCommentPos y x = do traceLocal ("layoutMoveToCommentPos", y, x) state <- mGet- if Data.Maybe.isJust (_lstate_commentCol state)- then do- mSet state- { _lstate_curYOrAddNewline = case _lstate_curYOrAddNewline state of- Left i -> if y == 0 then Left i else Right y- Right{} -> Right y- , _lstate_addSepSpace = Just $ case _lstate_curYOrAddNewline state of- Left{} -> if y == 0 then x else _lstate_indLevelLinger state + x- Right{} -> _lstate_indLevelLinger state + x- }- else do- mSet state- { _lstate_curYOrAddNewline = case _lstate_curYOrAddNewline state of- Left i -> if y == 0 then Left i else Right y- Right{} -> Right y- , _lstate_addSepSpace = Just- $ if y == 0 then x else _lstate_indLevelLinger state + x- , _lstate_commentCol = Just $ case _lstate_curYOrAddNewline state of- Left i -> i + fromMaybe 0 (_lstate_addSepSpace state)- Right{} -> lstate_baseY state- }+ mSet state+ { _lstate_curYOrAddNewline = case _lstate_curYOrAddNewline state of+ Left i -> if y == 0 then Left i else Right y+ Right{} -> Right y+ , _lstate_addSepSpace = if Data.Maybe.isJust (_lstate_commentCol state)+ then Just $ case _lstate_curYOrAddNewline state of+ Left{} -> if y == 0 then x else _lstate_indLevelLinger state + x+ Right{} -> _lstate_indLevelLinger state + x+ else Just $ if y == 0 then x else _lstate_indLevelLinger state + x+ , _lstate_commentCol = Just $ case _lstate_commentCol state of+ Just existing -> existing+ Nothing -> case _lstate_curYOrAddNewline state of+ Left i -> i + fromMaybe 0 (_lstate_addSepSpace state)+ Right{} -> lstate_baseY state+ } + -- | does _not_ add spaces to again reach the current base column. layoutWriteNewline :: ( MonadMultiWriter Text.Builder.Builder m@@ -222,7 +216,6 @@ Left{} -> Right 1 Right i -> Right (i + 1) , _lstate_addSepSpace = Nothing- , _lstate_inhibitMTEL = False } layoutWriteEnsureNewlineBlock@@ -239,7 +232,6 @@ Left{} -> Right 1 Right i -> Right $ max 1 i , _lstate_addSepSpace = Just $ lstate_baseY state- , _lstate_inhibitMTEL = False , _lstate_commentCol = Nothing } @@ -498,6 +490,7 @@ replicateM_ x $ mTell $ Text.Builder.fromString "\n" replicateM_ y $ mTell $ Text.Builder.fromString " " +-- TODO: update and use, or clean up. Currently dead code. layoutWritePriorComments :: ( Data.Data.Data ast , MonadMultiWriter Text.Builder.Builder m@@ -531,6 +524,7 @@ layoutWriteAppendSpaces y layoutWriteAppendMultiline $ Text.pack $ comment +-- TODO: update and use, or clean up. Currently dead code. -- this currently only extracs from the `annsDP` field of Annotations. -- per documentation, this seems sufficient, as the -- "..`annFollowingComments` are only added by AST transformations ..".
src/Language/Haskell/Brittany/Internal/Config.hs view
@@ -27,6 +27,7 @@ import qualified System.Console.CmdArgs.Explicit as CmdArgs import Language.Haskell.Brittany.Internal.Config.Types+import Language.Haskell.Brittany.Internal.Config.Types.Instances import Language.Haskell.Brittany.Internal.Utils import Data.Coerce ( Coercible, coerce )
src/Language/Haskell/Brittany/Internal/Config/Types.hs view
@@ -185,92 +185,6 @@ mempty = gmempty mappend = gmappend -aesonDecodeOptionsBrittany :: Aeson.Options-aesonDecodeOptionsBrittany = Aeson.defaultOptions- { Aeson.omitNothingFields = True- , Aeson.fieldLabelModifier = dropWhile (=='_')- }--#define makeFromJSON(type)\- instance FromJSON (type) where\- parseJSON = Aeson.genericParseJSON aesonDecodeOptionsBrittany-#define makeToJSON(type)\- instance ToJSON (type) where\- toJSON = Aeson.genericToJSON aesonDecodeOptionsBrittany;\- toEncoding = Aeson.genericToEncoding aesonDecodeOptionsBrittany--#define makeFromJSONMaybe(type)\- instance FromJSON (type Maybe) where\- parseJSON = Aeson.genericParseJSON aesonDecodeOptionsBrittany-#define makeFromJSONOption(type)\- instance FromJSON (type Option) where\- parseJSON = fmap (cMap Option) . parseJSON-#define makeToJSONMaybe(type)\- instance ToJSON (type Maybe) where\- toJSON = Aeson.genericToJSON aesonDecodeOptionsBrittany;\- toEncoding = Aeson.genericToEncoding aesonDecodeOptionsBrittany-#define makeToJSONOption(type)\- instance ToJSON (type Option) where\- toJSON = toJSON . cMap getOption;\- toEncoding = toEncoding . cMap getOption---makeFromJSONOption(CDebugConfig)-makeFromJSONMaybe(CDebugConfig)-makeToJSONOption(CDebugConfig)-makeToJSONMaybe(CDebugConfig)--makeFromJSON(IndentPolicy)-makeToJSON(IndentPolicy)-makeFromJSON(AltChooser)-makeToJSON(AltChooser)-makeFromJSON(ColumnAlignMode)-makeToJSON(ColumnAlignMode)-makeFromJSON(CPPMode)-makeToJSON(CPPMode)-makeFromJSON(ExactPrintFallbackMode)-makeToJSON(ExactPrintFallbackMode)--makeFromJSONOption(CLayoutConfig)-makeFromJSONMaybe(CLayoutConfig)-makeToJSONOption(CLayoutConfig)-makeToJSONMaybe(CLayoutConfig)--makeFromJSONOption(CErrorHandlingConfig)-makeFromJSONMaybe(CErrorHandlingConfig)-makeToJSONOption(CErrorHandlingConfig)-makeToJSONMaybe(CErrorHandlingConfig)--makeFromJSONOption(CForwardOptions)-makeFromJSONMaybe(CForwardOptions)-makeToJSONOption(CForwardOptions)-makeToJSONMaybe(CForwardOptions)--makeFromJSONOption(CPreProcessorConfig)-makeFromJSONMaybe(CPreProcessorConfig)-makeToJSONOption(CPreProcessorConfig)-makeToJSONMaybe(CPreProcessorConfig)--makeFromJSONOption(CConfig)-makeToJSONOption(CConfig)-makeToJSONMaybe(CConfig)---- This custom instance ensures the "omitNothingFields" behaviour not only for--- leafs, but for nodes of the config as well. This way e.g. "{}" is valid--- config file content.-instance FromJSON (CConfig Maybe) where- parseJSON (Object v) = Config- <$> v .:? Text.pack "conf_version"- <*> v .:?= Text.pack "conf_debug"- <*> v .:?= Text.pack "conf_layout"- <*> v .:?= Text.pack "conf_errorHandling"- <*> v .:?= Text.pack "conf_forward"- <*> v .:?= Text.pack "conf_preprocessor"- parseJSON invalid = Aeson.typeMismatch "Config" invalid---- Pretends that the value is {} when the key is not present.-(.:?=) :: FromJSON a => Object -> Text -> Parser a-o .:?= k = o .:? k >>= maybe (parseJSON (Aeson.object [])) pure data IndentPolicy = IndentPolicyLeft -- never create a new indentation at more -- than old indentation + amount
+ src/Language/Haskell/Brittany/Internal/Config/Types/Instances.hs view
@@ -0,0 +1,127 @@+{-# OPTIONS_GHC -fno-warn-orphans #-}+-- These optimizations are disabled to improve compile times (and compilation+-- memory usage). When we do not disable them, the CI servers take more than+-- 10 minutes to compile this module alone.+-- Having looked into aeson and how the instances are written, I still do+-- not understand what makes GHC choke so much here. The size of the raw+-- expressions below looks fairly negligible, so there must be some expansion+-- due to inlining going on. But even disabling INLINE pragmas in aeson did+-- not seem to change anything.+-- Nonetheless, this solution works and has no downsides because the+-- instances defined here are not in any way performance-critical.+{-# OPTIONS_GHC -fno-pre-inlining #-}+{-# OPTIONS_GHC -fno-specialise #-}+{-# OPTIONS_GHC -fignore-interface-pragmas #-}++module Language.Haskell.Brittany.Internal.Config.Types.Instances+where++++#include "prelude.inc"++import Data.Yaml+import qualified Data.Aeson.Types as Aeson++import Language.Haskell.Brittany.Internal.Config.Types++import GHC.Generics++++aesonDecodeOptionsBrittany :: Aeson.Options+aesonDecodeOptionsBrittany = Aeson.defaultOptions+ { Aeson.omitNothingFields = True+ , Aeson.fieldLabelModifier = dropWhile (=='_')+ }++#define makeFromJSON(type)\+ instance FromJSON (type) where\+ parseJSON = Aeson.genericParseJSON aesonDecodeOptionsBrittany;\+ {-# NOINLINE parseJSON #-}+#define makeToJSON(type)\+ instance ToJSON (type) where\+ toJSON = Aeson.genericToJSON aesonDecodeOptionsBrittany;\+ {-# NOINLINE toJSON #-};\+ toEncoding = Aeson.genericToEncoding aesonDecodeOptionsBrittany;\+ {-# NOINLINE toEncoding #-}++#define makeFromJSONMaybe(type)\+ instance FromJSON (type Maybe) where\+ parseJSON = Aeson.genericParseJSON aesonDecodeOptionsBrittany;\+ {-# NOINLINE parseJSON #-}+#define makeFromJSONOption(type)\+ instance FromJSON (type Option) where\+ parseJSON = fmap (cMap Option) . parseJSON;\+ {-# NOINLINE parseJSON #-}+#define makeToJSONMaybe(type)\+ instance ToJSON (type Maybe) where\+ toJSON = Aeson.genericToJSON aesonDecodeOptionsBrittany;\+ {-# NOINLINE toJSON #-};\+ toEncoding = Aeson.genericToEncoding aesonDecodeOptionsBrittany;\+ {-# NOINLINE toEncoding #-}+#define makeToJSONOption(type)\+ instance ToJSON (type Option) where\+ toJSON = toJSON . cMap getOption;\+ {-# NOINLINE toJSON #-};\+ toEncoding = toEncoding . cMap getOption;\+ {-# NOINLINE toEncoding #-}+++makeFromJSONOption(CDebugConfig)+makeFromJSONMaybe(CDebugConfig)+makeToJSONOption(CDebugConfig)+makeToJSONMaybe(CDebugConfig)++makeFromJSON(IndentPolicy)+makeToJSON(IndentPolicy)+makeFromJSON(AltChooser)+makeToJSON(AltChooser)+makeFromJSON(ColumnAlignMode)+makeToJSON(ColumnAlignMode)+makeFromJSON(CPPMode)+makeToJSON(CPPMode)+makeFromJSON(ExactPrintFallbackMode)+makeToJSON(ExactPrintFallbackMode)++makeFromJSONOption(CLayoutConfig)+makeFromJSONMaybe(CLayoutConfig)+makeToJSONOption(CLayoutConfig)+makeToJSONMaybe(CLayoutConfig)++makeFromJSONOption(CErrorHandlingConfig)+makeFromJSONMaybe(CErrorHandlingConfig)+makeToJSONOption(CErrorHandlingConfig)+makeToJSONMaybe(CErrorHandlingConfig)++makeFromJSONOption(CForwardOptions)+makeFromJSONMaybe(CForwardOptions)+makeToJSONOption(CForwardOptions)+makeToJSONMaybe(CForwardOptions)++makeFromJSONOption(CPreProcessorConfig)+makeFromJSONMaybe(CPreProcessorConfig)+makeToJSONOption(CPreProcessorConfig)+makeToJSONMaybe(CPreProcessorConfig)++makeFromJSONOption(CConfig)+makeToJSONOption(CConfig)+makeToJSONMaybe(CConfig)++-- This custom instance ensures the "omitNothingFields" behaviour not only for+-- leafs, but for nodes of the config as well. This way e.g. "{}" is valid+-- config file content.+instance FromJSON (CConfig Maybe) where+ parseJSON (Object v) = Config+ <$> v .:? Text.pack "conf_version"+ <*> v .:?= Text.pack "conf_debug"+ <*> v .:?= Text.pack "conf_layout"+ <*> v .:?= Text.pack "conf_errorHandling"+ <*> v .:?= Text.pack "conf_forward"+ <*> v .:?= Text.pack "conf_preprocessor"+ parseJSON invalid = Aeson.typeMismatch "Config" invalid++-- Pretends that the value is {} when the key is not present.+(.:?=) :: FromJSON a => Object -> Text -> Parser a+o .:?= k = o .:? k >>= maybe (parseJSON (Aeson.object [])) pure+
src/Language/Haskell/Brittany/Internal/ExactPrintUtils.hs view
@@ -5,6 +5,8 @@ , parseModuleFromString , commentAnnFixTransform , commentAnnFixTransformGlob+ , extractToplevelAnns+ , foldedAnnKeys ) where @@ -14,7 +16,6 @@ import Language.Haskell.Brittany.Internal.Types import Language.Haskell.Brittany.Internal.Config.Types-import Language.Haskell.Brittany.Internal.LayouterBasics import Language.Haskell.Brittany.Internal.Utils import DynFlags ( getDynFlags )@@ -36,6 +37,7 @@ import qualified Language.Haskell.GHC.ExactPrint.Delta as ExactPrint import qualified Data.Generics as SYB+-- import Data.Generics.Schemes @@ -109,11 +111,9 @@ commentAnnFixTransformGlob ast = do let extract :: forall a . SYB.Data a => a -> Seq (SrcSpan, ExactPrint.AnnKey) extract = -- traceFunctionWith "extract" (show . SYB.typeOf) show $- const Seq.empty `SYB.ext2Q` (\(L a b) -> f1 a b)- where- f1 b c = (const Seq.empty `SYB.extQ` f2 c) b- f2 c l = Seq.singleton (l, ExactPrint.mkAnnKey (L l c))- -- i wonder if there is a way to avoid re-constructing the L above..+ const Seq.empty+ `SYB.ext1Q`+ (\l@(L span _) -> Seq.singleton (span, ExactPrint.mkAnnKey l)) let nodes = SYB.everything (<>) extract ast let annsMap :: Map GHC.RealSrcLoc ExactPrint.AnnKey annsMap = Map.fromListWith@@ -209,3 +209,40 @@ ans' = Map.insert k1 an1' $ Map.insert k2 an2' ans ExactPrint.modifyAnnsT moveComments++-- | split a set of annotations in a module into a map from top-level module+-- elements to the relevant annotations. Avoids quadratic behaviour a trivial+-- implementation would have.+extractToplevelAnns+ :: Located (HsModule RdrName)+ -> ExactPrint.Anns+ -> Map ExactPrint.AnnKey ExactPrint.Anns+extractToplevelAnns lmod anns = output+ where+ (L _ (HsModule _ _ _ ldecls _ _)) = lmod+ declMap :: Map ExactPrint.AnnKey ExactPrint.AnnKey+ declMap = Map.unions $ ldecls <&> \ldecl ->+ Map.fromSet (const (ExactPrint.mkAnnKey ldecl)) (foldedAnnKeys ldecl)+ modKey = ExactPrint.mkAnnKey lmod+ output = groupMap (\k _ -> Map.findWithDefault modKey k declMap) anns++groupMap :: (Ord k, Ord l) => (k -> a -> l) -> Map k a -> Map l (Map k a)+groupMap f = Map.foldlWithKey' (\m k a -> Map.alter (insert k a) (f k a) m)+ Map.empty+ where+ insert k a Nothing = Just (Map.singleton k a)+ insert k a (Just m) = Just (Map.insert k a m)++foldedAnnKeys :: Data.Data.Data ast => ast -> Set ExactPrint.AnnKey+foldedAnnKeys ast = SYB.everything+ Set.union+ ( \x -> maybe+ Set.empty+ Set.singleton+ [ SYB.gmapQi 1 (\t -> ExactPrint.mkAnnKey $ L l t) x+ | locTyCon == SYB.typeRepTyCon (SYB.typeOf x)+ , l <- SYB.gmapQi 0 SYB.cast x+ ]+ )+ ast+ where locTyCon = SYB.typeRepTyCon (SYB.typeOf (L () ()))
src/Language/Haskell/Brittany/Internal/LayouterBasics.hs view
@@ -67,6 +67,7 @@ import Language.Haskell.Brittany.Internal.Config.Types import Language.Haskell.Brittany.Internal.Types import Language.Haskell.Brittany.Internal.Utils+import Language.Haskell.Brittany.Internal.ExactPrintUtils import RdrName ( RdrName(..) ) import GHC ( Located, runGhc, GenLocated(L), moduleNameString )@@ -81,8 +82,10 @@ import DataTreePrint +import Data.HList.HList + processDefault :: ( ExactPrint.Annotate.Annotate ast , MonadMultiWriter Text.Builder.Builder m@@ -222,20 +225,6 @@ _ -> [] ) -foldedAnnKeys :: Data.Data.Data ast => ast -> Set ExactPrint.AnnKey-foldedAnnKeys ast = everything- Set.union- ( \x -> maybe Set.empty- Set.singleton- [ gmapQi 1 (\t -> ExactPrint.mkAnnKey $ L l t) x- | locTyCon == typeRepTyCon (typeOf x)- , l <- gmapQi 0 cast x- ]- )- ast- where- locTyCon = typeRepTyCon (typeOf (L () ()))- filterAnns :: Data.Data.Data ast => ast -> ExactPrint.Anns -> ExactPrint.Anns filterAnns ast anns = Map.filterWithKey (\k _ -> k `Set.member` foldedAnnKeys ast) anns@@ -614,7 +603,7 @@ spacifyDocs [] = [] spacifyDocs ds = fmap appSep (List.init ds) ++ [List.last ds] -briDocMToPPM :: ToBriDocM a -> PPM a+briDocMToPPM :: ToBriDocM a -> PPMLocal a briDocMToPPM m = do readers <- MultiRWSS.mGetRawR let ((x, errs), debugs) =
src/Language/Haskell/Brittany/Internal/Layouters/Decl.hs view
@@ -43,7 +43,11 @@ layoutSig :: ToBriDoc Sig layoutSig lsig@(L _loc sig) = case sig of+#if MIN_VERSION_ghc(8,2,0) /* ghc-8.2 */+ TypeSig names (HsWC _ (HsIB _ typ _)) -> docWrapNode lsig $ do+#else /* ghc-8.0 */ TypeSig names (HsIB _ (HsWC _ _ typ)) -> docWrapNode lsig $ do+#endif nameStrs <- names `forM` lrdrNameToTextAnn let nameStr = Text.intercalate (Text.pack ", ") $ nameStrs typeDoc <- docSharedWrapper layoutType typ@@ -215,12 +219,18 @@ patPartParWrap = case mPatDoc of Nothing -> id Just patDoc -> docPar (return patDoc)- whereIndent <-- mAsk+ whereIndent <- do+ shouldSpecial <- mAsk <&> _conf_layout .> _lconfig_indentWhereSpecial .> confUnpack- .> Bool.bool BrIndentRegular (BrIndentSpecial 1)+ regularIndentAmount <- mAsk+ <&> _conf_layout+ .> _lconfig_indentAmount+ .> confUnpack+ pure $ if shouldSpecial+ then BrIndentSpecial (max 1 (regularIndentAmount `div` 2))+ else BrIndentRegular -- TODO: apart from this, there probably are more nodes below which could -- be shared between alternatives. wherePartMultiLine :: [ToBriDocM BriDocNumbered] <- case mWhereDocs of
src/Language/Haskell/Brittany/Internal/Layouters/Expr.hs view
@@ -94,7 +94,11 @@ ] HsLam{} -> unknownNodeError "HsLam too complex" lexpr+#if MIN_VERSION_ghc(8,2,0) /* ghc-8.2 */+ HsLamCase (MG lmatches@(L _ matches) _ _ _) -> do+#else /* ghc-8.0 */ HsLamCase _ (MG lmatches@(L _ matches) _ _ _) -> do+#endif binderDoc <- docLit $ Text.pack "->" funcPatDocs <- docWrapNode lmatches $ layoutPatternBind Nothing binderDoc `mapM` matches docSetParSpacing $ docAddBaseY BrIndentRegular $ docPar@@ -167,7 +171,11 @@ expDoc1 expDoc2 ]+#if MIN_VERSION_ghc(8,2,0) /* ghc-8.2 */+ HsAppType exp1 (HsWC _ ty1) -> do+#else /* ghc-8.0 */ HsAppType exp1 (HsWC _ _ ty1) -> do+#endif t <- docSharedWrapper layoutType ty1 e <- docSharedWrapper layoutExpr exp1 docAlt@@ -791,7 +799,11 @@ ] in [line1] ++ lineR ++ [lineN]) ]+#if MIN_VERSION_ghc(8,2,0) /* ghc-8.2 */+ ExprWithTySig exp1 (HsWC _ (HsIB _ typ1 _)) -> do+#else /* ghc-8.0 */ ExprWithTySig exp1 (HsIB _ (HsWC _ _ typ1)) -> do+#endif expDoc <- docSharedWrapper layoutExpr exp1 typDoc <- docSharedWrapper layoutType typ1 docSeq@@ -890,9 +902,11 @@ briDocByExactInlineOnly "HsTickPragma{}" lexpr EWildPat{} -> do docLit $ Text.pack "_"- EAsPat{} -> do- -- TODO- briDocByExactInlineOnly "EAsPat{}" lexpr+ EAsPat asName asExpr -> do+ docSeq+ [ docLit $ (lrdrNameToText asName) <> Text.pack "@"+ , layoutExpr asExpr+ ] EViewPat{} -> do -- TODO briDocByExactInlineOnly "EViewPat{}" lexpr@@ -902,9 +916,43 @@ HsWrap{} -> do -- TODO briDocByExactInlineOnly "HsWrap{}" lexpr+#if MIN_VERSION_ghc(8,2,0) /* ghc-8.2 */+ HsConLikeOut{} -> do+ -- TODO+ briDocByExactInlineOnly "HsWrap{}" lexpr+ ExplicitSum{} -> do+ -- TODO+ briDocByExactInlineOnly "ExplicitSum{}" lexpr+#endif ++#if MIN_VERSION_ghc(8,2,0) /* ghc-8.2 */ litBriDoc :: HsLit -> BriDocFInt litBriDoc = \case+ HsChar (SourceText t) _c -> BDFLit $ Text.pack t -- BDFLit $ Text.pack $ ['\'', c, '\'']+ HsCharPrim (SourceText t) _c -> BDFLit $ Text.pack t -- BDFLit $ Text.pack $ ['\'', c, '\'']+ HsString (SourceText t) _fastString -> BDFLit $ Text.pack t -- BDFLit $ Text.pack $ FastString.unpackFS fastString+ HsStringPrim (SourceText t) _byteString -> BDFLit $ Text.pack t -- BDFLit $ Text.pack $ Data.ByteString.Char8.unpack byteString+ HsInt (SourceText t) _i -> BDFLit $ Text.pack t -- BDFLit $ Text.pack $ show i+ HsIntPrim (SourceText t) _i -> BDFLit $ Text.pack t -- BDFLit $ Text.pack $ show i+ HsWordPrim (SourceText t) _i -> BDFLit $ Text.pack t -- BDFLit $ Text.pack $ show i+ HsInt64Prim (SourceText t) _i -> BDFLit $ Text.pack t -- BDFLit $ Text.pack $ show i+ HsWord64Prim (SourceText t) _i -> BDFLit $ Text.pack t -- BDFLit $ Text.pack $ show i+ HsInteger (SourceText t) _i _type -> BDFLit $ Text.pack t -- BDFLit $ Text.pack $ show i+ HsRat (FL t _) _type -> BDFLit $ Text.pack t+ HsFloatPrim (FL t _) -> BDFLit $ Text.pack t+ HsDoublePrim (FL t _) -> BDFLit $ Text.pack t+ _ -> error "litBriDoc: literal with no SourceText"++overLitValBriDoc :: OverLitVal -> BriDocFInt+overLitValBriDoc = \case+ HsIntegral (SourceText t) _ -> BDFLit $ Text.pack t+ HsFractional (FL t _) -> BDFLit $ Text.pack t+ HsIsString (SourceText t) _ -> BDFLit $ Text.pack t+ _ -> error "overLitValBriDoc: literal with no SourceText"+#else+litBriDoc :: HsLit -> BriDocFInt+litBriDoc = \case HsChar t _c -> BDFLit $ Text.pack t -- BDFLit $ Text.pack $ ['\'', c, '\''] HsCharPrim t _c -> BDFLit $ Text.pack t -- BDFLit $ Text.pack $ ['\'', c, '\''] HsString t _fastString -> BDFLit $ Text.pack t -- BDFLit $ Text.pack $ FastString.unpackFS fastString@@ -924,3 +972,4 @@ HsIntegral t _ -> BDFLit $ Text.pack t HsFractional (FL t _) -> BDFLit $ Text.pack t HsIsString t _ -> BDFLit $ Text.pack t+#endif
src/Language/Haskell/Brittany/Internal/Layouters/Pattern.hs view
@@ -102,7 +102,11 @@ Unboxed -> wrapPatListy args "(#" "#)" AsPat asName asPat -> do wrapPatPrepend asPat (docLit $ lrdrNameToText asName <> Text.pack "@")+#if MIN_VERSION_ghc(8,2,0) /* ghc-8.2 */+ SigPatIn pat1 (HsWC _ (HsIB _ ty1 _)) -> do+#else /* ghc-8.0 */ SigPatIn pat1 (HsIB _ (HsWC _ _ ty1)) -> do+#endif patDocs <- layoutPat pat1 tyDoc <- docSharedWrapper layoutType ty1 case Seq.viewr patDocs of@@ -127,8 +131,12 @@ wrapPatPrepend pat1 (docLit $ Text.pack "!") LazyPat pat1 -> do wrapPatPrepend pat1 (docLit $ Text.pack "~")- NPat llit@(L _ (OverLit olit _ _ _)) _ _ _ -> do- fmap Seq.singleton $ docWrapNode llit $ allocateNode $ overLitValBriDoc olit+ NPat llit@(L _ (OverLit olit _ _ _)) mNegative _ _ -> do+ litDoc <- docWrapNode llit $ allocateNode $ overLitValBriDoc olit+ negDoc <- docLit $ Text.pack "-"+ pure $ case mNegative of+ Just{} -> Seq.fromList [negDoc, litDoc]+ Nothing -> Seq.singleton litDoc -- if MIN_VERSION_ghc(8,0,0) -- VarPat n -> return $ stringLayouter lpat $ lrdrNameToText n
src/Language/Haskell/Brittany/Internal/Layouters/Type.hs view
@@ -19,6 +19,7 @@ import HsSyn import Name import Outputable ( ftext, showSDocUnsafe )+import BasicTypes import DataTreePrint @@ -27,7 +28,11 @@ layoutType :: ToBriDoc HsType layoutType ltype@(L _ typ) = docWrapNode ltype $ case typ of -- _ | traceShow (ExactPrint.Types.mkAnnKey ltype) False -> error "impossible"+#if MIN_VERSION_ghc(8,2,0) /* ghc-8.2 */+ HsTyVar _ name -> do+#else /* ghc-8.0 */ HsTyVar name -> do+#endif t <- lrdrNameToTextAnn name docWrapNode name $ docLit t HsForAllTy bndrs (L _ (HsQualTy (L _ cntxts@(_:_)) typ2)) -> do@@ -463,7 +468,11 @@ -- } -- , _layouter_ast = ltype -- }+#if MIN_VERSION_ghc(8,2,0) /* ghc-8.2 */+ HsIParamTy (L _ (HsIPName ipName)) typ1 -> do+#else /* ghc-8.0 */ HsIParamTy (HsIPName ipName) typ1 -> do+#endif typeDoc1 <- docSharedWrapper layoutType typ1 docAlt [ docSeq@@ -571,12 +580,16 @@ -- , _layouter_ast = ltype -- } HsSpliceTy{} -> -- TODO- briDocByExactInlineOnly "" ltype+ briDocByExactInlineOnly "HsSpliceTy{}" ltype HsDocTy{} -> -- TODO- briDocByExactInlineOnly "" ltype+ briDocByExactInlineOnly "HsDocTy{}" ltype HsRecTy{} -> -- TODO- briDocByExactInlineOnly "" ltype+ briDocByExactInlineOnly "HsRecTy{}" ltype+#if MIN_VERSION_ghc(8,2,0) /* ghc-8.2 */+ HsExplicitListTy _ _ typs -> do+#else /* ghc-8.0 */ HsExplicitListTy _ typs -> do+#endif typDocs <- docSharedWrapper layoutType `mapM` typs docAlt [ docSeq@@ -586,10 +599,24 @@ -- TODO ] HsExplicitTupleTy{} -> -- TODO- briDocByExactInlineOnly "" ltype- HsTyLit{} -> -- TODO- briDocByExactInlineOnly "" ltype+ briDocByExactInlineOnly "HsExplicitTupleTy{}" ltype+ HsTyLit lit -> case lit of+#if MIN_VERSION_ghc(8,2,0) /* ghc-8.2 */+ HsNumTy (SourceText srctext) _ -> docLit $ Text.pack srctext+ HsNumTy NoSourceText _ ->+ error "overLitValBriDoc: literal with no SourceText"+ HsStrTy (SourceText srctext) _ -> docLit $ Text.pack srctext+ HsStrTy NoSourceText _ ->+ error "overLitValBriDoc: literal with no SourceText"+#else /* ghc-8.0 */+ HsNumTy srctext _ -> docLit $ Text.pack srctext+ HsStrTy srctext _ -> docLit $ Text.pack srctext+#endif HsCoreTy{} -> -- TODO- briDocByExactInlineOnly "" ltype+ briDocByExactInlineOnly "HsCoreTy{}" ltype HsWildCardTy _ -> docLit $ Text.pack "_"+#if MIN_VERSION_ghc(8,2,0) /* ghc-8.2 */+ HsSumTy{} -> -- TODO+ briDocByExactInlineOnly "HsSumTy{}" ltype+#endif
src/Language/Haskell/Brittany/Internal/Prelude.hs view
@@ -1,68 +1,378 @@-module Language.Haskell.Brittany.Internal.Prelude+module Language.Haskell.Brittany.Internal.Prelude (module E) where -import Prelude-import qualified Data.Strict.Maybe as Strict-import Debug.Trace-import Control.Monad-import System.IO+import Data.Functor.Identity as E ( Identity(..) )+import Control.Concurrent.Chan as E ( Chan )+import Control.Concurrent.MVar as E ( MVar )+import Data.Int as E ( Int )+import Data.Word as E ( Word )+import Prelude as E ( Integer+ , Float+ , Double+ )+import Control.Monad.ST as E ( ST )+import Data.Bool as E ( Bool(..) )+import Data.Char as E ( Char )+import Data.Either as E ( Either(..) )+import Data.IORef as E ( IORef )+import Data.Maybe as E ( Maybe(..) )+import Data.Semigroup as E ( Option(..) )+import Data.Monoid as E ( Endo(..)+ , All(..)+ , Any(..)+ , Sum(..)+ , Product(..)+ , Alt(..)+ )+import Data.Ord as E ( Ordering(..)+ , Down(..)+ )+import Data.Ratio as E ( Ratio+ , Rational+ )+import Data.String as E ( String )+import Data.Void as E ( Void )+import System.IO as E ( IO )+import Data.Proxy as E ( Proxy(..) )+import Data.Sequence as E ( Seq ) -import Control.DeepSeq ( NFData, force )-import Control.Exception.Base ( evaluate )+import Data.Map as E ( Map )+import Data.Set as E ( Set ) -import Control.Applicative+import Data.Text as E ( Text ) +import Prelude as E ( Char+ , String+ , Int+ , Integer+ , Float+ , Double+ , Bool (..)+ , undefined+ , Eq (..)+ , Ord (..)+ , Enum (..)+ , Bounded (..)+ , Maybe (..)+ , Either (..)+ , IO+ , (<$>)+ , (.)+ , ($)+ , ($!)+ , Num (..)+ , Integral (..)+ , Fractional (..)+ , Floating (..)+ , RealFrac (..)+ , RealFloat (..)+ , fromIntegral+ , error+ , foldr+ , foldl+ , foldr1+ , id+ , map+ , subtract+ , putStrLn+ , putStr+ , Show (..)+ , print+ , fst+ , snd+ , (++)+ , not+ , (&&)+ , (||)+ , curry+ , uncurry+ , Ordering (..)+ , flip+ , const+ , seq+ , reverse+ , otherwise+ , traverse+ , realToFrac+ , or+ , and+ , head+ , any+ , (^)+ , Foldable+ , Traversable+ ) +import Data.Function as E ( fix+ ) -instance Applicative Strict.Maybe where- pure = Strict.Just- Strict.Just f <*> Strict.Just x = Strict.Just (f x)- _ <*> _ = Strict.Nothing+import Data.Foldable as E ( foldl'+ , foldr'+ , fold+ , asum+ ) -instance Monad Strict.Maybe where- return = Strict.Just- Strict.Nothing >>= _ = Strict.Nothing- Strict.Just x >>= f = f x+import Data.List as E ( partition+ , null+ , elem+ , notElem+ , minimum+ , maximum+ , length+ , all+ , take+ , drop+ , find+ , sum+ , zip+ , zip3+ , zipWith+ , repeat+ , replicate+ , iterate+ , nub+ , filter+ , intersperse+ , intercalate+ , isSuffixOf+ , isPrefixOf+ , dropWhile+ , takeWhile+ , unzip+ , break+ , transpose+ , sortBy+ , mapAccumL+ , mapAccumR+ , uncons+ ) -instance Alternative Strict.Maybe where- empty = Strict.Nothing- x <|> Strict.Nothing = x- _ <|> x = x+import Data.List.NonEmpty as E ( NonEmpty(..)+ , nonEmpty+ ) -traceFunctionWith- :: String -> (a -> String) -> (b -> String) -> (a -> b) -> (a -> b)-traceFunctionWith name s1 s2 f x =- trace traceStr y- where- y = f x- traceStr = name ++ "\nBEFORE:\n" ++ s1 x ++ "\nAFTER:\n" ++ s2 y+import Data.Tuple as E ( swap+ ) -(<&!>) :: Monad m => m a -> (a -> b) -> m b-(<&!>) = flip (<$!>)+import Data.Char as E ( ord+ , chr+ ) -putStrErrLn :: String -> IO ()-putStrErrLn s = hPutStrLn stderr s+import Data.Maybe as E ( fromMaybe+ , maybe+ , listToMaybe+ , maybeToList+ , catMaybes+ ) -printErr :: Show a => a -> IO ()-printErr = putStrErrLn . show+import Data.Word as E ( Word32+ ) -errorIf :: Bool -> a -> a-errorIf False = id-errorIf True = error "errorIf"+import Data.Ord as E ( comparing+ , Down (..)+ ) -errorIfNote :: Maybe String -> a -> a-errorIfNote Nothing = id-errorIfNote (Just x) = error x+import Data.Either as E ( either+ ) -(<&>) :: Functor f => f a -> (a -> b) -> f b-(<&>) = flip fmap-infixl 4 <&>+import Data.Ratio as E ( Ratio+ , (%)+ , numerator+ , denominator+ ) -(.>) :: (a -> b) -> (b -> c) -> (a -> c)-f .> g = g . f-infixl 9 .>+import Text.Read as E ( readMaybe+ ) -evaluateDeep :: NFData a => a -> IO a-evaluateDeep = evaluate . force+import Control.Monad as E ( Functor (..)+ , Monad (..)+ , MonadPlus (..)+ , mapM+ , mapM_+ , forM+ , forM_+ , sequence+ , sequence_+ , (=<<)+ , (>=>)+ , (<=<)+ , forever+ , void+ , join+ , replicateM+ , replicateM_+ , guard+ , when+ , unless+ , liftM+ , liftM2+ , liftM3+ , liftM4+ , liftM5+ , filterM+ , (<$!>)+ )++import Control.Applicative as E ( Applicative (..)+ , Alternative (..)+ )++import Foreign.Storable as E ( Storable )+import GHC.Exts as E ( Constraint )++import Control.Concurrent as E ( threadDelay+ , forkIO+ , forkOS+ )++import Control.Concurrent.MVar as E ( MVar+ , newEmptyMVar+ , newMVar+ , putMVar+ , readMVar+ , takeMVar+ , swapMVar+ )++import Control.Exception as E ( evaluate+ , bracket+ , assert+ )++import Debug.Trace as E ( trace+ , traceId+ , traceShowId+ , traceShow+ , traceStack+ , traceShowId+ , traceIO+ , traceM+ , traceShowM+ )++import Foreign.ForeignPtr as E ( ForeignPtr+ )++import Data.Monoid as E ( (<>)+ , mconcat+ , Monoid (..)+ )++import Data.Bifunctor as E ( bimap )+import Data.Functor as E ( (<$), ($>) )+import Data.Function as E ( (&) )+import System.IO as E ( hFlush+ , stdout+ )++import Data.Typeable as E ( Typeable+ )++import Control.Arrow as E ( first+ , second+ , (***)+ , (&&&)+ , (>>>)+ , (<<<)+ )++import Data.Functor.Identity as E ( Identity (..)+ )++import Data.Proxy as E ( Proxy (..)+ )++import Data.Version as E ( showVersion+ )++import Data.List.Extra as E ( nubOrd+ , stripSuffix+ )+import Control.Monad.Extra as E ( whenM+ , unlessM+ , ifM+ , notM+ , orM+ , andM+ , anyM+ , allM+ )++import Data.Tree as E ( Tree(..)+ )++import Control.Monad.Trans.MultiRWS as E ( -- MultiRWST (..)+ -- , MultiRWSTNull+ -- , MultiRWS+ -- , + MonadMultiReader(..)+ , MonadMultiWriter(..)+ , MonadMultiState(..)+ -- , runMultiRWST+ -- , runMultiRWSTASW+ -- , runMultiRWSTW+ -- , runMultiRWSTAW+ -- , runMultiRWSTSW+ -- , runMultiRWSTNil+ -- , runMultiRWSTNil_+ -- , withMultiReader+ -- , withMultiReader_+ -- , withMultiReaders+ -- , withMultiReaders_+ -- , withMultiWriter+ -- , withMultiWriterAW+ -- , withMultiWriterWA+ -- , withMultiWriterW+ -- , withMultiWriters+ -- , withMultiWritersAW+ -- , withMultiWritersWA+ -- , withMultiWritersW+ -- , withMultiState+ -- , withMultiStateAS+ -- , withMultiStateSA+ -- , withMultiStateA+ -- , withMultiStateS+ -- , withMultiState_+ -- , withMultiStates+ -- , withMultiStatesAS+ -- , withMultiStatesSA+ -- , withMultiStatesA+ -- , withMultiStatesS+ -- , withMultiStates_+ -- , inflateReader+ -- , inflateMultiReader+ -- , inflateWriter+ -- , inflateMultiWriter+ -- , inflateState+ -- , inflateMultiState+ -- , mapMultiRWST+ -- , mGetRawR+ -- , mGetRawW+ -- , mGetRawS+ -- , mPutRawR+ -- , mPutRawW+ -- , mPutRawS+ )++import Control.Monad.Trans.MultiReader ( runMultiReaderTNil+ , runMultiReaderTNil_+ , MultiReaderT (..)+ , MultiReader+ , MultiReaderTNull+ )++import Data.Text as E ( Text )++import Control.Monad.IO.Class as E ( MonadIO (..)+ )++import Control.Monad.Trans.Class as E ( lift+ )+import Control.Monad.Trans.Maybe as E ( MaybeT (..)+ )++import Data.Data as E ( toConstr+ )+
+ src/Language/Haskell/Brittany/Internal/PreludeUtils.hs view
@@ -0,0 +1,69 @@+{-# OPTIONS_GHC -fno-warn-orphans #-}+module Language.Haskell.Brittany.Internal.PreludeUtils+where++++import Prelude+import qualified Data.Strict.Maybe as Strict+import Debug.Trace+import Control.Monad+import System.IO++import Control.DeepSeq ( NFData, force )+import Control.Exception.Base ( evaluate )++import Control.Applicative++++instance Applicative Strict.Maybe where+ pure = Strict.Just+ Strict.Just f <*> Strict.Just x = Strict.Just (f x)+ _ <*> _ = Strict.Nothing++instance Monad Strict.Maybe where+ return = Strict.Just+ Strict.Nothing >>= _ = Strict.Nothing+ Strict.Just x >>= f = f x++instance Alternative Strict.Maybe where+ empty = Strict.Nothing+ x <|> Strict.Nothing = x+ _ <|> x = x++traceFunctionWith+ :: String -> (a -> String) -> (b -> String) -> (a -> b) -> (a -> b)+traceFunctionWith name s1 s2 f x =+ trace traceStr y+ where+ y = f x+ traceStr = name ++ "\nBEFORE:\n" ++ s1 x ++ "\nAFTER:\n" ++ s2 y++(<&!>) :: Monad m => m a -> (a -> b) -> m b+(<&!>) = flip (<$!>)++putStrErrLn :: String -> IO ()+putStrErrLn s = hPutStrLn stderr s++printErr :: Show a => a -> IO ()+printErr = putStrErrLn . show++errorIf :: Bool -> a -> a+errorIf False = id+errorIf True = error "errorIf"++errorIfNote :: Maybe String -> a -> a+errorIfNote Nothing = id+errorIfNote (Just x) = error x++(<&>) :: Functor f => f a -> (a -> b) -> f b+(<&>) = flip fmap+infixl 4 <&>++(.>) :: (a -> b) -> (b -> c) -> (a -> c)+f .> g = g . f+infixl 9 .>++evaluateDeep :: NFData a => a -> IO a+evaluateDeep = evaluate . force
src/Language/Haskell/Brittany/Internal/Transformations/Alt.hs view
@@ -79,8 +79,8 @@ $ rec $ briDoc where- -- this funtion is exponential by nature and cannot be improved in any- -- way i can think of, and if tried. (stupid StableNames.)+ -- this function is exponential by nature and cannot be improved in any+ -- way i can think of, and i've tried. (stupid StableNames.) -- transWrap :: BriDoc -> BriDocNumbered -- transWrap brDc = flip StateS.evalState (1::Int) -- $ Memo.startEvalMemoT@@ -334,8 +334,6 @@ BDFNonBottomSpacing bd -> rec bd BDFSetParSpacing bd -> rec bd BDFForceParSpacing bd -> rec bd- BDFProhibitMTEL bd ->- reWrap . BDFProhibitMTEL <$> rec bd BDFDebug s bd -> do acp :: AltCurPos <- mGet tellDebugMess $ "transformAlts: BDFDEBUG " ++ s ++ " (node-id=" ++ show brDcId ++ "): acp=" ++ show acp@@ -490,7 +488,6 @@ BDFForceParSpacing bd -> do mVs <- rec bd return $ [ vs | vs <- mVs, _vs_parFlag vs || _vs_paragraph vs == VerticalSpacingParNone ]- BDFProhibitMTEL bd -> rec bd BDFDebug s bd -> do r <- rec bd tellDebugMess $ "getSpacing: BDFDebug " ++ show s ++ " (node-id=" ++ show brDcId ++ "): mVs=" ++ show r@@ -593,7 +590,7 @@ -- Nonetheless I think the order of spacings should -- be preserved as it provides a deterministic -- choice for which spacings to prune (which is- -- an argument against simly using a Set).+ -- an argument against simply using a Set). -- I have also considered `fmap head . group` which -- seems to work similarly well for common cases -- and which might behave even better when it comes@@ -758,7 +755,6 @@ BDFForceParSpacing bd -> do mVs <- preFilterLimit <$> rec bd return $ [ vs | vs <- mVs, _vs_parFlag vs || _vs_paragraph vs == VerticalSpacingParNone ]- BDFProhibitMTEL bd -> rec bd BDFDebug s bd -> do r <- rec bd tellDebugMess $ "getSpacings: BDFDebug " ++ show s ++ " (node-id=" ++ show brDcId ++ "): vs=" ++ show (take 9 r)
src/Language/Haskell/Brittany/Internal/Transformations/Columns.hs view
@@ -129,7 +129,6 @@ BDAnnotationKW{} -> Nothing BDAnnotationRest{} -> Nothing BDEnsureIndent{} -> Nothing- BDProhibitMTEL{} -> Nothing BDSetParSpacing{} -> Nothing BDForceParSpacing{} -> Nothing BDDebug{} -> Nothing
src/Language/Haskell/Brittany/Internal/Types.hs view
@@ -28,8 +28,16 @@ -type PPM a = MultiRWSS.MultiRWS '[Config, ExactPrint.Anns] '[Text.Builder.Builder, [BrittanyError], Seq String] '[] a+type PPM = MultiRWSS.MultiRWS+ '[Map ExactPrint.AnnKey ExactPrint.Anns, Config, ExactPrint.Anns]+ '[Text.Builder.Builder, [BrittanyError], Seq String]+ '[] +type PPMLocal = MultiRWSS.MultiRWS+ '[Config, ExactPrint.Anns]+ '[Text.Builder.Builder, [BrittanyError], Seq String]+ '[]+ data LayoutState = LayoutState { _lstate_baseYs :: [Int] -- ^ stack of number of current indentation columns@@ -62,17 +70,10 @@ , _lstate_addSepSpace :: Maybe Int -- number of spaces to insert if anyone -- writes (any non-spaces) in the -- current line.- , _lstate_inhibitMTEL :: Bool- -- ^ inhibit move-to-exact-location.- -- normally, processing a node's annotation involves moving to the exact- -- (vertical) location of the node. this ensures that newlines in the- -- input are retained in the output.- -- While this flag is on, this behaviour will be disabled.- -- The flag is automatically turned off when inserting any kind of- -- newline. -- , _lstate_isNewline :: NewLineState -- -- captures if the layouter currently is in a new line, i.e. if the -- -- current line only contains (indentation) spaces.+ -- this is mostly superseeded by curYOrAddNewline, iirc. } lstate_baseY :: LayoutState -> Int@@ -91,7 +92,6 @@ ++ ",indLevelLinger=" ++ show (_lstate_indLevelLinger state) ++ ",commentCol=" ++ show (_lstate_commentCol state) ++ ",addSepSpace=" ++ show (_lstate_addSepSpace state)- ++ ",inhibitMTEL=" ++ show (_lstate_inhibitMTEL state) ++ "}" -- data NewLineState = NewLineStateInit -- initial state. we do not know if in a@@ -171,7 +171,7 @@ -- expected to have exactly two columns | ColBindStmt | ColDoLet -- the non-indented variant- | ColRecUpdate+ | ColRecUpdate -- used for both RecCon and RecUpd. TODO: refactor to reflect? | ColListComp | ColList | ColApp@@ -243,11 +243,6 @@ | BDSetParSpacing BriDoc | BDForceParSpacing BriDoc -- pseudo-deprecated- | BDProhibitMTEL BriDoc -- move to exact location- -- TODO: this constructor is deprecated. should- -- still work, but i should probably completely- -- remove it, as i have no proper usecase for- -- it anymore. | BDDebug String BriDoc deriving (Data.Data.Data, Eq, Ord) @@ -289,11 +284,6 @@ | BDFNonBottomSpacing (f (BriDocF f)) | BDFSetParSpacing (f (BriDocF f)) | BDFForceParSpacing (f (BriDocF f))- | BDFProhibitMTEL (f (BriDocF f)) -- move to exact location- -- TODO: this constructor is deprecated. should- -- still work, but i should probably completely- -- remove it, as i have no proper usecase for- -- it anymore. | BDFDebug String (f (BriDocF f)) -- deriving instance Data.Data.Data (BriDocF Identity)@@ -327,7 +317,6 @@ uniplate (BDNonBottomSpacing bd) = plate BDNonBottomSpacing |* bd uniplate (BDSetParSpacing bd) = plate BDSetParSpacing |* bd uniplate (BDForceParSpacing bd) = plate BDForceParSpacing |* bd- uniplate (BDProhibitMTEL bd) = plate BDProhibitMTEL |* bd uniplate (BDDebug s bd) = plate BDDebug |- s |* bd newtype NodeAllocIndex = NodeAllocIndex Int@@ -359,7 +348,6 @@ BDFNonBottomSpacing bd -> BDNonBottomSpacing $ rec bd BDFSetParSpacing bd -> BDSetParSpacing $ rec bd BDFForceParSpacing bd -> BDForceParSpacing $ rec bd- BDFProhibitMTEL bd -> BDProhibitMTEL $ rec bd BDFDebug s bd -> BDDebug (s ++ "@" ++ show (fst tpl)) $ rec bd where rec = unwrapBriDocNumbered@@ -395,7 +383,6 @@ BDNonBottomSpacing bd -> briDocSeqSpine bd BDSetParSpacing bd -> briDocSeqSpine bd BDForceParSpacing bd -> briDocSeqSpine bd- BDProhibitMTEL bd -> briDocSeqSpine bd BDDebug _s bd -> briDocSeqSpine bd briDocForceSpine :: BriDoc -> BriDoc
src/Language/Haskell/Brittany/Internal/Utils.hs view
@@ -23,6 +23,7 @@ , transformDownMay , FirstLastView(..) , splitFirstLast+ , lines' ) where @@ -280,3 +281,11 @@ transformDownMay f = g where g x = maybe x (Uniplate.descend g) $ f x _transformDownRec :: Uniplate.Uniplate on => (on -> Maybe on) -> (on -> on) _transformDownRec f = g where g x = maybe (Uniplate.descend g x) g $ f x++-- | similar to List.lines, but treating the case of final newline character+-- in such a manner that this function is the inverse of @intercalate "\n"@.+lines' :: String -> [String]+lines' s = case break (== '\n') s of+ (s1, []) -> [s1]+ (s1, [_]) -> [s1, ""]+ (s1, (_:r)) -> s1 : lines' r
srcinc/prelude.inc view
@@ -1,164 +1,60 @@ import qualified Data.ByteString-import qualified Data.ByteString.Builder-import qualified Data.ByteString.Builder.Extra-import qualified Data.ByteString.Builder.Prim +-- import qualified Data.ByteString.Builder+-- import qualified Data.ByteString.Builder.Extra+-- import qualified Data.ByteString.Builder.Prim import qualified Data.ByteString.Char8-import qualified Data.ByteString.Lazy.Builder-import qualified Data.ByteString.Lazy.Builder.ASCII-import qualified Data.ByteString.Lazy.Builder.Extras-import qualified Data.ByteString.Lazy.Char8-import qualified Data.ByteString.Lazy-import qualified Data.ByteString.Short-import qualified Data.ByteString.Unsafe+-- import qualified Data.ByteString.Lazy.Builder+-- import qualified Data.ByteString.Lazy.Builder.ASCII+-- import qualified Data.ByteString.Lazy.Builder.Extras+-- import qualified Data.ByteString.Lazy.Char8+-- import qualified Data.ByteString.Lazy+-- import qualified Data.ByteString.Short+-- import qualified Data.ByteString.Unsafe -import qualified Data.Graph-import qualified Data.IntMap-import qualified Data.IntMap.Lazy-import qualified Data.IntMap.Strict-import qualified Data.IntSet-import qualified Data.Map-import qualified Data.Map.Lazy-import qualified Data.Map.Strict-import qualified Data.Sequence-import qualified Data.Set-import qualified Data.Tree+-- import qualified Data.Graph+-- import qualified Data.IntMap+-- import qualified Data.IntMap.Lazy+-- import qualified Data.IntMap.Strict+-- import qualified Data.IntSet+-- import qualified Data.Map+-- import qualified Data.Map.Lazy+-- import qualified Data.Map.Strict+-- import qualified Data.Sequence+-- import qualified Data.Set+-- import qualified Data.Tree import qualified System.Directory -import qualified Control.Concurrent.Extra-import qualified Control.Exception.Extra-import qualified Control.Monad.Extra-import qualified Data.Either.Extra-import qualified Data.IORef.Extra+-- import qualified Control.Concurrent.Extra+-- import qualified Control.Exception.Extra+-- import qualified Control.Monad.Extra+-- import qualified Data.Either.Extra+-- import qualified Data.IORef.Extra import qualified Data.List.Extra-import qualified Data.Tuple.Extra-import qualified Data.Version.Extra-import qualified Numeric.Extra-import qualified System.Directory.Extra-import qualified System.Environment.Extra-import qualified System.IO.Extra-import qualified System.Info.Extra-import qualified System.Process.Extra-import qualified System.Time.Extra---- import qualified Control.Exception.Lens--- import qualified Control.Lens--- import qualified Control.Lens.At--- import qualified Control.Lens.Combinators--- import qualified Control.Lens.Cons--- import qualified Control.Lens.Each--- import qualified Control.Lens.Empty--- import qualified Control.Lens.Equality--- import qualified Control.Lens.Extras--- import qualified Control.Lens.Fold--- import qualified Control.Lens.Getter--- import qualified Control.Lens.Indexed--- import qualified Control.Lens.Internal--- import qualified Control.Lens.Internal.Bazaar--- import qualified Control.Lens.Internal.ByteString--- import qualified Control.Lens.Internal.Coerce--- import qualified Control.Lens.Internal.Context--- import qualified Control.Lens.Internal.Deque--- import qualified Control.Lens.Internal.Exception--- import qualified Control.Lens.Internal.FieldTH--- import qualified Control.Lens.Internal.Fold--- import qualified Control.Lens.Internal.Getter--- import qualified Control.Lens.Internal.Indexed--- import qualified Control.Lens.Internal.Instances--- import qualified Control.Lens.Internal.Iso--- import qualified Control.Lens.Internal.Level--- import qualified Control.Lens.Internal.List--- import qualified Control.Lens.Internal.Magma--- import qualified Control.Lens.Internal.Prism--- import qualified Control.Lens.Internal.PrismTH--- import qualified Control.Lens.Internal.Review--- import qualified Control.Lens.Internal.Setter--- import qualified Control.Lens.Internal.TH--- import qualified Control.Lens.Internal.Zoom--- import qualified Control.Lens.Iso--- import qualified Control.Lens.Lens--- import qualified Control.Lens.Level--- import qualified Control.Lens.Operators--- import qualified Control.Lens.Plated--- import qualified Control.Lens.Prism--- import qualified Control.Lens.Reified--- import qualified Control.Lens.Review--- import qualified Control.Lens.Setter--- import qualified Control.Lens.TH--- import qualified Control.Lens.Traversal--- import qualified Control.Lens.Tuple--- import qualified Control.Lens.Type--- import qualified Control.Lens.Wrapped--- import qualified Control.Lens.Zoom--- import qualified Control.Monad.Error.Lens--- import qualified Control.Parallel.Strategies.Lens--- import qualified Control.Seq.Lens--- import qualified Data.Array.Lens--- import qualified Data.Bits.Lens--- import qualified Data.ByteString.Lazy.Lens--- import qualified Data.ByteString.Lens--- import qualified Data.ByteString.Strict.Lens--- import qualified Data.Complex.Lens--- import qualified Data.Data.Lens--- import qualified Data.Dynamic.Lens--- import qualified Data.HashSet.Lens--- import qualified Data.IntSet.Lens--- import qualified Data.List.Lens--- import qualified Data.Map.Lens--- import qualified Data.Sequence.Lens--- import qualified Data.Set.Lens--- import qualified Data.Text.Lazy.Lens--- import qualified Data.Text.Lens--- import qualified Data.Text.Strict.Lens--- import qualified Data.Tree.Lens--- import qualified Data.Typeable.Lens--- import qualified Data.Vector.Generic.Lens--- import qualified Data.Vector.Lens--- import qualified GHC.Generics.Lens--- import qualified Generics.Deriving.Lens--- import qualified Language.Haskell.TH.Lens--- import qualified Numeric.Lens--- import qualified System.Exit.Lens--- import qualified System.FilePath.Lens--- import qualified System.IO.Error.Lens---- import qualified Control.Monad.Cont--- import qualified Control.Monad.Cont.Class--- import qualified Control.Monad.Error.Class--- import qualified Control.Monad.Except--- import qualified Control.Monad.Identity--- import qualified Control.Monad.List--- import qualified Control.Monad.RWS--- import qualified Control.Monad.RWS.Class--- import qualified Control.Monad.RWS.Lazy--- import qualified Control.Monad.RWS.Strict--- import qualified Control.Monad.Reader--- import qualified Control.Monad.Reader.Class--- import qualified Control.Monad.State--- import qualified Control.Monad.State.Class--- import qualified Control.Monad.State.Lazy--- import qualified Control.Monad.State.Strict--- import qualified Control.Monad.Trans--- import qualified Control.Monad.Writer--- import qualified Control.Monad.Writer.Class--- import qualified Control.Monad.Writer.Lazy--- import qualified Control.Monad.Writer.Strict+-- import qualified Data.Tuple.Extra+-- import qualified Data.Version.Extra+-- import qualified Numeric.Extra+-- import qualified System.Directory.Extra+-- import qualified System.Environment.Extra+-- import qualified System.IO.Extra+-- import qualified System.Info.Extra+-- import qualified System.Process.Extra+-- import qualified System.Time.Extra --- import qualified Control.Monad.Trans.MultiRWS-import qualified Control.Monad.Trans.MultiRWS.Lazy-import qualified Control.Monad.Trans.MultiRWS.Strict-import qualified Control.Monad.Trans.MultiReader-import qualified Control.Monad.Trans.MultiReader.Class-import qualified Control.Monad.Trans.MultiReader.Lazy-import qualified Control.Monad.Trans.MultiReader.Strict-import qualified Control.Monad.Trans.MultiState-import qualified Control.Monad.Trans.MultiState.Class-import qualified Control.Monad.Trans.MultiState.Lazy-import qualified Control.Monad.Trans.MultiState.Strict-import qualified Control.Monad.Trans.MultiWriter-import qualified Control.Monad.Trans.MultiWriter.Class-import qualified Control.Monad.Trans.MultiWriter.Lazy-import qualified Control.Monad.Trans.MultiWriter.Strict+-- import qualified Control.Monad.Trans.MultiRWS.Lazy+-- import qualified Control.Monad.Trans.MultiRWS.Strict+-- import qualified Control.Monad.Trans.MultiReader+-- import qualified Control.Monad.Trans.MultiReader.Class+-- import qualified Control.Monad.Trans.MultiReader.Lazy+-- import qualified Control.Monad.Trans.MultiReader.Strict+-- import qualified Control.Monad.Trans.MultiState+-- import qualified Control.Monad.Trans.MultiState.Class+-- import qualified Control.Monad.Trans.MultiState.Lazy+-- import qualified Control.Monad.Trans.MultiState.Strict+-- import qualified Control.Monad.Trans.MultiWriter+-- import qualified Control.Monad.Trans.MultiWriter.Class+-- import qualified Control.Monad.Trans.MultiWriter.Lazy+-- import qualified Control.Monad.Trans.MultiWriter.Strict import qualified Control.Monad.Trans.MultiRWS.Strict as MultiRWSS import qualified Control.Monad.Trans.MultiRWS.Lazy as MultiRWSL@@ -169,237 +65,59 @@ import qualified Text.PrettyPrint.Annotated.HughesPJ import qualified Text.PrettyPrint.Annotated.HughesPJClass -import qualified Text.PrettyPrint.HughesPJ-import qualified Text.PrettyPrint.HughesPJClass---- import qualified Data.Generics--- import qualified Data.Generics.Aliases--- import qualified Data.Generics.Basics--- import qualified Data.Generics.Builders--- import qualified Data.Generics.Instances--- import qualified Data.Generics.Schemes--- import qualified Data.Generics.Text--- import qualified Data.Generics.Twins--- import qualified Generics.SYB--- import qualified Generics.SYB.Aliases--- import qualified Generics.SYB.Basics--- import qualified Generics.SYB.Builders--- import qualified Generics.SYB.Instances--- import qualified Generics.SYB.Schemes--- import qualified Generics.SYB.Text--- import qualified Generics.SYB.Twins--import qualified Data.Text-import qualified Data.Text.Array-import qualified Data.Text.Encoding-import qualified Data.Text.Encoding.Error-import qualified Data.Text.Foreign-import qualified Data.Text.IO--- import qualified Data.Text.Internal--- import qualified Data.Text.Internal.Builder--- import qualified Data.Text.Internal.Builder.Functions--- import qualified Data.Text.Internal.Builder.Int.Digits--- import qualified Data.Text.Internal.Builder.RealFloat.Functions--- import qualified Data.Text.Internal.Encoding.Fusion--- import qualified Data.Text.Internal.Encoding.Fusion.Common--- import qualified Data.Text.Internal.Encoding.Utf16--- import qualified Data.Text.Internal.Encoding.Utf32--- import qualified Data.Text.Internal.Encoding.Utf8--- import qualified Data.Text.Internal.Functions--- import qualified Data.Text.Internal.Fusion--- import qualified Data.Text.Internal.Fusion.CaseMapping--- import qualified Data.Text.Internal.Fusion.Common--- import qualified Data.Text.Internal.Fusion.Size--- import qualified Data.Text.Internal.Fusion.Types--- import qualified Data.Text.Internal.IO--- import qualified Data.Text.Internal.Lazy--- import qualified Data.Text.Internal.Lazy.Encoding.Fusion--- import qualified Data.Text.Internal.Lazy.Fusion--- import qualified Data.Text.Internal.Lazy.Search--- import qualified Data.Text.Internal.Private--- import qualified Data.Text.Internal.Read--- import qualified Data.Text.Internal.Search--- import qualified Data.Text.Internal.Unsafe--- import qualified Data.Text.Internal.Unsafe.Char--- import qualified Data.Text.Internal.Unsafe.Shift-import qualified Data.Text.Lazy-import qualified Data.Text.Lazy.Builder--- import qualified Data.Text.Lazy.Builder.Int--- import qualified Data.Text.Lazy.Builder.RealFloat--- import qualified Data.Text.Lazy.Encoding--- import qualified Data.Text.Lazy.IO--- import qualified Data.Text.Lazy.Read--- import qualified Data.Text.Read--- import qualified Data.Text.Unsafe+-- import qualified Text.PrettyPrint.HughesPJ+-- import qualified Text.PrettyPrint.HughesPJClass --- import qualified Control.Applicative.Backwards--- import qualified Control.Applicative.Lift--- import qualified Control.Monad.IO.Class--- import qualified Control.Monad.Signatures--- import qualified Control.Monad.Trans.Class--- import qualified Control.Monad.Trans.Cont--- import qualified Control.Monad.Trans.Except--- import qualified Control.Monad.Trans.Identity--- import qualified Control.Monad.Trans.List--- import qualified Control.Monad.Trans.Maybe--- import qualified Control.Monad.Trans.RWS--- import qualified Control.Monad.Trans.RWS.Lazy--- import qualified Control.Monad.Trans.RWS.Strict--- import qualified Control.Monad.Trans.Reader--- import qualified Control.Monad.Trans.State--- import qualified Control.Monad.Trans.State.Lazy--- import qualified Control.Monad.Trans.State.Strict--- import qualified Control.Monad.Trans.Writer--- import qualified Control.Monad.Trans.Writer.Lazy--- import qualified Control.Monad.Trans.Writer.Strict--- import qualified Data.Functor.Classes--- import qualified Data.Functor.Compose--- import qualified Data.Functor.Constant--- import qualified Data.Functor.Product--- import qualified Data.Functor.Reverse--- import qualified Data.Functor.Sum+-- import qualified Data.Text+-- import qualified Data.Text.Array+-- import qualified Data.Text.Encoding+-- import qualified Data.Text.Encoding.Error+-- import qualified Data.Text.Foreign+-- import qualified Data.Text.IO+-- import qualified Data.Text.Lazy+-- import qualified Data.Text.Lazy.Builder --- import qualified Prelude--- import qualified Control.Applicative--- import qualified Control.Arrow--- import qualified Control.Category--- import qualified Control.Concurrent--- import qualified Control.Concurrent.Chan--- import qualified Control.Concurrent.MVar--- import qualified Control.Concurrent.QSem--- import qualified Control.Concurrent.QSemN--- import qualified Control.Exception--- import qualified Control.Exception.Base--- import qualified Control.Monad--- import qualified Control.Monad.Fix--- import qualified Control.Monad.ST--- import qualified Control.Monad.ST.Lazy--- import qualified Control.Monad.ST.Lazy.Unsafe--- import qualified Control.Monad.ST.Strict--- import qualified Control.Monad.ST.Unsafe--- import qualified Control.Monad.Zip-import qualified Data.Bifunctor-import qualified Data.Bits-import qualified Data.Bool-import qualified Data.Char+-- import qualified Data.Bifunctor+-- import qualified Data.Bits+-- import qualified Data.Bool+-- import qualified Data.Char import qualified Data.Coerce-import qualified Data.Complex+-- import qualified Data.Complex import qualified Data.Data-import qualified Data.Dynamic+-- import qualified Data.Dynamic import qualified Data.Either-import qualified Data.Eq-import qualified Data.Fixed+-- import qualified Data.Eq+-- import qualified Data.Fixed import qualified Data.Foldable-import qualified Data.Function-import qualified Data.Functor-import qualified Data.Functor.Identity-import qualified Data.IORef-import qualified Data.Int-import qualified Data.Ix-import qualified Data.List+-- import qualified Data.Function+-- import qualified Data.Functor+-- import qualified Data.Functor.Identity+-- import qualified Data.IORef+-- import qualified Data.Int+-- import qualified Data.Ix+-- import qualified Data.List import qualified Data.Maybe-import qualified Data.Monoid-import qualified Data.Ord-import qualified Data.Proxy--- import qualified Data.Ratio--- import qualified Data.STRef--- import qualified Data.STRef.Lazy--- import qualified Data.STRef.Strict--- import qualified Data.String--- import qualified Data.Traversable--- import qualified Data.Tuple--- import qualified Data.Type.Bool--- import qualified Data.Type.Coercion--- import qualified Data.Type.Equality--- import qualified Data.Typeable--- import qualified Data.Typeable.Internal--- import qualified Data.Unique--- import qualified Data.Version--- import qualified Data.Void--- import qualified Data.Word-import qualified Debug.Trace--- import qualified Foreign.C--- import qualified Foreign.C.Error--- import qualified Foreign.C.String--- import qualified Foreign.C.Types--- import qualified Foreign.Concurrent--- import qualified Foreign.ForeignPtr--- import qualified Foreign.ForeignPtr.Unsafe--- import qualified Foreign.Marshal--- import qualified Foreign.Marshal.Alloc--- import qualified Foreign.Marshal.Array--- import qualified Foreign.Marshal.Error--- import qualified Foreign.Marshal.Pool--- import qualified Foreign.Marshal.Unsafe--- import qualified Foreign.Marshal.Utils--- import qualified Foreign.Ptr--- import qualified Foreign.StablePtr--- import qualified Foreign.Storable-import qualified Numeric-import qualified Numeric.Natural--- import qualified System.CPUTime--- import qualified System.Console.GetOpt--- import qualified System.Environment--- import qualified System.Exit+-- import qualified Data.Monoid+-- import qualified Data.Ord+-- import qualified Data.Proxy+-- import qualified Debug.Trace+-- import qualified Numeric+-- import qualified Numeric.Natural import qualified System.IO--- import qualified System.IO.Error--- import qualified System.IO.Unsafe--- import qualified System.Info--- import qualified System.Mem--- import qualified System.Mem.StableName--- import qualified System.Mem.Weak--- import qualified System.Posix.Types--- import qualified System.Timeout--- import qualified Text.ParserCombinators.ReadP--- import qualified Text.ParserCombinators.ReadPrec--- import qualified Text.Printf--- import qualified Text.Read--- import qualified Text.Read.Lex--- import qualified Text.Show--- import qualified Text.Show.Functions-import qualified Unsafe.Coerce+-- import qualified Unsafe.Coerce --- import qualified Control.Arrow as Arrow--- import qualified Control.Category as Category--- import qualified Control.Concurrent as Concurrent--- import qualified Control.Concurrent.Chan as Chan--- import qualified Control.Concurrent.MVar as MVar--- import qualified Control.Exception as Exception--- import qualified Control.Exception.Base as Exception.Base--- import qualified Control.Monad as Monad--- import qualified Data.Bits as Bits import qualified Data.Bool as Bool--- import qualified Data.Char as Char--- import qualified Data.Complex as Complex--- import qualified Data.Either as Either--- import qualified Data.Eq as Eq import qualified Data.Foldable as Foldable--- import qualified Data.Fixed as Fixed--- import qualified Data.Functor.Identity as Identity--- import qualified Data.IORef as IORef--- import qualified Data.Int as Int--- import qualified Data.Ix as Ix--- import qualified Data.Maybe as Maybe--- import qualified Data.Monoid as Monoid--- import qualified Data.Ord as Ord--- import qualified Data.Proxy as Proxy--- import qualified Data.Traversable as Traversable--- import qualified Data.Void as Void import qualified GHC.OldList as List--- import qualified Text.Printf as Printf import qualified Data.Semigroup as Semigroup import qualified Data.ByteString as ByteString import qualified Data.ByteString.Lazy as ByteStringL --- import qualified Data.IntMap as IntMap import qualified Data.IntMap.Lazy as IntMapL import qualified Data.IntMap.Strict as IntMapS--- import qualified Data.IntSet as IntSet import qualified Data.Map as Map--- import qualified Data.Map.Lazy as MapL--- import qualified Data.Map.Strict as MapS import qualified Data.Sequence as Seq import qualified Data.Set as Set @@ -415,378 +133,15 @@ import qualified Data.Text.Lazy.Encoding as TextL.Encoding import qualified Data.Text.Lazy.IO as TextL.IO --- import qualified Control.Monad.Trans.Class as Trans.Class--- import qualified Control.Monad.Trans.Maybe as Trans.Maybe--- import qualified Control.Monad.Trans.RWS as RWS--- import qualified Control.Monad.Trans.RWS.Lazy as RWSL--- import qualified Control.Monad.Trans.RWS.Strict as RWSS--- import qualified Control.Monad.Trans.Reader as Reader import qualified Control.Monad.Trans.State as State import qualified Control.Monad.Trans.State.Lazy as StateL import qualified Control.Monad.Trans.State.Strict as StateS--- import qualified Control.Monad.Trans.Writer as Writer--- import qualified Control.Monad.Trans.Writer.Lazy as WriterL--- import qualified Control.Monad.Trans.Writer.Strict as Writer import qualified Control.Monad.Trans.Either as EitherT import qualified Data.Strict.Maybe as Strict import qualified Safe as Safe -import Data.Functor.Identity ( Identity(..) )-import Control.Concurrent.Chan ( Chan )-import Control.Concurrent.MVar ( MVar )-import Data.Int ( Int )-import Data.Word ( Word )-import Prelude ( Integer, Float, Double )-import Control.Monad.ST ( ST )-import Data.Bool ( Bool(..) )-import Data.Char ( Char )-import Data.Either ( Either(..) )-import Data.IORef ( IORef )-import Data.Maybe ( Maybe(..) )-import Data.Semigroup ( Option(..) )-import Data.Monoid ( Endo(..), All(..), Any(..), Sum(..), Product(..), Alt(..), )-import Data.Ord ( Ordering(..), Down(..) )-import Data.Ratio ( Ratio, Rational )-import Data.String ( String )-import Data.Void ( Void )-import System.IO ( IO )-import Data.Proxy ( Proxy(..) )-import Data.Sequence ( Seq ) -import Data.Map ( Map )-import Data.Set ( Set )--import Data.Text ( Text )--import Prelude ( Char- , String- , Int- , Integer- , Float- , Double- , Bool (..)- , undefined- , Eq (..)- , Ord (..)- , Enum (..)- , Bounded (..)- , Maybe (..)- , Either (..)- , IO- , (<$>)- , (.)- , ($)- , ($!)- , Num (..)- , Integral (..)- , Fractional (..)- , Floating (..)- , RealFrac (..)- , RealFloat (..)- , fromIntegral- , error- , foldr- , foldl- , foldr1- , id- , map- , subtract- , putStrLn- , putStr- , Show (..)- , print- , fst- , snd- , (++)- , not- , (&&)- , (||)- , curry- , uncurry- , Ordering (..)- , flip- , const- , seq- , reverse- , otherwise- , traverse- , realToFrac- , or- , and- , head- , any- , (^)- , Foldable- , Traversable- )--import Data.Function ( fix- )--import Data.Foldable ( foldl'- , foldr'- , fold- , asum- )--import Data.List ( partition- , null- , elem- , notElem- , minimum- , maximum- , length- , all- , take- , drop- , find- , sum- , zip- , zip3- , zipWith- , repeat- , replicate- , iterate- , nub- , filter- , intersperse- , intercalate- , isSuffixOf- , isPrefixOf- , dropWhile- , takeWhile- , unzip- , break- , transpose- , sortBy- , mapAccumL- , mapAccumR- , uncons- )--import Data.Tuple ( swap- )--import Data.Char ( ord- , chr- )--import Data.Maybe ( fromMaybe- , maybe- , listToMaybe- , maybeToList- , catMaybes- )--import Data.Word ( Word32- )--import Data.Ord ( comparing- , Down (..)- )--import Data.Either ( either- )--import Data.Ratio ( Ratio- , (%)- , numerator- , denominator- )--import Text.Read ( readMaybe- )--import Control.Monad ( Functor (..)- , Monad (..)- , MonadPlus (..)- , mapM- , mapM_- , forM- , forM_- , sequence- , sequence_- , (=<<)- , (>=>)- , (<=<)- , forever- , void- , join- , replicateM- , replicateM_- , guard- , when- , unless- , liftM- , liftM2- , liftM3- , liftM4- , liftM5- , filterM- , (<$!>)- )--import Control.Applicative ( Applicative (..)- , Alternative (..)- )--import Foreign.Storable ( Storable )-import GHC.Exts ( Constraint )--import Control.Concurrent ( threadDelay- , forkIO- , forkOS- )--import Control.Concurrent.MVar ( MVar- , newEmptyMVar- , newMVar- , putMVar- , readMVar- , takeMVar- , swapMVar- )--import Control.Exception ( evaluate- , bracket- , assert- )--import Debug.Trace ( trace- , traceId- , traceShowId- , traceShow- , traceStack- , traceShowId- , traceIO- , traceM- , traceShowM- )--import Foreign.ForeignPtr ( ForeignPtr- )--import Data.Monoid ( (<>)- , mconcat- , Monoid (..)- )--import Data.Bifunctor ( bimap )-import Data.Functor ( (<$), ($>) )-import Data.Function ( (&) )-import System.IO ( hFlush- , stdout- )--import Data.Typeable ( Typeable- )--import Control.Arrow ( first- , second- , (***)- , (&&&)- , (>>>)- , (<<<)- )--import Data.Functor.Identity ( Identity (..)- )--import Data.Proxy ( Proxy (..)- )--import Data.Version ( showVersion- )--import Data.List.Extra ( nubOrd- , stripSuffix- )-import Control.Monad.Extra ( whenM- , unlessM- , ifM- , notM- , orM- , andM- , anyM- , allM- )--import Data.Tree ( Tree(..)- )--import Control.Monad.Trans.MultiRWS ( -- MultiRWST (..)- -- , MultiRWSTNull- -- , MultiRWS- -- , - MonadMultiReader(..)- , MonadMultiWriter(..)- , MonadMultiState(..)- -- , runMultiRWST- -- , runMultiRWSTASW- -- , runMultiRWSTW- -- , runMultiRWSTAW- -- , runMultiRWSTSW- -- , runMultiRWSTNil- -- , runMultiRWSTNil_- -- , withMultiReader- -- , withMultiReader_- -- , withMultiReaders- -- , withMultiReaders_- -- , withMultiWriter- -- , withMultiWriterAW- -- , withMultiWriterWA- -- , withMultiWriterW- -- , withMultiWriters- -- , withMultiWritersAW- -- , withMultiWritersWA- -- , withMultiWritersW- -- , withMultiState- -- , withMultiStateAS- -- , withMultiStateSA- -- , withMultiStateA- -- , withMultiStateS- -- , withMultiState_- -- , withMultiStates- -- , withMultiStatesAS- -- , withMultiStatesSA- -- , withMultiStatesA- -- , withMultiStatesS- -- , withMultiStates_- -- , inflateReader- -- , inflateMultiReader- -- , inflateWriter- -- , inflateMultiWriter- -- , inflateState- -- , inflateMultiState- -- , mapMultiRWST- -- , mGetRawR- -- , mGetRawW- -- , mGetRawS- -- , mPutRawR- -- , mPutRawW- -- , mPutRawS- )--import Control.Monad.Trans.MultiReader ( runMultiReaderTNil- , runMultiReaderTNil_- , MultiReaderT (..)- , MultiReader- , MultiReaderTNull- )--import Data.Text ( Text )--import Control.Monad.IO.Class ( MonadIO (..)- )--import Control.Monad.Trans.Class ( lift- )-import Control.Monad.Trans.Maybe ( MaybeT (..)- )- import Language.Haskell.Brittany.Internal.Prelude--import Data.Data ( toConstr- )+import Language.Haskell.Brittany.Internal.PreludeUtils