packages feed

tilia 0.1.0.0 → 0.1.1.0

raw patch · 73 files changed

+2090/−613 lines, 73 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Tilia.Cpp.Macros: [macroAtLeast] :: Macros -> Map Text [Integer]
- Tilia.Cpp.Macros: [macroBelow] :: Macros -> Map Text [Integer]
- Tilia.Cpp.Macros: [macroNumbers] :: Macros -> Map Text Integer
- Tilia.Cpp.Macros: [macroVersions] :: Macros -> Map Text [Integer]
- Tilia.Doc.Combinators: group :: Span -> Doc -> Doc
- Tilia.Doc.Internal: groupLayout :: Maybe Span -> Layout
+ Tilia.Cpp.Macros: [macroExactNumbers] :: Macros -> Map Text Integer
+ Tilia.Cpp.Macros: [macroExactVersions] :: Macros -> Map Text [Integer]
+ Tilia.Cpp.Macros: [macroLowerBounds] :: Macros -> Map Text [Integer]
+ Tilia.Cpp.Macros: [macroPlannedPackages] :: Macros -> Maybe (Set Text)
+ Tilia.Cpp.Macros: [macroUpperBounds] :: Macros -> Map Text [Integer]
+ Tilia.Cpp.Merge: instance GHC.Classes.Eq Tilia.Cpp.Merge.Place
+ Tilia.Fixity.Cache: cachedPackageCache :: Cache -> IO (Maybe FilePath)
+ Tilia.Fixity.Cache: cachedSolveTime :: Cache -> IO (Maybe UTCTime)
+ Tilia.Fixity.Cache: storePackageCache :: Cache -> FilePath -> IO ()
+ Tilia.Fixity.Cache: storeSolveTime :: Cache -> UTCTime -> IO ()
+ Tilia.Fixity.Plan: [rememberSolveTime] :: Futility -> UTCTime -> IO ()
+ Tilia.Fixity.Plan: futilityFor :: Choice "useCache" -> FilePath -> Futility
+ Tilia.Fixity.Plan: plannedCompiler :: BuildPlan -> Maybe Version
+ Tilia.Render.Context: writtenOnOneLine :: Ctx -> Span -> Bool
+ Tilia.Render.Pattern: hsPatClosing :: Ctx -> ClosingIndent -> LPat GhcPs -> Doc
+ Tilia.Source: quoteEndingFrom :: Int -> Source -> Maybe Int
- Tilia.Cabal.Package: newPackageReader :: IO PackageReader
+ Tilia.Cabal.Package: newPackageReader :: Maybe Version -> IO PackageReader
- Tilia.Cpp.Macros: Macros :: Map Text [Integer] -> Map Text Integer -> Set Text -> Set Text -> Map Text [Integer] -> Map Text [Integer] -> Macros
+ Tilia.Cpp.Macros: Macros :: Map Text [Integer] -> Map Text Integer -> Set Text -> Set Text -> Maybe (Set Text) -> Map Text [Integer] -> Map Text [Integer] -> Macros
- Tilia.Fixity.Plan: Futility :: IO Bool -> IO () -> IO [Text] -> ([Text] -> IO ()) -> Futility
+ Tilia.Fixity.Plan: Futility :: IO Bool -> IO () -> IO [Text] -> ([Text] -> IO ()) -> (UTCTime -> IO ()) -> Futility
- Tilia.Fixity.Plan: plannedTarballs :: BuildPlan -> IO [(PlanPackage, FilePath)]
+ Tilia.Fixity.Plan: plannedTarballs :: Cache -> BuildPlan -> IO [(PlanPackage, FilePath)]
- Tilia.Source: sourceOf :: Lines -> [LEpaComment] -> Source
+ Tilia.Source: sourceOf :: Lines -> [LEpaComment] -> IntMap Int -> Source

Files

CHANGELOG.md view
@@ -1,3 +1,67 @@+## Tilia 0.1.1.0++* Keep code that every configuration prints alike out of the branches of a+  conditional in many more cases rather than copying it into each of them.+  [PR 229](https://github.com/mrkkrp/tilia/pull/229).+* Lay a construct holding a quasi-quotation written over several lines out+  as if the quasi-quotation were written on one line, since its lines are+  reproduced. It stays on the line of what comes before it, and what follows+  its `|]` stays on the line of the `|]`, rather than going on lines of+  their own. [Issue 208](https://github.com/mrkkrp/tilia/issues/208).+* A run whose build plan is up to date and whose cache is filled starts no+  other program: where `cabal` keeps the sources it downloads is remembered,+  the compiler's version is taken from the plan, and a plan that solving+  left as it was is not solved again on every run after a `.cabal` file is+  saved. [PR 236](https://github.com/mrkkrp/tilia/pull/236).+* The fixity a module declares for an operator it does not export is no+  longer taken to be that operator's fixity in the modules importing it,+  whether the module is read from its source or from its interface file. A+  module that brings in an operator of the same name from elsewhere is no+  longer declined over the two disagreeing.+  [Issue 238](https://github.com/mrkkrp/tilia/issues/238).+* A record field whose first line is written in each branch of a+  conditional, with a body the branches share after the `#endif`, comes out+  as written, rather than as its name, a `=` on a line of its own and a+  second conditional, which formatting again indented further. Where several+  such fields follow one another, the body of the first is no longer copied+  into each branch. [Issue 240](https://github.com/mrkkrp/tilia/issues/240).+* The `VERSION_` and `MIN_VERSION_` macros of a package the build plan does+  not hold are taken to be undefined, as Cabal defines them only for the+  dependencies of a component. A module is no longer declined over an+  operator that only a branch behind `#ifdef VERSION_x` imports where the+  plan has no `x`. [Issue 241](https://github.com/mrkkrp/tilia/issues/241).+* A pattern written over several lines keeps `<-` and the expression after+  it on its last line where they were written there, in a pattern guard as+  in a `do` block, and the closing bracket of a list or tuple pattern in a+  pattern guard comes out under the opening one, rather than a step further+  in, which only a layout block needs.+  [Issue 210](https://github.com/mrkkrp/tilia/issues/210).+* The `of` of a `case` written on a line of its own after a conditional+  comes out indented past the `case`, as written, rather than at the column+  of the statement, where it began a new one and the module no longer+  parsed. [Issue 237](https://github.com/mrkkrp/tilia/issues/237).+* `--check-ast` no longer reports a comment as lost where it carries on the+  trailing comment of the last import and sorting moves that import, with+  the comment, above another.+  [Issue 252](https://github.com/mrkkrp/tilia/issues/252).+* A type or class imported with `(..)` from a module that exports it without+  its members, such as `ParseError (..)` from `Text.Parsec`, is no longer+  taken to bring in every operator that module exports. A module that brings+  in an operator of the same name from elsewhere is no longer declined over+  the two disagreeing. [Issue 253](https://github.com/mrkkrp/tilia/issues/253).+* A `case` whose head is written whole in each branch of a conditional comes+  out as written, rather than with `case` once above the conditional and the+  scrutinee at the column of the statement, where it began a new one and the+  module no longer parsed. An `of` written after the `#endif` goes at the+  end of each branch, and a comment written after `of` stays after it rather+  than in front of it. [Issue 250](https://github.com/mrkkrp/tilia/issues/250).+* A `let` whose `in` ends its line, followed by another `let` on the next+  line, is kept as one of a chain however many lines its bindings take. One+  written in each branch of a conditional stays there as written, rather+  than coming out with its `let` and `in` outside the conditional and, once+  formatted again, as an `in let` on one line.+  [Issue 251](https://github.com/mrkkrp/tilia/issues/251).+ ## Tilia 0.1.0.0  ### Conditional compilation
bench/Tilia/Bench/Fixity.hs view
@@ -17,7 +17,7 @@ import Data.ByteString.Base16 qualified as B16 import Data.Choice (pattern Do, pattern Don't) import Data.Either (rights)-import Data.Foldable (for_)+import Data.Foldable (find, for_) import Data.IORef (newIORef, readIORef, writeIORef) import Data.Maybe (catMaybes, fromMaybe, listToMaybe) import Data.Text (Text)@@ -48,22 +48,51 @@ import Tilia.Fixity.Plan  -- | The packages of the Hackage corpus whose every module is read.-resolved :: [String]+resolved :: [Text] resolved =-  [ "lens-5.3.6",-    "aeson-2.3.1.0",-    "megaparsec-9.8.1",-    "servant-0.20.3.0",-    "conduit-1.3.6.1",-    "vector-0.13.2.0",-    "text-2.1.4",-    "free-5.2",-    "optics-0.4.2.1",-    "semigroupoids-6.0.2",-    "pandoc-types-1.23.1.2",-    "mtl-2.3.2"+  [ "lens",+    "aeson",+    "megaparsec",+    "servant",+    "conduit",+    "vector",+    "text",+    "free",+    "optics",+    "semigroupoids",+    "pandoc-types",+    "mtl"   ] +-- | The packages of the Hackage corpus the libraries of the resolved ones+-- depend on, which the plan holds with their tarballs.+heldDependencies :: [Text]+heldDependencies =+  [ "QuickCheck",+    "ansi-terminal",+    "attoparsec",+    "bifunctors",+    "comonad",+    "contravariant",+    "dlist",+    "exceptions",+    "hashable",+    "http-types",+    "optparse-applicative",+    "parser-combinators",+    "profunctors",+    "random",+    "resourcet",+    "scientific",+    "stm",+    "tasty",+    "th-abstraction",+    "time",+    "transformers",+    "unordered-containers",+    "uuid-types"+  ]+ -- | The packages the compiler ships with whose every interface is decoded. decoded :: [Text] decoded =@@ -75,21 +104,36 @@     "text"   ] --- | The packages the compiler ships with and the corpus does not hold, at--- the versions it ships, which the plan names so that the macros of their--- versions are defined.-shipped :: [(Text, Text)]-shipped =-  [ ("array", "0.5.8.0"),+-- | The packages the corpus's packages depend on and it does not hold, at+-- the versions the compiler ships or versions those packages accept, which+-- the plan names so that the macros of their versions are defined.+--+-- The plan is a fixed input rather than a model of a build: a regression+-- shows because every run reads the same branches of the same conditionals,+-- and how close the plan comes to one cabal would solve only changes which+-- branches those are, and so how the work is weighted. It need not follow+-- the base compiler or the corpus.+dependencies :: [(Text, Text)]+dependencies =+  [ ("StateVar", "1.2.2"),+    ("array", "0.5.8.0"),     ("base", "4.20.2.0"),     ("binary", "0.8.9.3"),     ("bytestring", "0.12.2.0"),     ("containers", "0.7"),     ("deepseq", "1.5.0.0"),     ("directory", "1.3.8.5"),+    ("distributive", "0.6.3"),     ("filepath", "1.5.4.0"),     ("ghc-prim", "0.12.0"),+    ("http-media", "0.8.1.1"),+    ("indexed-traversable", "0.1.5"),+    ("mono-traversable", "1.0.21.0"),+    ("os-string", "2.0.7"),+    ("primitive", "0.9.1.0"),     ("process", "1.6.26.1"),+    ("tagged", "0.8.11"),+    ("tasty-inspection-testing", "0.2.1"),     ("template-haskell", "2.22.0.0"),     ("unix", "2.8.7.0")   ]@@ -104,29 +148,51 @@ -- collections fall in the benchmarks that run after it, so this goes after -- the benchmarks of formatting. withFixityBenchmarks :: (([Benchmark], Text) -> IO a) -> IO (Either Text a)-withFixityBenchmarks use = do-  pid <- getCurrentPid-  let dir = printf "/tmp/tilia-bench-%010d" (fromIntegral pid :: Int)-  bracket_-    (createDirectoryIfMissing True (dir </> "tarballs"))-    (removePathForcibly dir)-    (fixityBenchmarks dir >>= traverse use)+withFixityBenchmarks use = case releases of+  Left problem -> pure (Left problem)+  Right (toResolve, held) -> do+    pid <- getCurrentPid+    let dir = printf "/tmp/tilia-bench-%010d" (fromIntegral pid :: Int)+    bracket_+      (createDirectoryIfMissing True (dir </> "tarballs"))+      (removePathForcibly dir)+      (fixityBenchmarks dir toResolve held >>= traverse use)+  where+    releases =+      (,)+        <$> traverse corpusRelease resolved+        <*> traverse corpusRelease heldDependencies +-- | The release of a package the Hackage corpus holds.+corpusRelease :: Text -> Either Text String+corpusRelease name =+  maybe (Left ("The Hackage corpus holds no " <> name <> ".")) Right $+    find ((== name) . ppName . planned) releases+  where+    releases = case corpusSource hackagePackages of+      HackageReleases names -> names+      _ -> []+ -- | The benchmarks of fixity resolution, set up in the directory given, and -- a digest of the interfaces they decode.-fixityBenchmarks :: FilePath -> IO (Either Text ([Benchmark], Text))-fixityBenchmarks dir = do+fixityBenchmarks ::+  -- | The directory to set them up in.+  FilePath ->+  -- | The releases whose every module is read.+  [String] ->+  -- | The releases the plan holds besides them.+  [String] ->+  IO (Either Text ([Benchmark], Text))+fixityBenchmarks dir toResolve held = do   corpus <- (</> corpusName hackagePackages) <$> corpusCache-  let releases = case corpusSource hackagePackages of-        HackageReleases names -> names-        _ -> []+  let releases = toResolve <> held       tarballOf release = dir </> "tarballs" </> release <.> "tar.gz"       tarballs = [(planned release, tarballOf release) | release <- releases]       plan =         BuildPlan           { bpCompiler = "ghc-9.10.3",             bpPackages =-              [PlanPackage n v PreExisting [] | (n, v) <- shipped]+              [PlanPackage n v PreExisting [] | (n, v) <- dependencies]                 <> fmap fst tarballs           }       fetched release = corpus </> release <.> "tar.gz"@@ -145,7 +211,7 @@             pure $ do               answers <- traverse (askModule resolver) modules               length <$> evaluate (force answers)-      packages <- for resolved $ \release -> do+      packages <- for toResolve $ \release -> do         modules <- fromMaybe [] <$> packageModules (tarballOf release)         filled <- newIORef False         let recalling = do@@ -167,15 +233,18 @@             digestOf interfaces           )   where-    planned release =-      let (name, version) = T.breakOnEnd "-" (T.pack release)-       in PlanPackage (T.dropEnd 1 name) version PreExisting []     decoding files = do       fresh <- evaluate (force [(m, BS.copy bytes) | (m, bytes) <- files])       pure $         length . rights           <$> evaluate             (force [fromHiFile m =<< decodeHiFile bytes | (m, bytes) <- fresh])++-- | A release of the Hackage corpus as a package of the plan.+planned :: String -> PlanPackage+planned release =+  let (name, version) = T.breakOnEnd "-" (T.pack release)+   in PlanPackage (T.dropEnd 1 name) version PreExisting []  -- | A cache of fixities in a directory. cacheUnder :: FilePath -> IO Cache
bench/bench.record view
@@ -29,93 +29,93 @@ interfaces 1c28e35fa2432d89  # stage      allocated  instructions  benchmark-check        305488704     625342633  Agda-2.8.0/src/full/Agda/Syntax/Translation/ConcreteToAbstract.hs-check        414949976     860211242  ShellCheck-0.11.0/src/ShellCheck/Analytics.hs-check        266244704     469758919  aeson-2.3.1.0/src/Data/Aeson/KeyMap.hs-check        200596704     518019905  blaze-html-0.9.2.0/src/Text/Blaze/Html5/Attributes.hs-check         64909672     129343878  brittany-0.14.0.2/source/library/Language/Haskell/Brittany/Internal/Transformations/Alt.hs-check         90215968     179673175  distributed-process-0.7.8/src/Control/Distributed/Process/Node.hs-check        128706544     268524094  esqueleto-3.6.0.3/test/PostgreSQL/Test.hs-check        523131744     947995155  haxl-2.5.1.1/Haxl/Core/Monad.hs-check        221699688     460191261  idris-1.3.4/src/Idris/Elab/Term.hs-check        337906104     578770578  lifted-base-0.2.3.12/Control/Exception/Lifted.hs-check         61404488     129978443  megaparsec-9.8.1/Text/Megaparsec/Internal.hs-check         82146616     174226709  optparse-applicative-0.19.0.0/tests/test.hs-check         51737448      90786165  pandoc-3.10.2/src/Text/Pandoc/Class/PandocPure.hs-check        164869144     342530190  pandoc-3.10.2/src/Text/Pandoc/Readers/Markdown.hs-check        222989200     447577790  pandoc-3.10.2/src/Text/Pandoc/Writers/Powerpoint/Output.hs-check        178219144     361706711  purescript-0.15.15/src/Language/PureScript/Errors.hs-check         88773224     186246171  purescript-0.15.15/src/Language/PureScript/TypeChecker/Types.hs-check         84087680     185592218  recursion-schemes-5.2.3/src/Data/Functor/Foldable.hs-check         98129704     205010076  servant-server-0.20.3.0/src/Servant/Server/Internal.hs-check        103037600     205852438  swagger2-2.9.1/src/Data/Swagger/Internal.hs-check        104700064     193733706  text-2.1.4/tests/Tests/Properties/Folds.hs-check         62559504     129686156  time-1.16.0.1/test/main/Test/Format/ParseTime.hs-check         71026768     139004696  tls-2.4.3/Network/TLS/Extension.hs-check        341584848     787667598  unpacked-containers-0/src/Map/Internal.hs-check        448129968     861308134  vector-0.13.2.0/src/Data/Vector/Generic.hs-check         72654288     151625740  xmonad-0.18.1/src/XMonad/Operations.hs-decode        27001936      44723576  base-4.20.2.0-decode         6037648       7373905  bytestring-0.12.2.0-decode         9504912      12150537  containers-0.7-decode        43420720      56428241  ghc-internal-9.1003.0-decode        11465032      15574443  template-haskell-2.22.0.0-decode         6206680       6722861  text-2.1.3-format       585714216    1132097581  Agda-2.8.0/src/full/Agda/Syntax/Translation/ConcreteToAbstract.hs-format      4268801648    8215706409  QuickCheck-2.18.0.0/src/Test/QuickCheck/Arbitrary.hs-format       903988776    1715848497  ShellCheck-0.11.0/src/ShellCheck/Analytics.hs-format       357145072     586914529  aeson-2.3.1.0/src/Data/Aeson/KeyMap.hs-format       174816696     326120695  blaze-html-0.9.2.0/src/Text/Blaze/Html5/Attributes.hs-format       125166848     237762136  brittany-0.14.0.2/source/library/Language/Haskell/Brittany/Internal/Transformations/Alt.hs-format       181178648     342948784  distributed-process-0.7.8/src/Control/Distributed/Process/Node.hs-format       313098528     589185783  esqueleto-3.6.0.3/test/PostgreSQL/Test.hs-format      3393194280    6954000450  haxl-2.5.1.1/Haxl/Core/Monad.hs-format       504082456     960666098  idris-1.3.4/src/Idris/Elab/Term.hs-format      1416130080    2802504216  lens-5.3.6/src/Control/Lens/Wrapped.hs-format       463051392     807326375  lifted-base-0.2.3.12/Control/Exception/Lifted.hs-format       114862912     219768412  megaparsec-9.8.1/Text/Megaparsec/Internal.hs-format       152090416     277909846  optparse-applicative-0.19.0.0/tests/test.hs-format        54641464      96646205  pandoc-3.10.2/src/Text/Pandoc/Class/PandocPure.hs-format       376993600     717475372  pandoc-3.10.2/src/Text/Pandoc/Readers/Markdown.hs-format       464955472     876728022  pandoc-3.10.2/src/Text/Pandoc/Writers/Powerpoint/Output.hs-format       374179808     706887086  purescript-0.15.15/src/Language/PureScript/Errors.hs-format       157522504     292522941  purescript-0.15.15/src/Language/PureScript/TypeChecker/Types.hs-format       129205776     233199212  recursion-schemes-5.2.3/src/Data/Functor/Foldable.hs-format       172818000     323062459  servant-server-0.20.3.0/src/Servant/Server/Internal.hs-format       174783648     327330430  swagger2-2.9.1/src/Data/Swagger/Internal.hs-format       716385648    1505690911  synthetic/comments-format       130290424     266483756  synthetic/conditionals-format        75942320     111837572  synthetic/imports-format        99529016     207055043  synthetic/nesting-format       838934048    1650403409  text-2.1.4/src/Data/Text/Internal/Fusion/CaseMapping.hs-format       251223896     409088661  text-2.1.4/tests/Tests/Properties/Folds.hs-format       138891552     257772182  time-1.16.0.1/test/main/Test/Format/ParseTime.hs-format       139419512     262626146  tls-2.4.3/Network/TLS/Extension.hs-format      1012155416    1980797816  unordered-containers-0.2.21/Data/HashMap/Internal.hs-format       507741568     947272176  unpacked-containers-0/src/Map/Internal.hs-format       551670016    1042468240  vector-0.13.2.0/src/Data/Vector/Generic.hs-format       139272304     260498387  xmonad-0.18.1/src/XMonad/Operations.hs-recall         8851176      20620493  aeson-2.3.1.0-recall         5953760      14216861  conduit-1.3.6.1-recall         5407168      12260501  free-5.2-recall        14502904      42766044  lens-5.3.6-recall         5564520      13033858  megaparsec-9.8.1-recall         5891216      13516032  mtl-2.3.2-recall         5062032      12025312  optics-0.4.2.1-recall         5291120      12823256  pandoc-types-1.23.1.2-recall         6078088      13974670  semigroupoids-6.0.2-recall         6898696      15358696  servant-0.20.3.0-recall         8956408      18332091  text-2.1.4-recall         7805920      17845506  vector-0.13.2.0-resolve     1934880160    3452012967  aeson-2.3.1.0-resolve      542464296     969320825  conduit-1.3.6.1-resolve      561754720     998716408  free-5.2-resolve     3142664696    5507450217  lens-5.3.6-resolve      235724304     461395455  megaparsec-9.8.1-resolve      252811728     486168500  mtl-2.3.2-resolve       84982856     215535259  optics-0.4.2.1-resolve       97405360     228106463  pandoc-types-1.23.1.2-resolve      237916832     461574873  semigroupoids-6.0.2-resolve      248183728     503102068  servant-0.20.3.0-resolve     1224151032    2166708926  text-2.1.4-resolve     2505871344    4300748284  vector-0.13.2.0+check        272354648     575981358  Agda-2.8.0/src/full/Agda/Syntax/Translation/ConcreteToAbstract.hs+check        411823456     855523727  ShellCheck-0.11.0/src/ShellCheck/Analytics.hs+check        260526152     461063479  aeson-2.3.1.0/src/Data/Aeson/KeyMap.hs+check        196550504     511610069  blaze-html-0.9.2.0/src/Text/Blaze/Html5/Attributes.hs+check         63623696     127394098  brittany-0.14.0.2/source/library/Language/Haskell/Brittany/Internal/Transformations/Alt.hs+check         84949968     171830970  distributed-process-0.7.8/src/Control/Distributed/Process/Node.hs+check        127362696     266504214  esqueleto-3.6.0.3/test/PostgreSQL/Test.hs+check        506858784     923788756  haxl-2.5.1.1/Haxl/Core/Monad.hs+check        215891816     451467945  idris-1.3.4/src/Idris/Elab/Term.hs+check        333601000     572292120  lifted-base-0.2.3.12/Control/Exception/Lifted.hs+check         60171824     128139113  megaparsec-9.8.1/Text/Megaparsec/Internal.hs+check         81898560     173856514  optparse-applicative-0.19.0.0/tests/test.hs+check         51558504      90521497  pandoc-3.10.2/src/Text/Pandoc/Class/PandocPure.hs+check        160564576     336134147  pandoc-3.10.2/src/Text/Pandoc/Readers/Markdown.hs+check        217005264     438646778  pandoc-3.10.2/src/Text/Pandoc/Writers/Powerpoint/Output.hs+check        177263168     360271324  purescript-0.15.15/src/Language/PureScript/Errors.hs+check         86199456     182395610  purescript-0.15.15/src/Language/PureScript/TypeChecker/Types.hs+check         76944368     174894002  recursion-schemes-5.2.3/src/Data/Functor/Foldable.hs+check         90285488     193297667  servant-server-0.20.3.0/src/Servant/Server/Internal.hs+check         99785848     200988911  swagger2-2.9.1/src/Data/Swagger/Internal.hs+check        104406992     193276384  text-2.1.4/tests/Tests/Properties/Folds.hs+check         62082528     128971807  time-1.16.0.1/test/main/Test/Format/ParseTime.hs+check         69973984     137412179  tls-2.4.3/Network/TLS/Extension.hs+check        322427128     758963691  unpacked-containers-0/src/Map/Internal.hs+check        438419048     846475201  vector-0.13.2.0/src/Data/Vector/Generic.hs+check         70657680     148642078  xmonad-0.18.1/src/XMonad/Operations.hs+decode        25613816      43571594  base-4.20.2.0+decode         5830408       7145065  bytestring-0.12.2.0+decode         9126328      11777525  containers-0.7+decode        42252744      55499725  ghc-internal-9.1003.0+decode        11189560      15486875  template-haskell-2.22.0.0+decode         6097120       6605095  text-2.1.3+format       586993080    1135630753  Agda-2.8.0/src/full/Agda/Syntax/Translation/ConcreteToAbstract.hs+format      4059772616    8036874388  QuickCheck-2.18.0.0/src/Test/QuickCheck/Arbitrary.hs+format       907373856    1723990920  ShellCheck-0.11.0/src/ShellCheck/Analytics.hs+format       330306320     571456793  aeson-2.3.1.0/src/Data/Aeson/KeyMap.hs+format       174818320     326282752  blaze-html-0.9.2.0/src/Text/Blaze/Html5/Attributes.hs+format       125893136     239428886  brittany-0.14.0.2/source/library/Language/Haskell/Brittany/Internal/Transformations/Alt.hs+format       181975648     344891996  distributed-process-0.7.8/src/Control/Distributed/Process/Node.hs+format       313302256     590497159  esqueleto-3.6.0.3/test/PostgreSQL/Test.hs+format       772624688    1542323569  haxl-2.5.1.1/Haxl/Core/Monad.hs+format       505622568     964281131  idris-1.3.4/src/Idris/Elab/Term.hs+format      1340529160    2711040392  lens-5.3.6/src/Control/Lens/Wrapped.hs+format       403478464     737112328  lifted-base-0.2.3.12/Control/Exception/Lifted.hs+format       115314000     221071613  megaparsec-9.8.1/Text/Megaparsec/Internal.hs+format       152138968     278467498  optparse-applicative-0.19.0.0/tests/test.hs+format        54506128      96618849  pandoc-3.10.2/src/Text/Pandoc/Class/PandocPure.hs+format       377550600     719032510  pandoc-3.10.2/src/Text/Pandoc/Readers/Markdown.hs+format       466875216     881659030  pandoc-3.10.2/src/Text/Pandoc/Writers/Powerpoint/Output.hs+format       374789216     709072870  purescript-0.15.15/src/Language/PureScript/Errors.hs+format       157590744     293012445  purescript-0.15.15/src/Language/PureScript/TypeChecker/Types.hs+format       129266384     233552107  recursion-schemes-5.2.3/src/Data/Functor/Foldable.hs+format       173044184     323789142  servant-server-0.20.3.0/src/Servant/Server/Internal.hs+format       174955608     327851739  swagger2-2.9.1/src/Data/Swagger/Internal.hs+format       716397560    1506784284  synthetic/comments+format       107750736     237375293  synthetic/conditionals+format        75942320     112110399  synthetic/imports+format        99934472     207607344  synthetic/nesting+format       838934536    1651811978  text-2.1.4/src/Data/Text/Internal/Fusion/CaseMapping.hs+format       223463632     390867496  text-2.1.4/tests/Tests/Properties/Folds.hs+format       139006432     258150558  time-1.16.0.1/test/main/Test/Format/ParseTime.hs+format       139530880     263037198  tls-2.4.3/Network/TLS/Extension.hs+format      1012732608    1984898669  unordered-containers-0.2.21/Data/HashMap/Internal.hs+format       509614800     951730877  unpacked-containers-0/src/Map/Internal.hs+format       551766528    1043391813  vector-0.13.2.0/src/Data/Vector/Generic.hs+format       139402192     260910396  xmonad-0.18.1/src/XMonad/Operations.hs+recall         5159192      11629716  aeson-2.3.1.0+recall         2222736       5117209  conduit-1.3.6.1+recall         1711296       3256971  free-5.2+recall        11087912      34729465  lens-5.3.6+recall         1794808       3797182  megaparsec-9.8.1+recall         2130864       4316158  mtl-2.3.2+recall         1290456       2773511  optics-0.4.2.1+recall         1533048       3627916  pandoc-types-1.23.1.2+recall         2303032       4716532  semigroupoids-6.0.2+recall         3296464       6712375  servant-0.20.3.0+recall         5195216       9137639  text-2.1.4+recall         4064960       8696024  vector-0.13.2.0+resolve     1871048824    3295554158  aeson-2.3.1.0+resolve      444504256     757669620  conduit-1.3.6.1+resolve      487648992     826960067  free-5.2+resolve     3076558528    5353588555  lens-5.3.6+resolve      216507192     378740037  megaparsec-9.8.1+resolve      233565064     403415365  mtl-2.3.2+resolve       65725248     132703282  optics-0.4.2.1+resolve       78157216     145313962  pandoc-types-1.23.1.2+resolve      138235048     248322418  semigroupoids-6.0.2+resolve      219372680     404689330  servant-0.20.3.0+resolve     1185759448    2051011736  text-2.1.4+resolve     2471261160    4205683979  vector-0.13.2.0
corpora/hackage/hackage.manifest view
@@ -57,7 +57,7 @@ formatted       3170eb1921b4  Agda-2.8.0/src/full/Agda/Interaction/Highlighting/Common.hs formatted       1fb0462a1b45  Agda-2.8.0/src/full/Agda/Interaction/Highlighting/Dot.hs formatted       712b081948e2  Agda-2.8.0/src/full/Agda/Interaction/Highlighting/Dot/Backend.hs-formatted       c6bb09f6d106  Agda-2.8.0/src/full/Agda/Interaction/Highlighting/Dot/Base.hs+formatted       fffa70657044  Agda-2.8.0/src/full/Agda/Interaction/Highlighting/Dot/Base.hs formatted       773365a6b3e4  Agda-2.8.0/src/full/Agda/Interaction/Highlighting/Emacs.hs formatted       4f4d736f1b38  Agda-2.8.0/src/full/Agda/Interaction/Highlighting/FromAbstract.hs formatted       5731f6a6b8ee  Agda-2.8.0/src/full/Agda/Interaction/Highlighting/Generate.hs@@ -230,7 +230,7 @@ formatted       ae0893a4561e  Agda-2.8.0/src/full/Agda/TypeChecking/LevelConstraints.hs formatted       07c423dfa0e3  Agda-2.8.0/src/full/Agda/TypeChecking/Lock.hs formatted       00b8f5e75aa7  Agda-2.8.0/src/full/Agda/TypeChecking/Lock.hs-boot-formatted       97862a8dea84  Agda-2.8.0/src/full/Agda/TypeChecking/MetaVars.hs+formatted       b1629098648f  Agda-2.8.0/src/full/Agda/TypeChecking/MetaVars.hs formatted       52101179c5b2  Agda-2.8.0/src/full/Agda/TypeChecking/MetaVars.hs-boot formatted       e1fc76d1f4fb  Agda-2.8.0/src/full/Agda/TypeChecking/MetaVars/Mention.hs formatted       9825c48e7a9c  Agda-2.8.0/src/full/Agda/TypeChecking/MetaVars/Occurs.hs@@ -333,7 +333,7 @@ formatted       2fe7b7e43894  Agda-2.8.0/src/full/Agda/TypeChecking/Rules/Record.hs formatted       31facbc5e0fe  Agda-2.8.0/src/full/Agda/TypeChecking/Rules/Term.hs formatted       ccd5b1bd7f62  Agda-2.8.0/src/full/Agda/TypeChecking/Rules/Term.hs-boot-formatted       49e329be866f  Agda-2.8.0/src/full/Agda/TypeChecking/Serialise.hs+formatted       1750e7e26332  Agda-2.8.0/src/full/Agda/TypeChecking/Serialise.hs formatted       3c2ae59cbddd  Agda-2.8.0/src/full/Agda/TypeChecking/Serialise/Base.hs formatted       0b03fe8ecc8f  Agda-2.8.0/src/full/Agda/TypeChecking/Serialise/Instances.hs formatted       6c20bf188f6d  Agda-2.8.0/src/full/Agda/TypeChecking/Serialise/Instances/Abstract.hs@@ -462,7 +462,7 @@ formatted       598740b3d57c  QuickCheck-2.18.0.0/examples/Simple.hs partly-checked  9da7c6c96a36  QuickCheck-2.18.0.0/src/Test/QuickCheck.hs formatted       02ad02d885d3  QuickCheck-2.18.0.0/src/Test/QuickCheck/All.hs-partly-checked  beeaa8cce68d  QuickCheck-2.18.0.0/src/Test/QuickCheck/Arbitrary.hs+partly-checked  2c029612a111  QuickCheck-2.18.0.0/src/Test/QuickCheck/Arbitrary.hs formatted       b394fbd4debb  QuickCheck-2.18.0.0/src/Test/QuickCheck/Compat.hs partly-checked  06fafd04e06a  QuickCheck-2.18.0.0/src/Test/QuickCheck/Exception.hs formatted       24dc2fbcd085  QuickCheck-2.18.0.0/src/Test/QuickCheck/Features.hs@@ -586,7 +586,7 @@ formatted       a2e378d49eb8  aeson-2.3.1.0/tests/PropertyRTFunctors.hs formatted       d54279308532  aeson-2.3.1.0/tests/PropertyRoundTrip.hs formatted       5c1372b7a444  aeson-2.3.1.0/tests/PropertyTH.hs-formatted       816e57772780  aeson-2.3.1.0/tests/RFC8785.hs+formatted       5b4efaf27bc6  aeson-2.3.1.0/tests/RFC8785.hs formatted       378b97660503  aeson-2.3.1.0/tests/Regression/Issue1138.hs formatted       1cfcacdcaf11  aeson-2.3.1.0/tests/Regression/Issue351.hs formatted       f000e9c51f1a  aeson-2.3.1.0/tests/Regression/Issue571.hs@@ -735,7 +735,7 @@ formatted       09bf54b50d8a  aws-0.25.3/Aws/S3/Commands/GetObject.hs formatted       b2f36afa32e0  aws-0.25.3/Aws/S3/Commands/GetService.hs formatted       d6ff6d8b8056  aws-0.25.3/Aws/S3/Commands/HeadObject.hs-formatted       bc19177d1d47  aws-0.25.3/Aws/S3/Commands/Multipart.hs+formatted       342f7fc5f61d  aws-0.25.3/Aws/S3/Commands/Multipart.hs formatted       311a84a6ddb3  aws-0.25.3/Aws/S3/Commands/PutBucket.hs formatted       2428bf962e66  aws-0.25.3/Aws/S3/Commands/PutBucketVersioning.hs formatted       046379db06b2  aws-0.25.3/Aws/S3/Commands/PutObject.hs@@ -785,10 +785,10 @@ formatted       5886bbdd46c9  aws-0.25.3/tests/S3/Main.hs formatted       44336eea1e26  aws-0.25.3/tests/Sqs/Main.hs formatted       001f1d1eb163  aws-0.25.3/tests/Utils.hs-formatted       b1dc0288cc34  base64-bytestring-1.2.1.0/Data/ByteString/Base64.hs+formatted       10172e7983b9  base64-bytestring-1.2.1.0/Data/ByteString/Base64.hs formatted       8d1de483b9c4  base64-bytestring-1.2.1.0/Data/ByteString/Base64/Internal.hs formatted       dae9abac8bd0  base64-bytestring-1.2.1.0/Data/ByteString/Base64/Lazy.hs-formatted       3a5cbd3642e2  base64-bytestring-1.2.1.0/Data/ByteString/Base64/URL.hs+formatted       efdde917444c  base64-bytestring-1.2.1.0/Data/ByteString/Base64/URL.hs formatted       0d8bf6b77f56  base64-bytestring-1.2.1.0/Data/ByteString/Base64/URL/Lazy.hs formatted       e865ae48f11b  base64-bytestring-1.2.1.0/Setup.hs formatted       0328dc0c3c7c  base64-bytestring-1.2.1.0/benchmarks/BM.hs@@ -1093,9 +1093,9 @@ formatted       e25fa77a311d  brittany-0.14.0.2/data/Test252.hs formatted       2abc462210d7  brittany-0.14.0.2/data/Test253.hs formatted       3dab93bb6c11  brittany-0.14.0.2/data/Test254.hs-formatted       ded4f913ac25  brittany-0.14.0.2/data/Test255.hs-formatted       7072c13a95c7  brittany-0.14.0.2/data/Test256.hs-formatted       f79f249e0890  brittany-0.14.0.2/data/Test257.hs+formatted       f91c2de89707  brittany-0.14.0.2/data/Test255.hs+formatted       fc8afe1bc2d8  brittany-0.14.0.2/data/Test256.hs+formatted       4b1d0ac4424f  brittany-0.14.0.2/data/Test257.hs formatted       a9cbb8a905a0  brittany-0.14.0.2/data/Test258.hs formatted       7c0c18756066  brittany-0.14.0.2/data/Test259.hs formatted       a9993e322f84  brittany-0.14.0.2/data/Test26.hs@@ -1569,7 +1569,7 @@ formatted       bf88ceabad43  conduit-1.3.6.1/src/Data/Conduit.hs formatted       1a953cd53139  conduit-1.3.6.1/src/Data/Conduit/Combinators.hs formatted       f520242138c3  conduit-1.3.6.1/src/Data/Conduit/Combinators/Stream.hs-formatted       ba13516336bd  conduit-1.3.6.1/src/Data/Conduit/Combinators/Unqualified.hs+formatted       7d754c7349cf  conduit-1.3.6.1/src/Data/Conduit/Combinators/Unqualified.hs formatted       8e861a915c2f  conduit-1.3.6.1/src/Data/Conduit/Internal.hs formatted       c35f5a66accc  conduit-1.3.6.1/src/Data/Conduit/Internal/Conduit.hs formatted       bbfd28e5b98b  conduit-1.3.6.1/src/Data/Conduit/Internal/Fusion.hs@@ -1611,7 +1611,7 @@ formatted       741778047cc1  criterion-1.6.5.0/examples/GoodReadFile.hs formatted       e85b2e0c3354  criterion-1.6.5.0/examples/Judy.hs formatted       7d1ede331f1f  criterion-1.6.5.0/examples/Maps.hs-formatted       f396bcf9c829  criterion-1.6.5.0/examples/Overhead.hs+formatted       fbcb8025853e  criterion-1.6.5.0/examples/Overhead.hs formatted       3a50edf5477c  criterion-1.6.5.0/examples/Quotes.hs formatted       e88811d40513  criterion-1.6.5.0/tests/Cleanup.hs formatted       78253dc00e1a  criterion-1.6.5.0/tests/Properties.hs@@ -1897,10 +1897,10 @@ formatted       7db3ef49d34f  esqueleto-3.6.0.3/test/Common/Test.hs formatted       07d3054c5606  esqueleto-3.6.0.3/test/Common/Test/CTE.hs formatted       1f83d04692e3  esqueleto-3.6.0.3/test/Common/Test/Import.hs-formatted       2e16567983e5  esqueleto-3.6.0.3/test/Common/Test/Models.hs+formatted       c62efabf2305  esqueleto-3.6.0.3/test/Common/Test/Models.hs formatted       1e1af0ff65e2  esqueleto-3.6.0.3/test/Common/Test/Select.hs formatted       6c403a7dbfd3  esqueleto-3.6.0.3/test/MySQL/Test.hs-formatted       649022fe6ecf  esqueleto-3.6.0.3/test/PostgreSQL/MigrateJSON.hs+formatted       585ace4874f8  esqueleto-3.6.0.3/test/PostgreSQL/MigrateJSON.hs formatted       b9c4d713d02f  esqueleto-3.6.0.3/test/PostgreSQL/Test.hs formatted       0e0ef1763885  esqueleto-3.6.0.3/test/SQLite/Test.hs formatted       9c274d8e66c1  esqueleto-3.6.0.3/test/Spec.hs@@ -1964,7 +1964,7 @@ formatted       7ec6f093e0ca  fay-0.24.2.0/src/Fay/Exts/NoAnnotation.hs formatted       bd1f234d96c0  fay-0.24.2.0/src/Fay/Exts/Scoped.hs formatted       f7856f337bee  fay-0.24.2.0/src/Fay/FFI.hs-formatted       7dd89da8a466  fay-0.24.2.0/src/Fay/Runtime.hs+formatted       b21a6a7c7e2f  fay-0.24.2.0/src/Fay/Runtime.hs formatted       0ac5069cbf76  fay-0.24.2.0/src/Fay/Types.hs formatted       6654772d79a6  fay-0.24.2.0/src/Fay/Types/CompileError.hs formatted       4f7fdfee2a8f  fay-0.24.2.0/src/Fay/Types/CompileResult.hs@@ -2188,6 +2188,41 @@ formatted       6ea0b301c8c4  fay-0.24.2.0/tests/whereBind.hs formatted       62b7dd25b5c9  fay-0.24.2.0/tests/whereBind2.hs formatted       dd52de0acf94  fay-0.24.2.0/tests/whereBind3.hs+formatted       3842f9681941  flatparse-0.5.6.1/bench/Attoparsec.hs+formatted       b150292cdb35  flatparse-0.5.6.1/bench/Bench.hs+formatted       238be2e5d5b3  flatparse-0.5.6.1/bench/Common.hs+formatted       008c0e1a942c  flatparse-0.5.6.1/bench/FPBasic.hs+formatted       de5590d5ade3  flatparse-0.5.6.1/bench/FPStateful.hs+formatted       691876a14ba8  flatparse-0.5.6.1/bench/Megaparsec.hs+formatted       4e5c403e7a3b  flatparse-0.5.6.1/bench/Parsec.hs+formatted       767291fb667b  flatparse-0.5.6.1/bench/ReadInteger.hs+formatted       94b6d379ba91  flatparse-0.5.6.1/src/FlatParse/Basic.hs+formatted       162dda57b01e  flatparse-0.5.6.1/src/FlatParse/Basic/Addr.hs+formatted       e944703d9644  flatparse-0.5.6.1/src/FlatParse/Basic/Base.hs+formatted       2f38d187e067  flatparse-0.5.6.1/src/FlatParse/Basic/Bytes.hs+formatted       a10fb5a46059  flatparse-0.5.6.1/src/FlatParse/Basic/Integers.hs+formatted       6a3463af4ece  flatparse-0.5.6.1/src/FlatParse/Basic/Parser.hs+formatted       91f628bd7bbb  flatparse-0.5.6.1/src/FlatParse/Basic/Switch.hs+formatted       402aaa49becf  flatparse-0.5.6.1/src/FlatParse/Basic/Text.hs+formatted       fbb54c111b6d  flatparse-0.5.6.1/src/FlatParse/Common/Assorted.hs+formatted       3022f28f8121  flatparse-0.5.6.1/src/FlatParse/Common/GHCExts.hs+formatted       c0055f39a562  flatparse-0.5.6.1/src/FlatParse/Common/Numbers.hs+formatted       b9e95be8021e  flatparse-0.5.6.1/src/FlatParse/Common/Parser.hs+formatted       1b42e699bc93  flatparse-0.5.6.1/src/FlatParse/Common/Position.hs+formatted       10cb24214eea  flatparse-0.5.6.1/src/FlatParse/Common/Switch.hs+formatted       412fc97e8505  flatparse-0.5.6.1/src/FlatParse/Examples/BasicLambda/Lexer.hs+formatted       2c72cb96232c  flatparse-0.5.6.1/src/FlatParse/Examples/BasicLambda/Parser.hs+formatted       e5272a875046  flatparse-0.5.6.1/src/FlatParse/Minimal.hs+formatted       3f356742f6e5  flatparse-0.5.6.1/src/FlatParse/Minimal/Internal.hs+formatted       7ecd84a0c48e  flatparse-0.5.6.1/src/FlatParse/Stateful.hs+formatted       122b007be519  flatparse-0.5.6.1/src/FlatParse/Stateful/Addr.hs+formatted       bc3b9c3f288a  flatparse-0.5.6.1/src/FlatParse/Stateful/Base.hs+formatted       944f11f97db1  flatparse-0.5.6.1/src/FlatParse/Stateful/Bytes.hs+formatted       68018af3f1d4  flatparse-0.5.6.1/src/FlatParse/Stateful/Integers.hs+formatted       b48d8164beaa  flatparse-0.5.6.1/src/FlatParse/Stateful/Parser.hs+formatted       b1441b8d4e2e  flatparse-0.5.6.1/src/FlatParse/Stateful/Switch.hs+formatted       c4498f63da8b  flatparse-0.5.6.1/src/FlatParse/Stateful/Text.hs+formatted       1a4004f0ef57  flatparse-0.5.6.1/test/Test.hs formatted       b3d258de0403  free-5.2/examples/PerfTH.hs formatted       24418bc38fac  free-5.2/examples/RetryTH.hs formatted       7641743d0c1f  free-5.2/examples/ValidationForm.hs@@ -2331,7 +2366,7 @@ formatted       270cd401eb34  haxl-2.5.1.1/Haxl/Core/Fetch.hs formatted       b4afaa8d717d  haxl-2.5.1.1/Haxl/Core/Flags.hs formatted       6116af7c8eab  haxl-2.5.1.1/Haxl/Core/Memo.hs-formatted       331b6d94ce03  haxl-2.5.1.1/Haxl/Core/Monad.hs+formatted       7f70ce88402f  haxl-2.5.1.1/Haxl/Core/Monad.hs formatted       19ee0e1d26fe  haxl-2.5.1.1/Haxl/Core/Parallel.hs formatted       d03eb9460c3a  haxl-2.5.1.1/Haxl/Core/Profile.hs formatted       015cb76495fb  haxl-2.5.1.1/Haxl/Core/RequestStore.hs@@ -2490,7 +2525,7 @@ formatted       aab2b0975534  hlint-3.10/src/Hint/Import.hs formatted       7fa5ea0b1e9a  hlint-3.10/src/Hint/Lambda.hs formatted       272b8222175a  hlint-3.10/src/Hint/List.hs-formatted       8f1d0c686e2b  hlint-3.10/src/Hint/ListRec.hs+formatted       1601e1e0f2da  hlint-3.10/src/Hint/ListRec.hs formatted       3027b7686bbd  hlint-3.10/src/Hint/Match.hs formatted       7215f269ef89  hlint-3.10/src/Hint/Monad.hs formatted       4d078aac9ede  hlint-3.10/src/Hint/Naming.hs@@ -2502,7 +2537,7 @@ formatted       5dd8e1ba7821  hlint-3.10/src/Hint/Restrict.hs formatted       a55fbaad4a77  hlint-3.10/src/Hint/Smell.hs formatted       3308ee100b88  hlint-3.10/src/Hint/Type.hs-formatted       a7c7f90eb40c  hlint-3.10/src/Hint/Unsafe.hs+formatted       c433ccccd5d9  hlint-3.10/src/Hint/Unsafe.hs formatted       48cd04ad2e02  hlint-3.10/src/HsColour.hs formatted       dd9801a47942  hlint-3.10/src/Idea.hs formatted       576b754ba5d4  hlint-3.10/src/Language/Haskell/HLint.hs@@ -2529,7 +2564,7 @@ formatted       f5ded9eab569  hspec-core-2.11.17/src/Test/Hspec/Core/Config.hs formatted       b9ed2689f1a4  hspec-core-2.11.17/src/Test/Hspec/Core/Config/Definition.hs formatted       93914a41d318  hspec-core-2.11.17/src/Test/Hspec/Core/Config/Options.hs-formatted       38a2774bf309  hspec-core-2.11.17/src/Test/Hspec/Core/Example.hs+formatted       56fd96dcc2e6  hspec-core-2.11.17/src/Test/Hspec/Core/Example.hs formatted       78f6f2a2f383  hspec-core-2.11.17/src/Test/Hspec/Core/Example/Location.hs formatted       19c90134f072  hspec-core-2.11.17/src/Test/Hspec/Core/Extension.hs formatted       b5766e2580e3  hspec-core-2.11.17/src/Test/Hspec/Core/Extension/Config.hs@@ -2543,7 +2578,7 @@ formatted       b8b03afd38ee  hspec-core-2.11.17/src/Test/Hspec/Core/Formatters.hs formatted       0f6c87760ec2  hspec-core-2.11.17/src/Test/Hspec/Core/Formatters/Diff.hs formatted       337da9e04e1d  hspec-core-2.11.17/src/Test/Hspec/Core/Formatters/Internal.hs-formatted       463fbae99397  hspec-core-2.11.17/src/Test/Hspec/Core/Formatters/Pretty.hs+formatted       64062a11578e  hspec-core-2.11.17/src/Test/Hspec/Core/Formatters/Pretty.hs formatted       71e26cb11ffa  hspec-core-2.11.17/src/Test/Hspec/Core/Formatters/Pretty/Parser.hs formatted       07264fb33ca8  hspec-core-2.11.17/src/Test/Hspec/Core/Formatters/Pretty/Unicode.hs formatted       32564aeda195  hspec-core-2.11.17/src/Test/Hspec/Core/Formatters/V1.hs@@ -2558,7 +2593,7 @@ formatted       559e8587e33c  hspec-core-2.11.17/src/Test/Hspec/Core/Runner/Eval.hs formatted       45d877a0b59c  hspec-core-2.11.17/src/Test/Hspec/Core/Runner/JobQueue.hs formatted       486c3e882e3e  hspec-core-2.11.17/src/Test/Hspec/Core/Runner/PrintSlowSpecItems.hs-formatted       800cbdaf0858  hspec-core-2.11.17/src/Test/Hspec/Core/Runner/Result.hs+formatted       451fa815b3f7  hspec-core-2.11.17/src/Test/Hspec/Core/Runner/Result.hs formatted       d699e2b567f5  hspec-core-2.11.17/src/Test/Hspec/Core/Shuffle.hs formatted       929d1248e847  hspec-core-2.11.17/src/Test/Hspec/Core/Spec.hs formatted       0aaa70c4113f  hspec-core-2.11.17/src/Test/Hspec/Core/Spec/Monad.hs@@ -2594,7 +2629,7 @@ formatted       7eadb8336461  hspec-core-2.11.17/test/Test/Hspec/Core/Runner/JobQueueSpec.hs formatted       0d283fd19887  hspec-core-2.11.17/test/Test/Hspec/Core/Runner/PrintSlowSpecItemsSpec.hs formatted       2781ae88628b  hspec-core-2.11.17/test/Test/Hspec/Core/Runner/ResultSpec.hs-formatted       5c98171187e3  hspec-core-2.11.17/test/Test/Hspec/Core/RunnerSpec.hs+formatted       b677cdaeef95  hspec-core-2.11.17/test/Test/Hspec/Core/RunnerSpec.hs formatted       711af46b8809  hspec-core-2.11.17/test/Test/Hspec/Core/ShuffleSpec.hs formatted       109f785c9f28  hspec-core-2.11.17/test/Test/Hspec/Core/SpecSpec.hs formatted       ccd964421c9d  hspec-core-2.11.17/test/Test/Hspec/Core/TimerSpec.hs@@ -2690,7 +2725,7 @@ formatted       3b956c85cb93  idris-1.3.4/src/Idris/Core/Elaborate.hs formatted       d0216dc5a258  idris-1.3.4/src/Idris/Core/Evaluate.hs formatted       9e811f74925b  idris-1.3.4/src/Idris/Core/Execute.hs-formatted       823bce2a23e1  idris-1.3.4/src/Idris/Core/ProofState.hs+formatted       a0c632cd26d6  idris-1.3.4/src/Idris/Core/ProofState.hs formatted       0ccd6a932fe8  idris-1.3.4/src/Idris/Core/ProofTerm.hs formatted       cd52f6495e8c  idris-1.3.4/src/Idris/Core/TT.hs formatted       d6069959015f  idris-1.3.4/src/Idris/Core/Typecheck.hs@@ -2739,7 +2774,7 @@ formatted       05a01adec344  idris-1.3.4/src/Idris/Package.hs formatted       2a5fae85b8c9  idris-1.3.4/src/Idris/Package/Common.hs formatted       90885df148d3  idris-1.3.4/src/Idris/Package/Parser.hs-formatted       ab0906fb24a3  idris-1.3.4/src/Idris/Parser.hs+formatted       da68c807f135  idris-1.3.4/src/Idris/Parser.hs formatted       e4d16cf46f6b  idris-1.3.4/src/Idris/Parser/Data.hs formatted       56341a9cef2a  idris-1.3.4/src/Idris/Parser/Expr.hs formatted       de7138f89659  idris-1.3.4/src/Idris/Parser/Helpers.hs@@ -2768,8 +2803,8 @@ formatted       9df5a10ea1fd  idris-1.3.4/test/TestData.hs formatted       720af8681b46  idris-1.3.4/test/TestRun.hs formatted       e865ae48f11b  intero-0.1.40/Setup.hs-formatted       41797b039ec2  intero-0.1.40/src/Completion.hs-formatted       808924ac99ff  intero-0.1.40/src/GhciFind.hs+formatted       621065d3b05d  intero-0.1.40/src/Completion.hs+formatted       b0784cea4075  intero-0.1.40/src/GhciFind.hs partly-checked  c0aea4c4237d  intero-0.1.40/src/GhciInfo.hs formatted       e0fd727cd7cd  intero-0.1.40/src/GhciMonad.hs formatted       43c5576cb10f  intero-0.1.40/src/GhciTags.hs@@ -2829,11 +2864,11 @@ formatted       36523e19eb43  leksah-0.16.2.2/src/IDE/Pane/WebKit/Output.hs formatted       6d01b337aa2d  leksah-0.16.2.2/src/IDE/Pane/Workspace.hs formatted       9b92bdd95195  leksah-0.16.2.2/src/IDE/PaneGroups.hs-formatted       043a3ca4d21e  leksah-0.16.2.2/src/IDE/Preferences.hs+formatted       bc4a7202f565  leksah-0.16.2.2/src/IDE/Preferences.hs formatted       b428f06dc6a8  leksah-0.16.2.2/src/IDE/Session.hs formatted       8fd5bd558558  leksah-0.16.2.2/src/IDE/SourceCandy.hs formatted       402da8621309  leksah-0.16.2.2/src/IDE/Statusbar.hs-formatted       188c4e9a0936  leksah-0.16.2.2/src/IDE/SymbolNavigation.hs+formatted       3df2a9c1d21f  leksah-0.16.2.2/src/IDE/SymbolNavigation.hs formatted       265b135c829e  leksah-0.16.2.2/src/IDE/TextEditor.hs formatted       fc7e53f0e945  leksah-0.16.2.2/src/IDE/TextEditor/Class.hs formatted       1c4c5952013a  leksah-0.16.2.2/src/IDE/TextEditor/CodeMirror.hs@@ -3082,7 +3117,7 @@ formatted       76559347a97c  pandoc-3.10.2/src/Text/Pandoc/Citeproc/Util.hs formatted       1b13d0dc5e1b  pandoc-3.10.2/src/Text/Pandoc/Class.hs formatted       121629e38e36  pandoc-3.10.2/src/Text/Pandoc/Class/CommonState.hs-formatted       e2b41d9d63a2  pandoc-3.10.2/src/Text/Pandoc/Class/IO.hs+formatted       9c00e6af7063  pandoc-3.10.2/src/Text/Pandoc/Class/IO.hs formatted       554e3fd3f722  pandoc-3.10.2/src/Text/Pandoc/Class/PandocIO.hs formatted       c65acaaeb3de  pandoc-3.10.2/src/Text/Pandoc/Class/PandocMonad.hs formatted       af26c6ef7be1  pandoc-3.10.2/src/Text/Pandoc/Class/PandocPure.hs@@ -3478,7 +3513,7 @@ formatted       b776165f7ac3  persistent-2.18.1.0/test/Database/Persist/TH/MultiBlockSpec/Model.hs formatted       baa7f67273ec  persistent-2.18.1.0/test/Database/Persist/TH/NestedSymbolsInTypeSpec.hs formatted       f0e370f995e7  persistent-2.18.1.0/test/Database/Persist/TH/NestedSymbolsInTypeSpecImports.hs-formatted       148f97b27fd9  persistent-2.18.1.0/test/Database/Persist/TH/NoFieldSelectorsSpec.hs+formatted       a12885a494b5  persistent-2.18.1.0/test/Database/Persist/TH/NoFieldSelectorsSpec.hs formatted       e227905a242e  persistent-2.18.1.0/test/Database/Persist/TH/OverloadedLabelSpec.hs formatted       ad712bcac46e  persistent-2.18.1.0/test/Database/Persist/TH/PersistWith/Model.hs formatted       8d58beb8b33c  persistent-2.18.1.0/test/Database/Persist/TH/PersistWith/Model2.hs@@ -3510,13 +3545,13 @@ formatted       04688f64c4e1  postgrest-9.0.1/src/PostgREST/Auth.hs formatted       0abbe3feaa05  postgrest-9.0.1/src/PostgREST/CLI.hs formatted       1b3df3371712  postgrest-9.0.1/src/PostgREST/Config.hs-formatted       26e0ccfa04f8  postgrest-9.0.1/src/PostgREST/Config/Database.hs+formatted       9796d49489e0  postgrest-9.0.1/src/PostgREST/Config/Database.hs formatted       9632241317fd  postgrest-9.0.1/src/PostgREST/Config/JSPath.hs formatted       b719e278251b  postgrest-9.0.1/src/PostgREST/Config/PgVersion.hs formatted       6c2ca99e2760  postgrest-9.0.1/src/PostgREST/Config/Proxy.hs formatted       65c66f863629  postgrest-9.0.1/src/PostgREST/ContentType.hs formatted       9200d4931d04  postgrest-9.0.1/src/PostgREST/Cors.hs-formatted       738b5e18a7a6  postgrest-9.0.1/src/PostgREST/DbStructure.hs+formatted       9961291af0c6  postgrest-9.0.1/src/PostgREST/DbStructure.hs formatted       a0f5c884d319  postgrest-9.0.1/src/PostgREST/DbStructure/Identifiers.hs formatted       29d8af69557a  postgrest-9.0.1/src/PostgREST/DbStructure/Proc.hs formatted       8670bffe5d4a  postgrest-9.0.1/src/PostgREST/DbStructure/Relationship.hs@@ -3527,7 +3562,7 @@ formatted       1dacd910468e  postgrest-9.0.1/src/PostgREST/Middleware.hs formatted       17654b363841  postgrest-9.0.1/src/PostgREST/OpenAPI.hs formatted       cdec9328f2d4  postgrest-9.0.1/src/PostgREST/Query/QueryBuilder.hs-formatted       9ac8d5c64df2  postgrest-9.0.1/src/PostgREST/Query/SqlFragment.hs+formatted       5f8a401dbb67  postgrest-9.0.1/src/PostgREST/Query/SqlFragment.hs formatted       5f4cbf20b7f3  postgrest-9.0.1/src/PostgREST/Query/Statements.hs formatted       7d83276a4311  postgrest-9.0.1/src/PostgREST/RangeQuery.hs formatted       4cecd3055b78  postgrest-9.0.1/src/PostgREST/Request/ApiRequest.hs@@ -3539,7 +3574,7 @@ formatted       793800bb054f  postgrest-9.0.1/src/PostgREST/Version.hs formatted       900b9c705574  postgrest-9.0.1/src/PostgREST/Workers.hs formatted       c719f882d27c  postgrest-9.0.1/test/doc/Main.hs-formatted       0aa4fe971d52  postgrest-9.0.1/test/spec/Feature/AndOrParamsSpec.hs+formatted       8293711c23f6  postgrest-9.0.1/test/spec/Feature/AndOrParamsSpec.hs formatted       ff8246e7adcd  postgrest-9.0.1/test/spec/Feature/AsymmetricJwtSpec.hs formatted       bac4b7907402  postgrest-9.0.1/test/spec/Feature/AudienceJwtSecretSpec.hs formatted       acbe9362314e  postgrest-9.0.1/test/spec/Feature/AuthSpec.hs@@ -3548,12 +3583,12 @@ formatted       db553e991f45  postgrest-9.0.1/test/spec/Feature/CorsSpec.hs formatted       343d3e3a465e  postgrest-9.0.1/test/spec/Feature/DeleteSpec.hs formatted       112082d3da25  postgrest-9.0.1/test/spec/Feature/DisabledOpenApiSpec.hs-formatted       ad7384965a9e  postgrest-9.0.1/test/spec/Feature/EmbedDisambiguationSpec.hs+formatted       42728b5ce4a4  postgrest-9.0.1/test/spec/Feature/EmbedDisambiguationSpec.hs formatted       f7a7ea3d2a87  postgrest-9.0.1/test/spec/Feature/EmbedInnerJoinSpec.hs formatted       a3dddabdb704  postgrest-9.0.1/test/spec/Feature/ExtraSearchPathSpec.hs formatted       ff20687cb475  postgrest-9.0.1/test/spec/Feature/HtmlRawOutputSpec.hs formatted       2e6a9474e718  postgrest-9.0.1/test/spec/Feature/IgnorePrivOpenApiSpec.hs-formatted       ea599ebfe99c  postgrest-9.0.1/test/spec/Feature/InsertSpec.hs+formatted       6fef53a41695  postgrest-9.0.1/test/spec/Feature/InsertSpec.hs formatted       6f6ff9c35189  postgrest-9.0.1/test/spec/Feature/JsonOperatorSpec.hs formatted       12271bc52ad6  postgrest-9.0.1/test/spec/Feature/LegacyGucsSpec.hs formatted       5228aaf9349c  postgrest-9.0.1/test/spec/Feature/MultipleSchemaSpec.hs@@ -3563,13 +3598,13 @@ formatted       1b9c2f6f5c75  postgrest-9.0.1/test/spec/Feature/OptionsSpec.hs formatted       89a1589ff0fe  postgrest-9.0.1/test/spec/Feature/ProxySpec.hs formatted       4e889783f9ba  postgrest-9.0.1/test/spec/Feature/QueryLimitedSpec.hs-formatted       343a60a46b7c  postgrest-9.0.1/test/spec/Feature/QuerySpec.hs+formatted       05c3032a3ad6  postgrest-9.0.1/test/spec/Feature/QuerySpec.hs formatted       06632a6a8e0a  postgrest-9.0.1/test/spec/Feature/RangeSpec.hs formatted       7cb746560127  postgrest-9.0.1/test/spec/Feature/RawOutputTypesSpec.hs formatted       b4a3ab5a81a9  postgrest-9.0.1/test/spec/Feature/RollbackSpec.hs formatted       dc5321d79fb3  postgrest-9.0.1/test/spec/Feature/RootSpec.hs formatted       77a649eeb2e6  postgrest-9.0.1/test/spec/Feature/RpcPreRequestGucsSpec.hs-formatted       79c99d7ebcf6  postgrest-9.0.1/test/spec/Feature/RpcSpec.hs+formatted       88cbb7230a8c  postgrest-9.0.1/test/spec/Feature/RpcSpec.hs formatted       73c0ab518a3d  postgrest-9.0.1/test/spec/Feature/SingularSpec.hs formatted       be03de84804f  postgrest-9.0.1/test/spec/Feature/UnicodeSpec.hs formatted       162dade8a566  postgrest-9.0.1/test/spec/Feature/UpdateSpec.hs@@ -4303,7 +4338,7 @@ formatted       8a25795f0c0a  stack-9.9.9/src/Stack/Config.hs formatted       db186c830bf3  stack-9.9.9/src/Stack/Constants.hs formatted       607b56eb6fc7  stack-9.9.9/src/Stack/Docker.hs-formatted       107229bac31d  stack-9.9.9/src/Stack/Docker/GlobalDB.hs+formatted       07449f4ddba3  stack-9.9.9/src/Stack/Docker/GlobalDB.hs formatted       7d15eaae39ff  stack-9.9.9/src/Stack/Dot.hs formatted       e3fe02818737  stack-9.9.9/src/Stack/Exec.hs formatted       69a1b5e114c2  stack-9.9.9/src/Stack/Fetch.hs@@ -4454,12 +4489,12 @@ formatted       59f835605e15  swagger2-2.9.1/src/Data/Swagger/Schema/Generator.hs formatted       7770e1fe2353  swagger2-2.9.1/src/Data/Swagger/Schema/Validation.hs formatted       2fd313eb8746  swagger2-2.9.1/src/Data/Swagger/SchemaOptions.hs-formatted       92d24f16cf77  swagger2-2.9.1/test/Data/Swagger/CommonTestTypes.hs+formatted       9054cc190971  swagger2-2.9.1/test/Data/Swagger/CommonTestTypes.hs formatted       88ae3e07f1d6  swagger2-2.9.1/test/Data/Swagger/ParamSchemaSpec.hs formatted       ba8d29dd4929  swagger2-2.9.1/test/Data/Swagger/Schema/GeneratorSpec.hs formatted       f1eacb0cba50  swagger2-2.9.1/test/Data/Swagger/Schema/ValidationSpec.hs formatted       bc07fee39679  swagger2-2.9.1/test/Data/Swagger/SchemaSpec.hs-formatted       b59e746b8895  swagger2-2.9.1/test/Data/SwaggerSpec.hs+formatted       be895fbebcab  swagger2-2.9.1/test/Data/SwaggerSpec.hs formatted       2fbd14b119a4  swagger2-2.9.1/test/Spec.hs formatted       1534dc51af48  swagger2-2.9.1/test/SpecCommon.hs formatted       cc17d35cb01d  swagger2-2.9.1/test/doctests.hs@@ -4539,14 +4574,14 @@ formatted       7580816061c0  text-2.1.4/src/Data/Text/Foreign.hs formatted       d26ae280631c  text-2.1.4/src/Data/Text/IO.hs formatted       8c24fec0de81  text-2.1.4/src/Data/Text/IO/Utf8.hs-formatted       653829dd073b  text-2.1.4/src/Data/Text/Internal.hs+formatted       abda1730fe53  text-2.1.4/src/Data/Text/Internal.hs formatted       48c631518261  text-2.1.4/src/Data/Text/Internal/ArrayUtils.hs formatted       bc619fb754b4  text-2.1.4/src/Data/Text/Internal/Builder.hs formatted       3a05c951a914  text-2.1.4/src/Data/Text/Internal/Builder/Functions.hs formatted       f5f871c975a4  text-2.1.4/src/Data/Text/Internal/Builder/Int/Digits.hs formatted       ab51e88834e1  text-2.1.4/src/Data/Text/Internal/Builder/RealFloat/Functions.hs formatted       7fa192160c9b  text-2.1.4/src/Data/Text/Internal/ByteStringCompat.hs-formatted       b4bfb3453a3f  text-2.1.4/src/Data/Text/Internal/Encoding.hs+formatted       4815054ed2f6  text-2.1.4/src/Data/Text/Internal/Encoding.hs formatted       43a1a670b3db  text-2.1.4/src/Data/Text/Internal/Encoding/Fusion.hs formatted       88e5c54a218b  text-2.1.4/src/Data/Text/Internal/Encoding/Fusion/Common.hs formatted       875961737225  text-2.1.4/src/Data/Text/Internal/Encoding/Utf16.hs@@ -5093,16 +5128,16 @@ formatted       f6f63b59cfb0  xmonad-0.18.1/tests/Properties/View.hs formatted       cd8d73c03759  xmonad-0.18.1/tests/Properties/Workspace.hs formatted       4e65334f7f2a  xmonad-0.18.1/tests/Utils.hs-formatted       d8adcc5e8871  yesod-core-1.7.0.0/bench/widget.hs+formatted       0ddb1fa8af3e  yesod-core-1.7.0.0/bench/widget.hs formatted       810a9b2932db  yesod-core-1.7.0.0/src/Yesod/Core.hs formatted       76a91abab9c7  yesod-core-1.7.0.0/src/Yesod/Core/Class/Breadcrumbs.hs formatted       d94322757109  yesod-core-1.7.0.0/src/Yesod/Core/Class/Dispatch.hs formatted       4e0e4c27884b  yesod-core-1.7.0.0/src/Yesod/Core/Class/Dispatch/ToParentRoute.hs formatted       96d18ec66a91  yesod-core-1.7.0.0/src/Yesod/Core/Class/Handler.hs-formatted       55ca7aed8601  yesod-core-1.7.0.0/src/Yesod/Core/Class/Yesod.hs+formatted       3b253a2dbaa1  yesod-core-1.7.0.0/src/Yesod/Core/Class/Yesod.hs formatted       7b7185683c72  yesod-core-1.7.0.0/src/Yesod/Core/Content.hs formatted       bc567e14f9ae  yesod-core-1.7.0.0/src/Yesod/Core/Dispatch.hs-formatted       dad160e4138f  yesod-core-1.7.0.0/src/Yesod/Core/Handler.hs+formatted       180c2fc8e3b6  yesod-core-1.7.0.0/src/Yesod/Core/Handler.hs formatted       88d4d8c2323a  yesod-core-1.7.0.0/src/Yesod/Core/Internal.hs formatted       212235b50682  yesod-core-1.7.0.0/src/Yesod/Core/Internal/LiteApp.hs formatted       b02eb40e75c3  yesod-core-1.7.0.0/src/Yesod/Core/Internal/Request.hs@@ -5136,11 +5171,11 @@ formatted       a739150f03f1  yesod-core-1.7.0.0/test/Hierarchy/Nest2.hs formatted       1998d7e7b6f0  yesod-core-1.7.0.0/test/Hierarchy/Nest2/NestInner.hs formatted       6e683051218c  yesod-core-1.7.0.0/test/Hierarchy/Nest3.hs-formatted       8f1d12dc181e  yesod-core-1.7.0.0/test/Hierarchy/ResourceTree.hs+formatted       929e2576fe48  yesod-core-1.7.0.0/test/Hierarchy/ResourceTree.hs formatted       f70ab72cd608  yesod-core-1.7.0.0/test/Route/DeepAritySpec.hs formatted       1a22181a9cf2  yesod-core-1.7.0.0/test/Route/DeepArityTypes.hs formatted       6cf89c893af0  yesod-core-1.7.0.0/test/Route/DiscoveryModeSpec.hs-formatted       8742e593c3d0  yesod-core-1.7.0.0/test/Route/FallthroughSpec.hs+formatted       ccb5ba6f357d  yesod-core-1.7.0.0/test/Route/FallthroughSpec.hs formatted       83547078da44  yesod-core-1.7.0.0/test/Route/FocusLeafConsSpec.hs formatted       b96279c392b7  yesod-core-1.7.0.0/test/Route/InlineParseClausesSpec.hs formatted       3a68d4c4db75  yesod-core-1.7.0.0/test/Route/InstanceProbeSpec.hs@@ -5149,98 +5184,98 @@ formatted       4ca53b8c21db  yesod-core-1.7.0.0/test/Route/MissingFocusTargetTypes.hs formatted       c4733044c565  yesod-core-1.7.0.0/test/Route/NestedParseClausesSpec.hs formatted       96c9db79de94  yesod-core-1.7.0.0/test/Route/PureQ.hs-formatted       1084d2ca990f  yesod-core-1.7.0.0/test/Route/RenderRouteSpec.hs-formatted       5cf00838dae7  yesod-core-1.7.0.0/test/Route/RouteAttrSpec.hs+formatted       2b6dc0f5b281  yesod-core-1.7.0.0/test/Route/RenderRouteSpec.hs+formatted       7c4edfc6aaf4  yesod-core-1.7.0.0/test/Route/RouteAttrSpec.hs formatted       9303c7a203b3  yesod-core-1.7.0.0/test/Route/SubDispatchAritySpec.hs-formatted       f355aa443a8a  yesod-core-1.7.0.0/test/RouteSpec.hs+formatted       9f64037d04f8  yesod-core-1.7.0.0/test/RouteSpec.hs formatted       186318ce7e7a  yesod-core-1.7.0.0/test/YesodCoreTest.hs-formatted       f0034c742a78  yesod-core-1.7.0.0/test/YesodCoreTest/Auth.hs-formatted       3a700bfeb45e  yesod-core-1.7.0.0/test/YesodCoreTest/BangSeparatorRuntime.hs+formatted       3b947e4eb93d  yesod-core-1.7.0.0/test/YesodCoreTest/Auth.hs+formatted       6642299a9e79  yesod-core-1.7.0.0/test/YesodCoreTest/BangSeparatorRuntime.hs formatted       e22fa3279a0b  yesod-core-1.7.0.0/test/YesodCoreTest/Breadcrumb.hs-formatted       3380dd13fc46  yesod-core-1.7.0.0/test/YesodCoreTest/Cache.hs-formatted       01cab2974794  yesod-core-1.7.0.0/test/YesodCoreTest/CleanPath.hs+formatted       d238709329bc  yesod-core-1.7.0.0/test/YesodCoreTest/Cache.hs+formatted       bc94d0ffbb1b  yesod-core-1.7.0.0/test/YesodCoreTest/CleanPath.hs formatted       36a004c6a4e3  yesod-core-1.7.0.0/test/YesodCoreTest/Content.hs-formatted       25b4b6405959  yesod-core-1.7.0.0/test/YesodCoreTest/Csrf.hs-formatted       b5d6ec2cfe62  yesod-core-1.7.0.0/test/YesodCoreTest/ErrorHandling.hs-formatted       d369eb73b47a  yesod-core-1.7.0.0/test/YesodCoreTest/ErrorHandling/CustomApp.hs-formatted       59bcbb168336  yesod-core-1.7.0.0/test/YesodCoreTest/Exceptions.hs-formatted       82e178e31f61  yesod-core-1.7.0.0/test/YesodCoreTest/FallthroughDispatch/Resources.hs+formatted       c32367062763  yesod-core-1.7.0.0/test/YesodCoreTest/Csrf.hs+formatted       4cf415b23a2b  yesod-core-1.7.0.0/test/YesodCoreTest/ErrorHandling.hs+formatted       34f03e725295  yesod-core-1.7.0.0/test/YesodCoreTest/ErrorHandling/CustomApp.hs+formatted       7bf251212b4a  yesod-core-1.7.0.0/test/YesodCoreTest/Exceptions.hs+formatted       a4440e79281d  yesod-core-1.7.0.0/test/YesodCoreTest/FallthroughDispatch/Resources.hs formatted       e4f8f0ea3e72  yesod-core-1.7.0.0/test/YesodCoreTest/FallthroughDispatch/Runtime.hs formatted       4d5c1d9a3551  yesod-core-1.7.0.0/test/YesodCoreTest/FallthroughMatrix/FirstFoo.hs-formatted       bd497866625d  yesod-core-1.7.0.0/test/YesodCoreTest/FallthroughMatrix/Resources.hs+formatted       948b8bdc1c2f  yesod-core-1.7.0.0/test/YesodCoreTest/FallthroughMatrix/Resources.hs formatted       8c70739a50e7  yesod-core-1.7.0.0/test/YesodCoreTest/FallthroughMatrix/Runtime.hs formatted       69eb694028b1  yesod-core-1.7.0.0/test/YesodCoreTest/Header.hs formatted       58f029383018  yesod-core-1.7.0.0/test/YesodCoreTest/InternalRequest.hs-formatted       f7afe29ae117  yesod-core-1.7.0.0/test/YesodCoreTest/JsAttributes.hs-formatted       84646813873d  yesod-core-1.7.0.0/test/YesodCoreTest/JsLoader.hs-formatted       f8cdd188f370  yesod-core-1.7.0.0/test/YesodCoreTest/JsLoaderSites/Bottom.hs-formatted       bda9b1f5f2d2  yesod-core-1.7.0.0/test/YesodCoreTest/Json.hs-formatted       23181a127cee  yesod-core-1.7.0.0/test/YesodCoreTest/Links.hs+formatted       b9334b4bc3fb  yesod-core-1.7.0.0/test/YesodCoreTest/JsAttributes.hs+formatted       c0d239626dd9  yesod-core-1.7.0.0/test/YesodCoreTest/JsLoader.hs+formatted       21bf15831aa6  yesod-core-1.7.0.0/test/YesodCoreTest/JsLoaderSites/Bottom.hs+formatted       d5d77fa729fa  yesod-core-1.7.0.0/test/YesodCoreTest/Json.hs+formatted       2b74547d4334  yesod-core-1.7.0.0/test/YesodCoreTest/Links.hs formatted       ab54e89c96fb  yesod-core-1.7.0.0/test/YesodCoreTest/LiteApp.hs formatted       418e263ba672  yesod-core-1.7.0.0/test/YesodCoreTest/Media.hs-formatted       0078c3a7e79d  yesod-core-1.7.0.0/test/YesodCoreTest/MediaData.hs-formatted       46b0e2d1153d  yesod-core-1.7.0.0/test/YesodCoreTest/Meta.hs-formatted       d8beeb52123f  yesod-core-1.7.0.0/test/YesodCoreTest/MultiPieceNestedRuntime.hs+formatted       b7985ba8cf16  yesod-core-1.7.0.0/test/YesodCoreTest/MediaData.hs+formatted       2e1b831d2b2d  yesod-core-1.7.0.0/test/YesodCoreTest/Meta.hs+formatted       8bfcf819eb45  yesod-core-1.7.0.0/test/YesodCoreTest/MultiPieceNestedRuntime.hs formatted       fb29902bb9c5  yesod-core-1.7.0.0/test/YesodCoreTest/NestedDispatch/InnerR.hs formatted       4c9ceb4fb663  yesod-core-1.7.0.0/test/YesodCoreTest/NestedDispatch/NestR.hs formatted       4aed48f429ab  yesod-core-1.7.0.0/test/YesodCoreTest/NestedDispatch/Parent0R.hs formatted       0f8ca6cd8fe6  yesod-core-1.7.0.0/test/YesodCoreTest/NestedDispatch/Parent0R/Child0R.hs formatted       762195ad3d8f  yesod-core-1.7.0.0/test/YesodCoreTest/NestedDispatch/ParentR.hs-formatted       7587ed701299  yesod-core-1.7.0.0/test/YesodCoreTest/NestedDispatch/Resources.hs+formatted       e8ef84185226  yesod-core-1.7.0.0/test/YesodCoreTest/NestedDispatch/Resources.hs formatted       a5347308f9b0  yesod-core-1.7.0.0/test/YesodCoreTest/NestedDispatch/Runtime.hs-formatted       2c72e04ebbc2  yesod-core-1.7.0.0/test/YesodCoreTest/NoOverloadedStrings.hs-formatted       320b6668f0c5  yesod-core-1.7.0.0/test/YesodCoreTest/NoOverloadedStringsSub.hs-formatted       ab80a9a09e84  yesod-core-1.7.0.0/test/YesodCoreTest/ParamDefaultSplit/Data.hs+formatted       14c0f6cfed84  yesod-core-1.7.0.0/test/YesodCoreTest/NoOverloadedStrings.hs+formatted       7624728d5d99  yesod-core-1.7.0.0/test/YesodCoreTest/NoOverloadedStringsSub.hs+formatted       982dc60b18aa  yesod-core-1.7.0.0/test/YesodCoreTest/ParamDefaultSplit/Data.hs formatted       a8472a7588f7  yesod-core-1.7.0.0/test/YesodCoreTest/ParamDefaultSplit/Runtime.hs formatted       3b1830a98315  yesod-core-1.7.0.0/test/YesodCoreTest/ParamFallthroughRuntime.hs-formatted       9191317f2178  yesod-core-1.7.0.0/test/YesodCoreTest/ParamFocusSplit/Resources.hs+formatted       93933a8e4c0d  yesod-core-1.7.0.0/test/YesodCoreTest/ParamFocusSplit/Resources.hs formatted       0d171db106f1  yesod-core-1.7.0.0/test/YesodCoreTest/ParamFocusSplit/Runtime.hs formatted       6f7510d0b57c  yesod-core-1.7.0.0/test/YesodCoreTest/ParamFocusSplit/SubR.hs formatted       46dbd15fa23d  yesod-core-1.7.0.0/test/YesodCoreTest/ParamNestedNoFallthroughRuntime.hs-formatted       32c5372b9148  yesod-core-1.7.0.0/test/YesodCoreTest/ParamNoExplicitArgs.hs+formatted       caf19758a717  yesod-core-1.7.0.0/test/YesodCoreTest/ParamNoExplicitArgs.hs formatted       30470908614f  yesod-core-1.7.0.0/test/YesodCoreTest/ParamNoFallthroughRuntime.hs formatted       cf6ee78ba4ee  yesod-core-1.7.0.0/test/YesodCoreTest/ParamSubsite/Data.hs-formatted       e0dfb958d109  yesod-core-1.7.0.0/test/YesodCoreTest/ParamSubsite/InstanceRuntime.hs+formatted       179fb9bca0b8  yesod-core-1.7.0.0/test/YesodCoreTest/ParamSubsite/InstanceRuntime.hs formatted       3597a9c3f0b7  yesod-core-1.7.0.0/test/YesodCoreTest/ParamSubsite/SplitNested.hs-formatted       f8d1220c3bf2  yesod-core-1.7.0.0/test/YesodCoreTest/ParamSubsite/SplitRuntime.hs-formatted       1981b86c26db  yesod-core-1.7.0.0/test/YesodCoreTest/ParamTopLevelRuntime.hs+formatted       98d7865bd49f  yesod-core-1.7.0.0/test/YesodCoreTest/ParamSubsite/SplitRuntime.hs+formatted       eb2add72057d  yesod-core-1.7.0.0/test/YesodCoreTest/ParamTopLevelRuntime.hs formatted       f991cd7adeb7  yesod-core-1.7.0.0/test/YesodCoreTest/ParameterizedSite.hs-formatted       0476a7be2abf  yesod-core-1.7.0.0/test/YesodCoreTest/ParameterizedSite/Compat.hs-formatted       b2b143cf4a47  yesod-core-1.7.0.0/test/YesodCoreTest/ParameterizedSite/PolyAny.hs-formatted       eb56902b1432  yesod-core-1.7.0.0/test/YesodCoreTest/ParameterizedSite/PolyShow.hs-formatted       acaebbfebc7a  yesod-core-1.7.0.0/test/YesodCoreTest/ParameterizedSite/SubRoute.hs-formatted       48e797fc7ef7  yesod-core-1.7.0.0/test/YesodCoreTest/ParameterizedSubData.hs+formatted       fa83ece3173f  yesod-core-1.7.0.0/test/YesodCoreTest/ParameterizedSite/Compat.hs+formatted       e39ccad26de5  yesod-core-1.7.0.0/test/YesodCoreTest/ParameterizedSite/PolyAny.hs+formatted       9fd56f7011c4  yesod-core-1.7.0.0/test/YesodCoreTest/ParameterizedSite/PolyShow.hs+formatted       c9b7c8d2f647  yesod-core-1.7.0.0/test/YesodCoreTest/ParameterizedSite/SubRoute.hs+formatted       0295cf17281c  yesod-core-1.7.0.0/test/YesodCoreTest/ParameterizedSubData.hs formatted       18a74bf9331c  yesod-core-1.7.0.0/test/YesodCoreTest/ParameterizedSubDispatch.hs-formatted       eb2ad79d2f60  yesod-core-1.7.0.0/test/YesodCoreTest/ParameterizedSubDispatch/Data.hs-formatted       c0c9e30ebea8  yesod-core-1.7.0.0/test/YesodCoreTest/ParameterizedSubDispatchRuntime.hs-formatted       09c5b840c977  yesod-core-1.7.0.0/test/YesodCoreTest/ParameterizedSubDispatchRuntime/Data.hs-formatted       4555e2245690  yesod-core-1.7.0.0/test/YesodCoreTest/RawResponse.hs-formatted       03a668e5cea8  yesod-core-1.7.0.0/test/YesodCoreTest/Redirect.hs+formatted       235413c6bdea  yesod-core-1.7.0.0/test/YesodCoreTest/ParameterizedSubDispatch/Data.hs+formatted       611119a277d4  yesod-core-1.7.0.0/test/YesodCoreTest/ParameterizedSubDispatchRuntime.hs+formatted       5ce3614534ad  yesod-core-1.7.0.0/test/YesodCoreTest/ParameterizedSubDispatchRuntime/Data.hs+formatted       30f807016614  yesod-core-1.7.0.0/test/YesodCoreTest/RawResponse.hs+formatted       4cc4d0ea318e  yesod-core-1.7.0.0/test/YesodCoreTest/Redirect.hs formatted       ddda63d607db  yesod-core-1.7.0.0/test/YesodCoreTest/RenderRouteSpec.hs formatted       139e78486aea  yesod-core-1.7.0.0/test/YesodCoreTest/RenderRouteSpec/TH.hs-formatted       1db9d98dbf8c  yesod-core-1.7.0.0/test/YesodCoreTest/Reps.hs-formatted       e18610f848a2  yesod-core-1.7.0.0/test/YesodCoreTest/RequestBodySize.hs+formatted       18f4acb4f7f4  yesod-core-1.7.0.0/test/YesodCoreTest/Reps.hs+formatted       4f0780801c93  yesod-core-1.7.0.0/test/YesodCoreTest/RequestBodySize.hs formatted       bf72ad1f5d18  yesod-core-1.7.0.0/test/YesodCoreTest/RuntimeHarness.hs-formatted       e78bf62c9259  yesod-core-1.7.0.0/test/YesodCoreTest/SplitSubsite/Data.hs+formatted       a03f5bc57962  yesod-core-1.7.0.0/test/YesodCoreTest/SplitSubsite/Data.hs formatted       df70dd2651a7  yesod-core-1.7.0.0/test/YesodCoreTest/SplitSubsite/NestedR.hs-formatted       a55ad04cebf6  yesod-core-1.7.0.0/test/YesodCoreTest/SplitSubsite/Runtime.hs+formatted       6b2e0c152d09  yesod-core-1.7.0.0/test/YesodCoreTest/SplitSubsite/Runtime.hs formatted       a05df238a9e5  yesod-core-1.7.0.0/test/YesodCoreTest/Ssl.hs formatted       203d5f3df4f0  yesod-core-1.7.0.0/test/YesodCoreTest/Streaming.hs-formatted       4a163efbc574  yesod-core-1.7.0.0/test/YesodCoreTest/StubLaxSameSite.hs-formatted       5831f923349c  yesod-core-1.7.0.0/test/YesodCoreTest/StubSslOnly.hs-formatted       6510112ce4b4  yesod-core-1.7.0.0/test/YesodCoreTest/StubStrictSameSite.hs-formatted       9cb2274c1880  yesod-core-1.7.0.0/test/YesodCoreTest/StubUnsecured.hs-formatted       7b7f0025954e  yesod-core-1.7.0.0/test/YesodCoreTest/SubSub.hs-formatted       b9e29405eb1b  yesod-core-1.7.0.0/test/YesodCoreTest/SubSubData.hs-formatted       dbed829ecef5  yesod-core-1.7.0.0/test/YesodCoreTest/SubsiteFallthrough/Data.hs+formatted       1bb69ad8619d  yesod-core-1.7.0.0/test/YesodCoreTest/StubLaxSameSite.hs+formatted       4d3bca26a6db  yesod-core-1.7.0.0/test/YesodCoreTest/StubSslOnly.hs+formatted       71fb08d5eb96  yesod-core-1.7.0.0/test/YesodCoreTest/StubStrictSameSite.hs+formatted       7fea39a22dcb  yesod-core-1.7.0.0/test/YesodCoreTest/StubUnsecured.hs+formatted       65fb43f7be25  yesod-core-1.7.0.0/test/YesodCoreTest/SubSub.hs+formatted       51df86ac759c  yesod-core-1.7.0.0/test/YesodCoreTest/SubSubData.hs+formatted       7cd0e7170008  yesod-core-1.7.0.0/test/YesodCoreTest/SubsiteFallthrough/Data.hs formatted       d10fd62ff3f7  yesod-core-1.7.0.0/test/YesodCoreTest/SubsiteFallthrough/Nested.hs-formatted       d5e98e912280  yesod-core-1.7.0.0/test/YesodCoreTest/SubsiteFallthrough/Runtime.hs-formatted       fffa6b1eb3e9  yesod-core-1.7.0.0/test/YesodCoreTest/SubsiteOptsFallthrough/Data.hs-formatted       a30c02d77457  yesod-core-1.7.0.0/test/YesodCoreTest/SubsiteOptsFallthrough/Runtime.hs-formatted       ce40781b74ec  yesod-core-1.7.0.0/test/YesodCoreTest/WaiSubsite.hs-formatted       67eac096b1a7  yesod-core-1.7.0.0/test/YesodCoreTest/Widget.hs+formatted       3b18d5d17513  yesod-core-1.7.0.0/test/YesodCoreTest/SubsiteFallthrough/Runtime.hs+formatted       440f7a2f5da2  yesod-core-1.7.0.0/test/YesodCoreTest/SubsiteOptsFallthrough/Data.hs+formatted       9726650eef04  yesod-core-1.7.0.0/test/YesodCoreTest/SubsiteOptsFallthrough/Runtime.hs+formatted       f8c3fc7e4983  yesod-core-1.7.0.0/test/YesodCoreTest/WaiSubsite.hs+formatted       f7823af32c7d  yesod-core-1.7.0.0/test/YesodCoreTest/Widget.hs formatted       a3265609217d  yesod-core-1.7.0.0/test/YesodCoreTest/YesodTest.hs-formatted       4c3c5fb5bdaf  yesod-core-1.7.0.0/test/YesodCoreTest/ZeroPieceShadow/FallApp.hs-formatted       b332d1f4e633  yesod-core-1.7.0.0/test/YesodCoreTest/ZeroPieceShadow/ShadowApp.hs+formatted       84b97f6c84a6  yesod-core-1.7.0.0/test/YesodCoreTest/ZeroPieceShadow/FallApp.hs+formatted       655445cfd3a8  yesod-core-1.7.0.0/test/YesodCoreTest/ZeroPieceShadow/ShadowApp.hs formatted       829a6148e881  yesod-core-1.7.0.0/test/YesodCoreTest/ZeroPieceShadowRuntime.hs formatted       23bd2996a55a  yesod-core-1.7.0.0/test/test.hs
corpora/hackage/hackage.report view
@@ -1,6 +1,6 @@ Hackage modules that currently do not format cleanly. -5240 examples, 5188 formatted.+5275 examples, 5223 formatted.  ========================================================================== does-not-parse (1)
corpora/vendored/declaration/value/comment-across-a-separator-out.hs view
@@ -16,10 +16,11 @@       stop     _ -> go n --- Crossing a token in the middle of a construct is another matter: it--- neither leaves the construct nor lands in front of it.+-- A token in the middle of a construct is another matter: a comment after+-- it stays after it, neither leaving the construct nor landing in front of+-- it. inTheMiddle n =-  case n {- worth a look -} of+  case n of {- worth a look -}     0 -> stop     _ -> go n 
corpora/vendored/declaration/value/comment-across-a-separator.hs view
@@ -13,8 +13,9 @@       stop     _ -> go n --- Crossing a token in the middle of a construct is another matter: it--- neither leaves the construct nor lands in front of it.+-- A token in the middle of a construct is another matter: a comment after+-- it stays after it, neither leaving the construct nor landing in front of+-- it. inTheMiddle n =   case n of {- worth a look -}     0 -> stop
corpora/vendored/declaration/value/function/let-chain-out.hs view
@@ -14,3 +14,12 @@ -- Written all on one line, the chain stays on it. fire :: Int -> Int fire x = let a = x + 1 in let b = a * 2 in a + b++-- A let whose bindings take several lines chains the same way where its in+-- ends the last of them.+cool :: Int -> Int+cool x =+  let a = x + 1+      b = a * 2 in+  let c = a + b+   in c
corpora/vendored/declaration/value/function/let-chain.hs view
@@ -14,3 +14,12 @@ -- Written all on one line, the chain stays on it. fire :: Int -> Int fire x = let a = x + 1 in let b = a * 2 in a + b++-- A let whose bindings take several lines chains the same way where its in+-- ends the last of them.+cool :: Int -> Int+cool x =+  let a = x + 1+      b = a * 2 in+  let c = a + b in+  c
+ corpora/vendored/declaration/value/list-pattern-written-across-lines-in-a-guard-out.hs view
@@ -0,0 +1,23 @@+primitives :: [Maybe Int] -> Int+primitives args = case () of+  _+    | [ Just a,+        Just b+      ] <- args ->+        a + b+    | otherwise -> 0++hdlTemplate :: [Maybe Int] -> Int+hdlTemplate args+  | [ Just a,+      Just b+    ] <- args =+      a + b+  | otherwise = 0++fromArguments :: IO [Maybe Int] -> IO Int+fromArguments getArgs = do+  [ Just a,+    Just b+    ] <- getArgs+  pure (a + b)
+ corpora/vendored/declaration/value/list-pattern-written-across-lines-in-a-guard.hs view
@@ -0,0 +1,22 @@+primitives :: [Maybe Int] -> Int+primitives args = case () of+  _+    | [ Just a+      , Just b+      ] <- args+    -> a + b+    | otherwise -> 0++hdlTemplate :: [Maybe Int] -> Int+hdlTemplate args+  | [ Just a+    , Just b+    ] <- args = a + b+  | otherwise = 0++fromArguments :: IO [Maybe Int] -> IO Int+fromArguments getArgs = do+  [ Just a+    , Just b+    ] <- getArgs+  pure (a + b)
+ corpora/vendored/declaration/value/quasi-quotation-written-across-lines-out.hs view
@@ -0,0 +1,25 @@+{-# LANGUAGE QuasiQuotes #-}++exceptions :: [String] -> String+exceptions es = [i|+    Encountered one or more exceptions.+  |] <> concat es++unexpected :: Int -> Maybe String+unexpected sp = Just (render sp [i|+    Something went wrong.+  |] Nothing)++checked :: IO ()+checked = withMessage [i|+    Checking.+  |] $ do+  check+  report++check :: Int+check = 1+{-# ANN check (Prim [Verilog, VHDL] [i|+  BlackBox:+    name: check+  |]) #-}
+ corpora/vendored/declaration/value/quasi-quotation-written-across-lines.hs view
@@ -0,0 +1,25 @@+{-# LANGUAGE QuasiQuotes #-}++exceptions :: [String] -> String+exceptions es = [i|+    Encountered one or more exceptions.+  |] <> concat es++unexpected :: Int -> Maybe String+unexpected sp = Just (render sp [i|+    Something went wrong.+  |] Nothing)++checked :: IO ()+checked = withMessage [i|+    Checking.+  |] $ do+  check+  report++check :: Int+check = 1+{-# ANN check (Prim [Verilog, VHDL] [i|+  BlackBox:+    name: check+  |]) #-}
corpora/vendored/other/cpp/bind-statement-begun-in-each-branch-out.hs view
@@ -8,13 +8,11 @@   y <-     g       (h x)-      a-      b #else   y <-     k       (h x)+#endif       a       b-#endif   pure y
+ corpora/vendored/other/cpp/branch-continuing-the-line-before-out.hs view
@@ -0,0 +1,15 @@+{-# LANGUAGE CPP #-}++module Report.Flush (flush) where++flush :: Bool -> IO ()+flush verbose =+#if defined(TRACE)+  when verbose $+    do+      traceIO "flushing"+      hFlush stdout+#else+  when verbose $+    hFlush stdout+#endif
+ corpora/vendored/other/cpp/branch-continuing-the-line-before.hs view
@@ -0,0 +1,10 @@+{-# LANGUAGE CPP #-}++module Report.Flush (flush) where++flush :: Bool -> IO ()+flush verbose = when verbose $+#if defined(TRACE)+  do traceIO "flushing"+#endif+     hFlush stdout
+ corpora/vendored/other/cpp/case-head-in-each-branch-out.hs view
@@ -0,0 +1,25 @@+{-# LANGUAGE CPP #-}++module Data.Aeson.BetterErrors.Internal (key, keyMay) where++key :: Text -> Object -> Parse Value+key k obj = do+#if MIN_VERSION_aeson(2,0,0)+  case KeyMap.lookup (Key.fromText k) obj of+#else+  case HashMap.lookup k obj of+#endif+    Just v -> pure v+    Nothing -> missing k++keyMay :: Text -> Maybe Object -> Parse (Maybe Value)+keyMay k value = case value of+  Just obj ->+#if MIN_VERSION_aeson(2,0,0)+    case KeyMap.lookup (Key.fromText k) obj of+#else+    case HashMap.lookup k obj of+#endif+      Just v -> pure (Just v)+      Nothing -> pure Nothing+  Nothing -> pure Nothing
+ corpora/vendored/other/cpp/case-head-in-each-branch.hs view
@@ -0,0 +1,25 @@+{-# LANGUAGE CPP #-}++module Data.Aeson.BetterErrors.Internal (key, keyMay) where++key :: Text -> Object -> Parse Value+key k obj = do+#if MIN_VERSION_aeson(2,0,0)+  case KeyMap.lookup (Key.fromText k) obj of+#else+  case HashMap.lookup k obj of+#endif+    Just v -> pure v+    Nothing -> missing k++keyMay :: Text -> Maybe Object -> Parse (Maybe Value)+keyMay k value = case value of+  Just obj ->+#if MIN_VERSION_aeson(2,0,0)+    case KeyMap.lookup (Key.fromText k) obj of+#else+    case HashMap.lookup k obj of+#endif+      Just v -> pure (Just v)+      Nothing -> pure Nothing+  Nothing -> pure Nothing
+ corpora/vendored/other/cpp/case-of-after-a-conditional-out.hs view
@@ -0,0 +1,30 @@+{-# LANGUAGE CPP #-}++module Lookup (check, find) where++check :: IO ()+check = do+  case answer+#ifdef SECOND+    second of+#else+    first of+#endif+    _ -> pure ()++find :: IO ()+find = do+  case lookupModule+#if __GLASGOW_HASKELL__ >= 900+    unitState+#else+    flags+#endif+    (moduleName "Polysemy")+#if __GLASGOW_HASKELL__ >= 904+    NoQualifier of+#else+    Nothing of+#endif+    Found _ -> pure ()+    _ -> fail "not found"
+ corpora/vendored/other/cpp/case-of-after-a-conditional.hs view
@@ -0,0 +1,32 @@+{-# LANGUAGE CPP #-}++module Lookup (check, find) where++check :: IO ()+check = do+  case answer+#ifdef SECOND+    second+#else+    first+#endif+    of+    _ -> pure ()++find :: IO ()+find = do+  case lookupModule+#if __GLASGOW_HASKELL__ >= 900+    unitState+#else+    flags+#endif+    (moduleName "Polysemy")+#if __GLASGOW_HASKELL__ >= 904+    NoQualifier+#else+    Nothing+#endif+    of+    Found _ -> pure ()+    _ -> fail "not found"
+ corpora/vendored/other/cpp/code-finishing-what-each-branch-begins-out.hs view
@@ -0,0 +1,90 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE LambdaCase #-}++-- What follows a conditional finishes the construct each of its branches+-- begins, and stays after the conditional rather than going into each+-- branch.+module Session.Store where++import Control.Arrow ((>>>))+import Control.Monad (forM_)++-- Left-hand sides.+lookupKey :: Maybe (Int, Int) -> Int -> Int+#if MIN_VERSION_base(4,16,0)+lookupKey (Just (k, _)) d =+#else+lookupKey (Just (k, _)) _d =+#endif+  k + 1+lookupKey Nothing d = d++-- Alternatives of a case.+expiry :: Maybe (Int, Int) -> Int+expiry m = case m of+#if MIN_VERSION_base(4,16,0)+  Just (_, t) ->+#else+  Just (t, _) ->+#endif+    t * 60+  Nothing -> 0++-- Signatures.+#if MIN_VERSION_base(4,16,0)+store ::+  (Show k, Ord k) =>+#else+store ::+  (Show k) =>+#endif+  k -> String+store = show++-- Applications.+#if MIN_VERSION_base(4,16,0)+render k =+  pad+    4+#else+render k =+  pad+    4+    ' '+#endif+    (show k)++-- Blocks.+dump :: [Int] -> IO ()+dump ks = do+#if MIN_VERSION_base(4,16,0)+  forM_ ks $ \k -> do+#else+  forM_ (reverse ks) $ \k -> do+#endif+    print k+    print (k * 2)++-- The alternatives of a lambda case.+classify :: Int -> Int+#if MIN_VERSION_base(4,16,0)+classify =+  negate >>> abs >>> \case+#else+classify =+  abs >>> \case+#endif+    0 -> 1+    n -> n++-- The qualifiers of a list comprehension.+names :: [(Int, String)] -> [String]+#if MIN_VERSION_base(4,16,0)+names xs =+  [ show n ++ s+#else+names xs =+  [ s+#endif+  | (n, s) <- xs+  ]
+ corpora/vendored/other/cpp/code-finishing-what-each-branch-begins.hs view
@@ -0,0 +1,79 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE LambdaCase #-}++-- What follows a conditional finishes the construct each of its branches+-- begins, and stays after the conditional rather than going into each+-- branch.+module Session.Store where++import Control.Arrow ((>>>))+import Control.Monad (forM_)++-- Left-hand sides.+lookupKey :: Maybe (Int, Int) -> Int -> Int+#if MIN_VERSION_base(4,16,0)+lookupKey (Just (k, _)) d =+#else+lookupKey (Just (k, _)) _d =+#endif+  k + 1+lookupKey Nothing d = d++-- Alternatives of a case.+expiry :: Maybe (Int, Int) -> Int+expiry m = case m of+#if MIN_VERSION_base(4,16,0)+  Just (_, t) ->+#else+  Just (t, _) ->+#endif+    t * 60+  Nothing -> 0++-- Signatures.+#if MIN_VERSION_base(4,16,0)+store :: (Show k, Ord k)+#else+store :: Show k+#endif+  => k -> String+store = show++-- Applications.+#if MIN_VERSION_base(4,16,0)+render k = pad 4+#else+render k = pad 4 ' '+#endif+             (show k)++-- Blocks.+dump :: [Int] -> IO ()+dump ks = do+#if MIN_VERSION_base(4,16,0)+  forM_ ks $ \k -> do+#else+  forM_ (reverse ks) $ \k -> do+#endif+    print k+    print (k * 2)++-- The alternatives of a lambda case.+classify :: Int -> Int+#if MIN_VERSION_base(4,16,0)+classify = negate >>> abs >>> \ case+#else+classify = abs >>> \ case+#endif+  0 -> 1+  n -> n++-- The qualifiers of a list comprehension.+names :: [(Int, String)] -> [String]+#if MIN_VERSION_base(4,16,0)+names xs = [ show n ++ s+#else+names xs = [ s+#endif+           | (n, s) <- xs+           ]
+ corpora/vendored/other/cpp/comments-around-code-shared-after-a-conditional-out.hs view
@@ -0,0 +1,25 @@+{-# LANGUAGE CPP #-}++module Config.Load where++#if MIN_VERSION_base(4,16,0)+load (Just path) verbose = -- with a path+#else+load path verbose = -- without one+#endif+  -- before the body+  readConfig path verbose -- after the body+-- after the declaration++retry r =+#if MIN_VERSION_base(4,16,0)+  backoff+    r -- end of the first branch+#else+  backoff+    r+    2+#endif+    -- before the argument+    (limit r) -- trailing+    -- under the argument
+ corpora/vendored/other/cpp/comments-around-code-shared-after-a-conditional.hs view
@@ -0,0 +1,22 @@+{-# LANGUAGE CPP #-}++module Config.Load where++#if MIN_VERSION_base(4,16,0)+load (Just path) verbose = -- with a path+#else+load path verbose = -- without one+#endif+  -- before the body+  readConfig path verbose -- after the body+-- after the declaration++retry r =+#if MIN_VERSION_base(4,16,0)+  backoff r -- end of the first branch+#else+  backoff r 2+#endif+    -- before the argument+    (limit r) -- trailing+    -- under the argument
+ corpora/vendored/other/cpp/context-in-one-branch-out.hs view
@@ -0,0 +1,26 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE ExplicitForAll #-}++-- A context in one branch only, before a type written over several lines.+module Terminal.Trace where++import GHC.Stack (HasCallStack)++traceMessage ::+#ifdef WITH_CALLSTACK+  (HasCallStack) =>+#endif+  String ->+  [(String, Int)] ->+  IO ()+traceMessage message _pairs = putStrLn message++traceLevel ::+  forall a.+#ifdef WITH_CALLSTACK+  (HasCallStack) =>+#endif+  (Show a) =>+  a ->+  IO ()+traceLevel = print
+ corpora/vendored/other/cpp/context-in-one-branch.hs view
@@ -0,0 +1,26 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE ExplicitForAll #-}++-- A context in one branch only, before a type written over several lines.+module Terminal.Trace where++import GHC.Stack (HasCallStack)++traceMessage ::+#ifdef WITH_CALLSTACK+  HasCallStack =>+#endif+  String ->+  [(String, Int)] ->+  IO ()+traceMessage message _pairs = putStrLn message++traceLevel ::+  forall a.+#ifdef WITH_CALLSTACK+  HasCallStack =>+#endif+  Show a =>+  a ->+  IO ()+traceLevel = print
corpora/vendored/other/cpp/data-or-newtype-out.hs view
@@ -9,12 +9,11 @@ data Cell = Cell   { cellRef :: {-# UNPACK #-} !(IORef Char),     cellCount :: {-# UNPACK #-} !Int-  } #else newtype Cell = Cell   { cellRef :: IORef Char-  } #endif+  }  blank :: Char blank = ' '
+ corpora/vendored/other/cpp/guard-head-in-each-branch-out.hs view
@@ -0,0 +1,33 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE MagicHash #-}+{-# LANGUAGE UnboxedTuples #-}++module FlatParse.Common.Numbers (anyDigit, report) where++anyDigit :: Word# -> Addr# -> Result+anyDigit acc s = case indexWord8OffAddr# s 0# of+#if MIN_VERSION_base(4,16,0)+  w+    | 1# <- leWord8# (wordToWord8# 0x30##) w,+      1# <- leWord8# w (wordToWord8# 0x39##) -> case timesWord2# acc 10## of+#else+  w+    | 1# <- leWord# 0x30## w,+      1# <- leWord# w 0x39## -> case timesWord2# acc 10## of+#endif+        (# 0##, r #) -> OK r+        _ -> Overflow+  _ -> Fail++report :: Handle -> Status -> IO ()+report h status+#ifdef mingw32_HOST_OS+  | isFailure status = do+      hPutStrLn h "failed"+#else+  | isFailure status,+    colour = do+      hPutStrLn h "\ESC[31mfailed\ESC[0m"+#endif+      hFlush h+  | otherwise = pure ()
+ corpora/vendored/other/cpp/guard-head-in-each-branch.hs view
@@ -0,0 +1,34 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE MagicHash #-}+{-# LANGUAGE UnboxedTuples #-}++module FlatParse.Common.Numbers (anyDigit, report) where++anyDigit :: Word# -> Addr# -> Result+anyDigit acc s = case indexWord8OffAddr# s 0# of+#if MIN_VERSION_base(4,16,0)+    w | 1# <- leWord8# (wordToWord8# 0x30##) w+      , 1# <- leWord8# w (wordToWord8# 0x39##)+      -> case timesWord2# acc 10## of+#else+    w | 1# <- leWord# 0x30## w+      , 1# <- leWord# w 0x39##+      -> case timesWord2# acc 10## of+#endif+          (# 0##, r #) -> OK r+          _ -> Overflow+    _ -> Fail++report :: Handle -> Status -> IO ()+report h status+#ifdef mingw32_HOST_OS+  | isFailure status+  = do+      hPutStrLn h "failed"+#else+  | isFailure status, colour+  = do+      hPutStrLn h "\ESC[31mfailed\ESC[0m"+#endif+      hFlush h+  | otherwise = pure ()
+ corpora/vendored/other/cpp/haddock-after-a-conditional-holding-a-class-head-out.hs view
@@ -0,0 +1,17 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE TypeFamilies #-}++module Test.Example where++-- A method's Haddock and signature written once, after a conditional that+-- holds the head of the class in each branch.+class+#ifdef ENABLE_HOOK_ARGS+  Example e where+  type Arg e+#else+  Example e where+#endif++  -- | Evaluates an example.+  evaluate :: e -> IO Bool
+ corpora/vendored/other/cpp/haddock-after-a-conditional-holding-a-class-head.hs view
@@ -0,0 +1,15 @@+{-# LANGUAGE CPP #-}+{-# LANGUAGE TypeFamilies #-}++module Test.Example where++-- A method's Haddock and signature written once, after a conditional that+-- holds the head of the class in each branch.+#ifdef ENABLE_HOOK_ARGS+class Example e where+  type Arg e+#else+class Example e where+#endif+  -- | Evaluates an example.+  evaluate :: e -> IO Bool
+ corpora/vendored/other/cpp/let-chain-behind-a-conditional-out.hs view
@@ -0,0 +1,15 @@+{-# LANGUAGE CPP #-}++module Kiln.Batch (batch) where++-- The first let of a chain, written in each branch with in at the end of+-- its line, stays in each branch as written.+batch :: Int -> Int -> Int+batch x s =+#if defined(LARGE)+  let a = large x in+#else+  let a = small x in+#endif+  let b = s + a+   in scale b
+ corpora/vendored/other/cpp/let-chain-behind-a-conditional.hs view
@@ -0,0 +1,15 @@+{-# LANGUAGE CPP #-}++module Kiln.Batch (batch) where++-- The first let of a chain, written in each branch with in at the end of+-- its line, stays in each branch as written.+batch :: Int -> Int -> Int+batch x s =+#if defined(LARGE)+  let a = large x in+#else+  let a = small x in+#endif+  let b = s + a in+  scale b
+ corpora/vendored/other/cpp/list-items-behind-two-questions-out.hs view
@@ -0,0 +1,18 @@+{-# LANGUAGE CPP #-}++module Laws.Mod (laws) where++#ifdef MIN_VERSION_semirings+laws :: (Ring a) => Proxy a -> [Laws]+#else+laws :: Proxy a -> [Laws]+#endif+laws p =+  [ eqLaws p+#ifdef MIN_VERSION_semirings+    , ringLaws p+#endif+#ifdef MIN_VERSION_vector+    , primLaws p+#endif+  ]
+ corpora/vendored/other/cpp/list-items-behind-two-questions.hs view
@@ -0,0 +1,18 @@+{-# LANGUAGE CPP #-}++module Laws.Mod (laws) where++#ifdef MIN_VERSION_semirings+laws :: (Ring a) => Proxy a -> [Laws]+#else+laws :: Proxy a -> [Laws]+#endif+laws p =+  [ eqLaws p+#ifdef MIN_VERSION_semirings+  , ringLaws p+#endif+#ifdef MIN_VERSION_vector+  , primLaws p+#endif+  ]
corpora/vendored/other/cpp/method-moving-to-an-instance-of-its-own-out.hs view
@@ -11,10 +11,8 @@  #if MIN_VERSION_base(4,11,0) instance Semigroup Summary where-  Summary x1 x2 `mappend` Summary y1 y2 = Summary (x1 + y1) (x2 + y2)-#else-  Summary x1 x2 `mappend` Summary y1 y2 = Summary (x1 + y1) (x2 + y2) #endif+  Summary x1 x2 `mappend` Summary y1 y2 = Summary (x1 + y1) (x2 + y2)  isSuccess :: Summary -> Bool isSuccess (Summary _ failures) = failures == 0
+ corpora/vendored/other/cpp/question-asked-again-inside-a-declaration-out.hs view
@@ -0,0 +1,18 @@+{-# LANGUAGE CPP #-}++module Network.Client (connect) where++#if MIN_VERSION_network(3,0,0)+connect :: Socket -> SockAddr -> Int -> IO Connection+connect sock addr timeout = do+#else+connect :: Socket -> SockAddr -> IO Connection+connect sock addr = do+#endif+  handle <- socketToHandle sock ReadWriteMode+  peer <- getPeerName sock+#if MIN_VERSION_network(3,0,0)+  withTimeout timeout (open handle peer)+#else+  open handle peer+#endif
+ corpora/vendored/other/cpp/question-asked-again-inside-a-declaration.hs view
@@ -0,0 +1,18 @@+{-# LANGUAGE CPP #-}++module Network.Client (connect) where++#if MIN_VERSION_network(3,0,0)+connect :: Socket -> SockAddr -> Int -> IO Connection+connect sock addr timeout = do+#else+connect :: Socket -> SockAddr -> IO Connection+connect sock addr = do+#endif+  handle <- socketToHandle sock ReadWriteMode+  peer <- getPeerName sock+#if MIN_VERSION_network(3,0,0)+  withTimeout timeout (open handle peer)+#else+  open handle peer+#endif
+ corpora/vendored/other/cpp/record-field-begun-in-each-branch-out.hs view
@@ -0,0 +1,16 @@+{-# LANGUAGE CPP #-}++module Xeno.DOM (parse) where++parse :: Process+parse =+  Process+    {+#if MIN_VERSION_bytestring(0,11,0)+      openF = \(BS name_start name_len) -> do+#else+      openF = \(PS _ name_start name_len) -> do+#endif+        index <- readRef sizeRef+        write index name_start name_len+    }
+ corpora/vendored/other/cpp/record-field-begun-in-each-branch.hs view
@@ -0,0 +1,14 @@+{-# LANGUAGE CPP #-}++module Xeno.DOM (parse) where++parse :: Process+parse = Process {+#if MIN_VERSION_bytestring(0,11,0)+    openF = \(BS name_start name_len) -> do+#else+    openF = \(PS _ name_start name_len) -> do+#endif+      index <- readRef sizeRef+      write index name_start name_len+  }
+ corpora/vendored/other/cpp/record-fields-begun-in-each-branch-out.hs view
@@ -0,0 +1,34 @@+{-# LANGUAGE CPP #-}++module Xeno.DOM.Robust (parse) where++parse :: Process+parse =+  Process+    {+#if MIN_VERSION_bytestring(0,11,0)+      openF = \(BS name_start name_len) -> do+#else+      openF = \(PS _ name_start name_len) -> do+#endif+        index <- readRef sizeRef+        write index name_start name_len,+#if MIN_VERSION_bytestring(0,11,0)+      textF = \(BS text_start text_len) -> do+#else+      textF = \(PS _ text_start text_len) -> do+#endif+        write 0 text_start text_len,+#if MIN_VERSION_bytestring(0,11,0)+      closeF = \closeTag@(BS _ _) -> do+#else+      closeF = \closeTag@(PS s _ _) -> do+#endif+        parent <- readRef parentRef+#if MIN_VERSION_bytestring(0,11,0)+        let openTag = BS (plusForeignPtr offset0 parent) 0+#else+        let openTag = PS s (parent + offset0) 0+#endif+        pure (openTag == closeTag)+    }
+ corpora/vendored/other/cpp/record-fields-begun-in-each-branch.hs view
@@ -0,0 +1,32 @@+{-# LANGUAGE CPP #-}++module Xeno.DOM.Robust (parse) where++parse :: Process+parse = Process {+#if MIN_VERSION_bytestring(0,11,0)+    openF = \(BS name_start name_len) -> do+#else+    openF = \(PS _ name_start name_len) -> do+#endif+      index <- readRef sizeRef+      write index name_start name_len+#if MIN_VERSION_bytestring(0,11,0)+  , textF = \(BS text_start text_len) -> do+#else+  , textF = \(PS _ text_start text_len) -> do+#endif+      write 0 text_start text_len+#if MIN_VERSION_bytestring(0,11,0)+  , closeF = \closeTag@(BS _ _) -> do+#else+  , closeF = \closeTag@(PS s _ _) -> do+#endif+      parent <- readRef parentRef+#if MIN_VERSION_bytestring(0,11,0)+      let openTag = BS (plusForeignPtr offset0 parent) 0+#else+      let openTag = PS s (parent + offset0) 0+#endif+      pure (openTag == closeTag)+  }
src/Tilia/Cabal/Package.hs view
@@ -23,6 +23,7 @@   ) where +import Control.Concurrent.MVar (modifyMVar, newMVar) import Data.ByteString qualified as BS import Data.Generics.Schemes (listify) import Data.IORef@@ -111,17 +112,20 @@ type PackageReader = FilePath -> IO (Either PackageProblem [Extension])  -- | A 'PackageReader' that remembers what it has already worked out.-newPackageReader :: IO PackageReader-newPackageReader = do+newPackageReader ::+  -- | The compiler's version, where the build plan names it, which spares+  -- asking the compiler.+  Maybe Version ->+  IO PackageReader+newPackageReader planned = do   covering <- newIORef Map.empty   described <- newIORef Map.empty-  asked <- newIORef Nothing-  let compiler =-        readIORef asked >>= \case-          Just version -> pure version-          Nothing -> do-            version <- compilerVersion-            version <$ writeIORef asked (Just version)+  known <- newMVar (Just <$> planned)+  let compiler = modifyMVar known $ \case+        Just version -> pure (Just version, version)+        Nothing -> do+          version <- compilerVersion+          pure (Just version, version)   pure $ \path -> quietly (Left NoPackageFile) $ do     file <- canonicalizePath path     from <- startingDirectory file
src/Tilia/Cpp/Macros.hs view
@@ -21,49 +21,62 @@ import Data.Text (Text) import Data.Text qualified as T --- | What is known about macros.+-- | What is known about macros, either from a build plan or implied by the+-- answers a configuration gives its conditionals. data Macros = Macros-  { -- | The macros that take a version apart and compare it:-    -- @MIN_VERSION_containers@ and the like, each under the version the-    -- plan resolved that package to. @MIN_VERSION_GLASGOW_HASKELL@ is one-    -- of these, under the compiler's four-part version.-    macroVersions :: Map Text [Integer],-    -- | The macros that stand for a number, which is @__GLASGOW_HASKELL__@-    -- and its patch levels.-    macroNumbers :: Map Text Integer,-    -- | The macros known to be defined, though not to what.+  { -- | The versions from the build plan that @MIN_VERSION_@ macros compare+    -- with, by macro name, for packages the plan holds at one version only,+    -- and the compiler's version for @MIN_VERSION_GLASGOW_HASKELL@.+    macroExactVersions :: Map Text [Integer],+    -- | The numbers that @__GLASGOW_HASKELL__@ and its patch levels expand+    -- to, from the build plan.+    macroExactNumbers :: Map Text Integer,+    -- | The macros known to be defined as implied by the answers that reach+    -- a configuration.     macroDefined :: Set Text,-    -- | The macros known not to be defined, such as those of the compilers-    -- other than the one the plan is for, like @__MHS__@.+    -- | The macros known not to be defined: from the build plan, those of+    -- the compilers other than the one it is for, like @__MHS__@, and+    -- otherwise implied by the answers that reach a configuration.     macroUndefined :: Set Text,-    -- | The version, or number, each macro is known to reach, a number-    -- being a version of one part.-    macroAtLeast :: Map Text [Integer],-    -- | The version, or number, each macro is known to stay below.-    macroBelow :: Map Text [Integer]+    -- | Every package the build plan holds, at however many versions, as+    -- their version macros spell them: the @VERSION_@ and @MIN_VERSION_@+    -- macros of any other package are not defined. 'Nothing' without a+    -- build plan.+    macroPlannedPackages :: Maybe (Set Text),+    -- | Implied by answers, the version, or number, each macro is known to+    -- reach, a number being a version of one part.+    macroLowerBounds :: Map Text [Integer],+    -- | Implied by answers, the version, or number, each macro is known to+    -- stay below.+    macroUpperBounds :: Map Text [Integer]   }   deriving (Eq, Show)  instance Semigroup Macros where   a <> b =     Macros-      { macroVersions = macroVersions a <> macroVersions b,-        macroNumbers = macroNumbers a <> macroNumbers b,+      { macroExactVersions = macroExactVersions a <> macroExactVersions b,+        macroExactNumbers = macroExactNumbers a <> macroExactNumbers b,         macroDefined = macroDefined a <> macroDefined b,         macroUndefined = macroUndefined a <> macroUndefined b,-        macroAtLeast = Map.unionWith max (macroAtLeast a) (macroAtLeast b),-        macroBelow = Map.unionWith min (macroBelow a) (macroBelow b)+        macroPlannedPackages =+          macroPlannedPackages a <|> macroPlannedPackages b,+        macroLowerBounds =+          Map.unionWith max (macroLowerBounds a) (macroLowerBounds b),+        macroUpperBounds =+          Map.unionWith min (macroUpperBounds a) (macroUpperBounds b)       }  instance Monoid Macros where   mempty =     Macros-      { macroVersions = Map.empty,-        macroNumbers = Map.empty,+      { macroExactVersions = Map.empty,+        macroExactNumbers = Map.empty,         macroDefined = Set.empty,         macroUndefined = Set.empty,-        macroAtLeast = Map.empty,-        macroBelow = Map.empty+        macroPlannedPackages = Nothing,+        macroLowerBounds = Map.empty,+        macroUpperBounds = Map.empty       }  -- | Does a conditional's guard hold, where what is known settles it?@@ -83,26 +96,30 @@         | h -> mempty{macroDefined = Set.singleton n}         | otherwise -> mempty{macroUndefined = Set.singleton n}       Reaches n v-        | h -> mempty{macroAtLeast = Map.singleton n (trimmed v)}-        | otherwise -> mempty{macroBelow = Map.singleton n (trimmed v)}+        | h -> mempty{macroLowerBounds = Map.singleton n (trimmed v)}+        | otherwise -> mempty{macroUpperBounds = Map.singleton n (trimmed v)}       Macro n | h -> mempty{macroDefined = Set.singleton n}       _ -> mempty  -- | Whether a macro is defined, where that is known. isDefined :: Macros -> Text -> Maybe Bool isDefined macros n-  | Map.member n (macroVersions macros)-      || Map.member n (macroNumbers macros)+  | Map.member n (macroExactVersions macros)+      || Map.member n (macroExactNumbers macros)       || Set.member n (macroDefined macros) =       Just True   | Set.member n (macroUndefined macros) = Just False+  | Just held <- macroPlannedPackages macros,+    Just p <- T.stripPrefix "VERSION_" n <|> T.stripPrefix "MIN_VERSION_" n,+    Set.notMember p held =+      Just False   | otherwise = Nothing  -- | The number a macro stands for, where that is known. numberOf :: Macros -> Text -> Maybe Integer numberOf macros n = case isDefined macros n of   Just False -> Just 0-  _ -> Map.lookup n (macroNumbers macros)+  _ -> Map.lookup n (macroExactNumbers macros)  -- | Does a macro's version, or number, reach this one, where what is known -- settles it?@@ -110,13 +127,13 @@ reaches macros n wanted = case held of   Just v -> Just (trimmed v >= w)   Nothing-    | any (>= w) (Map.lookup n (macroAtLeast macros)) -> Just True-    | any (<= w) (Map.lookup n (macroBelow macros)) -> Just False+    | any (>= w) (Map.lookup n (macroLowerBounds macros)) -> Just True+    | any (<= w) (Map.lookup n (macroUpperBounds macros)) -> Just False     | otherwise -> Nothing   where     w = trimmed wanted     held =-      Map.lookup n (macroVersions macros) <|> (pure <$> numberOf macros n)+      Map.lookup n (macroExactVersions macros) <|> (pure <$> numberOf macros n)  -- | A version without the zeros at its end, which 'compare' orders as -- versions are ordered.
src/Tilia/Cpp/Merge.hs view
@@ -13,9 +13,12 @@ import Control.Monad (guard) import Data.Char (isSpace) import Data.Function (on)-import Data.List (groupBy, maximumBy, sortOn, stripPrefix, transpose, unsnoc)-import Data.Maybe (fromMaybe, listToMaybe, mapMaybe, maybeToList)+import Data.List (groupBy, maximumBy, minimumBy, sortOn, stripPrefix, transpose, unsnoc)+import Data.Maybe (fromMaybe, isJust, listToMaybe, mapMaybe, maybeToList)+import Data.Monoid (All (..), Any (..)) import Data.Ord (comparing)+import Data.Set (Set)+import Data.Set qualified as Set import Data.Text (Text) import Data.Text qualified as T import Tilia.Cpp.Directives (Guard (..), Varied (..), untouched)@@ -30,6 +33,7 @@     conditionalRange,     foldChildren,     layoutInside,+    mapChildren,     onlyBreaks,     onlySpacing,     printedFrom,@@ -40,14 +44,7 @@     wrap,   ) import Tilia.Source (Lines, lineAt)-import Tilia.Span-  ( Span,-    covers,-    meets,-    spanEndLine,-    spanStartColumn,-    spanStartLine,-  )+import Tilia.Span (Span (..), covers, endOf, endPoint, meets, startOf, startPoint)  -- | A conditional other than the one asked about that answering a question -- settles, for some answers at least.@@ -80,10 +77,12 @@ merge written conditionals guards varied settledOthers = go Broken   where     go _ [] = mempty-    go layout ds@(d : rest)-      | all (agree varied layout d) rest = d+    go layout ds@(d : _)+      | s : others <- spines,+        all (agreeAll varied layout s) others =+          d       | Just xs <- traverse only spines = alongside layout xs-      | otherwise = factored layout spines+      | otherwise = factored middle layout spines       where         spines = fmap (spineAt layout) ds @@ -92,8 +91,9 @@       | Just wds <- traverse unwrap xs,         Just w <- joint wds =           case (w, go (layoutInside layout w) (fmap snd wds)) of-            (WLocated _, DCppChoice{})-              | spans <- [s | (WLocated s, _) <- wds],+            (WLocated _, merged)+              | onlyChoice merged,+                spans <- [s | (WLocated s, _) <- wds],                 Just opened <- unwrapping layout spans xs ->                   opened             (WGroup l, DCppChoice{})@@ -131,19 +131,24 @@           Just (w, x) -> wrap w <$> openedAgainst inside (layoutInside l w) x           Nothing -> case spineAt l d of             parts@(_ : _ : _) ->-              Just . factored l $+              Just . factored middle l $                 [if k == inside then parts else [e] | (k, e) <- zip [0 ..] xs]             _ -> Nothing -    factored layout ss =-      let same = agree varied layout-          shared = foldl1 (lcs anchoring same) ss-          cut = fmap (segments (anchored same) shared) ss+    factored within layout ss =+      let same (x, _) (y, _) = agree varied layout x y+          common as bs =+            [ (x, is <> js)+            | ((x, is), (_, js)) <- lcs (anchoring . fst) same as bs+            ]+          shared = foldl1 common [zip s (pure <$> [0 :: Int ..]) | s <- ss]+          cut =+            [cutAt [is !! k | (_, is) <- shared] s | (k, s) <- zip [0 ..] ss]           stretches = transpose (fmap fst cut)           anchors = transpose (fmap snd cut)-       in mconcat (woven layout stretches (fmap (go layout) anchors))+       in mconcat (woven within layout stretches (fmap (go layout) anchors)) -    woven layout (s : ss) (c : cs)+    woven within layout (s : ss) (c : cs)       | all (maybe False ((== DSpace) . snd) . unsnoc) s,         Just r <- regionOf c,         spanStartLine r == spanEndLine r,@@ -154,12 +159,13 @@               ws               [(g, b <> gap <> c) | (g, b) <- bs]               (e <> gap <> c)-            : woven layout ss cs-      | otherwise = stretch : c : woven layout ss cs+            : woven within layout ss cs+      | otherwise = stretch : c : woven within layout ss cs       where-        stretch = foldMap (varying layout) (cutAtConditionals s)-    woven layout ss [] = fmap (foldMap (varying layout) . cutAtConditionals) ss-    woven _ [] _ = []+        stretch = foldMap (varying within layout) (cutAtConditionals s)+    woven within layout ss [] =+      fmap (foldMap (varying within layout) . cutAtConditionals) ss+    woven _ _ [] _ = []      -- A stretch the configurations disagree over, cut where one conditional     -- asking the question ends and the next begins, so that each comes out@@ -194,13 +200,13 @@           | otherwise = sortOn fst (o : os)         ascending os = and (zipWith (<=) os (drop 1 os)) -    varying layout ss =+    varying within layout ss =       let (opening, ss1) = sharedStart layout ss           (ss2, closing) = sharedEnd layout ss1           (lead, ss3, trail) = hoisted layout ss2        in mconcat opening             <> mconcat lead-            <> middle layout ss3+            <> within layout ss3             <> mconcat trail             <> mconcat closing @@ -225,13 +231,39 @@       | all (alike layout s) rest = mconcat s       | Just xs <- traverse only ss = go layout xs       | Just (c, tails) <- commaLed layout ss = c <> middle layout tails-      | Just merged <- alongsideHeads layout ss,-        weigh layout merged < weigh layout apart =-          merged-      | otherwise = apart+      | otherwise =+          minimumBy+            (comparing (weigh layout))+            (apart : maybeToList (alongsideHeads layout ss) <> byLines)       where         apart = choice (fmap (mconcat . commaFirst) ss)+        byLines+          | not (any continuing ss),+            not (null (foldr1 Set.intersection (foldMap writtenAt <$> ss))),+            (ls, cuts) <- unzip (fmap (linesOf layout) ss),+            or cuts =+              [factored whole layout ls]+          | otherwise = []+        continuing = \case+          x : xs+            | printsNothing x -> continuing xs+            | Just (_, y) <- unwrap x -> continuing (spine y <> xs)+            | otherwise -> x == DSpace+          [] -> False +    whole _ [] = mempty+    whole layout ss@(s : rest)+      | all (alike layout s) rest = mconcat s+      | Just splits <- traverse firstPart ss,+        not (any (\(_, x, _) -> onOneLine layout x) splits) =+          go layout [mconcat (spacing <> [x]) | (spacing, x, _) <- splits]+            <> whole layout [more | (_, _, more) <- splits]+      | otherwise = choice (fmap mconcat ss)++    firstPart parts = case break (not . blank) parts of+      (spacing, x : more) -> Just (spacing, x, more)+      _ -> Nothing+     commaFirst = \case       x : DBreak : rest | x == Doc.comma -> x : Doc.space : rest       xs -> xs@@ -275,7 +307,7 @@                 ( joined                     (glued (go layout heads))                     (middle layout tails)-                    (varying layout tails)+                    (varying middle layout tails)                 )         _ -> Nothing       where@@ -353,6 +385,9 @@      breaking = \case       DDeclarationsStart -> True+      DCat a b -> breaking a && breaking b+      DNest _ d -> not (printsNothing d) && breaking d+      DGroup _ d -> not (printsNothing d) && breaking d       d -> onlyBreaks d      choice ds@@ -386,34 +421,55 @@  -- | Would these two documents print the same, laid out like this? agree :: Varied -> Layout -> Doc -> Doc -> Bool-agree varied layout a b = alike (chunked (spineAt layout a)) (chunked (spineAt layout b))+agree varied layout a b+  | lone a, lone b = agreeOn varied layout a b+  | otherwise = agreeAll varied layout (spineAt layout a) (spineAt layout b)   where-    alike (Left s : xs) (Left t : ys) = s == t && alike xs ys-    alike (Right x : xs) (Right y : ys) = here x y && alike xs ys-    alike [] [] = True-    alike _ _ = False-    chunked ds =-      let (space, rest) = span onlySpacing ds-       in Left (spaceOf layout space) : case rest of-            [] -> []-            x : more -> Right x : chunked more-    inside x y = agree varied layout x y-    here x y = case (x, y) of-      (DLocated s x', DLocated t y') ->-        s == t-          && ( untouched varied (reach s x') && untouched varied (reach t y')-                 || inside x' y'-             )-      (DCppChoice ws bs x', DCppChoice ws' cs y') ->-        ws == ws'-          && length bs == length cs-          && and [g == h && inside p q | ((g, p), (h, q)) <- zip bs cs]-          && inside x' y'-      _ -> case (unwrap x, unwrap y) of-        (Just (w, x'), Just (v, y')) ->-          w == v && agree varied (layoutInside layout w) x' y'-        _ -> x == y+    lone = \case+      DCat{} -> False+      DVariant{} -> False+      d -> not (onlySpacing d) +-- | Would these two spines print the same, laid out like this?+agreeAll :: Varied -> Layout -> [Doc] -> [Doc] -> Bool+agreeAll varied layout xs ys =+  spaceOf layout space == spaceOf layout space' && case (rest, rest') of+    ([], []) -> True+    (x : more, y : more') ->+      agreeOn varied layout x y && agreeAll varied layout more more'+    _ -> False+  where+    (space, rest) = span onlySpacing xs+    (space', rest') = span onlySpacing ys++-- | Would these two elements of spines print the same, laid out like this?+agreeOn :: Varied -> Layout -> Doc -> Doc -> Bool+agreeOn varied layout x y = case (x, y) of+  (DLocated s x', DLocated t y') ->+    s == t+      && ( untouched varied (reach s x')+             && untouched varied (reach t y')+             && startPoint s /= endPoint s+             || inside x' y'+         )+  (DCppChoice ws bs x', DCppChoice ws' cs y') ->+    ws == ws'+      && length bs == length cs+      && and [g == h && inside p q | ((g, p), (h, q)) <- zip bs cs]+      && inside x' y'+  _ -> case (unwrap x, unwrap y) of+    (Just (w, x'), Just (v, y')) ->+      w == v && agree varied (layoutInside layout w) x' y'+    _ -> x == y+  where+    inside = agree varied layout++-- | Is this document one choice, in nothing but wrappers?+onlyChoice :: Doc -> Bool+onlyChoice = \case+  DCppChoice{} -> True+  d -> maybe False (onlyChoice . snd) (unwrap d)+ -- | Does this document, laid out flat, print a choice before anything else? beginsWithChoice :: Doc -> Bool beginsWithChoice d = case filter (not . onlySpacing) (spineAt Flat d) of@@ -602,23 +658,18 @@   [Doc] ->   [Doc] ->   [Change]-changesAgainst varied same bs xs = go 0 bs xs (lcs anchoring same bs xs)+changesAgainst varied same bs xs =+  go 0 0 bs xs (lcs held (same `on` snd) bs' xs')   where-    anchor = anchored same--    go i b x [] = between i b x-    go i b x (c : cs) =-      let (b', b'') = break (anchor c) b-          (x', x'') = break (anchor c) x-          j = i + length b'-       in between i b' x'-            <> held j (listToMaybe b'') (listToMaybe x'')-            <> go (j + 1) (drop 1 b'') (drop 1 x'') cs+    bs' = zip [0 ..] bs+    xs' = zip [0 ..] xs+    held = anchoring . snd -    held j (Just b') (Just x')-      | not (same b' x') =-          [Change{chFrom = j, chTo = j + 1, chWith = [x'], chVaried = varied}]-    held _ _ _ = []+    go i _ b x [] = between i b x+    go i j b x (((p, _), (q, _)) : cs) =+      let (b', b'') = splitAt (p - i) b+          (x', x'') = splitAt (q - j) x+       in between i b' x' <> go (p + 1) (q + 1) (drop 1 b'') (drop 1 x'') cs      between i b x =       [ Change@@ -705,6 +756,135 @@           (lineAt (spanStartLine s) written)       Nothing -> False +-- | The lines a run of documents prints and the space between them, each in+-- the wrappers it is printed in, and whether that cuts an element of the+-- run.+linesOf :: Layout -> [Doc] -> ([Doc], Bool)+linesOf layout xs = (plain . mconcat <$> filter (not . null) ps, cut)+  where+    (ps, _, cut) = partsOf layout Within xs++-- | Does this document print on one line, holding neither a line break nor+-- a choice?+onOneLine :: Layout -> Doc -> Bool+onOneLine layout = all single . spineAt layout+  where+    single x = case unwrap x of+      Just (w, y) -> onOneLine (layoutInside layout w) y+      Nothing -> case x of+        DHardBreak -> False+        DBreak -> layout == Flat+        DSoftBreak -> layout == Flat+        DVerbatimBreak{} -> False+        DCppChoice{} -> False+        _ -> True++-- | A line less the wrappers that make no difference to it: a group around+-- what does not depend on the layout, and a region around regions and+-- nothing else, which say where the line was written already.+plain :: Doc -> Doc+plain = \case+  DGroup _ d | layoutFree d -> plain d+  DLocated _ d | onlyRegions d -> plain d+  DFence _ d | onlyRegions d -> plain d+  d -> mapChildren plain d+  where+    layoutFree = \case+      DBreak -> False+      DSoftBreak -> False+      DVariant{} -> False+      DCppChoice{} -> False+      DGroup{} -> True+      d -> getAll (foldChildren (All . layoutFree) d)+    onlyRegions d = isJust (regionOf d) && not (bare d)+    bare = \case+      DLocated{} -> False+      DFence{} -> False+      DText t -> not (T.null t)+      DHoldBack{} -> True+      d -> getAny (foldChildren (Any . bare) d)++-- | Where a part of a run of documents begins.+data Place+  = -- | On a line, after what the line already holds.+    Within+  | -- | Between two lines.+    Between+  deriving (Eq)++-- | The parts a run of documents is cut into: its lines and the space+-- between them, each in the wrappers it is printed in.+partsOf ::+  -- | The layout the run is printed in.+  Layout ->+  -- | Where the run begins.+  Place ->+  -- | The run.+  [Doc] ->+  -- | The parts in order, the first of them what the run adds to the part+  -- it begins in, empty where the run begins a part of its own; where the+  -- run ends, which is where what follows it begins; and whether an element+  -- of the run holds what is printed on more than one line, so that the cut+  -- went through it.+  ([[Doc]], Place, Bool)+partsOf layout = walk [[]] False+  where+    walk ls cut place = \case+      [] -> (reverse ls, place, cut)+      x : xs+        | Just (w, y) <- unwrap x,+          w /= WCppMarginNote,+          w /= WAlign || place == Between,+          let inside = layoutInside layout w,+          (ps, place', cut') <- partsOf inside place (spineAt inside y),+          length (filter (not . null) ps) > 1 ->+            walk+              (onto (if w == WAlign then ps else wrapped w ps) ls)+              (cut || cut' || length (filter (not . all blank) ps) > 1)+              place'+              xs+        | printsNothing x || x == DSpace -> walk (onto [[x]] ls) cut place xs+        | opensWithBreak layout x,+          place == Between ->+            walk (onto [[x]] ls) cut place xs+        | opensWithBreak layout x -> walk ([x] : ls) cut Between xs+        | place == Within -> walk (onto [[x]] ls) cut place xs+        | otherwise -> walk ([x] : ls) cut Within xs+    onto ps ls = case (ps, ls) of+      (p : rest, l : done) -> reverse rest <> ((l <> p) : done)+      _ -> reverse ps <> ls+    wrapped w = case w of+      WLocated s -> marked DLocated s (startOf s) True+      WFence s -> marked DFence s (startOf s) True+      _ -> fmap (\p -> [wrap w (mconcat p) | not (null p)])+    marked region s from first = \case+      [] -> []+      p : rest+        | all blank p -> p : marked region s from first rest+        | Just r <- regionOf d -> p : marked region s (endOf r) False rest+        | otherwise -> [region s' d] : marked region s s' False rest+        where+          d = mconcat p+          final = all (all blank) rest+          s'+            | first && final = s+            | first = startOf s+            | final = endOf s+            | otherwise = from++-- | Where the regions a document holds were written.+writtenAt :: Doc -> Set Span+writtenAt = \case+  DLocated s d -> Set.insert s (writtenAt d)+  DFence s d -> Set.insert s (writtenAt d)+  d -> foldChildren writtenAt d++-- | Does this document print nothing but space and what ends a line?+blank :: Doc -> Bool+blank = all spacing . spine+  where+    spacing x = onlySpacing x || maybe False (blank . snd) (unwrap x)+ -- | Does the first thing this document puts on the page end a line? opensWithBreak :: Layout -> Doc -> Bool opensWithBreak layout d = case dropWhile (== DSpace) (spineAt layout d) of@@ -740,10 +920,12 @@  -- | The longest run of elements two spines have in common, in order, -- allowing for anything either of them has that the other does not, of--- those that could hold them together.-lcs :: (a -> Bool) -> (a -> a -> Bool) -> [a] -> [a] -> [a]+-- those that could hold them together, each with its counterpart.+lcs :: (a -> Bool) -> (a -> b -> Bool) -> [a] -> [b] -> [(a, b)] lcs holds same xs ys =-  filter holds opening <> table middleX middleY <> filter holds closing+  filter (holds . fst) (zip opening ys)+    <> table middleX middleY+    <> filter (holds . fst) closing   where     agreeing as bs = length (takeWhile id (zipWith same as bs)) @@ -751,8 +933,9 @@     (opening, xs1) = splitAt ahead xs     ys1 = drop ahead ys     behind = agreeing (reverse xs1) (reverse ys1)-    (middleX, closing) = splitAt (length xs1 - behind) xs1-    middleY = take (length ys1 - behind) ys1+    (middleX, closingX) = splitAt (length xs1 - behind) xs1+    (middleY, closingY) = splitAt (length ys1 - behind) ys1+    closing = zip closingX closingY      table [] _ = []     table _ [] = []@@ -765,23 +948,19 @@               (n, acc) : case rest of                 [] -> []                 ((y, (dn, ds), (an, as')) : more)-                  | holds x, same x y -> cells (dn + 1) (x : ds) more+                  | holds x, same x y -> cells (dn + 1) ((x, y) : ds) more                   | n >= an -> cells n acc more                   | otherwise -> cells an as' more --- | Only let something that was printed line two spines up.-anchored :: (Doc -> Doc -> Bool) -> Doc -> Doc -> Bool-anchored same a b = anchoring a && same a b- -- | Could this element hold two spines together, if it turned up in both? anchoring :: Doc -> Bool anchoring = \case   DVerbatimBreak _ _ -> False   DText "," -> False   DDeclarationsStart -> False-  DNest _ d -> located d || not (printsNothing d)+  DNest _ d -> located d || not (blank d)   DAlign d -> located d || not (printsNothing d)-  DGroup _ d -> located d || not (printsNothing d)+  DGroup _ d -> located d || not (blank d)   d -> not (onlySpacing d)   where     located = \case@@ -793,27 +972,14 @@       DGroup _ d -> located d       _ -> False --- | A spine cut at the elements it shares with the others: one stretch--- before each of them, and one after the last, and the elements themselves.------ The matched elements come back rather than being dropped because the--- caller cannot assume they are interchangeable: 'agree' does not look--- inside a region the conditional leaves alone.-segments ::-  -- | Whether an element of the spine is the shared one being looked for.-  (a -> a -> Bool) ->-  -- | The shared elements, in order, to cut at.-  [a] ->-  -- | The spine to cut.-  [a] ->-  -- | The stretches between the cuts, and the elements cut at.-  ([[a]], [a])-segments same = go+-- | A spine cut at the given positions: one stretch before each of them,+-- and one after the last.+cutAt :: [Int] -> [a] -> ([[a]], [a])+cutAt = go 0   where-    go [] s = ([s], [])-    go (c : cs) s = case break (same c) s of-      (before', matched : rest) -> keeping before' matched (go cs rest)-      (before', []) -> keeping before' c (go cs [])-      where-        keeping before' matched (stretches, anchors) =-          (before' : stretches, matched : anchors)+    go _ [] s = ([s], [])+    go i (p : ps) s = case splitAt (p - i) s of+      (before, x : after) ->+        let (stretches, xs) = go (p + 1) ps after+         in (before : stretches, x : xs)+      (before, []) -> ([before], [])
src/Tilia/Doc/Combinators.hs view
@@ -23,7 +23,6 @@      -- * Layout     Layout (..),-    group,     flat,     broken,     variant,@@ -81,7 +80,6 @@     Layout (..),     LineStart (..),     TrailingWhitespace (..),-    groupLayout,     mapChildren,     printsNothing,   )@@ -103,7 +101,7 @@ space = DSpace  -- | A place the line may break. It becomes a line break if the enclosing--- 'group' is broken, and a space if it is flat. This is the workhorse: it+-- group is broken, and a space if it is flat. This is the workhorse: it -- is what lets one printer serve both layouts. breakOrSpace :: Doc breakOrSpace = DBreak@@ -153,11 +151,6 @@ ---------------------------------------------------------------------------- -- Layout --- | Lay the document out as the input had it: flat if the construct was--- written on one line, broken if it was spread across several.-group :: Span -> Doc -> Doc-group s = DGroup (groupLayout (Just s))- -- | Force flat layout. flat :: Doc -> Doc flat = DGroup Flat@@ -166,7 +159,7 @@ broken :: Doc -> Doc broken = DGroup Broken --- | Choose according to the layout the enclosing 'group' settled on.+-- | Choose according to the layout the enclosing group settled on. -- -- Reach for this only when the two layouts differ by more than where the -- breaks fall.
src/Tilia/Doc/Internal.hs view
@@ -23,7 +23,6 @@     Layout (..),     LineStart (..),     TrailingWhitespace (..),-    groupLayout,      -- * Rendering     RenderOptions (..),@@ -37,7 +36,7 @@ import Data.Maybe (listToMaybe, mapMaybe) import Data.Text (Text) import Data.Text qualified as T-import Tilia.Span (Span, isSingleLine, spanEndLine, spanStartLine)+import Tilia.Span (Span, spanEndLine, spanStartLine)  ---------------------------------------------------------------------------- -- Documents@@ -292,14 +291,6 @@   | -- | Keep it.     KeepWhitespace   deriving (Eq, Show)---- | Decide how to lay a group out.-groupLayout :: Maybe Span -> Layout-groupLayout = \case-  Nothing -> Flat-  Just s-    | isSingleLine s -> Flat-    | otherwise -> Broken  ---------------------------------------------------------------------------- -- Rendering
src/Tilia/Equivalence.hs view
@@ -21,7 +21,7 @@ import Data.Choice (pattern Is) import Data.Data import Data.IORef (IORef, atomicModifyIORef', newIORef, readIORef)-import Data.List (sortOn)+import Data.List (sortOn, unsnoc) import Data.List.NonEmpty (NonEmpty (..)) import Data.List.NonEmpty qualified as NE import Data.Map.Strict (Map)@@ -61,6 +61,7 @@   ( Comment (..),     Pragma (..),     asOrdinary,+    carriedOnFrom,     commentPragma,     commentTrailing,     triggerEscaped,@@ -466,13 +467,13 @@     asRead m =       concatMap (asOrdinary (sourceLines (pmSource m))) (comments (pmSource m)) -    belowHeader m = filter (not . inHeader m) . ordinary-    withinHeader m = filter (inHeader m) . ordinary+    belowHeader m cs = filter (not . inHeader m cs) (ordinary cs)+    withinHeader m cs = filter (inHeader m cs) (ordinary cs)     settled = sortOn bodyKey -    inHeader m c = case lastRearrangedLine m of-      Nothing -> False-      Just lastLine -> spanStartLine (commentSpan c) <= lastLine+    inHeader m cs = case lastRearrangedLine m cs of+      Nothing -> const False+      Just lastLine -> (<= lastLine) . spanStartLine . commentSpan      lost = pragmasOf before `Set.difference` pragmasOf after     gained = pragmasOf after `Set.difference` pragmasOf before@@ -523,16 +524,32 @@   ls -> ls  -- | The last line the formatter may reorder: the end of the last import, or--- of the module header where there are no imports.+-- of the module header where there are no imports, and of the comments+-- under it that carry on a remark at its end and travel with it. -- -- 'Nothing' where the module has neither header nor imports.-lastRearrangedLine :: HsModule GhcPs -> Maybe Int-lastRearrangedLine m = spanEndLine <$> (spansOf (hsmodImports m) <> header)+lastRearrangedLine :: HsModule GhcPs -> [Comment] -> Maybe Int+lastRearrangedLine m cs =+  carriedPast . spanEndLine <$> (spansOf (hsmodImports m) <> header)   where     header =       foldMap spanOf (hsmodName m)         <> foldMap spanOf (hsmodDeprecMessage (hsmodExt m))         <> foldMap spanOf (hsmodExports m)+    carriedPast lastLine =+      maybe lastLine (spanEndLine . commentSpan . snd) . unsnoc $+        takeWhile+          (maybe False ((<= lastLine) . fst) . carriedOnFrom (remarks <> run))+          run+      where+        remarks = [c | c <- cs, spanEndLine (commentSpan c) == lastLine]+        run = following (lastLine + 1) cs+    following n = \case+      c : more+        | spanStartLine (commentSpan c) < n -> following n more+        | spanStartLine (commentSpan c) == n ->+            c : following (spanEndLine (commentSpan c) + 1) more+      _ -> []  -- | The pragmas a module carries, however they were written. --
src/Tilia/Fixity.hs view
@@ -344,6 +344,7 @@   where     declared = Map.map (Set.map snd) (declaredMembers hsModule)     fromIE = \case+      IEThingAbs _ n _ -> [(nameOf n, Set.empty)]       IEThingAll _ n _ -> [(nameOf n, kids) | Just kids <- [Map.lookup (nameOf n) declared]]       IEThingWith _ n _ ns _ -> [(nameOf n, Set.fromList (fmap nameOf ns))]       _ -> []
src/Tilia/Fixity/Cache.hs view
@@ -21,6 +21,10 @@     storeFutileSolve,     cachedFutileFetch,     storeFutileFetch,+    cachedSolveTime,+    storeSolveTime,+    cachedPackageCache,+    storePackageCache,   ) where @@ -37,7 +41,9 @@ import Data.Text qualified as T import Data.Text.IO qualified as T import Data.Text.Read qualified as T+import Data.Time (UTCTime) import Data.Time.Format (defaultTimeLocale, formatTime)+import Data.Time.Format.ISO8601 (iso8601ParseM, iso8601Show) import System.Directory   ( XdgDirectory (XdgCache),     createDirectoryIfMissing,@@ -437,6 +443,31 @@ storeFutileFetch :: Cache -> [Text] -> IO () storeFutileFetch cache =   writeAtomically (at cache ["fetches", tokenOf cache]) . T.unlines++-- | When the project was last solved under this plan.+cachedSolveTime :: Cache -> IO (Maybe UTCTime)+cachedSolveTime cache =+  join+    <$> readIfPresent+      (at cache ["solve-times", tokenOf cache])+      (iso8601ParseM . T.unpack . T.strip)++-- | Remember when the project was solved under this plan.+storeSolveTime :: Cache -> UTCTime -> IO ()+storeSolveTime cache =+  writeAtomically (at cache ["solve-times", tokenOf cache])+    . T.pack+    . iso8601Show++-- | Where @cabal@ last said it keeps the sources it downloads.+cachedPackageCache :: Cache -> IO (Maybe FilePath)+cachedPackageCache cache =+  readIfPresent (at cache ["package-cache", tokenOf cache]) (T.unpack . T.strip)++-- | Remember where @cabal@ keeps the sources it downloads.+storePackageCache :: Cache -> FilePath -> IO ()+storePackageCache cache =+  writeAtomically (at cache ["package-cache", tokenOf cache]) . T.pack  -- | Render a fixity declaration as fields. renderFixity :: ((Namespace, OpName), Fixity) -> [Text]
src/Tilia/Fixity/Interface.hs view
@@ -17,7 +17,7 @@ import Data.Char (isUpper) import Data.Map.Strict (Map) import Data.Map.Strict qualified as Map-import Data.Maybe (mapMaybe, maybeToList)+import Data.Maybe (isNothing, mapMaybe, maybeToList) import Data.Set (Set) import Data.Set qualified as Set import Data.Text (Text)@@ -31,8 +31,8 @@  -- | What an interface says about the operators a module offers. data Interface = Interface-  { -- | The fixities the module declares itself, by the namespace each-    -- governs.+  { -- | The fixities the module declares itself for the names it exports,+    -- by the namespace each governs.     interfaceDeclares :: Fixities,     -- | The names it reexports, each with the source module.     interfaceReexports :: [(Text, OpName)],@@ -74,7 +74,11 @@       Right         Interface           { interfaceDeclares =-              Map.fromList [((namespace, op), fixity) | (namespace, op, fixity) <- hiFixities],+              Map.fromList+                [ ((namespace, op), fixity)+                | (namespace, op, fixity) <- hiFixities,+                  Set.member (namespace, op) exportedHere+                ],             interfaceReexports =               [ (m, op)               | names <- exports,@@ -85,22 +89,22 @@             interfaceExports =               Just                 Certain-                  { certainNames = Set.fromList [(namespace, op) | (_, namespace, op) <- exported],+                  { certainNames = exportedHere,                     certainMembers = members                   }           }   where     exports = concatMap resolved hiExports     exported = concatMap exportedNames hiExports+    exportedHere =+      Set.fromList [(namespace, op) | (_, namespace, op) <- exported]     members =       Map.fromListWith         Set.union         [ (op, Set.fromList [(namespace, kid) | (_, namespace, kid) <- kids])-        | parent@(_, _, op) : named <- exports,-          let kids = case named of-                first : rest | first == parent -> rest-                _ -> named,-          not (null kids)+        | AvailTC p ns <- hiExports,+          Just parent@(_, _, op) <- [known p],+          let kids = filter (/= parent) (mapMaybe known ns)         ]     exportedNames = \case       Avail n -> maybeToList (known n)@@ -125,7 +129,10 @@           { interfaceDeclares =               namespaced                 (typeNamesIn out)-                (Map.fromList (concatMap declared (sectionsNamed "fixities"))),+                ( Map.restrictKeys+                    fixities+                    (foldMap ownExports (sectionsNamed "exports:"))+                ),             interfaceReexports = concatMap reexports (sectionsNamed "exports:"),             interfaceMembers =               Map.unionsWith Set.union (fmap membersIn (sectionsNamed "exports:")),@@ -140,7 +147,15 @@       | (heading, body) <- sections out,         heading == name       ]+    fixities = Map.fromList (concatMap declared (sectionsNamed "fixities"))     declared = mapMaybe fixityEntry . T.splitOn ","+    ownExports section =+      Set.fromList+        [ OpName name+        | (parent, kids) <- exportEntries section,+          name <- parent : kids,+          isNothing (moduleOf name)+        ]     reexports = concatMap reexportsIn . T.words     membersIn section =       Map.fromListWith
src/Tilia/Fixity/Plan.hs view
@@ -20,6 +20,7 @@     tokenForEnvAndBuildPlan,     tokenForBuildPlan,     macrosOf,+    plannedCompiler,      -- * Readiness     Readiness (..),@@ -33,6 +34,7 @@     guessedPackageCacheRoot,     Futility (..),     undiscoveredFutility,+    futilityFor,     prepareWith,     loadPlan, @@ -97,7 +99,9 @@ import Data.Text qualified as T import Data.Text.Encoding qualified as T import Data.Text.Read qualified as T+import Data.Time (UTCTime, getCurrentTime) import Data.Unique (Unique, newUnique)+import Distribution.Version (Version, mkVersion) import GHC.Generics (Generic) import GHC.Hs (HsModule) import GHC.Hs.Extension (GhcPs)@@ -382,14 +386,14 @@ macrosOf :: BuildPlan -> Macros macrosOf plan =   mempty-    { macroVersions =+    { macroExactVersions =         Map.fromList           ( [ ("MIN_VERSION_" <> underscored name, version)             | (name, [version]) <- Map.toList (Map.map Set.toList versions)             ]               <> [("MIN_VERSION_GLASGOW_HASKELL", v) | v <- toList compiler]           ),-      macroNumbers =+      macroExactNumbers =         Map.fromList           [ entry           | (major : minor : patches) <- toList compiler,@@ -402,7 +406,9 @@       macroUndefined =         if null compiler           then Set.empty-          else Set.fromList ["__MHS__", "__HUGS__"]+          else Set.fromList ["__MHS__", "__HUGS__"],+      macroPlannedPackages =+        Just (Set.fromList [underscored (ppName p) | p <- bpPackages plan])     }   where     versions =@@ -420,6 +426,12 @@         _ -> Nothing     nth i xs = if i < length xs then xs !! i else 0 +-- | The version of GHC a plan is for, where it is for GHC.+plannedCompiler :: BuildPlan -> Maybe Version+plannedCompiler plan =+  mkVersion . fmap fromInteger+    <$> (numberedVersion =<< T.stripPrefix "ghc-" (bpCompiler plan))+ -- | The modules @cabal@ writes itself for a plan's packages. generatedModules :: BuildPlan -> Set Text generatedModules plan =@@ -500,7 +512,8 @@   readBuildPlan (planPathFor projectDir) >>= \case     Left _ -> pure PlanMissing     Right plan -> do-      newer <- filesNewerThanPlan plan projectDir+      solved <- cachedSolveTime =<< openCache caching =<< tokenForBuildPlan plan+      newer <- filesNewerThanPlan plan projectDir solved       let covered = plannedComponents plan           missing = [spellComponent c | c <- wanted, c `notElem` covered]       case (newer, missing) of@@ -514,16 +527,14 @@ -- | The packages the plan expects to fetch whose sources are not here. sourcesShortOf :: Choice "useCache" -> BuildPlan -> IO [PlanPackage] sourcesShortOf caching plan = do-  tarballs <- filter (isFetchable . fst) <$> plannedTarballs plan+  cache <- openCache caching =<< tokenForBuildPlan plan+  tarballs <- filter (isFetchable . fst) <$> plannedTarballs cache plan   absent <- fmap fst <$> filterM (fmap not . doesFileExist . snd) tarballs-  short <--    if null absent-      then pure []-      else do-        cache <- openCache caching =<< tokenForBuildPlan plan-        installed <- getInstalledPackages cache-        pure (filter (not . builtAlready installed) absent)-  pure short+  if null absent+    then pure []+    else do+      installed <- getInstalledPackages cache+      pure (filter (not . builtAlready installed) absent)  -- | Has the compiler got this package already? builtAlready :: [InstalledPackage] -> PlanPackage -> Bool@@ -531,10 +542,12 @@   where     matches i = ipName i == ppName p && ipVersion i == ppVersion p --- | The project files that have changed since the plan was written.-filesNewerThanPlan :: BuildPlan -> FilePath -> IO [FilePath]-filesNewerThanPlan plan projectDir = quietly [] $ do-  planTime <- getModificationTime (planPathFor projectDir)+-- | The project files that have changed since the plan was written, and+-- since the last solve, which leaves a plan it would not change as it was.+filesNewerThanPlan :: BuildPlan -> FilePath -> Maybe UTCTime -> IO [FilePath]+filesNewerThanPlan plan projectDir solved = quietly [] $ do+  written <- getModificationTime (planPathFor projectDir)+  let planTime = maybe written (max written) solved   atRoot <- quietly [] (listDirectory projectDir)   inPackages <- concat <$> traverse cabalFilesIn (localDirs plan)   let candidates =@@ -565,7 +578,10 @@     -- | The packages an earlier fetch was still short of afterwards.     fetchWasFutileFor :: IO [Text],     -- | Remember what a fetch left missing.-    rememberFutileFetch :: [Text] -> IO ()+    rememberFutileFetch :: [Text] -> IO (),+    -- | Remember when a solve started, so that no change made before it+    -- makes the plan stale.+    rememberSolveTime :: UTCTime -> IO ()   }  -- | The state when we know nothing about futile actions yet.@@ -575,7 +591,8 @@     { solveWasFutile = pure False,       rememberFutileSolve = pure (),       fetchWasFutileFor = pure [],-      rememberFutileFetch = const (pure ())+      rememberFutileFetch = const (pure ()),+      rememberSolveTime = const (pure ())     }  -- | A memory kept in the cache, under the plan the project has now.@@ -586,7 +603,8 @@       rememberFutileSolve = withCache () storeFutileSolve,       fetchWasFutileFor = withCache [] cachedFutileFetch,       rememberFutileFetch = \packages ->-        withCache () (`storeFutileFetch` packages)+        withCache () (`storeFutileFetch` packages),+      rememberSolveTime = \started -> withCache () (`storeSolveTime` started)     }   where     withCache fallback use =@@ -645,10 +663,12 @@                   left <- sourcesShortOf caching plan                   rememberFutileFetch futility (fmap ppName left)                   pure (Right ())-    solveThenFetch =+    solveThenFetch = do+      started <- getCurrentTime       tryWholeProject ["build", ":all", "--dry-run"] >>= \case         Left err -> pure (Left err)-        Right () ->+        Right () -> do+          rememberSolveTime futility started           checkReadiness caching wanted projectDir >>= \case             SourcesMissing _ -> fetch             PlanNarrow _ -> rememberFutileSolve futility >> fetchWhatIsShort@@ -724,15 +744,29 @@       _ -> readBuildPlan (planPathFor projectDir)  -- | Every planned package whose source could be in the package cache, with--- where that would be.-plannedTarballs :: BuildPlan -> IO [(PlanPackage, FilePath)]-plannedTarballs plan = do-  cacheRoot <- packageCacheRoot-  repos <- quietly [] (Data.List.sort <$> listDirectory cacheRoot)-  traverse-    (\p -> (,) p <$> tarballFor cacheRoot repos p)-    [p | p <- bpPackages plan, not (isLocal p)]+-- where that would be: under the package cache @cabal@ last named, unless+-- a tarball it downloads is not there, when @cabal@ is asked again.+plannedTarballs :: Cache -> BuildPlan -> IO [(PlanPackage, FilePath)]+plannedTarballs cache plan =+  cachedPackageCache cache >>= \case+    Just remembered -> do+      tarballs <- under remembered+      absent <-+        filterM+          (fmap not . doesFileExist . snd)+          (filter (isFetchable . fst) tarballs)+      if null absent then pure tarballs else asked+    Nothing -> asked   where+    asked = do+      cacheRoot <- packageCacheRoot+      storePackageCache cache cacheRoot+      under cacheRoot+    under cacheRoot = do+      repos <- quietly [] (Data.List.sort <$> listDirectory cacheRoot)+      traverse+        (\p -> (,) p <$> tarballFor cacheRoot repos p)+        [p | p <- bpPackages plan, not (isLocal p)]     isLocal p = case ppSource p of       LocalPackage _ -> True       CheckedOut _ -> True@@ -870,11 +904,11 @@   BuildPlan ->   IO Resolver newResolverVia caching routes plan = do+  cache <- openCache caching =<< tokenForBuildPlan plan   tarballs <-     if FromSource `elem` routes-      then plannedTarballs plan+      then plannedTarballs cache plan       else pure []-  cache <- openCache caching =<< tokenForBuildPlan plan   installed <- getInstalledPackages cache   newResolverWith routes cache installed tarballs plan @@ -898,7 +932,7 @@   local <- localModules plan   flights <- newMVar (Flights Map.empty Map.empty)   answersRead <- newMemo-  askPackage <- newPackageReader+  askPackage <- newPackageReader (plannedCompiler plan)   extensionsRead <- newMemo   summariesRead <- newMemo   archivesRead <- newMemo@@ -1518,12 +1552,16 @@       more <- reached $ \i ->         Map.notMember (importModule i) listed && any (suppliedBy i) members       let answers = Map.union listed more+          parts = fmap (exported answers reexported) items       pure . together $         mempty-          { establishedFixities = summaryFixities summary,+          { establishedFixities =+              Map.restrictKeys+                (summaryFixities summary)+                (foldMap (certainNames . establishedCertain) parts),             establishedMembers = summaryListedMembers summary           }-          : fmap (exported answers reexported) items+          : parts   where     imports = summaryImports summary     declared = summaryDeclaredMembers summary
src/Tilia/Format.hs view
@@ -67,6 +67,7 @@     loadPlan,     macrosOf,     newResolverVia,+    plannedCompiler,     readGivenPlan,     scopeFor,   )@@ -259,7 +260,7 @@           then [FromInterface, FromSource] <$ liftIO (fetchUninstalled caching root plan)           else pure [FromInterface]       (,) plan <$> liftIO (newResolverVia caching routes plan)-  askPackage <- liftIO newPackageReader+  askPackage <- liftIO (newPackageReader (plannedCompiler plan))   notes <-     if isTrue debugFixity       then Just <$> liftIO (newIORef Map.empty)
src/Tilia/Parser.hs view
@@ -104,7 +104,7 @@           Right             ParsedModule               { pmModule = hsModule,-                pmSource = sourceOf written (lexedComments start),+                pmSource = uncurry (sourceOf written) (lexed start),                 pmGathered = gathered hsModule,                 pmSourceType = sourceType,                 pmPrologue = prologueOf (lineTexts written),@@ -182,16 +182,26 @@       GHC.ITsemi -> False       t -> not (isComment t) --- | Lex every comment, in source order, from the state a parse starts in.-lexedComments :: GHC.PState -> [LEpaComment]-lexedComments s =+-- | Lex every comment, in source order, and the line each quasi-quotation+-- written over several lines ends on, by the line it begins on, from the+-- state a parse starts in.+lexed :: GHC.PState -> ([LEpaComment], IntMap Int)+lexed s =   case GHC.lexTokenStream (GHC.options s) (GHC.buffer s) loc of     GHC.PFailed _ -> error "Tilia: a module that parses cannot fail to lex"     GHC.POk _ tokens ->-      [ GHC.commentToAnnotation (GHC.L l t)-      | GHC.L (GHC.RealSrcSpan l _) t <- tokens,-        isComment t-      ]+      ( [ GHC.commentToAnnotation (GHC.L l t)+        | GHC.L (GHC.RealSrcSpan l _) t <- tokens,+          isComment t+        ],+        IntMap.fromList+          [ (GHC.srcSpanStartLine l, GHC.srcSpanEndLine l)+          | GHC.xtest GHC.QqBit (GHC.pExtsBitmap (GHC.options s)),+            GHC.L (GHC.RealSrcSpan l _) t <- tokens,+            isQuasiQuote t,+            GHC.srcSpanStartLine l < GHC.srcSpanEndLine l+          ]+      )   where     loc = GHC.psRealLoc (GHC.loc s) @@ -202,6 +212,13 @@   GHC.ITblockComment _ _ -> True   GHC.ITdocComment _ _ -> True   GHC.ITdocOptions _ _ -> True+  _ -> False++-- | Is this token a quasi-quotation?+isQuasiQuote :: GHC.Token -> Bool+isQuasiQuote = \case+  GHC.ITquasiQuote _ -> True+  GHC.ITqQuasiQuote _ -> True   _ -> False  -- | The state to start reading a module in.
src/Tilia/Render/Context.hs view
@@ -34,6 +34,7 @@     layoutFrom,     layoutWithin,     layoutAcross,+    writtenOnOneLine,     attachOperator,      -- * Haddocks@@ -70,6 +71,7 @@     SourceType,     blankAt,     directivePresentOnLine,+    quoteEndingFrom,     sourceLines,   ) import Tilia.Span@@ -294,7 +296,7 @@ -- of an @if@—and for nothing else. atSpan :: Ctx -> Maybe Span -> Doc -> Doc atSpan _ Nothing d = d-atSpan _ (Just s) d = located s (group s d)+atSpan ctx (Just s) d = located s (layoutFrom ctx (Just s) d)  -- | A keyword, claiming the span it was written on. keywordAt :: Ctx -> Maybe Span -> Text -> Doc@@ -309,10 +311,12 @@ -- | Lay a region out as it was written, and claim nothing. -- -- The region decides one thing—whether what is printed here goes on one--- line or several.+-- line or several. The lines of a quasi-quotation count as one, since they+-- are reproduced rather than laid out. layoutFrom :: Ctx -> Maybe Span -> Doc -> Doc-layoutFrom _ Nothing d = flat d-layoutFrom _ (Just s) d = group s d+layoutFrom ctx s+  | maybe True (writtenOnOneLine ctx) s = flat+  | otherwise = broken  -- | Lay a construct out from the region its contents occupy rather than the -- region it occupies.@@ -328,7 +332,7 @@   Doc layoutWithin ctx whole contents d   | any (holdsLineComment ctx) whole = broken d-  | otherwise = maybe (flat d) (`group` d) contents+  | otherwise = layoutFrom ctx contents d  -- | 'layoutFrom' over the region several located things cover. layoutAcross :: (HasLoc l) => Ctx -> [GenLocated l a] -> Doc -> Doc@@ -364,6 +368,15 @@   where     indentation o =       located (mkSpan (spanStartLine o, 1) (startPoint o)) mempty++-- | Was the region written on one line, the lines of a quasi-quotation+-- counting as one?+writtenOnOneLine :: Ctx -> Span -> Bool+writtenOnOneLine ctx s = from (spanStartLine s)+  where+    from n =+      n >= spanEndLine s+        || maybe False from (quoteEndingFrom n (ctxSource ctx))  -- | Does a comment that takes whole lines begin inside this span? holdsLineComment :: Ctx -> Span -> Bool
src/Tilia/Render/Expression.hs view
@@ -101,7 +101,7 @@   SectionR _ op x -> hsExpr ctx op <> breakOrSpace <> indent (hsExpr ctx x)   ExplicitTuple _ args boxity -> tuple ctx here (closingFor site) boxity args   ExplicitSum _ tag arity e -> unboxedSum (closingFor site) tag arity (hsExpr ctx e)-  HsCase _ e mg -> caseOf ctx site (ExprBody ctx) e mg+  HsCase anns e mg -> caseOf ctx site (ExprBody ctx) anns e mg   HsIf anns c t e -> ifThenElse ctx (bodyIn (ExprBody ctx) (siteBracing site)) anns c t e   HsMultiIf _ guards ->     txt "if"@@ -237,7 +237,7 @@     lastArg = NE.last args     initSpan = spanOf f <> (startOf <$> spanOf lastArg)     placement-      | maybe False isSingleLine initSpan = exprHangs (unLoc lastArg)+      | maybe False (writtenOnOneLine ctx) initSpan = exprHangs (unLoc lastArg)       | otherwise = Normal     headAndInit bracing =       hsExprIn ctx site{siteApplicand = True, siteBracing = bracing} func@@ -301,7 +301,12 @@   Doc fieldBind ctx label HsFieldBind{..} =   label hfbLHS-    <> includeUnless hfbPun (space <> txt "=" <> attach placement (hsExpr ctx hfbRHS))+    <> includeUnless+      hfbPun+      ( space+          <> maybe id located (tokenSpan =<< hfbAnn) (txt "=")+          <> attach placement (hsExpr ctx hfbRHS)+      )   where     placement       | sameLine (spanOf hfbLHS) (spanOf hfbRHS) = exprHangs (unLoc hfbRHS)@@ -400,7 +405,7 @@       endsHanging = exprHangs (unLoc (lastOperand chain)) == Hanging       couldTrail previous o =         isSeparator (fixityOf ctx o)-          && maybe False isSingleLine (chainSpan spanOf previous)+          && maybe False (writtenOnOneLine ctx) (chainSpan spanOf previous)           && placement == Normal           && not (isDoBlock (lastOperand previous)) @@ -461,9 +466,12 @@   LastStmt _ body _ _ -> printBody (mkBody site body)   BodyStmt _ body _ _ -> printBody (mkBody site body)   BindStmt arrow p f ->-    hsPat ctx p+    hsPatClosing ctx (closingFor site) p       <> nest 1 (space <> maybe id located (uniTokenSpan arrow) (txt "<-"))-      <> layoutFrom ctx (spanOf p <> spanOf f) (attach placement (printBody bound))+      <> layoutFrom+        ctx+        (fmap endOf (spanOf p) <> spanOf f)+        (attach placement (printBody bound))     where       bound = mkBody plainSite f       placement@@ -582,14 +590,17 @@   Ctx ->   Site ->   BodyOf body b ->+  EpAnnHsCase ->   LHsExpr GhcPs ->   MatchGroup GhcPs (LocatedA body) ->   Doc-caseOf ctx site mkBody scrutinee mg =-  txt "case"+caseOf ctx site mkBody EpAnnHsCase{..} scrutinee mg =+  maybe id located (tokenSpan hsCaseAnnCase) (txt "case")     <> space     <> hsExpr ctx scrutinee-    <> joinedBy "of"+    <> space+    <> indent (maybe id located (tokenSpan hsCaseAnnOf) (txt "of"))+    <> breakOrSpace     <> bracedForSite site alternatives   where     alternatives b = underSite site (matchGroup ctx b mkBody CaseStyle mg)@@ -664,18 +675,19 @@   Doc letIn ctx bodyOf nested (letToken, inToken) binds body =   align $-    txt "let"+    written (tokenSpan letToken) (txt "let")       <> space       <> align         ( localBinds ctx NoBrace binds             <> foldMap (emptyAnchor . startOf) (tokenSpan inToken)         )-      <> (if chained then space else variant space (hardBreak <> txt " "))-      <> txt "in"+      <> written (tokenSpan inToken) (separator <> txt "in")       <> (if chained then breakOrSpace else space)       <> align (printBody (bodyOf body))   where-    chained = nested && sameLine (tokenSpan letToken) (tokenSpan inToken)+    chained = nested && not (sameLine (tokenSpan inToken) (spanOf body))+    separator = if chained then space else variant space (hardBreak <> txt " ")+    written s d = if chained then fenceWithin ctx s d else d  -- | The bindings of a @let@ or a @where@. localBinds :: Ctx -> Bracing -> HsLocalBinds GhcPs -> Doc@@ -768,7 +780,7 @@       <> indent (hsExpr ctx e)   HsCmdLam _ variant' mg -> lambda ctx site variant' (CmdBody ctx) mg   HsCmdPar _ c -> parens (hsCmd ctx plainSite c)-  HsCmdCase _ e mg -> caseOf ctx site (CmdBody ctx) e mg+  HsCmdCase anns e mg -> caseOf ctx site (CmdBody ctx) anns e mg   HsCmdIf anns _ c t e ->     ifThenElse ctx (bodyIn (CmdBody ctx) (siteBracing site)) anns c t e   HsCmdLet tokens binds c ->@@ -1088,16 +1100,19 @@   [] -> atSpan ctx (grhsSpan grhs) (printBody bound)   _ ->     maybe id located (spanOf lgrhs) . layoutFrom ctx (grhsSpan grhs) $+      maybe id fence headSpan guardHead+        <> nest+          (if parentPlacement == Normal then 1 else 0)+          (attach placement (printBody bound))+  where+    GRHS EpAnn{anns = GrhsAnn{ga_vbar, ga_sep}} guards body = grhs+    guardHead =       txt "|"         <> space         <> align (commaSep (fmap (align . hsStmt ctx) guards))         <> space         <> indent (txt separator)-        <> nest-          (if parentPlacement == Normal then 1 else 0)-          (attach placement (printBody bound))-  where-    GRHS EpAnn{anns = GrhsAnn{ga_sep}} guards body = grhs+    headSpan = (<>) <$> (tokenSpan =<< ga_vbar) <*> separatorSpan     bound = bodyIn mkBody bracing body     separator = case style of       EqualsSign -> "="
src/Tilia/Render/Pattern.hs view
@@ -9,6 +9,7 @@ -- | Patterns. module Tilia.Render.Pattern   ( hsPat,+    hsPatClosing,     fieldOcc,     unboxedSum,   )@@ -32,8 +33,12 @@  -- | A pattern. hsPat :: Ctx -> LPat GhcPs -> Doc-hsPat ctx = hsPatIn ctx NoBrace (Isn't #inAsPat)+hsPat ctx = hsPatClosing ctx Indented +-- | A pattern whose outermost bracket closes where it is told to.+hsPatClosing :: Ctx -> ClosingIndent -> LPat GhcPs -> Doc+hsPatClosing ctx = hsPatIn ctx NoBrace (Isn't #inAsPat)+ -- | A pattern that knows where it stands. hsPatIn ::   -- | The context.@@ -42,10 +47,13 @@   Bracing ->   -- | Is this inside an as-pattern?   Choice "inAsPat" ->+  -- | Where its outermost bracket closes.+  ClosingIndent ->   -- | The pattern.   LPat GhcPs ->   Doc-hsPatIn ctx bracing inAsPat l = at ctx l (patBody ctx bracing inAsPat (spanOf l))+hsPatIn ctx bracing inAsPat closing l =+  at ctx l (patBody ctx bracing inAsPat closing (spanOf l))  -- | Every shape a pattern can take. patBody ::@@ -55,24 +63,31 @@   Bracing ->   -- | Is this inside an as-pattern?   Choice "inAsPat" ->+  -- | Where its outermost bracket closes.+  ClosingIndent ->   -- | Where the pattern was written.   Maybe Span ->   -- | The pattern.   Pat GhcPs ->   Doc-patBody ctx bracing inAsPat here = \case+patBody ctx bracing inAsPat closing here = \case   WildPat _ -> txt "_"   VarPat _ n -> name ctx n   LazyPat _ p -> txt "~" <> recur p-  AsPat _ n p -> name ctx n <> txt "@" <> hsPatIn ctx bracing (Is #inAsPat) p-  ParPat _ p -> parensWith Indented (insideBrackets here (recur p))+  AsPat _ n p ->+    name ctx n <> txt "@" <> hsPatIn ctx bracing (Is #inAsPat) Indented p+  ParPat _ p -> parensWith closing (insideBrackets here (recur p))   BangPat _ p -> txt "!" <> recur p-  ListPat _ ps -> bracketsWith Indented (insideBrackets here (commaSep (fmap recur ps)))+  ListPat _ ps ->+    bracketsWith closing (insideBrackets here (commaSep (fmap recur ps)))   TuplePat _ ps boxity ->-    tupleBrackets boxity (insideBrackets here (commaSep (fmap (align . recur) ps)))+    tupleBrackets+      boxity+      closing+      (insideBrackets here (commaSep (fmap (align . recur) ps)))   OrPat _ ps ->     itemsSepBy (fromBool (isTrue inAsPat)) bracing (fmap recur (NE.toList ps))-  SumPat _ p tag arity -> unboxedSum Indented tag arity (recur p)+  SumPat _ p tag arity -> unboxedSum closing tag arity (recur p)   ConPat _ con details -> conPattern ctx bracing inAsPat here con details   ViewPat _ e p ->     align $@@ -94,7 +109,7 @@   EmbTyPat _ (HsTP _ ty) -> txt "type" <> space <> hsType ctx ty   InvisPat _ (HsTP _ ty) -> txt "@" <> hsType ctx ty   where-    recur = hsPatIn ctx bracing inAsPat+    recur = hsPatIn ctx bracing inAsPat Indented  -- | A constructor pattern, in whichever of its three forms. conPattern ::@@ -126,7 +141,7 @@       recur l         <> attachOperator Normal (spanOf l) (spanOf con) (spanOf r) (name ctx con) (recur r)   where-    recur = hsPatIn ctx bracing inAsPat+    recur = hsPatIn ctx bracing inAsPat Indented     field = either wildcard (at_ ctx (patFieldBind ctx))     wildcard l = at ctx l (const (txt ".."))     visibleFields dotdot fields = case dotdot of@@ -156,10 +171,10 @@     after = replicate (arity - tag) space  -- | The brackets a tuple pattern is written with.-tupleBrackets :: Boxity -> Doc -> Doc+tupleBrackets :: Boxity -> ClosingIndent -> Doc -> Doc tupleBrackets = \case-  Boxed -> parensWith Indented-  Unboxed -> unboxedWith Indented+  Boxed -> parensWith+  Unboxed -> unboxedWith  -- | With @NegativeLiterals@ on, @- 1@ and @-1@ are different expressions, so -- the minus of a negated literal has to keep its distance.
src/Tilia/Source.hs view
@@ -19,9 +19,14 @@      -- * Its comments     comments,++    -- * Its quasi-quotations+    quoteEndingFrom,   ) where +import Data.IntMap.Strict (IntMap)+import Data.IntMap.Strict qualified as IntMap import GHC.Parser.Annotation (LEpaComment) import Tilia.Comments (Comment, commentsOf) import Tilia.Source.Lines@@ -37,7 +42,10 @@   { -- | The lines, numbered from one as the compiler numbers them.     srcLines :: !Lines,     -- | Every comment in the module, in source order.-    srcComments :: [Comment]+    srcComments :: [Comment],+    -- | The line each quasi-quotation written over several lines ends on,+    -- by the line it begins on.+    srcQuotes :: IntMap Int   }  -- | The lines of a source.@@ -50,13 +58,22 @@   Lines ->   -- | Every comment of the module, in source order.   [LEpaComment] ->+  -- | The line each quasi-quotation written over several lines ends on, by+  -- the line it begins on.+  IntMap Int ->   Source-sourceOf ls cs =+sourceOf ls cs qs =   Source     { srcLines = ls,-      srcComments = commentsOf ls cs+      srcComments = commentsOf ls cs,+      srcQuotes = qs     }  -- | Every comment in a module, in source order. comments :: Source -> [Comment] comments = srcComments++-- | The line a quasi-quotation that begins on this line ends on, if it ends+-- on another.+quoteEndingFrom :: Int -> Source -> Maybe Int+quoteEndingFrom n = IntMap.lookup n . srcQuotes
tests/Tilia/Cabal/PackageSpec.hs view
@@ -14,6 +14,7 @@ import System.IO.Temp (withSystemTempDirectory) import Test.Hspec import Tilia.Cabal.Package (PackageProblem (..), newPackageReader)+import Tilia.Fixity.Plan (BuildPlan (..), plannedCompiler)  spec :: Spec spec = do@@ -112,6 +113,13 @@         (has BangPatterns library, has Strict library)           `shouldBe` (False, False) +    it "take the compiler's version from the plan where it names one" $+      inPackage conditionalExtensions ["src"] $ \root -> do+        ask <- newPackageReader (plannedCompiler (BuildPlan "ghc-8.4.4" []))+        library <- ask (root </> "src" </> "M.hs")+        (has StarIsType library, has BangPatterns library)+          `shouldBe` (True, True)+     it "take in their own branch's too, for a module only it declares" $       inPackage conditionalExtensions ["src", "old"] $ \root -> do         old <- asked (root </> "old" </> "Old.hs")@@ -134,21 +142,21 @@   describe "a reader kept between files" $ do     it "answers as a fresh one would" $       inPackage twoComponents ["src", "test"] $ \root -> do-        ask <- newPackageReader+        ask <- newPackageReader Nothing         kept <- traverse ask (modules root)         fresh <- traverse asked (modules root)         kept `shouldBe` fresh      it "reads a package once, not once per file" $       inPackage twoComponents ["src"] $ \root -> do-        ask <- newPackageReader+        ask <- newPackageReader Nothing         first <- ask (root </> "src" </> "A.hs")         removeFile (root </> "demo.cabal")         ask (root </> "src" </> "B.hs") `shouldReturn` first      it "remembers every directory the walk went through" $       inPackage twoComponents ["src" </> "deep"] $ \root -> do-        ask <- newPackageReader+        ask <- newPackageReader Nothing         deep <- ask (root </> "src" </> "deep" </> "A.hs")         removeFile (root </> "demo.cabal")         ask (root </> "src" </> "B.hs") `shouldReturn` deep@@ -362,7 +370,7 @@ -- is not about caching wants. asked :: FilePath -> IO (Either PackageProblem [Extension]) asked path = do-  ask <- newPackageReader+  ask <- newPackageReader Nothing   ask path  -- | One module in each of the two components.
tests/Tilia/Corpus.hs view
@@ -236,6 +236,7 @@     "esqueleto-3.6.0.3",     "exceptions-0.10.12",     "fay-0.24.2.0",+    "flatparse-0.5.6.1",     "free-5.2",     "fsnotify-0.4.4.0",     "hakyll-4.17.0.0",@@ -357,7 +358,10 @@     "declaration" </> "data" </> "multiline-arg-parens.hs",     "module-header" </> "multiline-with-comments.hs",     "declaration" </> "value" </> "function" </> "awkward-comment-1.hs",-    "declaration" </> "signature" </> "pattern" </> "multiline.hs"+    "declaration" </> "signature" </> "pattern" </> "multiline.hs",+    "declaration" </> "splice" </> "quasiquote.hs",+    "declaration" </> "value" </> "function" </> "quasi-quotes.hs",+    "declaration" </> "value" </> "function" </> "operator-comments-0.hs"   ]     <> ormoluRecordBraces     <> ormoluUnreadable@@ -1075,7 +1079,7 @@ packageReaderFor corpus   | not (corpusInPackages corpus) = pure (const (pure []))   | otherwise = do-      reader <- newPackageReader+      reader <- newPackageReader Nothing       pure (fmap (either (const []) id) . reader)  -- | The extensions an example may be written with.
tests/Tilia/Cpp/MacrosSpec.hs view
@@ -15,18 +15,19 @@ macros :: Macros macros =   mempty-    { macroVersions =+    { macroExactVersions =         Map.fromList           [ ("MIN_VERSION_thing", [1, 2, 3]),             ("MIN_VERSION_GLASGOW_HASKELL", [9, 10, 3, 0])           ],-      macroNumbers =+      macroExactNumbers =         Map.fromList           [ ("__GLASGOW_HASKELL__", 910),             ("__GLASGOW_HASKELL_PATCHLEVEL1__", 3),             ("__GLASGOW_HASKELL_PATCHLEVEL2__", 0)           ],-      macroUndefined = Set.fromList ["__MHS__", "__HUGS__"]+      macroUndefined = Set.fromList ["__MHS__", "__HUGS__"],+      macroPlannedPackages = Just (Set.fromList ["thing"])     }  -- | What this guard comes to, given the plan above.@@ -51,8 +52,19 @@       fmap answer ["if MIN_VERSION_thing(1,2)", "if MIN_VERSION_thing(1,2,3,1)"]         `shouldBe` [Just True, Just False] -    it "says nothing about a package the plan does not name" $-      answer "if MIN_VERSION_other(1,0,0)" `shouldBe` Nothing+    it "has the macros of a package the plan does not hold undefined" $+      fmap+        answer+        [ "ifdef VERSION_other",+          "ifndef VERSION_other",+          "if defined(MIN_VERSION_other)",+          "if MIN_VERSION_other(1,0,0)"+        ]+        `shouldBe` [Just False, Just True, Just False, Just False]++    it "says nothing about other packages where the plan's are unknown" $+      guardHolds macros{macroPlannedPackages = Nothing} "ifdef VERSION_other"+        `shouldBe` Nothing    describe "a guard about the compiler" $ do     it "reads its version as the compiler spells it" $
tests/Tilia/Cpp/PropertiesSpec.hs view
@@ -83,7 +83,8 @@ -- else, so that a module comes out with some of its conditionals answered -- and some of them left open. macros :: Macros-macros = mempty{macroVersions = Map.fromList [("MIN_VERSION_thing", [1, 2, 3])]}+macros =+  mempty{macroExactVersions = Map.fromList [("MIN_VERSION_thing", [1, 2, 3])]}  format :: Text -> Either Text Text format source = case formatWithCpp defaultParserConfig defaultRenderConfig "M.hs" source of
tests/Tilia/Doc/CombinatorsSpec.hs view
@@ -20,12 +20,6 @@       out (flat (txt "a" <> breakOrNothing <> txt "b")) `shouldBe` "ab\n"     it "becomes a break when broken, leaving nothing behind" $       out (broken (txt "a" <> breakOrNothing <> txt "b")) `shouldBe` "a\nb\n"-    it "follows a single-line span" $-      out (group (mkSpan (1, 1) (1, 9)) (txt "a" <> breakOrSpace <> txt "b"))-        `shouldBe` "a b\n"-    it "follows a multi-line span" $-      out (group (mkSpan (1, 1) (2, 9)) (txt "a" <> breakOrSpace <> txt "b"))-        `shouldBe` "a\nb\n"     it "lets an inner group override the enclosing layout" $       out (flat (txt "a" <> broken (breakOrSpace <> txt "b")))         `shouldBe` "a\nb\n"@@ -37,10 +31,6 @@       out (flat (variant (txt "one") (txt "many"))) `shouldBe` "one\n"     it "takes the second branch when broken" $       out (broken (variant (txt "one") (txt "many"))) `shouldBe` "many\n"-    it "follows the span like any other group" $ do-      let v = variant (txt "one") (txt "many")-      out (group (mkSpan (1, 1) (1, 9)) v) `shouldBe` "one\n"-      out (group (mkSpan (1, 1) (2, 9)) v) `shouldBe` "many\n"    describe "provenance" $     it "does not affect layout" $ do
tests/Tilia/Doc/InternalSpec.hs view
@@ -10,7 +10,6 @@ import Tilia.Doc.Internal   ( Doc (DCppDirective, DHoldBack),     Spill (..),-    groupLayout,   ) import Tilia.Span @@ -27,14 +26,6 @@     it "takes the earlier start column when starts share a line" $       mkSpan (1, 9) (1, 20) <> mkSpan (1, 3) (1, 5)         `shouldBe` mkSpan (1, 3) (1, 20)--  describe "groupLayout" $ do-    it "goes flat with no span" $-      groupLayout Nothing `shouldBe` Flat-    it "goes flat for a single-line span" $-      groupLayout (Just (mkSpan (1, 1) (1, 9))) `shouldBe` Flat-    it "goes broken for a multi-line span" $-      groupLayout (Just (mkSpan (1, 1) (2, 9))) `shouldBe` Broken    describe "atoms" $ do     it "renders nothing for an empty document" $
tests/Tilia/Doc/PropertiesSpec.hs view
@@ -50,14 +50,6 @@         let t = out (flat d)          in counterexample (show t) (length (T.lines t) <= 1) -    it "renders a group with a single-line span as flat" $-      property $ \(FlatSafeDoc d) (SingleLineSpan s) ->-        out (group s d) === out (flat d)--    it "renders a group with a multi-line span as broken" $-      property $ \(FlatSafeDoc d) (MultiLineSpan s) ->-        out (group s d) === out (broken d)-   describe "provenance" $     it "does not affect the output" $       property $ \(AnyDoc d) (AnySpan s) ->
tests/Tilia/EquivalenceSpec.hs view
@@ -134,6 +134,14 @@       "module M where\n\n-- about Set\nimport Data.Set\n\n-- about Map\nimport Data.Map\n"         `keepsTheCommentsOf` "module M where\n\n-- about Map\nimport Data.Map\n\n-- about Set\nimport Data.Set\n" +    it "does not mind a comment carried on under the last import moving with it" $+      "module M where\nimport Data.Maybe\nimport Data.Char () -- not needed, just\n                    -- re-exported\n"+        `keepsTheCommentsOf` "module M where\n\nimport Data.Char () -- not needed, just\n                    -- re-exported\nimport Data.Maybe\n"++    it "notices a comment carried on under the last import going missing" $+      "module M where\nimport Data.Maybe\nimport Data.Char () -- not needed, just\n                    -- re-exported\n"+        `losesTheCommentsOf` "module M where\n\nimport Data.Char () -- not needed, just\nimport Data.Maybe\n"+ ---------------------------------------------------------------------------- -- Helpers 
tests/Tilia/Fixity/DependenciesSpec.hs view
@@ -17,7 +17,7 @@  import Control.Monad (filterM) import Data.ByteString qualified as BS-import Data.Choice (pattern Do, pattern Is)+import Data.Choice (pattern Do, pattern Don't, pattern Is) import Data.Foldable (for_) import Data.List (isSuffixOf, sort) import Data.Map.Strict qualified as Map@@ -33,6 +33,7 @@ import Tilia.BootFixities (bootFixities) import Tilia.Cpp (blankCpp) import Tilia.Fixity+import Tilia.Fixity.Cache (PlanToken (..), openCache) import Tilia.Fixity.Interface (Interface (..), readInterface) import Tilia.Fixity.PackageDb import Tilia.Fixity.Plan@@ -65,11 +66,12 @@       readFromSourcePackages =         Set.fromList (fmap depPackage dependencies)           `Set.difference` shippedPackages+  noCache <- runIO (openCache (Don't #useCache) (PlanToken ""))   missing <-     runIO $       filterM (fmap not . doesFileExist . snd)         . filter ((`Set.member` readFromSourcePackages) . ppName . fst)-        =<< plannedTarballs plan+        =<< plannedTarballs noCache plan   describe "the tree this project is built against" $ do     it "is a real dependency tree and not an empty plan" $       length dependencies `shouldSatisfy` (>= 30)
tests/Tilia/Fixity/InterfaceSpec.hs view
@@ -19,7 +19,7 @@ spec = do   describe "what a module declares" $ do     it "reads a fixity line" $-      declares "fixities infixl 9 !, infixl 9 !?, infixl 9 \\\\\n"+      declares "exports:\n  !\n  !?\n  \\\\\nfixities infixl 9 !, infixl 9 !?, infixl 9 \\\\\n"         `shouldBe` [ (OpName "!", Fixity LeftAssoc 9),                      (OpName "!?", Fixity LeftAssoc 9),                      (OpName "\\\\", Fixity LeftAssoc 9)@@ -27,7 +27,8 @@      it "reads one wrapped across lines" $       declares-        "fixities infixr 0 $, infixr 0 $!, infixl 4 *>, infixr 5 ++,\n\+        "exports:\n  $\n  $!\n  *>\n  ++\n  .\n  :|\n  <$\n\+        \fixities infixr 0 $, infixr 0 $!, infixl 4 *>, infixr 5 ++,\n\         \         infixr 9 ., infixr 5 :|, infixl 4 <$\n"         `shouldBe` [ (OpName "$", Fixity RightAssoc 0),                      (OpName "$!", Fixity RightAssoc 0),@@ -39,22 +40,22 @@                    ]      it "reads every direction, and a name used in backticks" $-      declares "fixities infixl 7 div, infix 4 ===, infixr 1 .&&.\n"+      declares "exports:\n  div\n  ===\n  .&&.\nfixities infixl 7 div, infix 4 ===, infixr 1 .&&.\n"         `shouldBe` [ (OpName ".&&.", Fixity RightAssoc 1),                      (OpName "===", Fixity NoAssoc 4),                      (OpName "div", Fixity LeftAssoc 7)                    ]      it "reads the precedence GHC gives the function arrow" $-      declares "fixities infixr -1 ->\n"+      declares "exports:\n  ->\nfixities infixr -1 ->\n"         `shouldBe` [(OpName "->", Fixity RightAssoc (-1))]      it "reads it alongside ordinary ones" $-      declares "fixities infixr -1 ->, infixl 9 !\n"+      declares "exports:\n  ->\n  !\nfixities infixr -1 ->, infixl 9 !\n"         `shouldBe` [(OpName "!", Fixity LeftAssoc 9), (OpName "->", Fixity RightAssoc (-1))]      it "passes over an entry it cannot read, and keeps the rest" $-      declares "fixities infixl notadigit ?, infixl 9 !, infixl\n"+      declares "exports:\n  ?\n  !\nfixities infixl notadigit ?, infixl 9 !, infixl\n"         `shouldBe` [(OpName "!", Fixity LeftAssoc 9)]      it "says nothing for a module that declares nothing" $@@ -114,31 +115,31 @@    describe "which namespace a fixity governs" $ do     it "gives one to types where the module declares a type of that name" $-      declaresIn "fixities infix 4 :~:\nab12\n  data (:~:) a b where\n"+      declaresIn "exports:\n  :~:\nfixities infix 4 :~:\nab12\n  data (:~:) a b where\n"         `shouldBe` [((InTypes, OpName ":~:"), Fixity NoAssoc 4)]      it "gives one to terms where nothing declares a type of that name" $-      declaresIn "fixities infixl 9 !\nab12\n  (!) :: Int -> Int -> Int\n"+      declaresIn "exports:\n  !\nfixities infixl 9 !\nab12\n  (!) :: Int -> Int -> Int\n"         `shouldBe` [((InTerms, OpName "!"), Fixity LeftAssoc 9)]      it "reads a type synonym as a type" $-      declaresIn "fixities infixr 5 :+\nab12\n  type (:+) :: * -> * -> *\n"+      declaresIn "exports:\n  :+\nfixities infixr 5 :+\nab12\n  type (:+) :: * -> * -> *\n"         `shouldBe` [((InTypes, OpName ":+"), Fixity RightAssoc 5)]      it "reads a type family as a type" $-      declaresIn "fixities infixl 6 ==\nab12\n  type family (==) a b where\n"+      declaresIn "exports:\n  ==\nfixities infixl 6 ==\nab12\n  type family (==) a b where\n"         `shouldBe` [((InTypes, OpName "=="), Fixity LeftAssoc 6)]      it "reads a class as a type" $-      declaresIn "fixities infixl 4 <%>\nab12\n  class (<%>) a where\n"+      declaresIn "exports:\n  <%>\nfixities infixl 4 <%>\nab12\n  class (<%>) a where\n"         `shouldBe` [((InTypes, OpName "<%>"), Fixity LeftAssoc 4)]      it "takes a role declaration as saying the name is a type" $-      declaresIn "fixities infixl 9 !\nab12\n  type role (!) nominal\n"+      declaresIn "exports:\n  !\nfixities infixl 9 !\nab12\n  type role (!) nominal\n"         `shouldBe` [((InTypes, OpName "!"), Fixity LeftAssoc 9)]      it "is not misled by declarations of other names" $-      declaresIn "fixities infixl 9 !\nab12\n  data Other a b where\n  (!) :: Int\n"+      declaresIn "exports:\n  !\nfixities infixl 9 !\nab12\n  data Other a b where\n  (!) :: Int\n"         `shouldBe` [((InTerms, OpName "!"), Fixity LeftAssoc 9)]    describe "the members of a name" $ do@@ -180,12 +181,42 @@               )           ) +    it "gives a type exported without its members none" $+      fmap+        interfaceMembers+        (fromHiFile "M" (HiFile "M" [AvailTC (inM InTypes "T") [inM InTypes "T"]] []))+        `shouldBe` Right (Map.fromList [(OpName "T", Set.empty)])+     it "does not take a type for exported where only its field is" $       fmap         (fmap certainNames . interfaceExports)         (fromHiFile "M" (HiFile "M" [AvailTC (inM InTypes "T") [inM InTerms "field"]] []))         `shouldBe` Right (Just (Set.fromList [(InTerms, OpName "field")])) +  describe "a fixity for a name the module does not export" $ do+    it "is left out of a decoded interface" $+      fmap+        (Map.toList . interfaceDeclares)+        ( fromHiFile+            "M"+            ( HiFile+                "M"+                [Avail (inM InTerms "<+>")]+                [ (InTerms, OpName "<+>", Fixity LeftAssoc 3),+                  (InTerms, OpName "<~>", Fixity RightAssoc 2)+                ]+            )+        )+        `shouldBe` Right [((InTerms, OpName "<+>"), Fixity LeftAssoc 3)]++    it "is left out of what ghc --show-iface prints" $+      declares "exports:\n  <+>\n  parser\nfixities infixl 3 <+>, infixr 2 <~>\n"+        `shouldBe` [(OpName "<+>", Fixity LeftAssoc 3)]++    it "is left out where the module passes on another name spelled the same" $+      declares "exports:\n  GHC.Internal.Base.>>=\nfixities infixr 2 >>=\n"+        `shouldBe` []+   describe "sections it has no use for" $     it "is not confused by the rest of the file" $ do       let out =@@ -194,6 +225,7 @@             \interface Data.Aeson 9103\n\             \  interface hash: 6b4f\n\             \exports:\n\+            \  !\n\             \  Data.Aeson.Types.FromJSON..:\n\             \fixities infixl 9 !\n\             \direct package dependencies: base-4.20.2.0 bytestring-0.12.2.0\n\@@ -214,7 +246,7 @@         `shouldBe` Nothing      it "reads one that names the module asked for" $-      declares "fixities infixl 9 !\n" `shouldBe` [(OpName "!", Fixity LeftAssoc 9)]+      declares "exports:\n  !\nfixities infixl 9 !\n" `shouldBe` [(OpName "!", Fixity LeftAssoc 9)]  header :: Text -> Text header modName = "interface " <> modName <> " 9103\n"
tests/Tilia/Fixity/PlanSpec.hs view
@@ -33,10 +33,12 @@ import Data.Text qualified as T import Data.Text.Encoding qualified as T import Data.Text.IO qualified as T+import Data.Time (addUTCTime, getCurrentTime) import System.Directory   ( createDirectoryIfMissing,     doesFileExist,     getPermissions,+    setModificationTime,     setOwnerExecutable,     setPermissions,   )@@ -48,6 +50,7 @@ import Test.Hspec import Tilia.Cpp.Macros (Macros (..)) import Tilia.Fixity+import Tilia.Fixity.Cache (PlanToken (..), openCache, storePackageCache) import Tilia.Fixity.PackageDb   ( Installed (..),     InstalledPackage (..),@@ -65,7 +68,7 @@ spec = do   preparation   tokens-  compilerMacros+  plannedMacros   reexports   hscModules   generatedModuleSpec@@ -117,17 +120,34 @@             ]         } --- | What a plan says about the macros of the compiler it is for.-compilerMacros :: Spec-compilerMacros = describe "the macros a plan settles" $ do+-- | What a plan says about macros.+plannedMacros :: Spec+plannedMacros = describe "the macros a plan settles" $ do   it "has those of other compilers undefined under a plan for GHC" $     macroUndefined (macrosOf (planFor "ghc-9.10.3"))       `shouldBe` Set.fromList ["__MHS__", "__HUGS__"]    it "has nothing undefined under a plan for another compiler" $     macroUndefined (macrosOf (planFor "mhs-0.15.4.0")) `shouldBe` Set.empty++  it "holds every package of the plan, as its version macros spell it" $+    macroPlannedPackages (macrosOf twoPackages)+      `shouldBe` Just (Set.fromList ["base", "data_default"])   where     planFor compiler = BuildPlan{bpCompiler = compiler, bpPackages = []}+    twoPackages =+      BuildPlan+        { bpCompiler = "ghc-9.10.3",+          bpPackages =+            [ PlanPackage+                { ppName = name,+                  ppVersion = "1.0",+                  ppSource = PreExisting,+                  ppComponents = []+                }+            | name <- ["base", "data-default"]+            ]+        }  -- | 'Plan.checkReadiness', with the cache in use as it is by default. checkReadiness :: [PlanComponent] -> FilePath -> IO Readiness@@ -215,6 +235,25 @@       readIORef steps         `shouldReturn` [solving, narrowSolve, fetching, narrowFetch] +  it "does not solve again where solving left the plan as it was" $+    withChangedPackage $ \dir -> do+      stale <- checkReadiness [] dir+      stale `shouldBe` PlanStale [dir </> "thing.cabal"]+      steps <- newIORef []+      prepareWith (obliging steps) (futilityFor (Do #useCache) dir) [] dir stale+        `shouldReturn` Right ()+      readIORef steps `shouldReturn` [solving]+      checkReadiness [] dir `shouldReturn` Ready++  it "solves again where a file changed after the last solve" $+    withChangedPackage $ \dir -> do+      stale <- checkReadiness [] dir+      steps <- newIORef []+      _ <- prepareWith (obliging steps) (futilityFor (Do #useCache) dir) [] dir stale+      later <- addUTCTime 60 <$> getCurrentTime+      setModificationTime (dir </> "thing.cabal") later+      checkReadiness [] dir `shouldReturn` PlanStale [dir </> "thing.cabal"]+   describe "a plan narrower than the run" $ do     it "notices a component the plan says nothing about" $       withTempProject (Just twoComponents) $ \dir ->@@ -379,6 +418,19 @@     chased "module M ((<+>)) where\nimport Control.Arrow\ninfixr 3 <+>\n(<+>) :: Int -> Int -> Int\na <+> b = a + b\n"       `shouldReturn` Just (Fixity RightAssoc 3) +  it "is not the module's own where the module does not export it" $+    chased "module M (parser) where\ninfixr 3 <+>\n(<+>) :: Int -> Int -> Int\na <+> b = a + b\nparser :: Int\nparser = 1 <+> 2\n"+      `shouldReturn` Nothing++  it "is the module's own for a constructor handed on with its type" $ do+    answer <- chasedModule "module M (T (..)) where\ndata T = Int :+ Int\ninfixl 6 :+\n"+    Map.lookup (InTerms, OpName ":+") (establishedFixities answer)+      `shouldBe` Just (Fixity LeftAssoc 6)++  it "is not the module's own for a constructor its type is handed on without" $ do+    answer <- chasedModule "module M (T) where\ndata T = Int :+ Int\ninfixl 6 :+\n"+    Map.lookup (InTerms, OpName ":+") (establishedFixities answer) `shouldBe` Nothing+   it "is not answered at all when the module it came from cannot be read" $     chased "module M ((<+>)) where\nimport No.Such.Module\n"       `shouldReturn` Nothing@@ -575,6 +627,41 @@       withLayouts $         \xdg _ -> guessedPackageCacheRoot `shouldReturn` xdg +  describe "and where it was remembered" $ do+    it "is not asked again where the plan's tarballs are there" $+      withRemembered True $ \root asked found -> do+        asked `shouldBe` []+        found `shouldBe` [root </> "hackage.haskell.org/thing/1.0/thing-1.0.tar.gz"]++    it "is asked again where a tarball of the plan is not there" $+      withRemembered False $ \_ asked _ ->+        asked `shouldBe` ["path"]++-- | Find the tarballs of a plan wanting one package from Hackage, where the+-- package cache was remembered to be a directory of its own, holding the+-- tarball or not, and hand over the directory, the commands the stand-in+-- for @cabal@ was given, and where each tarball was found.+withRemembered ::+  Bool ->+  (FilePath -> [String] -> [FilePath] -> Expectation) ->+  Expectation+withRemembered holding act =+  withSystemTempDirectory "tilia-remembered" $ \root -> do+    let at = root </> "hackage.haskell.org" </> "thing" </> "1.0"+    when holding $ do+      createDirectoryIfMissing True at+      T.writeFile (at </> "thing-1.0.tar.gz") "not really a tarball"+    cache <- openCache (Do #useCache) (PlanToken (T.pack (takeBaseName root)))+    storePackageCache cache root+    withTempProject (Just (fromRepository hackage)) $ \dir ->+      readBuildPlan (planPathFor dir) >>= \case+        Left why -> expectationFailure (T.unpack why)+        Right plan -> do+          (asked, found) <- runsCabal (plannedTarballs cache plan)+          act root asked (fmap snd found)+  where+    hackage = "{\"type\":\"secure-repo\",\"uri\":\"https://hackage.haskell.org/\"}"+ -- | A plan handed over to be taken as it is. givenPlans :: Spec givenPlans = describe "a plan trusted as up to date" $ do@@ -721,9 +808,11 @@         readBuildPlan (planPathFor dir) >>= \case           Left why -> expectationFailure (T.unpack why)           Right plan ->-            plannedTarballs plan >>= \case-              [(_, found)] -> act found-              other -> expectationFailure (show (fmap snd other))+            openCache (Don't #useCache) (PlanToken "")+              >>= (`plannedTarballs` plan)+              >>= \case+                [(_, found)] -> act found+                other -> expectationFailure (show (fmap snd other))   where     put cabalDir (repo, held, version) = do       let at =@@ -1287,6 +1376,13 @@         Map.lookup (OpName "T") members           `shouldBe` Just (Set.fromList [OpName "A", OpName ":|"]) +    it "reads none for a type a local module exports without them"+      $ withFakeProject+        [("src/Members.hs", "module Members (T) where\ndata T = A | Int :| Int\n")]+      $ \rs -> do+        members <- membersIn rs "Members"+        Map.lookup (OpName "T") members `shouldBe` Just Set.empty+     it "follows a type to the module that declares it"       $ withFakeProject         [ ("src/Facade.hs", "module Facade (T (..)) where\nimport Inner\n"),@@ -1591,6 +1687,17 @@         lookupFixity scope InTerms Nothing (OpName "Node")           `shouldBe` Unresolved (ModuleChain ("Core" :| ["A"]) :| []) +    it "brings in no operator with a type exported without its members"+      $ withFakeProject+        [ ("src/Ops.hs", "module Ops (T, (<+>)) where\ninfixr 1 <+>\ndata T = T\n(<+>) :: Int -> Int -> Int\na <+> b = a + b\n"),+          ("src/Other.hs", "module Other ((<+>)) where\ninfixl 6 <+>\n(<+>) :: Int -> Int -> Int\na <+> b = a - b\n")+        ]+      $ \rs -> do+        let m = parse "module C (w) where\nimport Ops (T (..))\nimport Other\nw = 1 <+> 2\n"+        scope <- scopeFor rs (Is #implicitPrelude) (pure (pmModule m))+        lookupFixity scope InTerms Nothing (OpName "<+>")+          `shouldBe` Resolved (Fixity LeftAssoc 6) (DeclaredIn "Other")+   describe "the whole pipeline, from source text to a fixity" $ do     it "resolves an operator through a real import" $       endToEnd resolver "module M where\nimport Prettyprinter\n" $ \scope ->@@ -1733,6 +1840,23 @@  writePlan :: FilePath -> Text -> IO () writePlan dir = T.writeFile (planPathFor dir)++-- | A project whose @.cabal@ file changed after its plan was written, under+-- a plan of its own, so that what it leaves in the cache is its own.+withChangedPackage :: (FilePath -> IO a) -> IO a+withChangedPackage act =+  withTempProject Nothing $ \dir -> do+    writePlan dir $+      "{\"compiler-id\":\"ghc-0.0\",\"install-plan\":\+      \[{\"pkg-name\":\""+        <> T.pack (takeBaseName dir)+        <> "\",\"pkg-version\":\"1.0\",\"component-name\":\"lib\",\+           \\"pkg-src\":{\"type\":\"local\",\"path\":\"/nowhere\"}}]}"+    now <- getCurrentTime+    setModificationTime (planPathFor dir) (addUTCTime (-60) now)+    T.writeFile (dir </> "thing.cabal") ""+    setModificationTime (dir </> "thing.cabal") (addUTCTime (-30) now)+    act dir  -- | A plan naming one package that no package cache can have a tarball -- for, so that reading it leaves something to fetch.
tests/Tilia/FixitySpec.hs view
@@ -459,6 +459,10 @@       listedMembersIn "module M (T (..)) where\nimport Elsewhere\n"         `shouldBe` [] +    it "hands on no members of a name exported without them" $+      listedMembersIn "module M (T, U) where\nimport Elsewhere\ndata T = A | Int :| Int\n"+        `shouldBe` [(OpName "T", []), (OpName "U", [])]+   describe "layer 2: imports" $ do     it "brings in an operator among the members of a type" $       lookupFixity (scopeWithMembers "import Members (T (..))\n") InTerms Nothing (OpName ":|")
tests/Tilia/Gen.hs view
@@ -7,8 +7,6 @@     PlainDoc (..),     FlatSafeDoc (..),     AnySpan (..),-    SingleLineSpan (..),-    MultiLineSpan (..),     docTexts,   ) where@@ -29,29 +27,6 @@ instance Arbitrary AnySpan where   arbitrary = AnySpan <$> genSpan   shrink (AnySpan s) = AnySpan <$> shrinkSpan s---- | A span that occupied one line.-newtype SingleLineSpan = SingleLineSpan Span-  deriving (Eq, Show)--instance Arbitrary SingleLineSpan where-  arbitrary = do-    l <- choose (1, 20)-    c0 <- choose (1, 40)-    c1 <- choose (c0, 80)-    pure (SingleLineSpan (mkSpan (l, c0) (l, c1)))---- | A span that ran across several lines.-newtype MultiLineSpan = MultiLineSpan Span-  deriving (Eq, Show)--instance Arbitrary MultiLineSpan where-  arbitrary = do-    l0 <- choose (1, 20)-    n <- choose (1, 5)-    c0 <- choose (1, 40)-    c1 <- choose (1, 80)-    pure (MultiLineSpan (mkSpan (l0, c0) (l0 + n, c1)))  genSpan :: Gen Span genSpan = do
tests/Tilia/WithProjectPlan.hs view
@@ -14,7 +14,7 @@ where  import Control.Monad (filterM, unless)-import Data.Choice (pattern Do)+import Data.Choice (pattern Do, pattern Don't) import Data.Maybe (isNothing, listToMaybe, mapMaybe) import Data.Set (Set) import Data.Set qualified as Set@@ -31,6 +31,7 @@     componentsOfTarget,     describeTargetProblem,   )+import Tilia.Fixity.Cache (PlanToken (..), openCache) import Tilia.Fixity.PackageDb   ( Installed (..),     InstalledPackage (..),@@ -76,11 +77,12 @@ fetchMissingSources :: BuildPlan -> IO () fetchMissingSources plan = do   installed <- readInstalledPackages+  noCache <- openCache (Don't #useCache) (PlanToken "")   let unread = modulelessIn installed   absent <-     filterM (fmap not . doesFileExist . snd)       . filter (not . (`Set.member` unread) . ppName . fst)-      =<< plannedTarballs plan+      =<< plannedTarballs noCache plan   unless (null absent) $ do     putStrLn ("fetching the source of " <> show (length absent) <> " package(s)")     refused <- filterM (fmap isNothing . fetch . fst) absent
tilia.cabal view
@@ -1,6 +1,6 @@ cabal-version: 2.4 name: tilia-version: 0.1.0.0+version: 0.1.1.0 license: BSD-3-Clause license-file: LICENSE.md maintainer: Mark Karpov <markkarpov92@gmail.com>@@ -252,6 +252,7 @@     temporary ^>=1.3,     text >=2.1 && <3,     tilia,+    time >=1.9 && <1.16,     zlib >=0.6 && <0.8,    ghc-options: