diff --git a/.buildkite/pipeline.yml b/.buildkite/pipeline.yml index c307297e..f719d92b 100644 --- a/.buildkite/pipeline.yml +++ b/.buildkite/pipeline.yml @@ -1,15 +1,11 @@ steps: - - label: Build and test with GHC 8.10.7 - command: | - nix-build --keep-going --no-out-link --argstr ormoluCompiler ghc8107 - timeout: 100 - label: Build and test with GHC 9.0.2 command: | nix-build --keep-going --no-out-link --argstr ormoluCompiler ghc902 timeout: 100 - - label: Build and test with GHC 9.2.1 + - label: Build and test with GHC 9.2.4 command: | - nix-build --keep-going --no-out-link --argstr ormoluCompiler ghc921 + nix-build --keep-going --no-out-link --argstr ormoluCompiler ghc924 timeout: 100 - wait - label: Check formatting @@ -22,6 +18,7 @@ steps: if [[ $BUILDKITE_BRANCH == "master" ]]; then ormolu-live/deploy.sh else - nix-build -A ormoluLive.ormoluLive --arg ormoluLiveLink false -j 1 + nix-build -A ormoluLive.ormoluLive -j 1 \ + --arg ormoluLiveLink false --argstr ormoluCompiler ghc8107 fi timeout: 100 diff --git a/CHANGELOG.md b/CHANGELOG.md index 5871306f..f5156a12 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,8 @@ both huge `.cabal` files and a large number of individual modules. [Issue 897](https://github.com/tweag/ormolu/issues/897). +* Switched to `ghc-lib-parser-9.4`. + ## Ormolu 0.5.0.0 * Changed the way operator fixities and precedences are inferred. diff --git a/cabal.project b/cabal.project index 876e7d44..8a08ab04 100644 --- a/cabal.project +++ b/cabal.project @@ -4,3 +4,9 @@ constraints: ormolu +dev -- miso does not specify bounds on servant constraints: servant >=0.18 && <0.20 + +-- prune unnecessary dependencies +constraints: warp -x509, wai-app-static -cryptonite + +-- due to GHCJS 8.10 +allow-older: ghc-lib-parser:base diff --git a/data/examples/declaration/signature/inline/noinline-out.hs b/data/examples/declaration/signature/inline/noinline-out.hs index 96cbb1c6..03209339 100644 --- a/data/examples/declaration/signature/inline/noinline-out.hs +++ b/data/examples/declaration/signature/inline/noinline-out.hs @@ -9,3 +9,7 @@ bar = id baz :: Int -> Int baz = id {-# NOINLINE [~2] baz #-} + +blub :: Int -> Int +blub = baz +{-# OPAQUE blub #-} diff --git a/data/examples/declaration/signature/inline/noinline.hs b/data/examples/declaration/signature/inline/noinline.hs index e648ee12..2fea6535 100644 --- a/data/examples/declaration/signature/inline/noinline.hs +++ b/data/examples/declaration/signature/inline/noinline.hs @@ -11,3 +11,7 @@ baz :: Int -> Int baz = id {-# NOINLINE [~2] baz #-} + +blub :: Int -> Int +blub = baz +{-# opaque blub #-} diff --git a/data/examples/declaration/value/function/lambda-case-out.hs b/data/examples/declaration/value/function/lambda-case-out.hs index c4eedab0..2aaa5783 100644 --- a/data/examples/declaration/value/function/lambda-case-out.hs +++ b/data/examples/declaration/value/function/lambda-case-out.hs @@ -7,3 +7,11 @@ foo = \case 5 -> 10 i | i > 5 -> 11 _ -> 12 + +foo :: Maybe a -> Maybe a -> Maybe a -> Int +foo = \cases Nothing Just {} Nothing -> 1; _ _ _ -> 0 + +foo :: Maybe Int -> Maybe Int -> Int +foo = \cases + (Just a) (Just a) -> a + a + _ _ -> 0 diff --git a/data/examples/declaration/value/function/lambda-case.hs b/data/examples/declaration/value/function/lambda-case.hs index f6f0fb7a..7691778a 100644 --- a/data/examples/declaration/value/function/lambda-case.hs +++ b/data/examples/declaration/value/function/lambda-case.hs @@ -7,3 +7,11 @@ foo = \case 5 -> 10 i | i > 5 -> 11 _ -> 12 + +foo :: Maybe a -> Maybe a -> Maybe a -> Int +foo = \cases Nothing Just{} Nothing -> 1; _ _ _ -> 0 + +foo :: Maybe Int -> Maybe Int -> Int +foo = \cases + (Just a) (Just a) -> a + a + _ _ -> 0 diff --git a/data/examples/declaration/value/function/unboxed-sums-out.hs b/data/examples/declaration/value/function/unboxed-sums-out.hs index 8a860629..c9185f58 100644 --- a/data/examples/declaration/value/function/unboxed-sums-out.hs +++ b/data/examples/declaration/value/function/unboxed-sums-out.hs @@ -22,3 +22,5 @@ baz = (# | | | 10 | | | | | #) + +type UbxPair = (# | #) diff --git a/data/examples/declaration/value/function/unboxed-sums.hs b/data/examples/declaration/value/function/unboxed-sums.hs index ef4e09ee..c4cafc99 100644 --- a/data/examples/declaration/value/function/unboxed-sums.hs +++ b/data/examples/declaration/value/function/unboxed-sums.hs @@ -12,3 +12,5 @@ baz :: (# Int | baz = (# | | | 10 | | | | | #) + +type UbxPair = (# | #) diff --git a/data/examples/other/invalid-haddock-weird-out.hs b/data/examples/other/invalid-haddock-weird-out.hs index a4d16a2c..233f2bbd 100644 --- a/data/examples/other/invalid-haddock-weird-out.hs +++ b/data/examples/other/invalid-haddock-weird-out.hs @@ -1,3 +1,5 @@ {-# LANGUAGE TemplateHaskell #-} -foo = foo -- \|# ${ +foo = foo + +-- \|# ${ diff --git a/default.nix b/default.nix index ad1b38d7..9e1d4f5c 100644 --- a/default.nix +++ b/default.nix @@ -1,4 +1,4 @@ -{ ormoluCompiler ? "ghc8107", +{ ormoluCompiler ? "ghc924", ormoluLiveLink ? true }: @@ -22,27 +22,21 @@ let }; }; in [ - ({ lib, ... }: { - config = { - dontStrip = false; - dontPatchELF = false; - enableDeadCodeElimination = true; - packages.ormolu.writeHieFiles = true; - }; - # Make Cabal reinstallable - options.nonReinstallablePkgs = - # See https://github.com/input-output-hk/haskell.nix/issues/1177 - let adapt = ps: if lib.hasPrefix "ghc9" ormoluCompiler - then ps ++ [ "exceptions" "stm" ] else ps; - in lib.mkOption { apply = ps: adapt (lib.remove "Cabal" ps); }; - }) + { + packages.ormolu.writeHieFiles = true; + } ({ pkgs, lib, ... }: lib.mkIf pkgs.stdenv.hostPlatform.isGhcjs { + reinstallableLibGhc = false; packages.ormolu = { flags.fixity-th = false; writeHieFiles = lib.mkForce false; }; packages.ormolu-live.ghcOptions = lib.optional (!ormoluLiveLink) "-fno-code"; + packages.ghc-lib-parser.patches = [ + # see https://github.com/ghcjs/ghcjs/issues/836 + ./nix/lexer-no-unlifted-newtypes.patch + ]; }) (gitTH "ormolu" "") (gitTH "ormolu-live" "../") @@ -58,6 +52,7 @@ let extractHackageInfo = hsPkgs.extract-hackage-info.components.exes.extract-hackage-info; ormoluLive = hsPkgs.projectCross.ghcjs.hsPkgs.ormolu-live.components.exes.ormolu-live .overrideAttrs (_: pkgs.lib.optionalAttrs (!ormoluLiveLink) { + outputs = [ "out" ]; installPhase = '' mkdir -p $out ''; @@ -65,13 +60,16 @@ let expectedFailures = [ "Agda" + "brittany" "esqueleto" "haxl" "hlint" - "idris" "leksah" + "lens" + "pandoc" "pipes" "postgrest" + "purescript" ]; ormolizedPackages = let @@ -251,31 +249,32 @@ in { find . -name '*.hs' -exec cp --parents {} $out \; ''; }; - binaries = { - Linux = hsPkgs.projectCross.musl64.hsPkgs.ormolu.components.exes.ormolu; + binaries = let hsPkgsOpt = hsPkgs.appendModule { + modules = [{ + dontStrip = false; + dontPatchELF = false; + enableDeadCodeElimination = true; + }]; + }; in { + Linux = hsPkgsOpt.projectCross.musl64.hsPkgs.ormolu.components.exes.ormolu; macOS = pkgs.runCommand "ormolu-macOS" { buildInputs = [ pkgs.macdylibbundler ]; } '' mkdir -p $out/bin - cp ${ormoluExe}/bin/ormolu $out/bin/ormolu + cp ${hsPkgsOpt.ormolu.components.exes.ormolu}/bin/ormolu $out/bin/ormolu chmod 755 $out/bin/ormolu dylibbundler -b \ -x $out/bin/ormolu \ -d $out/bin \ -p '@executable_path' ''; - Windows = hsPkgs.projectCross.mingwW64.hsPkgs.ormolu.components.exes.ormolu; + Windows = hsPkgsOpt.projectCross.mingwW64.hsPkgs.ormolu.components.exes.ormolu; }; -} // pkgs.lib.optionalAttrs (pkgs.lib.hasPrefix "ghc810" ormoluCompiler) { +} // pkgs.lib.optionalAttrs (pkgs.lib.hasPrefix "ghc92" ormoluCompiler) { inherit extractHackageInfo; weeder = pkgs.runCommand "ormolu-weeder" { - buildInputs = [ - ormoluExe - # Weeder >= 2.3 requires an ugly workaround: - # https://github.com/ocharles/weeder/pull/81 - (hsPkgs.tool "weeder" "2.2.0") - ]; + buildInputs = [ (hsPkgs.tool "weeder" "2.4.0") ]; } '' mkdir -p $out export XDG_CACHE_HOME=$TMPDIR/cache @@ -284,6 +283,7 @@ in { --hie-directory ${ormoluExe.hie} \ --hie-directory ${ormolu.components.tests.tests.hie} ''; +} // pkgs.lib.optionalAttrs (pkgs.lib.hasPrefix "ghc810" ormoluCompiler) { ormoluLive = { inherit ormoluLive; website = pkgs.stdenv.mkDerivation { @@ -297,9 +297,10 @@ in { installPhase = '' cp -r . $out ORMOLU_LIVE=${ormoluLive}/bin/ormolu-live.jsexe + # ADVANCED/SIMPLE optimizations break semantics :( closure-compiler \ $ORMOLU_LIVE/all.js --externs $ORMOLU_LIVE/all.js.externs \ - -O ADVANCED --jscomp_off=checkVars -W QUIET \ + -O WHITESPACE_ONLY --jscomp_off=checkVars -W QUIET \ --js_output_file $out/all.min.js ''; }; diff --git a/expected-failures/Agda.txt b/expected-failures/Agda.txt index 3dbcb3e5..98d7042f 100644 --- a/expected-failures/Agda.txt +++ b/expected-failures/Agda.txt @@ -2,7 +2,7 @@ Found .cabal file Agda.cabal, but it did not mention Setup.hs Found .cabal file Agda.cabal, but it did not mention src/data/MAlonzo/src/MAlonzo/RTE.hs Found .cabal file Agda.cabal, but it did not mention src/data/MAlonzo/src/MAlonzo/RTE/Float.hs src/full/Agda/Syntax/Internal.hs -@@ -621,32 +668,28 @@ +@@ -624,32 +671,28 @@ _ -> Nothing ----------------------------------------------------------------------------- @@ -46,6 +46,6 @@ src/full/Agda/Syntax/Internal.hs -- @ AST of input and AST of formatted code differ. - at src/full/Agda/Syntax/Internal.hs:640:5 + at src/full/Agda/Syntax/Internal.hs:643:5 Please, consider reporting the bug. To format anyway, use --unsafe. diff --git a/expected-failures/brittany.txt b/expected-failures/brittany.txt new file mode 100644 index 00000000..3639b4e8 --- /dev/null +++ b/expected-failures/brittany.txt @@ -0,0 +1,611 @@ +Found .cabal file brittany.cabal, but it did not mention data/Test1.hs +Found .cabal file brittany.cabal, but it did not mention data/Test10.hs +Found .cabal file brittany.cabal, but it did not mention data/Test100.hs +Found .cabal file brittany.cabal, but it did not mention data/Test101.hs +Found .cabal file brittany.cabal, but it did not mention data/Test102.hs +Found .cabal file brittany.cabal, but it did not mention data/Test103.hs +Found .cabal file brittany.cabal, but it did not mention data/Test104.hs +Found .cabal file brittany.cabal, but it did not mention data/Test105.hs +Found .cabal file brittany.cabal, but it did not mention data/Test106.hs +Found .cabal file brittany.cabal, but it did not mention data/Test107.hs +Found .cabal file brittany.cabal, but it did not mention data/Test108.hs +Found .cabal file brittany.cabal, but it did not mention data/Test109.hs +Found .cabal file brittany.cabal, but it did not mention data/Test11.hs +Found .cabal file brittany.cabal, but it did not mention data/Test110.hs +Found .cabal file brittany.cabal, but it did not mention data/Test111.hs +Found .cabal file brittany.cabal, but it did not mention data/Test112.hs +Found .cabal file brittany.cabal, but it did not mention data/Test113.hs +Found .cabal file brittany.cabal, but it did not mention data/Test114.hs +Found .cabal file brittany.cabal, but it did not mention data/Test115.hs +Found .cabal file brittany.cabal, but it did not mention data/Test116.hs +Found .cabal file brittany.cabal, but it did not mention data/Test117.hs +Found .cabal file brittany.cabal, but it did not mention data/Test118.hs +Found .cabal file brittany.cabal, but it did not mention data/Test119.hs +Found .cabal file brittany.cabal, but it did not mention data/Test12.hs +Found .cabal file brittany.cabal, but it did not mention data/Test120.hs +Found .cabal file brittany.cabal, but it did not mention data/Test121.hs +Found .cabal file brittany.cabal, but it did not mention data/Test122.hs +Found .cabal file brittany.cabal, but it did not mention data/Test123.hs +Found .cabal file brittany.cabal, but it did not mention data/Test124.hs +Found .cabal file brittany.cabal, but it did not mention data/Test125.hs +Found .cabal file brittany.cabal, but it did not mention data/Test126.hs +Found .cabal file brittany.cabal, but it did not mention data/Test127.hs +Found .cabal file brittany.cabal, but it did not mention data/Test128.hs +Found .cabal file brittany.cabal, but it did not mention data/Test129.hs +Found .cabal file brittany.cabal, but it did not mention data/Test13.hs +Found .cabal file brittany.cabal, but it did not mention data/Test130.hs +Found .cabal file brittany.cabal, but it did not mention data/Test131.hs +Found .cabal file brittany.cabal, but it did not mention data/Test132.hs +Found .cabal file brittany.cabal, but it did not mention data/Test133.hs +Found .cabal file brittany.cabal, but it did not mention data/Test134.hs +Found .cabal file brittany.cabal, but it did not mention data/Test135.hs +Found .cabal file brittany.cabal, but it did not mention data/Test136.hs +Found .cabal file brittany.cabal, but it did not mention data/Test137.hs +Found .cabal file brittany.cabal, but it did not mention data/Test138.hs +Found .cabal file brittany.cabal, but it did not mention data/Test139.hs +Found .cabal file brittany.cabal, but it did not mention data/Test14.hs +Found .cabal file brittany.cabal, but it did not mention data/Test140.hs +Found .cabal file brittany.cabal, but it did not mention data/Test141.hs +Found .cabal file brittany.cabal, but it did not mention data/Test142.hs +Found .cabal file brittany.cabal, but it did not mention data/Test143.hs +Found .cabal file brittany.cabal, but it did not mention data/Test144.hs +Found .cabal file brittany.cabal, but it did not mention data/Test145.hs +Found .cabal file brittany.cabal, but it did not mention data/Test146.hs +Found .cabal file brittany.cabal, but it did not mention data/Test147.hs +Found .cabal file brittany.cabal, but it did not mention data/Test148.hs +Found .cabal file brittany.cabal, but it did not mention data/Test149.hs +Found .cabal file brittany.cabal, but it did not mention data/Test15.hs +Found .cabal file brittany.cabal, but it did not mention data/Test150.hs +Found .cabal file brittany.cabal, but it did not mention data/Test151.hs +Found .cabal file brittany.cabal, but it did not mention data/Test152.hs +Found .cabal file brittany.cabal, but it did not mention data/Test153.hs +Found .cabal file brittany.cabal, but it did not mention data/Test154.hs +Found .cabal file brittany.cabal, but it did not mention data/Test155.hs +Found .cabal file brittany.cabal, but it did not mention data/Test156.hs +Found .cabal file brittany.cabal, but it did not mention data/Test157.hs +Found .cabal file brittany.cabal, but it did not mention data/Test158.hs +Found .cabal file brittany.cabal, but it did not mention data/Test159.hs +Found .cabal file brittany.cabal, but it did not mention data/Test16.hs +Found .cabal file brittany.cabal, but it did not mention data/Test160.hs +Found .cabal file brittany.cabal, but it did not mention data/Test161.hs +Found .cabal file brittany.cabal, but it did not mention data/Test162.hs +Found .cabal file brittany.cabal, but it did not mention data/Test163.hs +Found .cabal file brittany.cabal, but it did not mention data/Test164.hs +Found .cabal file brittany.cabal, but it did not mention data/Test165.hs +Found .cabal file brittany.cabal, but it did not mention data/Test166.hs +Found .cabal file brittany.cabal, but it did not mention data/Test167.hs +Found .cabal file brittany.cabal, but it did not mention data/Test168.hs +Found .cabal file brittany.cabal, but it did not mention data/Test169.hs +Found .cabal file brittany.cabal, but it did not mention data/Test17.hs +Found .cabal file brittany.cabal, but it did not mention data/Test170.hs +Found .cabal file brittany.cabal, but it did not mention data/Test171.hs +Found .cabal file brittany.cabal, but it did not mention data/Test172.hs +Found .cabal file brittany.cabal, but it did not mention data/Test173.hs +Found .cabal file brittany.cabal, but it did not mention data/Test174.hs +Found .cabal file brittany.cabal, but it did not mention data/Test175.hs +Found .cabal file brittany.cabal, but it did not mention data/Test176.hs +Found .cabal file brittany.cabal, but it did not mention data/Test177.hs +Found .cabal file brittany.cabal, but it did not mention data/Test178.hs +Found .cabal file brittany.cabal, but it did not mention data/Test179.hs +Found .cabal file brittany.cabal, but it did not mention data/Test18.hs +Found .cabal file brittany.cabal, but it did not mention data/Test180.hs +Found .cabal file brittany.cabal, but it did not mention data/Test181.hs +Found .cabal file brittany.cabal, but it did not mention data/Test182.hs +Found .cabal file brittany.cabal, but it did not mention data/Test183.hs +Found .cabal file brittany.cabal, but it did not mention data/Test184.hs +Found .cabal file brittany.cabal, but it did not mention data/Test185.hs +Found .cabal file brittany.cabal, but it did not mention data/Test186.hs +Found .cabal file brittany.cabal, but it did not mention data/Test187.hs +Found .cabal file brittany.cabal, but it did not mention data/Test188.hs +Found .cabal file brittany.cabal, but it did not mention data/Test189.hs +Found .cabal file brittany.cabal, but it did not mention data/Test19.hs +Found .cabal file brittany.cabal, but it did not mention data/Test190.hs +Found .cabal file brittany.cabal, but it did not mention data/Test191.hs +Found .cabal file brittany.cabal, but it did not mention data/Test192.hs +Found .cabal file brittany.cabal, but it did not mention data/Test193.hs +Found .cabal file brittany.cabal, but it did not mention data/Test194.hs +Found .cabal file brittany.cabal, but it did not mention data/Test195.hs +Found .cabal file brittany.cabal, but it did not mention data/Test196.hs +Found .cabal file brittany.cabal, but it did not mention data/Test197.hs +Found .cabal file brittany.cabal, but it did not mention data/Test198.hs +Found .cabal file brittany.cabal, but it did not mention data/Test199.hs +Found .cabal file brittany.cabal, but it did not mention data/Test2.hs +Found .cabal file brittany.cabal, but it did not mention data/Test20.hs +Found .cabal file brittany.cabal, but it did not mention data/Test200.hs +Found .cabal file brittany.cabal, but it did not mention data/Test201.hs +Found .cabal file brittany.cabal, but it did not mention data/Test202.hs +Found .cabal file brittany.cabal, but it did not mention data/Test203.hs +Found .cabal file brittany.cabal, but it did not mention data/Test204.hs +Found .cabal file brittany.cabal, but it did not mention data/Test205.hs +Found .cabal file brittany.cabal, but it did not mention data/Test206.hs +Found .cabal file brittany.cabal, but it did not mention data/Test207.hs +Found .cabal file brittany.cabal, but it did not mention data/Test208.hs +Found .cabal file brittany.cabal, but it did not mention data/Test209.hs +Found .cabal file brittany.cabal, but it did not mention data/Test21.hs +Found .cabal file brittany.cabal, but it did not mention data/Test210.hs +Found .cabal file brittany.cabal, but it did not mention data/Test211.hs +Found .cabal file brittany.cabal, but it did not mention data/Test212.hs +Found .cabal file brittany.cabal, but it did not mention data/Test213.hs +Found .cabal file brittany.cabal, but it did not mention data/Test214.hs +Found .cabal file brittany.cabal, but it did not mention data/Test215.hs +Found .cabal file brittany.cabal, but it did not mention data/Test216.hs +Found .cabal file brittany.cabal, but it did not mention data/Test217.hs +Found .cabal file brittany.cabal, but it did not mention data/Test218.hs +Found .cabal file brittany.cabal, but it did not mention data/Test219.hs +Found .cabal file brittany.cabal, but it did not mention data/Test22.hs +Found .cabal file brittany.cabal, but it did not mention data/Test220.hs +Found .cabal file brittany.cabal, but it did not mention data/Test221.hs +Found .cabal file brittany.cabal, but it did not mention data/Test222.hs +Found .cabal file brittany.cabal, but it did not mention data/Test223.hs +Found .cabal file brittany.cabal, but it did not mention data/Test224.hs +Found .cabal file brittany.cabal, but it did not mention data/Test225.hs +Found .cabal file brittany.cabal, but it did not mention data/Test226.hs +Found .cabal file brittany.cabal, but it did not mention data/Test227.hs +Found .cabal file brittany.cabal, but it did not mention data/Test228.hs +Found .cabal file brittany.cabal, but it did not mention data/Test229.hs +Found .cabal file brittany.cabal, but it did not mention data/Test23.hs +Found .cabal file brittany.cabal, but it did not mention data/Test230.hs +Found .cabal file brittany.cabal, but it did not mention data/Test231.hs +Found .cabal file brittany.cabal, but it did not mention data/Test232.hs +Found .cabal file brittany.cabal, but it did not mention data/Test233.hs +Found .cabal file brittany.cabal, but it did not mention data/Test234.hs +Found .cabal file brittany.cabal, but it did not mention data/Test235.hs +Found .cabal file brittany.cabal, but it did not mention data/Test236.hs +Found .cabal file brittany.cabal, but it did not mention data/Test237.hs +Found .cabal file brittany.cabal, but it did not mention data/Test238.hs +Found .cabal file brittany.cabal, but it did not mention data/Test239.hs +Found .cabal file brittany.cabal, but it did not mention data/Test24.hs +Found .cabal file brittany.cabal, but it did not mention data/Test240.hs +Found .cabal file brittany.cabal, but it did not mention data/Test241.hs +Found .cabal file brittany.cabal, but it did not mention data/Test242.hs +Found .cabal file brittany.cabal, but it did not mention data/Test243.hs +Found .cabal file brittany.cabal, but it did not mention data/Test244.hs +Found .cabal file brittany.cabal, but it did not mention data/Test245.hs +Found .cabal file brittany.cabal, but it did not mention data/Test246.hs +Found .cabal file brittany.cabal, but it did not mention data/Test247.hs +Found .cabal file brittany.cabal, but it did not mention data/Test248.hs +Found .cabal file brittany.cabal, but it did not mention data/Test249.hs +Found .cabal file brittany.cabal, but it did not mention data/Test25.hs +Found .cabal file brittany.cabal, but it did not mention data/Test250.hs +Found .cabal file brittany.cabal, but it did not mention data/Test251.hs +Found .cabal file brittany.cabal, but it did not mention data/Test252.hs +Found .cabal file brittany.cabal, but it did not mention data/Test253.hs +Found .cabal file brittany.cabal, but it did not mention data/Test254.hs +Found .cabal file brittany.cabal, but it did not mention data/Test255.hs +Found .cabal file brittany.cabal, but it did not mention data/Test256.hs +Found .cabal file brittany.cabal, but it did not mention data/Test257.hs +Found .cabal file brittany.cabal, but it did not mention data/Test258.hs +Found .cabal file brittany.cabal, but it did not mention data/Test259.hs +Found .cabal file brittany.cabal, but it did not mention data/Test26.hs +Found .cabal file brittany.cabal, but it did not mention data/Test260.hs +Found .cabal file brittany.cabal, but it did not mention data/Test261.hs +Found .cabal file brittany.cabal, but it did not mention data/Test262.hs +Found .cabal file brittany.cabal, but it did not mention data/Test263.hs +Found .cabal file brittany.cabal, but it did not mention data/Test264.hs +Found .cabal file brittany.cabal, but it did not mention data/Test265.hs +Found .cabal file brittany.cabal, but it did not mention data/Test266.hs +Found .cabal file brittany.cabal, but it did not mention data/Test267.hs +Found .cabal file brittany.cabal, but it did not mention data/Test268.hs +Found .cabal file brittany.cabal, but it did not mention data/Test269.hs +Found .cabal file brittany.cabal, but it did not mention data/Test27.hs +Found .cabal file brittany.cabal, but it did not mention data/Test270.hs +Found .cabal file brittany.cabal, but it did not mention data/Test271.hs +Found .cabal file brittany.cabal, but it did not mention data/Test272.hs +Found .cabal file brittany.cabal, but it did not mention data/Test273.hs +Found .cabal file brittany.cabal, but it did not mention data/Test274.hs +Found .cabal file brittany.cabal, but it did not mention data/Test275.hs +Found .cabal file brittany.cabal, but it did not mention data/Test276.hs +Found .cabal file brittany.cabal, but it did not mention data/Test277.hs +Found .cabal file brittany.cabal, but it did not mention data/Test278.hs +Found .cabal file brittany.cabal, but it did not mention data/Test279.hs +Found .cabal file brittany.cabal, but it did not mention data/Test28.hs +Found .cabal file brittany.cabal, but it did not mention data/Test280.hs +Found .cabal file brittany.cabal, but it did not mention data/Test281.hs +Found .cabal file brittany.cabal, but it did not mention data/Test282.hs +Found .cabal file brittany.cabal, but it did not mention data/Test283.hs +Found .cabal file brittany.cabal, but it did not mention data/Test284.hs +Found .cabal file brittany.cabal, but it did not mention data/Test285.hs +Found .cabal file brittany.cabal, but it did not mention data/Test286.hs +Found .cabal file brittany.cabal, but it did not mention data/Test287.hs +Found .cabal file brittany.cabal, but it did not mention data/Test288.hs +Found .cabal file brittany.cabal, but it did not mention data/Test289.hs +Found .cabal file brittany.cabal, but it did not mention data/Test29.hs +Found .cabal file brittany.cabal, but it did not mention data/Test290.hs +Found .cabal file brittany.cabal, but it did not mention data/Test291.hs +Found .cabal file brittany.cabal, but it did not mention data/Test292.hs +Found .cabal file brittany.cabal, but it did not mention data/Test293.hs +Found .cabal file brittany.cabal, but it did not mention data/Test294.hs +Found .cabal file brittany.cabal, but it did not mention data/Test295.hs +Found .cabal file brittany.cabal, but it did not mention data/Test296.hs +Found .cabal file brittany.cabal, but it did not mention data/Test297.hs +Found .cabal file brittany.cabal, but it did not mention data/Test298.hs +Found .cabal file brittany.cabal, but it did not mention data/Test299.hs +Found .cabal file brittany.cabal, but it did not mention data/Test3.hs +Found .cabal file brittany.cabal, but it did not mention data/Test30.hs +Found .cabal file brittany.cabal, but it did not mention data/Test300.hs +Found .cabal file brittany.cabal, but it did not mention data/Test301.hs +Found .cabal file brittany.cabal, but it did not mention data/Test302.hs +Found .cabal file brittany.cabal, but it did not mention data/Test303.hs +Found .cabal file brittany.cabal, but it did not mention data/Test304.hs +Found .cabal file brittany.cabal, but it did not mention data/Test305.hs +Found .cabal file brittany.cabal, but it did not mention data/Test306.hs +Found .cabal file brittany.cabal, but it did not mention data/Test307.hs +Found .cabal file brittany.cabal, but it did not mention data/Test308.hs +Found .cabal file brittany.cabal, but it did not mention data/Test309.hs +Found .cabal file brittany.cabal, but it did not mention data/Test31.hs +Found .cabal file brittany.cabal, but it did not mention data/Test310.hs +Found .cabal file brittany.cabal, but it did not mention data/Test311.hs +Found .cabal file brittany.cabal, but it did not mention data/Test312.hs +Found .cabal file brittany.cabal, but it did not mention data/Test313.hs +Found .cabal file brittany.cabal, but it did not mention data/Test314.hs +Found .cabal file brittany.cabal, but it did not mention data/Test315.hs +Found .cabal file brittany.cabal, but it did not mention data/Test316.hs +Found .cabal file brittany.cabal, but it did not mention data/Test317.hs +Found .cabal file brittany.cabal, but it did not mention data/Test318.hs +Found .cabal file brittany.cabal, but it did not mention data/Test319.hs +Found .cabal file brittany.cabal, but it did not mention data/Test32.hs +Found .cabal file brittany.cabal, but it did not mention data/Test320.hs +Found .cabal file brittany.cabal, but it did not mention data/Test321.hs +Found .cabal file brittany.cabal, but it did not mention data/Test322.hs +Found .cabal file brittany.cabal, but it did not mention data/Test323.hs +Found .cabal file brittany.cabal, but it did not mention data/Test324.hs +Found .cabal file brittany.cabal, but it did not mention data/Test325.hs +Found .cabal file brittany.cabal, but it did not mention data/Test326.hs +Found .cabal file brittany.cabal, but it did not mention data/Test327.hs +Found .cabal file brittany.cabal, but it did not mention data/Test328.hs +Found .cabal file brittany.cabal, but it did not mention data/Test329.hs +Found .cabal file brittany.cabal, but it did not mention data/Test33.hs +Found .cabal file brittany.cabal, but it did not mention data/Test330.hs +Found .cabal file brittany.cabal, but it did not mention data/Test331.hs +Found .cabal file brittany.cabal, but it did not mention data/Test332.hs +Found .cabal file brittany.cabal, but it did not mention data/Test333.hs +Found .cabal file brittany.cabal, but it did not mention data/Test334.hs +Found .cabal file brittany.cabal, but it did not mention data/Test335.hs +Found .cabal file brittany.cabal, but it did not mention data/Test336.hs +Found .cabal file brittany.cabal, but it did not mention data/Test337.hs +Found .cabal file brittany.cabal, but it did not mention data/Test338.hs +Found .cabal file brittany.cabal, but it did not mention data/Test339.hs +Found .cabal file brittany.cabal, but it did not mention data/Test34.hs +Found .cabal file brittany.cabal, but it did not mention data/Test340.hs +Found .cabal file brittany.cabal, but it did not mention data/Test341.hs +Found .cabal file brittany.cabal, but it did not mention data/Test342.hs +Found .cabal file brittany.cabal, but it did not mention data/Test343.hs +Found .cabal file brittany.cabal, but it did not mention data/Test344.hs +Found .cabal file brittany.cabal, but it did not mention data/Test345.hs +Found .cabal file brittany.cabal, but it did not mention data/Test346.hs +Found .cabal file brittany.cabal, but it did not mention data/Test347.hs +Found .cabal file brittany.cabal, but it did not mention data/Test348.hs +Found .cabal file brittany.cabal, but it did not mention data/Test349.hs +Found .cabal file brittany.cabal, but it did not mention data/Test35.hs +Found .cabal file brittany.cabal, but it did not mention data/Test350.hs +Found .cabal file brittany.cabal, but it did not mention data/Test351.hs +Found .cabal file brittany.cabal, but it did not mention data/Test352.hs +Found .cabal file brittany.cabal, but it did not mention data/Test353.hs +Found .cabal file brittany.cabal, but it did not mention data/Test354.hs +Found .cabal file brittany.cabal, but it did not mention data/Test355.hs +Found .cabal file brittany.cabal, but it did not mention data/Test356.hs +Found .cabal file brittany.cabal, but it did not mention data/Test357.hs +Found .cabal file brittany.cabal, but it did not mention data/Test358.hs +Found .cabal file brittany.cabal, but it did not mention data/Test359.hs +Found .cabal file brittany.cabal, but it did not mention data/Test36.hs +Found .cabal file brittany.cabal, but it did not mention data/Test360.hs +Found .cabal file brittany.cabal, but it did not mention data/Test361.hs +Found .cabal file brittany.cabal, but it did not mention data/Test362.hs +Found .cabal file brittany.cabal, but it did not mention data/Test363.hs +Found .cabal file brittany.cabal, but it did not mention data/Test364.hs +Found .cabal file brittany.cabal, but it did not mention data/Test365.hs +Found .cabal file brittany.cabal, but it did not mention data/Test366.hs +Found .cabal file brittany.cabal, but it did not mention data/Test367.hs +Found .cabal file brittany.cabal, but it did not mention data/Test368.hs +Found .cabal file brittany.cabal, but it did not mention data/Test369.hs +Found .cabal file brittany.cabal, but it did not mention data/Test37.hs +Found .cabal file brittany.cabal, but it did not mention data/Test370.hs +Found .cabal file brittany.cabal, but it did not mention data/Test371.hs +Found .cabal file brittany.cabal, but it did not mention data/Test372.hs +Found .cabal file brittany.cabal, but it did not mention data/Test373.hs +Found .cabal file brittany.cabal, but it did not mention data/Test374.hs +Found .cabal file brittany.cabal, but it did not mention data/Test375.hs +Found .cabal file brittany.cabal, but it did not mention data/Test376.hs +Found .cabal file brittany.cabal, but it did not mention data/Test377.hs +Found .cabal file brittany.cabal, but it did not mention data/Test378.hs +Found .cabal file brittany.cabal, but it did not mention data/Test379.hs +Found .cabal file brittany.cabal, but it did not mention data/Test38.hs +data/Test38.hs +@@ -1,6 +1,6 @@ + -- a + func :: -- b +- -- c ++ -- c + a -> -- d + -- e + ( -- f + + Formatting is not idempotent. + Please, consider reporting the bug. +Found .cabal file brittany.cabal, but it did not mention data/Test380.hs +Found .cabal file brittany.cabal, but it did not mention data/Test381.hs +Found .cabal file brittany.cabal, but it did not mention data/Test382.hs +Found .cabal file brittany.cabal, but it did not mention data/Test383.hs +Found .cabal file brittany.cabal, but it did not mention data/Test384.hs +Found .cabal file brittany.cabal, but it did not mention data/Test385.hs +Found .cabal file brittany.cabal, but it did not mention data/Test386.hs +Found .cabal file brittany.cabal, but it did not mention data/Test387.hs +Found .cabal file brittany.cabal, but it did not mention data/Test388.hs +Found .cabal file brittany.cabal, but it did not mention data/Test389.hs +Found .cabal file brittany.cabal, but it did not mention data/Test39.hs +Found .cabal file brittany.cabal, but it did not mention data/Test390.hs +Found .cabal file brittany.cabal, but it did not mention data/Test391.hs +Found .cabal file brittany.cabal, but it did not mention data/Test392.hs +Found .cabal file brittany.cabal, but it did not mention data/Test393.hs +Found .cabal file brittany.cabal, but it did not mention data/Test394.hs +data/Test394.hs +@@ -1,7 +1,7 @@ + -- brittany { lconfig_columnAlignMode: { tag: ColumnAlignModeDisabled }, lconfig_indentPolicy: IndentPolicyLeft } + -- a + func :: -- b +- -- c ++ -- c + a -> -- d + -- e + ( -- f + + Formatting is not idempotent. + Please, consider reporting the bug. +Found .cabal file brittany.cabal, but it did not mention data/Test395.hs +Found .cabal file brittany.cabal, but it did not mention data/Test396.hs +Found .cabal file brittany.cabal, but it did not mention data/Test397.hs +Found .cabal file brittany.cabal, but it did not mention data/Test398.hs +Found .cabal file brittany.cabal, but it did not mention data/Test399.hs +Found .cabal file brittany.cabal, but it did not mention data/Test4.hs +Found .cabal file brittany.cabal, but it did not mention data/Test40.hs +Found .cabal file brittany.cabal, but it did not mention data/Test400.hs +Found .cabal file brittany.cabal, but it did not mention data/Test401.hs +Found .cabal file brittany.cabal, but it did not mention data/Test402.hs +Found .cabal file brittany.cabal, but it did not mention data/Test403.hs +Found .cabal file brittany.cabal, but it did not mention data/Test404.hs +Found .cabal file brittany.cabal, but it did not mention data/Test405.hs +Found .cabal file brittany.cabal, but it did not mention data/Test406.hs +Found .cabal file brittany.cabal, but it did not mention data/Test407.hs +Found .cabal file brittany.cabal, but it did not mention data/Test408.hs +Found .cabal file brittany.cabal, but it did not mention data/Test409.hs +Found .cabal file brittany.cabal, but it did not mention data/Test41.hs +Found .cabal file brittany.cabal, but it did not mention data/Test410.hs +Found .cabal file brittany.cabal, but it did not mention data/Test411.hs +Found .cabal file brittany.cabal, but it did not mention data/Test412.hs +Found .cabal file brittany.cabal, but it did not mention data/Test413.hs +Found .cabal file brittany.cabal, but it did not mention data/Test414.hs +Found .cabal file brittany.cabal, but it did not mention data/Test415.hs +Found .cabal file brittany.cabal, but it did not mention data/Test416.hs +Found .cabal file brittany.cabal, but it did not mention data/Test417.hs +Found .cabal file brittany.cabal, but it did not mention data/Test418.hs +Found .cabal file brittany.cabal, but it did not mention data/Test419.hs +Found .cabal file brittany.cabal, but it did not mention data/Test42.hs +Found .cabal file brittany.cabal, but it did not mention data/Test420.hs +Found .cabal file brittany.cabal, but it did not mention data/Test421.hs +Found .cabal file brittany.cabal, but it did not mention data/Test422.hs +Found .cabal file brittany.cabal, but it did not mention data/Test423.hs +Found .cabal file brittany.cabal, but it did not mention data/Test424.hs +Found .cabal file brittany.cabal, but it did not mention data/Test425.hs +Found .cabal file brittany.cabal, but it did not mention data/Test426.hs +Found .cabal file brittany.cabal, but it did not mention data/Test427.hs +Found .cabal file brittany.cabal, but it did not mention data/Test428.hs +Found .cabal file brittany.cabal, but it did not mention data/Test429.hs +Found .cabal file brittany.cabal, but it did not mention data/Test43.hs +Found .cabal file brittany.cabal, but it did not mention data/Test430.hs +Found .cabal file brittany.cabal, but it did not mention data/Test431.hs +Found .cabal file brittany.cabal, but it did not mention data/Test432.hs +Found .cabal file brittany.cabal, but it did not mention data/Test433.hs +Found .cabal file brittany.cabal, but it did not mention data/Test434.hs +Found .cabal file brittany.cabal, but it did not mention data/Test435.hs +Found .cabal file brittany.cabal, but it did not mention data/Test436.hs +Found .cabal file brittany.cabal, but it did not mention data/Test437.hs +Found .cabal file brittany.cabal, but it did not mention data/Test438.hs +Found .cabal file brittany.cabal, but it did not mention data/Test439.hs +Found .cabal file brittany.cabal, but it did not mention data/Test44.hs +Found .cabal file brittany.cabal, but it did not mention data/Test440.hs +Found .cabal file brittany.cabal, but it did not mention data/Test441.hs +Found .cabal file brittany.cabal, but it did not mention data/Test442.hs +Found .cabal file brittany.cabal, but it did not mention data/Test443.hs +Found .cabal file brittany.cabal, but it did not mention data/Test444.hs +Found .cabal file brittany.cabal, but it did not mention data/Test445.hs +Found .cabal file brittany.cabal, but it did not mention data/Test446.hs +Found .cabal file brittany.cabal, but it did not mention data/Test447.hs +Found .cabal file brittany.cabal, but it did not mention data/Test448.hs +Found .cabal file brittany.cabal, but it did not mention data/Test449.hs +Found .cabal file brittany.cabal, but it did not mention data/Test45.hs +Found .cabal file brittany.cabal, but it did not mention data/Test450.hs +Found .cabal file brittany.cabal, but it did not mention data/Test451.hs +Found .cabal file brittany.cabal, but it did not mention data/Test452.hs +Found .cabal file brittany.cabal, but it did not mention data/Test453.hs +Found .cabal file brittany.cabal, but it did not mention data/Test454.hs +Found .cabal file brittany.cabal, but it did not mention data/Test455.hs +Found .cabal file brittany.cabal, but it did not mention data/Test456.hs +Found .cabal file brittany.cabal, but it did not mention data/Test457.hs +Found .cabal file brittany.cabal, but it did not mention data/Test458.hs +Found .cabal file brittany.cabal, but it did not mention data/Test459.hs +Found .cabal file brittany.cabal, but it did not mention data/Test46.hs +Found .cabal file brittany.cabal, but it did not mention data/Test460.hs +Found .cabal file brittany.cabal, but it did not mention data/Test461.hs +Found .cabal file brittany.cabal, but it did not mention data/Test462.hs +Found .cabal file brittany.cabal, but it did not mention data/Test463.hs +Found .cabal file brittany.cabal, but it did not mention data/Test464.hs +Found .cabal file brittany.cabal, but it did not mention data/Test465.hs +Found .cabal file brittany.cabal, but it did not mention data/Test466.hs +Found .cabal file brittany.cabal, but it did not mention data/Test467.hs +Found .cabal file brittany.cabal, but it did not mention data/Test468.hs +Found .cabal file brittany.cabal, but it did not mention data/Test469.hs +Found .cabal file brittany.cabal, but it did not mention data/Test47.hs +Found .cabal file brittany.cabal, but it did not mention data/Test470.hs +Found .cabal file brittany.cabal, but it did not mention data/Test471.hs +Found .cabal file brittany.cabal, but it did not mention data/Test472.hs +Found .cabal file brittany.cabal, but it did not mention data/Test473.hs +Found .cabal file brittany.cabal, but it did not mention data/Test474.hs +Found .cabal file brittany.cabal, but it did not mention data/Test475.hs +Found .cabal file brittany.cabal, but it did not mention data/Test476.hs +Found .cabal file brittany.cabal, but it did not mention data/Test477.hs +Found .cabal file brittany.cabal, but it did not mention data/Test478.hs +Found .cabal file brittany.cabal, but it did not mention data/Test479.hs +Found .cabal file brittany.cabal, but it did not mention data/Test48.hs +Found .cabal file brittany.cabal, but it did not mention data/Test480.hs +Found .cabal file brittany.cabal, but it did not mention data/Test481.hs +Found .cabal file brittany.cabal, but it did not mention data/Test482.hs +Found .cabal file brittany.cabal, but it did not mention data/Test483.hs +Found .cabal file brittany.cabal, but it did not mention data/Test484.hs +Found .cabal file brittany.cabal, but it did not mention data/Test485.hs +Found .cabal file brittany.cabal, but it did not mention data/Test486.hs +Found .cabal file brittany.cabal, but it did not mention data/Test487.hs +Found .cabal file brittany.cabal, but it did not mention data/Test488.hs +Found .cabal file brittany.cabal, but it did not mention data/Test489.hs +Found .cabal file brittany.cabal, but it did not mention data/Test49.hs +Found .cabal file brittany.cabal, but it did not mention data/Test490.hs +Found .cabal file brittany.cabal, but it did not mention data/Test491.hs +Found .cabal file brittany.cabal, but it did not mention data/Test492.hs +Found .cabal file brittany.cabal, but it did not mention data/Test493.hs +Found .cabal file brittany.cabal, but it did not mention data/Test494.hs +Found .cabal file brittany.cabal, but it did not mention data/Test495.hs +Found .cabal file brittany.cabal, but it did not mention data/Test496.hs +Found .cabal file brittany.cabal, but it did not mention data/Test497.hs +Found .cabal file brittany.cabal, but it did not mention data/Test498.hs +Found .cabal file brittany.cabal, but it did not mention data/Test499.hs +Found .cabal file brittany.cabal, but it did not mention data/Test5.hs +Found .cabal file brittany.cabal, but it did not mention data/Test50.hs +Found .cabal file brittany.cabal, but it did not mention data/Test500.hs +Found .cabal file brittany.cabal, but it did not mention data/Test501.hs +Found .cabal file brittany.cabal, but it did not mention data/Test502.hs +Found .cabal file brittany.cabal, but it did not mention data/Test503.hs +Found .cabal file brittany.cabal, but it did not mention data/Test504.hs +Found .cabal file brittany.cabal, but it did not mention data/Test505.hs +Found .cabal file brittany.cabal, but it did not mention data/Test506.hs +Found .cabal file brittany.cabal, but it did not mention data/Test507.hs +Found .cabal file brittany.cabal, but it did not mention data/Test508.hs +Found .cabal file brittany.cabal, but it did not mention data/Test509.hs +Found .cabal file brittany.cabal, but it did not mention data/Test51.hs +data/Test51.hs +@@ -1,14 +1,11 @@ + {-# LANGUAGE DatatypeContexts #-} +- data +- ( LooooooooooooooooooooongConstraint a +- , LooooooooooooooooooooongConstraint b +- ) => +- MyRecord a b +- = MyConstructor +- { foo1, foo2 +- :: loooooooooooooooooooooooooooooooong +- -> loooooooooooooooooooooooooooooooong +- , bar :: a +- , bazz :: b +- } + ++ data MyRecord a b = MyConstructor ++ { foo1, ++ foo2 :: ++ loooooooooooooooooooooooooooooooong -> ++ loooooooooooooooooooooooooooooooong, ++ bar :: a, ++ bazz :: b ++ } ++ + + AST of input and AST of formatted code differ. + at data/Test51.hs:(2,1)-(13,5) + Please, consider reporting the bug. + To format anyway, use --unsafe. +Found .cabal file brittany.cabal, but it did not mention data/Test510.hs +Found .cabal file brittany.cabal, but it did not mention data/Test511.hs +Found .cabal file brittany.cabal, but it did not mention data/Test512.hs +Found .cabal file brittany.cabal, but it did not mention data/Test513.hs +Found .cabal file brittany.cabal, but it did not mention data/Test514.hs +Found .cabal file brittany.cabal, but it did not mention data/Test515.hs +Found .cabal file brittany.cabal, but it did not mention data/Test516.hs +Found .cabal file brittany.cabal, but it did not mention data/Test517.hs +Found .cabal file brittany.cabal, but it did not mention data/Test518.hs +Found .cabal file brittany.cabal, but it did not mention data/Test519.hs +Found .cabal file brittany.cabal, but it did not mention data/Test52.hs +Found .cabal file brittany.cabal, but it did not mention data/Test520.hs +Found .cabal file brittany.cabal, but it did not mention data/Test521.hs +Found .cabal file brittany.cabal, but it did not mention data/Test522.hs +Found .cabal file brittany.cabal, but it did not mention data/Test523.hs +Found .cabal file brittany.cabal, but it did not mention data/Test524.hs +Found .cabal file brittany.cabal, but it did not mention data/Test525.hs +Found .cabal file brittany.cabal, but it did not mention data/Test526.hs +Found .cabal file brittany.cabal, but it did not mention data/Test527.hs +Found .cabal file brittany.cabal, but it did not mention data/Test528.hs +Found .cabal file brittany.cabal, but it did not mention data/Test529.hs +Found .cabal file brittany.cabal, but it did not mention data/Test53.hs +Found .cabal file brittany.cabal, but it did not mention data/Test530.hs +Found .cabal file brittany.cabal, but it did not mention data/Test531.hs +Found .cabal file brittany.cabal, but it did not mention data/Test532.hs +Found .cabal file brittany.cabal, but it did not mention data/Test533.hs +Found .cabal file brittany.cabal, but it did not mention data/Test534.hs +Found .cabal file brittany.cabal, but it did not mention data/Test535.hs +Found .cabal file brittany.cabal, but it did not mention data/Test536.hs +Found .cabal file brittany.cabal, but it did not mention data/Test537.hs +Found .cabal file brittany.cabal, but it did not mention data/Test538.hs +Found .cabal file brittany.cabal, but it did not mention data/Test539.hs +Found .cabal file brittany.cabal, but it did not mention data/Test54.hs +Found .cabal file brittany.cabal, but it did not mention data/Test540.hs +Found .cabal file brittany.cabal, but it did not mention data/Test55.hs +Found .cabal file brittany.cabal, but it did not mention data/Test56.hs +Found .cabal file brittany.cabal, but it did not mention data/Test57.hs +Found .cabal file brittany.cabal, but it did not mention data/Test58.hs +Found .cabal file brittany.cabal, but it did not mention data/Test59.hs +Found .cabal file brittany.cabal, but it did not mention data/Test6.hs +Found .cabal file brittany.cabal, but it did not mention data/Test60.hs +Found .cabal file brittany.cabal, but it did not mention data/Test61.hs +Found .cabal file brittany.cabal, but it did not mention data/Test62.hs +Found .cabal file brittany.cabal, but it did not mention data/Test63.hs +Found .cabal file brittany.cabal, but it did not mention data/Test64.hs +Found .cabal file brittany.cabal, but it did not mention data/Test65.hs +data/Test65.hs +@@ -1,9 +1,9 @@ + data Foo = Bar + { -- a + foo :: -- b +- -- c ++ -- c + Baz, -- d +- -- e ++ -- e + bars :: Bizzz + } + deriving (Show, Eq, Monad, Functor, Traversable, Foldable) + + Formatting is not idempotent. + Please, consider reporting the bug. +Found .cabal file brittany.cabal, but it did not mention data/Test66.hs +Found .cabal file brittany.cabal, but it did not mention data/Test67.hs +Found .cabal file brittany.cabal, but it did not mention data/Test68.hs +Found .cabal file brittany.cabal, but it did not mention data/Test69.hs +Found .cabal file brittany.cabal, but it did not mention data/Test7.hs +Found .cabal file brittany.cabal, but it did not mention data/Test70.hs +Found .cabal file brittany.cabal, but it did not mention data/Test71.hs +Found .cabal file brittany.cabal, but it did not mention data/Test72.hs +Found .cabal file brittany.cabal, but it did not mention data/Test73.hs +Found .cabal file brittany.cabal, but it did not mention data/Test74.hs +Found .cabal file brittany.cabal, but it did not mention data/Test75.hs +Found .cabal file brittany.cabal, but it did not mention data/Test76.hs +Found .cabal file brittany.cabal, but it did not mention data/Test77.hs +Found .cabal file brittany.cabal, but it did not mention data/Test78.hs +Found .cabal file brittany.cabal, but it did not mention data/Test79.hs +Found .cabal file brittany.cabal, but it did not mention data/Test8.hs +Found .cabal file brittany.cabal, but it did not mention data/Test80.hs +Found .cabal file brittany.cabal, but it did not mention data/Test81.hs +Found .cabal file brittany.cabal, but it did not mention data/Test82.hs +Found .cabal file brittany.cabal, but it did not mention data/Test83.hs +Found .cabal file brittany.cabal, but it did not mention data/Test84.hs +Found .cabal file brittany.cabal, but it did not mention data/Test85.hs +Found .cabal file brittany.cabal, but it did not mention data/Test86.hs +Found .cabal file brittany.cabal, but it did not mention data/Test87.hs +Found .cabal file brittany.cabal, but it did not mention data/Test88.hs +Found .cabal file brittany.cabal, but it did not mention data/Test89.hs +Found .cabal file brittany.cabal, but it did not mention data/Test9.hs +Found .cabal file brittany.cabal, but it did not mention data/Test90.hs +Found .cabal file brittany.cabal, but it did not mention data/Test91.hs +Found .cabal file brittany.cabal, but it did not mention data/Test92.hs +Found .cabal file brittany.cabal, but it did not mention data/Test93.hs +Found .cabal file brittany.cabal, but it did not mention data/Test94.hs +Found .cabal file brittany.cabal, but it did not mention data/Test95.hs +Found .cabal file brittany.cabal, but it did not mention data/Test96.hs +Found .cabal file brittany.cabal, but it did not mention data/Test97.hs +Found .cabal file brittany.cabal, but it did not mention data/Test98.hs +Found .cabal file brittany.cabal, but it did not mention data/Test99.hs diff --git a/expected-failures/esqueleto.txt b/expected-failures/esqueleto.txt index 9628f320..b52aca2d 100644 --- a/expected-failures/esqueleto.txt +++ b/expected-failures/esqueleto.txt @@ -1,4 +1,4 @@ Found .cabal file esqueleto.cabal, but it did not mention Setup.hs -src/Database/Esqueleto/Internal/Internal.hs:409:1 +src/Database/Esqueleto/Internal/Internal.hs:411:1 The GHC parser (in Haddock mode) failed: lexical error in string/character literal at character 's' diff --git a/expected-failures/haxl.txt b/expected-failures/haxl.txt index 9a0e960d..ca615630 100644 --- a/expected-failures/haxl.txt +++ b/expected-failures/haxl.txt @@ -1,4 +1 @@ -Haxl/Core/DataCache.hs:54:49 - The GHC parser (in Haddock mode) failed: - Not a data constructor: `!' Found .cabal file haxl.cabal, but it did not mention Setup.hs diff --git a/expected-failures/hlint.txt b/expected-failures/hlint.txt index 8d77a1b7..f3e83db9 100644 --- a/expected-failures/hlint.txt +++ b/expected-failures/hlint.txt @@ -3,21 +3,20 @@ Found .cabal file hlint.cabal, but it did not mention data/HLint_QuickCheck.hs Found .cabal file hlint.cabal, but it did not mention data/HLint_TypeCheck.hs Found .cabal file hlint.cabal, but it did not mention data/Test.hs src/Extension.hs -@@ -17,7 +17,8 @@ +@@ -17,6 +17,7 @@ UnboxedTuples, UnboxedSums, -- breaks (#) lens operator QuasiQuotes, -- breaks [x| ...], making whitespace free list comps break -- {- DoRec , -} RecursiveDo -- breaks rec +- {- DoRec , -} RecursiveDo, -- breaks rec + {- DoRec , -} -+ RecursiveDo -- breaks rec ++ RecursiveDo, -- breaks rec + LexicalNegation -- changes '-', see https://github.com/ndmitchell/hlint/issues/1230 ] - reallyBadExtensions = - Formatting is not idempotent. Please, consider reporting the bug. src/Hint/Bracket.hs -@@ -239,8 +239,11 @@ +@@ -263,8 +263,11 @@ let y = noLoc $ HsApp noExtField a1 (noLoc (HsPar noExtField a2)), let r = Replace Expr (toSS e) [("a", toSS a1), ("b", toSS a2)] "a (b)" ] diff --git a/expected-failures/idris.txt b/expected-failures/idris.txt deleted file mode 100644 index fcc17775..00000000 --- a/expected-failures/idris.txt +++ /dev/null @@ -1,7 +0,0 @@ -Found .cabal file idris.cabal, but it did not mention Setup.hs -src/Idris/Parser.hs:1052:1 - The GHC parser (in Haddock mode) failed: - parse error on input `@' -src/Idris/Parser/Expr.hs:75:1 - The GHC parser (in Haddock mode) failed: - parse error on input `@' diff --git a/expected-failures/lens.txt b/expected-failures/lens.txt new file mode 100644 index 00000000..fe39836b --- /dev/null +++ b/expected-failures/lens.txt @@ -0,0 +1,4 @@ +Found .cabal file lens-properties/lens-properties.cabal, but it did not mention lens-properties/Setup.hs +tests/properties.hs:121:26-28 + The GHC parser (in Haddock mode) failed: + parse error on input `KVS' diff --git a/expected-failures/pandoc.txt b/expected-failures/pandoc.txt new file mode 100644 index 00000000..41557eb3 --- /dev/null +++ b/expected-failures/pandoc.txt @@ -0,0 +1,30 @@ +Found .cabal file pandoc.cabal, but it did not mention Setup.hs +src/Text/Pandoc/Readers/Org/Inlines.hs +@@ -182,7 +182,8 @@ + cs' <- cs + case cs' of + [] -> return [] +- (d : ds) -> -- TODO needs refinement ++ (d : ds) -> ++ -- TODO needs refinement + case sty of + TextStyle -> + return $ + + Formatting is not idempotent. + Please, consider reporting the bug. +src/Text/Pandoc/Readers/RST.hs +@@ -1120,7 +1120,7 @@ + -- if no ":class:" field is given, the default is the role name + classFieldClasses = maybe [role] T.words (lookup "class" fields) +- -- nub in case role name & language class are the same +- in nub (classFieldClasses ++ codeLanguageClass ++ oldClasses) ++ in -- nub in case role name & language class are the same ++ nub (classFieldClasses ++ codeLanguageClass ++ oldClasses) + + attr = + let (ident, baseClasses, keyValues) = baseAttr + + Formatting is not idempotent. + Please, consider reporting the bug. +Found .cabal file pandoc.cabal, but it did not mention test/command/3510-src.hs diff --git a/expected-failures/postgrest.txt b/expected-failures/postgrest.txt index 18fe4e01..a9263c80 100644 --- a/expected-failures/postgrest.txt +++ b/expected-failures/postgrest.txt @@ -1,45 +1,40 @@ Found .cabal file postgrest.cabal, but it did not mention Setup.hs -src/PostgREST/DbRequestBuilder.hs -@@ -149,12 +149,11 @@ +src/PostgREST/Request/DbRequestBuilder.hs +@@ -202,12 +202,11 @@ -- /projects?select=clients(*) origin == tableName relTable - && target == tableName relFTable -- projects + && target == tableName relForeignTable -- projects - || -- clients + || ( origin == tableName relTable -- clients -- /projects?select=projects_client_id_fkey(*) - ( origin == tableName relTable -- && Just target == relConstraint -- projects +- && matchConstraint (Just target) relCardinality -- projects - -- projects_client_id_fkey - ) -+ && Just target == relConstraint -- projects ++ && matchConstraint (Just target) relCardinality -- projects + -- projects_client_id_fkey + ) || -- /projects?select=client_id(*) ( origin == tableName relTable -@@ -163,19 +162,16 @@ +@@ -216,16 +215,14 @@ ) ) && ( isNothing hint - || -- hint is optional -+ || hint == relConstraint -- hint is optional ++ || matchConstraint hint relCardinality -- hint is optional -- /projects?select=clients!projects_client_id_fkey(*) -- hint == relConstraint +- matchConstraint hint relCardinality - || -- projects_client_id_fkey + || matchFKSingleCol hint relColumns -- projects_client_id_fkey -- /projects?select=clients!client_id(*) or /projects?select=clients!id(*) - matchFKSingleCol hint relColumns - || matchFKSingleCol hint relFColumns -- client_id + || matchFKSingleCol hint relForeignColumns -- client_id - || -- id -+ || ( relType == M2M -- id - -- /users?select=tasks!users_tasks(*) -- ( relType == M2M -- && hint == (tableName . junTable <$> relJunction) -- many-to-many between users and tasks -- -- users_tasks -- ) -+ && hint == (tableName . junTable <$> relJunction) -- many-to-many between users and tasks -+ -- users_tasks -+ ) ++ || matchJunction hint relCardinality -- id + -- /users?select=tasks!users_tasks(*) many-to-many between users and tasks +- matchJunction hint relCardinality -- users_tasks ++ -- users_tasks ) ) allRels diff --git a/expected-failures/purescript.txt b/expected-failures/purescript.txt new file mode 100644 index 00000000..fc8cefac --- /dev/null +++ b/expected-failures/purescript.txt @@ -0,0 +1,42 @@ +Found .cabal file purescript.cabal, but it did not mention Setup.hs +src/Language/PureScript/CoreFn/CSE.hs +@@ -218,11 +218,12 @@ + at d . non mempty . at e %%<~ \case + Nothing -> freshIdent (nameHint e) <&> \ident -> ((True, ident), Just ident) + Just ident -> pure ((False, ident), Just ident) ++ where + -- A reminder: as with %%=, the first element of the returned pair is the + -- final result of the expression, and the second element is the value to + -- stuff back through the lens into the state. (The difference is that %%<~ + -- enables doing monadic work in the RHS, namely `freshIdent` here.) +- where ++ + nameHint = \case + App _ v1 v2 + | Var _ n <- v1, + + Formatting is not idempotent. + Please, consider reporting the bug. +src/Language/PureScript/CoreFn/Laziness.hs +@@ -527,12 +527,12 @@ + makeForceCall ann ident' + q -> Var ann q + in (ident, rewriteExpr <$> item) +- -- All that's left to do is run the above replacement on every item, +- -- translate items from our `RecursiveGroupItem` representation back into the +- -- form CoreFn expects, and inform the caller whether we made any laziness +- -- transformations after all. (That last bit of information is used to +- -- determine if the runtime factory function needs to be injected.) +- in (uncurry fromRGI . replaceReferencesWithForceCall <$> items, Any . not $ IM.null replacements) ++ in -- All that's left to do is run the above replacement on every item, ++ -- translate items from our `RecursiveGroupItem` representation back into the ++ -- form CoreFn expects, and inform the caller whether we made any laziness ++ -- transformations after all. (That last bit of information is used to ++ -- determine if the runtime factory function needs to be injected.) ++ (uncurry fromRGI . replaceReferencesWithForceCall <$> items, Any . not $ IM.null replacements) + where + nullAnn = ssAnn nullSourceSpan + runtimeLazy = Var nullAnn . Qualified ByNullSourcePos $ InternalIdent RuntimeLazyFactory + + Formatting is not idempotent. + Please, consider reporting the bug. diff --git a/extract-hackage-info/extract-hackage-info.cabal b/extract-hackage-info/extract-hackage-info.cabal index 1525a92f..9f3163fd 100644 --- a/extract-hackage-info/extract-hackage-info.cabal +++ b/extract-hackage-info/extract-hackage-info.cabal @@ -12,17 +12,16 @@ executable extract-hackage-info build-depends: aeson >=1.0 && <3.0, base >=4.12 && <5.0, - bytestring >=0.10 && <0.11, + bytestring >=0.10 && <0.12, containers >=0.6 && <0.7, directory >=1.0 && <2.0, filepath >=1.2 && <1.5, - ghc-lib-parser >=9.2 && <9.3, optparse-applicative >=0.14 && <0.18, ormolu, pcre2 >=2.0 && <3.0, tagsoup >=0.14 && <0.15, text >=0.2 && <3.0, - text-format >=0.3 && <0.4 + formatting >=7.1 && <7.2 - if !impl(ghc >=8.10 && <8.11) + if !impl(ghc >=9.2 && <9.3) buildable: False diff --git a/extract-hackage-info/src/Main.hs b/extract-hackage-info/src/Main.hs index cd5c8999..95c15620 100644 --- a/extract-hackage-info/src/Main.hs +++ b/extract-hackage-info/src/Main.hs @@ -27,18 +27,14 @@ import qualified Data.Set as Set import Data.Text (Text) import qualified Data.Text as T import Data.Text.Encoding (decodeLatin1) -import Data.Text.Format hiding (format) -import qualified Data.Text.Format as Format -import Data.Text.Format.Params (Params) import qualified Data.Text.IO as TIO -import qualified Data.Text.Lazy as TL -import GHC.Utils.Monad (mapMaybeM) +import Formatting import Options.Applicative import Ormolu.Fixity hiding (packageToOps, packageToPopularity) import System.Directory (doesDirectoryExist, listDirectory) import System.Exit (ExitCode (ExitFailure), exitWith) import System.FilePath (makeRelative, splitPath, ()) -import System.IO (Handle, stderr, stdout) +import System.IO (stderr, stdout) import Text.HTML.TagSoup (Tag (TagText), parseTags) import Text.HTML.TagSoup.Match (tagCloseLit, tagOpenLit) import Text.Regex.Pcre2 (capture, regex) @@ -66,18 +62,10 @@ data State = State } deriving (Eq) --- | Format using the strict variant of "Data.Text". -format :: forall ps. Params ps => Format -> ps -> Text -format f p = TL.toStrict $ Format.format f p - --- | Put a formatted string. -hPutFmtLn :: forall ps. Params ps => Handle -> Format -> ps -> IO () -hPutFmtLn h f p = TIO.hPutStrLn h $ format f p - -- | Exit with an error message. -exitWithFmt :: forall ps. Params ps => Format -> ps -> IO () -exitWithFmt f p = do - hPutFmtLn stderr f p +exitWithMsg :: Text -> IO () +exitWithMsg t = do + TIO.hPutStrLn stderr t exitWith (ExitFailure 1) showT :: Show a => a -> Text @@ -113,18 +101,19 @@ getPackageName :: IO Text getPackageName rootPath filePath = do unless (rootPath `isPrefixOf` filePath) $ - exitWithFmt - "{} do not start with {}" - (T.pack filePath, T.pack rootPath) + exitWithMsg $ + sformat (string % " does not start with " % string) rootPath filePath let packageName = stripSuffix' "/" $ T.pack . head . splitPath $ makeRelative rootPath filePath stripSuffix' suffix txt = fromMaybe txt $ T.stripSuffix suffix txt when (T.null packageName) $ - exitWithFmt - "Extracted package name is empty for {} (base path = {})" - (T.pack filePath, T.pack rootPath) + exitWithMsg $ + sformat + ("Extracted package name is empty for " % string % " (base path = " % string % ")") + filePath + rootPath return packageName -- | Try to read the specified file using utf-8 encoding first, @@ -132,17 +121,18 @@ getPackageName rootPath filePath = do readFileUtf8Latin1 :: FilePath -> IO Text readFileUtf8Latin1 filePath = catch @IOException (TIO.readFile filePath) $ \e -> do - hPutFmtLn + hprintLn stderr - "Unable to read {} with UTF-8 ({}), trying latin1 encoding..." - (filePath, show e) + ("Unable to read " % string % " with UTF-8 (" % shown % "), trying latin1 encoding...") + filePath + e decodeLatin1 <$> ByteString.readFile filePath -- | Extract the first element and last element from a list if possible, and -- return the tuple (first, middle, last) where middle corresponds to all -- the elements in between. firstMiddleLast :: [a] -> Maybe (a, [a], a) -firstMiddleLast string = case string of +firstMiddleLast = \case x1 : x2 : xs -> Just (x1, init (x2 : xs), last (x2 : xs)) _ -> Nothing @@ -325,10 +315,10 @@ extractHoogleInfo hoogleDatabasePath = do (extractFixitiesFromFile hoogleDatabasePath) (State {sPackageToOps = Map.empty, sProcessedFiles = 0}) hoogleFiles - hPutFmtLn + hprintLn stdout - "{} Hoogle files processed!" - (Only sProcessedFiles) + (int % " Hoogle files processed!") + sProcessedFiles let (packageToOps, selfConflicts) = finalizePackageToOps sPackageToOps displayFixityStats packageToOps displaySelfConflicts selfConflicts @@ -338,10 +328,10 @@ extractHoogleInfo hoogleDatabasePath = do displaySelfConflicts :: [SelfConflict] -> IO () displaySelfConflicts selfConflicts = unless (null selfConflicts) $ do - hPutFmtLn + hprintLn stdout - "Found {} conflicting declarations within packages themselves:" - (Only $ length selfConflicts) + ("Found" % int % " conflicting declarations within packages themselves:") + (length selfConflicts) TIO.putStrLn $ T.intercalate "\n" selfConflictLines where selfConflictLines = concat $ showSc <$> sortedSelfConflicts @@ -352,19 +342,28 @@ displaySelfConflicts selfConflicts = ) selfConflicts showSc SelfConflict {scPackageName, scOperatorName, scConflictingDefs} = - format - "(in {}) {}" - (scPackageName, scOperatorName) + sformat + ("(in " % string % ") " % string) + scPackageName + scOperatorName : indentLines (showT <$> scConflictingDefs) -- | Display stats about the Hoogle database processing. displayFixityStats :: Map String FixityMap -> IO () displayFixityStats packageToOps = - hPutFmtLn + hprintLn stdout - "Found {} operator declarations across {} packages for a total of \ - \{} distinct operators" - (declCount, packagesCount, distinctOpCount) + ( "Found " + % int + % " operator declarations across " + % int + % " packages for a total of " + % int + % " distinct operators" + ) + declCount + packagesCount + distinctOpCount where packagesCount = Map.size packageToOps declCount = sum $ Map.size <$> fixityMaps @@ -392,10 +391,10 @@ extractHackageInfo filePath = do name = T.unpack . T.strip . head $ T.split (== ' ') rawName dlCount = readT $ T.strip rawDlCount :: Int _ -> do - hPutFmtLn + hprintLn stdout - "Invalid line: {}" - (Only $ T.intercalate " " $ showT <$> tags) + ("Invalid line: " % stext) + (T.intercalate " " $ showT <$> tags) return Nothing extractText tags = T.intercalate "" $ extractText' <$> tags extractText' = \case @@ -412,11 +411,11 @@ extractHackageInfo filePath = do _ -> True ) isBlank t = null $ dropWhile (`elem` [' ', '\t', '\n']) (T.unpack t) - result <- Map.fromList <$> mapMaybeM processRow (groupOn "tr" tableBody) - hPutFmtLn + result <- Map.fromList . catMaybes <$> traverse processRow (groupOn "tr" tableBody) + hprintLn stdout - "Found popularity information for {} packages" - (Only $ Map.size result) + ("Found popularity information for " % int % " packages") + (Map.size result) return result -- | Limit the number of items in a map. diff --git a/nix/lexer-no-unlifted-newtypes.patch b/nix/lexer-no-unlifted-newtypes.patch new file mode 100644 index 00000000..eedcc38e --- /dev/null +++ b/nix/lexer-no-unlifted-newtypes.patch @@ -0,0 +1,79 @@ +diff --git a/compiler/GHC/Parser/Lexer.x b/compiler/GHC/Parser/Lexer.x +index f3a3109..12505db 100644 +--- a/compiler/GHC/Parser/Lexer.x ++++ b/compiler/GHC/Parser/Lexer.x +@@ -44,10 +44,6 @@ + {-# LANGUAGE BangPatterns #-} + {-# LANGUAGE LambdaCase #-} + {-# LANGUAGE MultiWayIf #-} +-{-# LANGUAGE UnboxedTuples #-} +-{-# LANGUAGE UnboxedSums #-} +-{-# LANGUAGE UnliftedNewtypes #-} +-{-# LANGUAGE PatternSynonyms #-} + + + {-# OPTIONS_GHC -funbox-strict-fields #-} +@@ -57,7 +53,7 @@ module GHC.Parser.Lexer ( + Token(..), lexer, lexerDbg, + ParserOpts(..), mkParserOpts, + PState (..), initParserState, initPragState, +- P(..), ParseResult(POk, PFailed), ++ P(..), ParseResult(..), + allocateComments, allocatePriorComments, allocateFinalComments, + MonadP(..), + getRealSrcLoc, getPState, +@@ -2325,25 +2321,17 @@ data LayoutContext + deriving Show + + -- | The result of running a parser. +-newtype ParseResult a = PR (# (# PState, a #) | PState #) +- +--- | The parser has consumed a (possibly empty) prefix of the input and produced +--- a result. Use 'getPsMessages' to check for accumulated warnings and non-fatal +--- errors. +--- +--- The carried parsing state can be used to resume parsing. +-pattern POk :: PState -> a -> ParseResult a +-pattern POk s a = PR (# (# s , a #) | #) +- +--- | The parser has consumed a (possibly empty) prefix of the input and failed. +--- +--- The carried parsing state can be used to resume parsing. It is the state +--- right before failure, including the fatal parse error. 'getPsMessages' and +--- 'getPsErrorMessages' must return a non-empty bag of errors. +-pattern PFailed :: PState -> ParseResult a +-pattern PFailed s = PR (# | s #) +- +-{-# COMPLETE POk, PFailed #-} ++data ParseResult a ++ = POk -- ^ The parser has consumed a (possibly empty) prefix ++ -- of the input and produced a result. Use 'getMessages' ++ -- to check for accumulated warnings and non-fatal errors. ++ PState -- ^ The resulting parsing state. Can be used to resume parsing. ++ a -- ^ The resulting value. ++ | PFailed -- ^ The parser has consumed a (possibly empty) prefix ++ -- of the input and failed. ++ PState -- ^ The parsing state right before failure, including the fatal ++ -- parse error. 'getMessages' and 'getErrorMessages' must return ++ -- a non-empty bag of errors. + + -- | Test whether a 'WarningFlag' is set + warnopt :: WarningFlag -> ParserOpts -> Bool +@@ -3111,7 +3099,7 @@ srcParseErr + srcParseErr options buf len loc = mkPlainErrorMsgEnvelope loc (PsErrParse token details) + where + token = lexemeToString (offsetBytes (-len) buf) len +- pattern_ = decodePrevNChars 8 buf ++ pattern = decodePrevNChars 8 buf + last100 = decodePrevNChars 100 buf + doInLast100 = "do" `isInfixOf` last100 + mdoInLast100 = "mdo" `isInfixOf` last100 +@@ -3122,7 +3110,7 @@ srcParseErr options buf len loc = mkPlainErrorMsgEnvelope loc (PsErrParse token + , ped_do_in_last_100 = doInLast100 + , ped_mdo_in_last_100 = mdoInLast100 + , ped_pat_syn_enabled = ps_enabled +- , ped_pattern_parsed = pattern_ == "pattern " ++ , ped_pattern_parsed = pattern == "pattern " + } + + -- Report a parse failure, giving the span of the previous token as diff --git a/nix/sources.json b/nix/sources.json index 4a5699ff..8d454c4c 100644 --- a/nix/sources.json +++ b/nix/sources.json @@ -5,10 +5,10 @@ "homepage": "https://input-output-hk.github.io/haskell.nix", "owner": "input-output-hk", "repo": "haskell.nix", - "rev": "18ebf60137dd2ff1be7363eb46f67ebfa366d1dd", - "sha256": "036wl8zg1ps5lh8k2071nwfijzkhczp7p4i0ymxvda825fsf0bhd", + "rev": "3c9acea8fe73057e36b54e74962cfecf21e5c1e3", + "sha256": "1j4w5hiwdv4s0paq50kbyxxhkyp4sd7rhzbrg3lz7cvd96g2bw34", "type": "tarball", - "url": "https://github.com/input-output-hk/haskell.nix/archive/18ebf60137dd2ff1be7363eb46f67ebfa366d1dd.tar.gz", + "url": "https://github.com/input-output-hk/haskell.nix/archive/3c9acea8fe73057e36b54e74962cfecf21e5c1e3.tar.gz", "url_template": "https://github.com///archive/.tar.gz" } } diff --git a/nix/sources.nix b/nix/sources.nix index 1938409d..9a01c8ac 100644 --- a/nix/sources.nix +++ b/nix/sources.nix @@ -31,8 +31,28 @@ let if spec ? branch then "refs/heads/${spec.branch}" else if spec ? tag then "refs/tags/${spec.tag}" else abort "In git source '${name}': Please specify `ref`, `tag` or `branch`!"; + submodules = if spec ? submodules then spec.submodules else false; + submoduleArg = + let + nixSupportsSubmodules = builtins.compareVersions builtins.nixVersion "2.4" >= 0; + emptyArgWithWarning = + if submodules == true + then + builtins.trace + ( + "The niv input \"${name}\" uses submodules " + + "but your nix's (${builtins.nixVersion}) builtins.fetchGit " + + "does not support them" + ) + {} + else {}; + in + if nixSupportsSubmodules + then { inherit submodules; } + else emptyArgWithWarning; in - builtins.fetchGit { url = spec.repo; inherit (spec) rev; inherit ref; }; + builtins.fetchGit + ({ url = spec.repo; inherit (spec) rev; inherit ref; } // submoduleArg); fetch_local = spec: spec.path; diff --git a/ormolu-live/deploy.sh b/ormolu-live/deploy.sh index 9b905b8b..5b0d8d5c 100755 --- a/ormolu-live/deploy.sh +++ b/ormolu-live/deploy.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash set -eo pipefail -ORMOLU_LIVE=$(nix-build -A ormoluLive.website -j 1) +ORMOLU_LIVE=$(nix-build -A ormoluLive.website --argstr ormoluCompiler ghc8107 -j 1) netlify deploy --alias=$(git log -1 --format="%H") -d $ORMOLU_LIVE netlify deploy --prod -d $ORMOLU_LIVE diff --git a/ormolu-live/shell.nix b/ormolu-live/shell.nix index 95aa2a7b..bb8be807 100644 --- a/ormolu-live/shell.nix +++ b/ormolu-live/shell.nix @@ -1 +1 @@ -(import ../default.nix { }).dev.ormoluLiveShell +(import ../default.nix { ormoluCompiler = "ghc8107"; }).dev.ormoluLiveShell diff --git a/ormolu-live/src/Main.hs b/ormolu-live/src/Main.hs index a5a111b0..93d38588 100644 --- a/ormolu-live/src/Main.hs +++ b/ormolu-live/src/Main.hs @@ -10,11 +10,10 @@ import Data.Maybe (maybeToList) import Data.Text (Text) import qualified Data.Text as T import Development.GitRev -import GHC.Driver.Ppr (showSDocDump) +import GHC.Driver.Ppr (showSDocUnsafe) import GHC.Generics (Generic) import qualified GHC.Hs.Dump as Dump import GHC.SyntaxHighlighter -import GHC.Utils.Outputable (defaultSDocContext) import qualified Language.Javascript.JSaddle.Warp.Extra as JSaddleWarp import Miso import Miso.String (MisoString, fromMisoString, ms) @@ -255,7 +254,7 @@ viewModel model@Model {..} = printSnippet = \case O.ParsedSnippet O.ParseResult {..} -> T.pack - . showSDocDump defaultSDocContext + . showSDocUnsafe . Dump.showAstData Dump.NoBlankSrcSpan Dump.NoBlankEpAnnotations $ prParsedSource O.RawSnippet r -> r diff --git a/ormolu.cabal b/ormolu.cabal index 9e4bbb04..20b9629f 100644 --- a/ormolu.cabal +++ b/ormolu.cabal @@ -4,7 +4,7 @@ version: 0.5.0.1 license: BSD-3-Clause license-file: LICENSE.md maintainer: Mark Karpov -tested-with: ghc ==8.10.7 ghc ==9.0.2 ghc ==9.2.1 +tested-with: ghc ==9.0.2 ghc ==9.2.4 homepage: https://github.com/tweag/ormolu bug-reports: https://github.com/tweag/ormolu/issues synopsis: A formatter for Haskell source code @@ -92,7 +92,7 @@ library other-modules: GHC.DynFlags default-language: Haskell2010 build-depends: - Cabal >=3.6 && <3.7, + Cabal-syntax >=3.8 && <3.9, Diff >=0.4 && <1.0, MemoTrie >=0.6 && <0.7, aeson >=1.0 && <3.0, @@ -105,7 +105,7 @@ library dlist >=0.8 && <2.0, exceptions >=0.6 && <0.11, filepath >=1.2 && <1.5, - ghc-lib-parser >=9.2 && <9.3, + ghc-lib-parser >=9.4 && <9.5, megaparsec >=9.0, mtl >=2.0 && <3.0, syb >=0.7 && <0.8, @@ -140,7 +140,7 @@ executable ormolu base >=4.12 && <5.0, containers >=0.5 && <0.7, filepath >=1.2 && <1.5, - ghc-lib-parser >=9.2 && <9.3, + ghc-lib-parser >=9.4 && <9.5, gitrev >=1.3 && <1.4, optparse-applicative >=0.14 && <0.18, ormolu, @@ -179,7 +179,7 @@ test-suite tests containers >=0.5 && <0.7, directory ^>=1.3, filepath >=1.2 && <1.5, - ghc-lib-parser >=9.2 && <9.3, + ghc-lib-parser >=9.4 && <9.5, hspec >=2.0 && <3.0, hspec-megaparsec >=2.2, megaparsec >=9.0, diff --git a/src/GHC/DynFlags.hs b/src/GHC/DynFlags.hs index edb243d1..5c4a4c51 100644 --- a/src/GHC/DynFlags.hs +++ b/src/GHC/DynFlags.hs @@ -38,6 +38,7 @@ fakeSettings = platformIsCrossCompiling = False, platformLeadingUnderscore = False, platformTablesNextToCode = False, + platformHasLibm = False, platform_constants = Nothing }, sPlatformMisc = PlatformMisc {}, diff --git a/src/Ormolu/Diff/ParseResult.hs b/src/Ormolu/Diff/ParseResult.hs index ed9fd82b..7c31628a 100644 --- a/src/Ormolu/Diff/ParseResult.hs +++ b/src/Ormolu/Diff/ParseResult.hs @@ -1,9 +1,13 @@ {-# LANGUAGE BangPatterns #-} --- needed on GHC 9.0 due to simplified subsumption -{-# LANGUAGE ImpredicativeTypes #-} +{-# LANGUAGE CPP #-} +{-# LANGUAGE RankNTypes #-} {-# LANGUAGE RecordWildCards #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE ViewPatterns #-} +#if !MIN_VERSION_base(4,17,0) +-- needed on GHC 9.0 and 9.2 due to simplified subsumption +{-# LANGUAGE ImpredicativeTypes #-} +#endif -- | This module allows us to diff two 'ParseResult's. module Ormolu.Diff.ParseResult @@ -143,7 +147,7 @@ matchIgnoringSrcSpans a = genericQuery a -- as we normalize arrow styles (e.g. -> vs →), we consider them equal here unicodeArrowStyleEq :: HsArrow GhcPs -> GenericQ ParseResultDiff unicodeArrowStyleEq (HsUnrestrictedArrow _) (castArrow -> Just (HsUnrestrictedArrow _)) = Same - unicodeArrowStyleEq (HsLinearArrow _ _) (castArrow -> Just (HsLinearArrow _ _)) = Same + unicodeArrowStyleEq (HsLinearArrow _) (castArrow -> Just (HsLinearArrow _)) = Same unicodeArrowStyleEq (HsExplicitMult _ _ t) (castArrow -> Just (HsExplicitMult _ _ t')) = genericQuery t t' unicodeArrowStyleEq _ _ = Different [] castArrow :: Typeable a => a -> Maybe (HsArrow GhcPs) diff --git a/src/Ormolu/Imports.hs b/src/Ormolu/Imports.hs index ccaf0df4..5f0eb2c4 100644 --- a/src/Ormolu/Imports.hs +++ b/src/Ormolu/Imports.hs @@ -19,6 +19,7 @@ import GHC.Data.FastString import GHC.Hs import GHC.Hs.ImpExp as GHC import GHC.Types.Name.Reader +import GHC.Types.PkgQual import GHC.Types.SourceText import GHC.Types.SrcLoc import GHC.Unit.Module.Name @@ -81,7 +82,7 @@ importId (L _ ImportDecl {..}) = ImportId { importIsPrelude = isPrelude, importIdName = moduleName, - importPkgQual = LexicalFastString . sl_fs <$> ideclPkgQual, + importPkgQual = rawPkgQualToLFS ideclPkgQual, importSource = ideclSource, importSafe = ideclSafe, importQualified = case ideclQualified of @@ -95,6 +96,9 @@ importId (L _ ImportDecl {..}) = where isPrelude = moduleNameString moduleName == "Prelude" moduleName = unLoc ideclName + rawPkgQualToLFS = \case + RawPkgQual fs -> Just . LexicalFastString . sl_fs $ fs + NoRawPkgQual -> Nothing -- | Normalize a collection of import\/export items. normalizeLies :: [LIE GhcPs] -> [LIE GhcPs] diff --git a/src/Ormolu/Parser.hs b/src/Ormolu/Parser.hs index a5287eea..6a3f9b02 100644 --- a/src/Ormolu/Parser.hs +++ b/src/Ormolu/Parser.hs @@ -19,23 +19,24 @@ import Data.Functor import Data.Generics import qualified Data.List as L import qualified Data.List.NonEmpty as NE -import Data.Ord (Down (Down)) import GHC.Data.Bag (bagToList) import qualified GHC.Data.EnumSet as EnumSet import qualified GHC.Data.FastString as GHC import qualified GHC.Data.StringBuffer as GHC import qualified GHC.Driver.CmdLine as GHC +import GHC.Driver.Config.Parser (initParserOpts) import GHC.Driver.Session as GHC import GHC.DynFlags (baseDynFlags) import GHC.Hs hiding (UnicodeSyntax) import GHC.LanguageExtensions.Type (Extension (..)) import qualified GHC.Parser as GHC -import GHC.Parser.Errors.Ppr (pprError) import qualified GHC.Parser.Header as GHC import qualified GHC.Parser.Lexer as GHC +import GHC.Types.Error (getMessages) import qualified GHC.Types.SourceError as GHC (handleSourceError) import GHC.Types.SrcLoc -import GHC.Utils.Error (Severity (..), errMsgSeverity, errMsgSpan) +import GHC.Utils.Error +import GHC.Utils.Outputable (defaultSDocContext) import qualified GHC.Utils.Panic as GHC import Ormolu.Config import Ormolu.Exception @@ -45,7 +46,7 @@ import Ormolu.Parser.CommentStream import Ormolu.Parser.Result import Ormolu.Processing.Common import Ormolu.Processing.Preprocess -import Ormolu.Utils (incSpanLine) +import Ormolu.Utils (incSpanLine, showOutputable) -- | Parse a complete module from string. parseModule :: @@ -99,13 +100,22 @@ parseModuleSnippet :: parseModuleSnippet Config {..} fixityMap dynFlags path rawInput = liftIO $ do let (input, indent) = removeIndentation . linesInRegion cfgRegion $ rawInput let pStateErrors pstate = - let errs = fmap pprError . bagToList $ GHC.getErrorMessages pstate + let errs = bagToList . getMessages $ GHC.getPsErrorMessages pstate fixupErrSpan = incSpanLine (regionPrefixLength cfgRegion) - in case L.sortOn (Down . SeverityOrd . errMsgSeverity) errs of + rateSeverity = \case + SevError -> 1 :: Int + SevWarning -> 2 + SevIgnore -> 3 + showErr = + showOutputable + . formatBulleted defaultSDocContext + . diagnosticMessage + . errMsgDiagnostic + in case L.sortOn (rateSeverity . errMsgSeverity) errs of [] -> Nothing err : _ -> -- Show instance returns a short error message - Just (fixupErrSpan (errMsgSpan err), show err) + Just (fixupErrSpan (errMsgSpan err), showErr err) parser = case cfgSourceType of ModuleSource -> GHC.parseModule SignatureSource -> GHC.parseSignature @@ -150,12 +160,12 @@ normalizeModule hsmod = hsmodDecls = filter (not . isBlankDocD . unLoc) (hsmodDecls hsmod), hsmodHaddockModHeader = - mfilter (not . isBlankDocString . unLoc) (hsmodHaddockModHeader hsmod), + mfilter (not . isBlankDocString) (hsmodHaddockModHeader hsmod), hsmodExports = (fmap . fmap) (filter (not . isBlankDocIE . unLoc)) (hsmodExports hsmod) } where - isBlankDocString = all isSpace . unpackHDS + isBlankDocString = all isSpace . renderHsDocString . hsDocString . unLoc isBlankDocD = \case DocD _ s -> isBlankDocString $ docDeclDoc s _ -> False @@ -165,8 +175,8 @@ normalizeModule hsmod = _ -> False dropBlankTypeHaddocks = \case - L _ (HsDocTy _ ty (L _ ds)) :: LHsType GhcPs - | isBlankDocString ds -> ty + L _ (HsDocTy _ ty s) :: LHsType GhcPs + | isBlankDocString s -> ty a -> a -- | Enable all language extensions that we think should be enabled by @@ -224,34 +234,7 @@ runParser parser flags filename input = GHC.unP parser parseState where location = mkRealSrcLoc (GHC.mkFastString filename) 1 1 buffer = GHC.stringToStringBuffer input - parseState = GHC.initParserState (opts flags) buffer location - opts = - GHC.mkParserOpts - <$> GHC.warningFlags - <*> GHC.extensionFlags - <*> GHC.safeImportsOn - <*> GHC.gopt GHC.Opt_Haddock - <*> GHC.gopt GHC.Opt_KeepRawTokenStream - <*> const True - --- | Wrap GHC's 'Severity' to add 'Ord' instance. -newtype SeverityOrd = SeverityOrd Severity - -instance Eq SeverityOrd where - s1 == s2 = compare s1 s2 == EQ - -instance Ord SeverityOrd where - compare (SeverityOrd s1) (SeverityOrd s2) = - compare (f s1) (f s2) - where - f :: Severity -> Int - f SevOutput = 1 - f SevFatal = 2 - f SevInteractive = 3 - f SevDump = 4 - f SevInfo = 5 - f SevWarning = 6 - f SevError = 7 + parseState = GHC.initParserState (initParserOpts flags) buffer location ---------------------------------------------------------------------------- -- Helpers taken from HLint @@ -268,7 +251,11 @@ parsePragmasIntoDynFlags :: IO (Either String ([GHC.Warn], DynFlags)) parsePragmasIntoDynFlags flags extraOpts filepath str = catchErrors $ do - let fileOpts = GHC.getOptions flags (GHC.stringToStringBuffer str) filepath + let (_warnings, fileOpts) = + GHC.getOptions + (initParserOpts flags) + (GHC.stringToStringBuffer str) + filepath (flags', leftovers, warnings) <- parseDynamicFilePragma flags (extraOpts <> fileOpts) case NE.nonEmpty leftovers of diff --git a/src/Ormolu/Parser/CommentStream.hs b/src/Ormolu/Parser/CommentStream.hs index 0a5f7813..861441d5 100644 --- a/src/Ormolu/Parser/CommentStream.hs +++ b/src/Ormolu/Parser/CommentStream.hs @@ -29,8 +29,8 @@ import qualified Data.List.NonEmpty as NE import qualified Data.Map.Lazy as M import Data.Maybe import qualified Data.Set as S +import qualified GHC.Data.Strict as Strict import GHC.Hs (HsModule) -import GHC.Hs.Decls (HsDecl (..), LDocDecl, LHsDecl) import GHC.Hs.Doc import GHC.Hs.Extension import GHC.Hs.ImpExp @@ -87,22 +87,15 @@ mkCommentStream input hsModule = EpaComments cs -> cs EpaCommentsBalanced pcs fcs -> pcs <> fcs -- All spans of valid Haddock comments - -- (everywhere where we use p_hsDoc{String,Name}) validHaddockCommentSpans = S.fromList . mapMaybe srcSpanToRealSrcSpan . mconcat - [ fmap getLoc . listify (only @LHsDocString), - fmap getLocA . listify (only @(LDocDecl GhcPs)), - fmap getLocA . listify isDocD, + [ fmap getLoc . listify (only @(LHsDoc GhcPs)), fmap getLocA . listify isIEDocLike ] $ hsModule where - isDocD :: LHsDecl GhcPs -> Bool - isDocD = \case - L _ DocD {} -> True - _ -> False isIEDocLike :: LIE GhcPs -> Bool isIEDocLike = \case L _ IEGroup {} -> True @@ -231,8 +224,8 @@ extractPragmas input = go initialLs id id (y : ys) -> let (ls', y') = mkComment ls y in if onTheSameLine - (RealSrcSpan (getRealSrcSpan x) Nothing) - (RealSrcSpan (getRealSrcSpan y) Nothing) + (RealSrcSpan (getRealSrcSpan x) Strict.Nothing) + (RealSrcSpan (getRealSrcSpan y) Strict.Nothing) then go' ls' [y'] ys else go' ls [] xs @@ -240,10 +233,13 @@ extractPragmas input = go initialLs id id unAnnotationComment :: GHC.LEpaComment -> Maybe (RealLocated String) unAnnotationComment (L (GHC.Anchor anchor _) (GHC.EpaComment eck _)) = case eck of - GHC.EpaDocCommentNext s -> haddock "|" s -- @-- |@ - GHC.EpaDocCommentPrev s -> haddock "^" s -- @-- ^@ - GHC.EpaDocCommentNamed s -> haddock "$" s -- @-- $@ - GHC.EpaDocSection k s -> haddock (replicate k '*') s -- @-- *@ + GHC.EpaDocComment s -> + let trigger = case s of + MultiLineDocString t _ -> Just t + NestedDocString t _ -> Just t + -- should not occur + GeneratedDocString _ -> Nothing + in haddock trigger (renderHsDocString s) GHC.EpaDocOptions s -> mkL s GHC.EpaLineComment s -> mkL $ case take 3 s of @@ -255,9 +251,15 @@ unAnnotationComment (L (GHC.Anchor anchor _) (GHC.EpaComment eck _)) = where mkL = Just . L anchor insertAt x xs n = take (n - 1) xs ++ x ++ drop (n - 1) xs - haddock trigger = + haddock mtrigger = mkL . dashPrefix . escapeHaddockTriggers . (trigger <>) <=< dropBlank where + trigger = case mtrigger of + Just HsDocStringNext -> "|" + Just HsDocStringPrevious -> "^" + Just (HsDocStringNamed n) -> "$" <> n + Just (HsDocStringGroup k) -> replicate k '*' + Nothing -> "" dashPrefix s = "--" <> spaceIfNecessary <> s where spaceIfNecessary = case s of diff --git a/src/Ormolu/Parser/Pragma.hs b/src/Ormolu/Parser/Pragma.hs index 3f9c1ca1..0f38e2af 100644 --- a/src/Ormolu/Parser/Pragma.hs +++ b/src/Ormolu/Parser/Pragma.hs @@ -11,9 +11,10 @@ where import Control.Monad import Data.Char (isSpace, toLower) import qualified Data.List as L -import qualified GHC.Data.EnumSet as ES import GHC.Data.FastString (mkFastString, unpackFS) import GHC.Data.StringBuffer +import GHC.Driver.Config.Parser (initParserOpts) +import GHC.DynFlags (baseDynFlags) import qualified GHC.Parser.Lexer as L import GHC.Types.SrcLoc @@ -67,14 +68,7 @@ tokenize input = location = mkRealSrcLoc (mkFastString "") 1 1 buffer = stringToStringBuffer input parseState = L.initParserState parserOpts buffer location - parserOpts = - L.mkParserOpts - ES.empty - ES.empty - True - True - True - True + parserOpts = initParserOpts baseDynFlags -- | Haskell lexer. pLexer :: L.P [L.Token] diff --git a/src/Ormolu/Printer/Combinators.hs b/src/Ormolu/Printer/Combinators.hs index 78c0edb0..863d696d 100644 --- a/src/Ormolu/Printer/Combinators.hs +++ b/src/Ormolu/Printer/Combinators.hs @@ -75,6 +75,7 @@ where import Control.Monad import Data.List (intersperse) import Data.Text (Text) +import qualified GHC.Data.Strict as Strict import GHC.Types.SrcLoc import Ormolu.Printer.Comments import Ormolu.Printer.Internal @@ -109,7 +110,7 @@ located (L l' a) f = case loc' l' of RealSrcSpan l _ -> do spitPrecedingComments l withEnclosingSpan l $ - switchLayout [RealSrcSpan l Nothing] (f a) + switchLayout [RealSrcSpan l Strict.Nothing] (f a) spitFollowingComments l -- | A version of 'located' with arguments flipped. diff --git a/src/Ormolu/Printer/Meat/Common.hs b/src/Ormolu/Printer/Meat/Common.hs index 82503419..c345f8a8 100644 --- a/src/Ormolu/Printer/Meat/Common.hs +++ b/src/Ormolu/Printer/Meat/Common.hs @@ -10,6 +10,7 @@ module Ormolu.Printer.Meat.Common p_rdrName, p_qualName, p_infixDefHelper, + p_hsDoc, p_hsDocString, p_hsDocName, p_sourceText, @@ -19,6 +20,7 @@ where import Control.Monad import qualified Data.Text as T import GHC.Hs.Doc +import GHC.Hs.Extension (GhcPs) import GHC.Hs.ImpExp import GHC.Parser.Annotation import GHC.Types.Name.Occurrence (OccName (..)) @@ -130,6 +132,18 @@ p_infixDefHelper isInfix indentArgs name args = breakpoint inciIf indentArgs $ sitcc (sep breakpoint sitcc args) +-- | Print a Haddock. +p_hsDoc :: + -- | Haddock style + HaddockStyle -> + -- | Finish the doc string with a newline + Bool -> + -- | The 'LHsDoc' to render + LHsDoc GhcPs -> + R () +p_hsDoc hstyle needsNewline = + p_hsDocString hstyle needsNewline . fmap hsDocString + -- | Print a Haddock. p_hsDocString :: -- | Haddock style diff --git a/src/Ormolu/Printer/Meat/Declaration.hs b/src/Ormolu/Printer/Meat/Declaration.hs index 9438a487..1991f489 100644 --- a/src/Ormolu/Printer/Meat/Declaration.hs +++ b/src/Ormolu/Printer/Meat/Declaration.hs @@ -125,10 +125,10 @@ p_hsDecl style = \case SpliceD _ x -> p_spliceDecl x DocD _ docDecl -> case docDecl of - DocCommentNext str -> p_hsDocString Pipe False (noLoc str) - DocCommentPrev str -> p_hsDocString Caret False (noLoc str) - DocCommentNamed name str -> p_hsDocString (Named name) False (noLoc str) - DocGroup n str -> p_hsDocString (Asterisk n) False (noLoc str) + DocCommentNext str -> p_hsDoc Pipe False str + DocCommentPrev str -> p_hsDoc Caret False str + DocCommentNamed name str -> p_hsDoc (Named name) False str + DocGroup n str -> p_hsDoc (Asterisk n) False str RoleAnnotD _ x -> p_roleAnnot x KindSigD _ s -> p_standaloneKindSig s @@ -314,7 +314,7 @@ patBindNames (VarPat _ (L _ n)) = [n] patBindNames (WildPat _) = [] patBindNames (LazyPat _ (L _ p)) = patBindNames p patBindNames (BangPat _ (L _ p)) = patBindNames p -patBindNames (ParPat _ (L _ p)) = patBindNames p +patBindNames (ParPat _ _ (L _ p) _) = patBindNames p patBindNames (ListPat _ ps) = concatMap (patBindNames . unLoc) ps patBindNames (AsPat _ (L _ n) (L _ p)) = n : patBindNames p patBindNames (SumPat _ (L _ p) _ _) = patBindNames p diff --git a/src/Ormolu/Printer/Meat/Declaration/Data.hs b/src/Ormolu/Printer/Meat/Declaration/Data.hs index 3c0448c0..70292a3f 100644 --- a/src/Ormolu/Printer/Meat/Declaration/Data.hs +++ b/src/Ormolu/Printer/Meat/Declaration/Data.hs @@ -13,6 +13,7 @@ where import Control.Monad import Data.Maybe (isJust, maybeToList) import Data.Void +import qualified GHC.Data.Strict as Strict import GHC.Hs import GHC.Types.Fixity import GHC.Types.ForeignCall @@ -105,7 +106,7 @@ p_conDecl :: R () p_conDecl singleConstRec = \case ConDeclGADT {..} -> do - mapM_ (p_hsDocString Pipe True) con_doc + mapM_ (p_hsDoc Pipe True) con_doc let conDeclSpn = fmap getLocA con_names <> [getLocA con_bndrs] @@ -114,7 +115,7 @@ p_conDecl singleConstRec = \case where conArgsSpans = case con_g_args of PrefixConGADT xs -> getLocA . hsScaledThing <$> xs - RecConGADT x -> [getLocA x] + RecConGADT x _ -> [getLocA x] switchLayout conDeclSpn $ do case con_names of [] -> return () @@ -135,26 +136,28 @@ p_conDecl singleConstRec = \case PrefixConGADT xs -> let go (HsScaled a b) t = addCLocAA t b (HsFunTy EpAnnNotUsed a b t) in foldr go con_res_ty xs - RecConGADT r -> + RecConGADT r _ -> addCLocAA r con_res_ty $ HsFunTy EpAnnNotUsed - (HsUnrestrictedArrow NormalSyntax) + (HsUnrestrictedArrow noHsUniTok) (la2la $ HsRecTy EpAnnNotUsed <$> r) con_res_ty qualTy = case con_mb_cxt of Nothing -> conTy Just qs -> addCLocAA qs conTy $ - HsQualTy NoExtField (Just qs) conTy + HsQualTy NoExtField qs conTy quantifiedTy = addCLocAA con_bndrs qualTy $ hsOuterTyVarBndrsToHsType (unLoc con_bndrs) qualTy p_hsType (unLoc quantifiedTy) ConDeclH98 {..} -> do - mapM_ (p_hsDocString Pipe True) con_doc + mapM_ (p_hsDoc Pipe True) con_doc let conDeclWithContextSpn = - [RealSrcSpan real Nothing | AddEpAnn AnnForall (EpaSpan real) <- epAnnAnns con_ext] + [ RealSrcSpan real Strict.Nothing + | AddEpAnn AnnForall (EpaSpan real) <- epAnnAnns con_ext + ] <> fmap getLocA con_ex_tvs <> maybeToList (fmap getLocA con_mb_cxt) <> conDeclSpn diff --git a/src/Ormolu/Printer/Meat/Declaration/Instance.hs b/src/Ormolu/Printer/Meat/Declaration/Instance.hs index 5f5fe588..7f10b7ad 100644 --- a/src/Ormolu/Printer/Meat/Declaration/Instance.hs +++ b/src/Ormolu/Printer/Meat/Declaration/Instance.hs @@ -70,7 +70,7 @@ p_clsInstDecl ClsInstDecl {..} = do ) <$> cid_tyfam_insts dataFamInsts = - ( getLocA &&& fmap (InstD NoExtField . DataFamInstD EpAnnNotUsed) + ( getLocA &&& fmap (InstD NoExtField . DataFamInstD NoExtField) ) <$> cid_datafam_insts allDecls = diff --git a/src/Ormolu/Printer/Meat/Declaration/OpTree.hs b/src/Ormolu/Printer/Meat/Declaration/OpTree.hs index 4d526bd2..8344f161 100644 --- a/src/Ormolu/Printer/Meat/Declaration/OpTree.hs +++ b/src/Ormolu/Printer/Meat/Declaration/OpTree.hs @@ -217,7 +217,7 @@ tyOpPlacement = \case -- | Convert a LHsType containing an operator tree to the 'OpTree' -- intermediate representation. tyOpTree :: LHsType GhcPs -> OpTree (LHsType GhcPs) (LocatedN RdrName) -tyOpTree (L _ (HsOpTy NoExtField l op r)) = +tyOpTree (L _ (HsOpTy _ _ l op r)) = OpBranches [tyOpTree l, tyOpTree r] [op] tyOpTree n = OpNode n diff --git a/src/Ormolu/Printer/Meat/Declaration/RoleAnnotation.hs b/src/Ormolu/Printer/Meat/Declaration/RoleAnnotation.hs index b59222bc..0d0d60d8 100644 --- a/src/Ormolu/Printer/Meat/Declaration/RoleAnnotation.hs +++ b/src/Ormolu/Printer/Meat/Declaration/RoleAnnotation.hs @@ -11,14 +11,13 @@ where import GHC.Core.Coercion.Axiom import GHC.Hs hiding (anns) import GHC.Types.Name.Reader -import GHC.Types.SrcLoc import Ormolu.Printer.Combinators import Ormolu.Printer.Meat.Common p_roleAnnot :: RoleAnnotDecl GhcPs -> R () p_roleAnnot (RoleAnnotDecl _ l_name anns) = p_roleAnnot' l_name anns -p_roleAnnot' :: LocatedN RdrName -> [Located (Maybe Role)] -> R () +p_roleAnnot' :: LocatedN RdrName -> [XRec GhcPs (Maybe Role)] -> R () p_roleAnnot' l_name anns = do txt "type role" breakpoint diff --git a/src/Ormolu/Printer/Meat/Declaration/Rule.hs b/src/Ormolu/Printer/Meat/Declaration/Rule.hs index c060d76d..76b5631c 100644 --- a/src/Ormolu/Printer/Meat/Declaration/Rule.hs +++ b/src/Ormolu/Printer/Meat/Declaration/Rule.hs @@ -36,7 +36,7 @@ p_ruleDecl (HsRule _ ruleName activation tyvars ruleBndrs lhs rhs) = do -- in the input or no forall at all. We do not want to add redundant -- foralls, so let's just skip the empty ones. unless (null ruleBndrs) $ - p_forallBndrs ForAllInvis p_ruleBndr (reLocA <$> ruleBndrs) + p_forallBndrs ForAllInvis p_ruleBndr ruleBndrs breakpoint inci $ do located lhs p_hsExpr diff --git a/src/Ormolu/Printer/Meat/Declaration/Signature.hs b/src/Ormolu/Printer/Meat/Declaration/Signature.hs index 95276d4c..e2b5b8e9 100644 --- a/src/Ormolu/Printer/Meat/Declaration/Signature.hs +++ b/src/Ormolu/Printer/Meat/Declaration/Signature.hs @@ -144,9 +144,10 @@ p_specSig name ts InlinePragma {..} = pragmaBraces $ do p_inlineSpec :: InlineSpec -> R () p_inlineSpec = \case - Inline -> txt "INLINE" - Inlinable -> txt "INLINEABLE" - NoInline -> txt "NOINLINE" + Inline _ -> txt "INLINE" + Inlinable _ -> txt "INLINEABLE" + NoInline _ -> txt "NOINLINE" + Opaque _ -> txt "OPAQUE" NoUserInlinePrag -> return () p_activation :: Activation -> R () @@ -212,7 +213,7 @@ p_completeSig cs' mty = breakpoint inci (p_rdrName ty) -p_sccSig :: LocatedN RdrName -> Maybe (Located StringLiteral) -> R () +p_sccSig :: LocatedN RdrName -> Maybe (XRec GhcPs StringLiteral) -> R () p_sccSig loc literal = pragma "SCC" . inci $ do p_rdrName loc forM_ literal $ \x -> do diff --git a/src/Ormolu/Printer/Meat/Declaration/TypeFamily.hs b/src/Ormolu/Printer/Meat/Declaration/TypeFamily.hs index 447595da..f5fc6dd1 100644 --- a/src/Ormolu/Printer/Meat/Declaration/TypeFamily.hs +++ b/src/Ormolu/Printer/Meat/Declaration/TypeFamily.hs @@ -28,7 +28,7 @@ p_famDecl style FamilyDecl {fdTyVars = HsQTvs {..}, ..} = do Associated -> mempty Free -> " family" let headerSpns = getLocA fdLName : (getLocA <$> hsq_explicit) - headerAndSigSpns = getLoc fdResultSig : headerSpns + headerAndSigSpns = getLocA fdResultSig : headerSpns inci . switchLayout headerAndSigSpns $ do breakpoint switchLayout headerSpns $ do @@ -58,7 +58,7 @@ p_famDecl style FamilyDecl {fdTyVars = HsQTvs {..}, ..} = do inci (sep newline (located' p_tyFamInstEqn) eqs) p_familyResultSigL :: - Located (FamilyResultSig GhcPs) -> + LFamilyResultSig GhcPs -> Maybe (R ()) p_familyResultSigL (L _ a) = case a of NoSig NoExtField -> Nothing diff --git a/src/Ormolu/Printer/Meat/Declaration/Value.hs b/src/Ormolu/Printer/Meat/Declaration/Value.hs index 9429e4de..9ec04b24 100644 --- a/src/Ormolu/Printer/Meat/Declaration/Value.hs +++ b/src/Ormolu/Printer/Meat/Declaration/Value.hs @@ -2,8 +2,10 @@ {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE RecordWildCards #-} +{-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeFamilies #-} +{-# LANGUAGE TypeOperators #-} {-# LANGUAGE ViewPatterns #-} module Ormolu.Printer.Meat.Declaration.Value @@ -35,6 +37,7 @@ import qualified Data.Text as Text import Data.Void import GHC.Data.Bag (bagToList) import GHC.Data.FastString (FastString, lengthFS) +import qualified GHC.Data.Strict as Strict import GHC.Hs import GHC.LanguageExtensions.Type (Extension (NegativeLiterals)) import GHC.Parser.CharClass (is_space) @@ -65,12 +68,11 @@ data GroupStyle = EqualSign | RightArrow -p_valDecl :: HsBindLR GhcPs GhcPs -> R () +p_valDecl :: HsBind GhcPs -> R () p_valDecl = \case FunBind _ funId funMatches _ -> p_funBind funId funMatches PatBind _ pat grhss _ -> p_match PatternBind False NoSrcStrict [pat] grhss VarBind {} -> notImplemented "VarBinds" -- introduced by the type checker - AbsBinds {} -> notImplemented "AbsBinds" -- introduced by the type checker PatSynBind _ psb -> p_patSynBind psb p_funBind :: @@ -86,7 +88,7 @@ p_matchGroup :: p_matchGroup = p_matchGroup' exprPlacement p_hsExpr p_matchGroup' :: - ( Anno (GRHS GhcPs (LocatedA body)) ~ SrcSpan, + ( Anno (GRHS GhcPs (LocatedA body)) ~ SrcAnn NoEpAnns, Anno (Match GhcPs (LocatedA body)) ~ SrcSpanAnnA ) => -- | How to get body placement @@ -155,7 +157,7 @@ p_match :: p_match = p_match' exprPlacement p_hsExpr p_match' :: - (Anno (GRHS GhcPs (LocatedA body)) ~ SrcSpan) => + (Anno (GRHS GhcPs (LocatedA body)) ~ SrcAnn NoEpAnns) => -- | How to get body placement (body -> Placement) -> -- | How to print body @@ -243,7 +245,7 @@ p_match' placer render style isInfix strictness m_pats GRHSs {..} = do || not (onTheSameLine spn grhssSpan) -> Normal _ -> blockPlacement placer grhssGRHSs - guardNeedsLineBreak :: Located (GRHS GhcPs body) -> Bool + guardNeedsLineBreak :: XRec GhcPs (GRHS GhcPs body) -> Bool guardNeedsLineBreak (L _ (GRHS _ guardLStmts _)) = case guardLStmts of [] -> False [g] -> not . isOneLineSpan . getLocA $ g @@ -255,7 +257,7 @@ p_match' placer render style isInfix strictness m_pats GRHSs {..} = do else EqualSign sep breakpoint - (located' (p_grhs' placement placer render groupStyle) . reLocA) + (located' (p_grhs' placement placer render groupStyle)) grhssGRHSs p_where = do unless (eqEmptyLocalBinds grhssLocalBinds) $ do @@ -353,14 +355,14 @@ p_hsCmd' s = \case space located expr p_hsExpr HsCmdLam _ mgroup -> p_matchGroup' cmdPlacement p_hsCmd Lambda mgroup - HsCmdPar _ c -> parens N (located c p_hsCmd) + HsCmdPar _ _ c _ -> parens N (located c p_hsCmd) HsCmdCase _ e mgroup -> p_case cmdPlacement p_hsCmd e mgroup - HsCmdLamCase _ mgroup -> - p_lamcase cmdPlacement p_hsCmd mgroup + HsCmdLamCase _ variant mgroup -> + p_lamcase variant cmdPlacement p_hsCmd mgroup HsCmdIf _ _ if' then' else' -> p_if cmdPlacement p_hsCmd if' then' else' - HsCmdLet _ localBinds c -> + HsCmdLet _ _ localBinds _ c -> p_let p_hsCmd localBinds c HsCmdDo _ es -> do txt "do" @@ -522,16 +524,12 @@ p_hsLocalBinds = \case sitcc $ sepSemi p_item' (attachRelativePos binds) HsValBinds _ _ -> notImplemented "HsValBinds" HsIPBinds epAnn (IPBinds _ xs) -> pseudoLocated epAnn $ do - -- Second argument of IPBind is always Left before type-checking. - let p_ipBind (IPBind _ (Left name) expr) = do - atom name + let p_ipBind (IPBind _ (L _ name) expr) = do + atom @HsIPName name space equals breakpoint useBraces $ inci $ located expr p_hsExpr - p_ipBind (IPBind _ (Right _) _) = - -- Should only occur after the type checker - notImplemented "IPBind _ (Right _) _" sepSemi (located' p_ipBind) xs EmptyLocalBinds _ -> return () where @@ -540,13 +538,13 @@ p_hsLocalBinds = \case -- depend on the layout being correctly set. pseudoLocated = \case EpAnn {anns = AnnList {al_anchor = Just Anchor {anchor}}} -> - located (L (RealSrcSpan anchor Nothing) ()) . const + located (L (RealSrcSpan anchor Strict.Nothing) ()) . const _ -> id -p_lhsFieldLabel :: Located (HsFieldLabel GhcPs) -> R () -p_lhsFieldLabel = located' $ p_lFieldLabelString . hflLabel +p_ldotFieldOcc :: XRec GhcPs (DotFieldOcc GhcPs) -> R () +p_ldotFieldOcc = located' $ p_lFieldLabelString . dfoLabel where - p_lFieldLabelString (L s fs) = parensIfOp . atom @FastString $ fs + p_lFieldLabelString (L (locA -> s) fs) = parensIfOp . atom @FastString $ fs where -- HACK For OverloadedRecordUpdate: -- In operator field updates (i.e. `f {(+) = 1}`), we don't have @@ -560,24 +558,27 @@ p_lhsFieldLabel = located' $ p_lFieldLabelString . hflLabel parens N | otherwise = id -p_fieldLabels :: [Located (HsFieldLabel GhcPs)] -> R () -p_fieldLabels flss = - sep (txt ".") p_lhsFieldLabel flss +p_ldotFieldOccs :: [XRec GhcPs (DotFieldOcc GhcPs)] -> R () +p_ldotFieldOccs = sep (txt ".") p_ldotFieldOcc -p_hsRecField :: - (id -> R ()) -> - HsRecField' id (LHsExpr GhcPs) -> +p_fieldOcc :: FieldOcc GhcPs -> R () +p_fieldOcc FieldOcc {..} = p_rdrName foLabel + +p_hsFieldBind :: + (lhs ~ GenLocated l a, HasSrcSpan l) => + (lhs -> R ()) -> + HsFieldBind lhs (LHsExpr GhcPs) -> R () -p_hsRecField p_lbl HsRecField {..} = do - located hsRecFieldLbl p_lbl - unless hsRecPun $ do +p_hsFieldBind p_lhs HsFieldBind {..} = do + p_lhs hfbLHS + unless hfbPun $ do space equals let placement = - if onTheSameLine (getLoc hsRecFieldLbl) (getLocA hsRecFieldArg) - then exprPlacement (unLoc hsRecFieldArg) + if onTheSameLine (getLoc' hfbLHS) (getLocA hfbRHS) + then exprPlacement (unLoc hfbRHS) else Normal - placeHanging placement (located hsRecFieldArg p_hsExpr) + placeHanging placement (located hfbRHS p_hsExpr) p_hsExpr :: HsExpr GhcPs -> R () p_hsExpr = p_hsExpr' N @@ -586,11 +587,7 @@ p_hsExpr' :: BracketStyle -> HsExpr GhcPs -> R () p_hsExpr' s = \case HsVar _ name -> p_rdrName name HsUnboundVar _ occ -> atom occ - HsConLikeOut _ _ -> notImplemented "HsConLikeOut" - HsRecFld _ x -> - case x of - Unambiguous _ name -> p_rdrName name - Ambiguous _ name -> p_rdrName name + HsRecSel _ fldOcc -> p_fieldOcc fldOcc HsOverLabel _ v -> do txt "#" atom v @@ -605,8 +602,8 @@ p_hsExpr' s = \case r -> atom r HsLam _ mgroup -> p_matchGroup Lambda mgroup - HsLamCase _ mgroup -> - p_lamcase exprPlacement p_hsExpr mgroup + HsLamCase _ variant mgroup -> + p_lamcase variant exprPlacement p_hsExpr mgroup HsApp _ f x -> do let -- In order to format function applications with multiple parameters -- nicer, traverse the AST to gather the function and all the @@ -696,7 +693,7 @@ p_hsExpr' s = \case -- negated literals, as `- 1` and `-1` have differing AST. when (negativeLiterals && isLiteral) space located e p_hsExpr - HsPar _ e -> + HsPar _ _ e _ -> parens s (located e (dontUseBraces . p_hsExpr)) SectionL _ x op -> do located x p_hsExpr @@ -719,7 +716,9 @@ p_hsExpr' s = \case case boxity of Boxed -> parens Unboxed -> parensHash - enclSpan <- fmap (flip RealSrcSpan Nothing) . maybeToList <$> getEnclosingSpan (const True) + enclSpan <- + fmap (flip RealSrcSpan Strict.Nothing) . maybeToList + <$> getEnclosingSpan (const True) if isSection then switchLayout [] . parens' s $ @@ -737,9 +736,9 @@ p_hsExpr' s = \case txt "if" breakpoint inci . inci $ sep newline (located' (p_grhs RightArrow)) guards - HsLet _ localBinds e -> + HsLet _ _ localBinds _ e -> p_let p_hsExpr localBinds e - HsDo _ ctx es -> do + HsDo _ doFlavor es -> do let doBody moduleName header = do forM_ moduleName $ \m -> atom m *> txt "." txt header @@ -762,52 +761,48 @@ p_hsExpr' s = \case txt "|" space p_parBody lists - case ctx of + case doFlavor of DoExpr moduleName -> doBody moduleName "do" MDoExpr moduleName -> doBody moduleName "mdo" ListComp -> compBody MonadComp -> compBody - ArrowExpr -> notImplemented "ArrowExpr" GhciStmtCtxt -> notImplemented "GhciStmtCtxt" - PatGuard _ -> notImplemented "PatGuard" - ParStmtCtxt _ -> notImplemented "ParStmtCtxt" - TransStmtCtxt _ -> notImplemented "TransStmtCtxt" ExplicitList _ xs -> brackets s $ sep commaDel (sitcc . located' p_hsExpr) xs RecordCon {..} -> do - located rcon_con atom + p_rdrName rcon_con breakpoint let HsRecFields {..} = rcon_flds - p_lbl = p_rdrName . rdrNameFieldOcc - fields = located' (p_hsRecField p_lbl) <$> rec_flds - dotdot = - case rec_dotdot of - Just {} -> [txt ".."] - Nothing -> [] + p_lhs = located' $ p_rdrName . foLabel + fields = located' (p_hsFieldBind p_lhs) <$> rec_flds + dotdot = case rec_dotdot of + Just {} -> [txt ".."] + Nothing -> [] inci . braces N $ sep commaDel sitcc (fields <> dotdot) RecordUpd {..} -> do located rupd_expr p_hsExpr breakpoint let p_updLbl = - p_rdrName . \case - Unambiguous NoExtField n -> n - Ambiguous NoExtField n -> n + located' $ + p_rdrName . \case + (Unambiguous NoExtField n :: AmbiguousFieldOcc GhcPs) -> n + Ambiguous NoExtField n -> n p_recFields p_lbl = - sep commaDel (sitcc . located' (p_hsRecField p_lbl)) + sep commaDel (sitcc . located' (p_hsFieldBind p_lbl)) inci . braces N $ either (p_recFields p_updLbl) - (p_recFields (p_fieldLabels . coerce)) + (p_recFields $ located' $ coerce p_ldotFieldOccs) rupd_flds HsGetField {..} -> do located gf_expr p_hsExpr txt "." - p_lhsFieldLabel gf_field + p_ldotFieldOcc gf_field HsProjection {..} -> parens N $ do txt "." - p_fieldLabels (NE.toList proj_flds) + p_ldotFieldOccs (NE.toList proj_flds) ExprWithTySig _ x HsWC {hswc_body} -> sitcc $ do located x p_hsExpr space @@ -836,9 +831,13 @@ p_hsExpr' s = \case txt ".." space located to p_hsExpr - HsBracket epAnn x -> p_hsBracket epAnn x - HsRnBracketOut {} -> notImplemented "HsRnBracketOut" - HsTcBracketOut {} -> notImplemented "HsTcBracketOut" + HsTypedBracket _ expr -> do + txt "[||" + breakpoint' + located expr p_hsExpr + breakpoint' + txt "||]" + HsUntypedBracket epAnn x -> p_hsQuote epAnn x HsSpliceE _ splice -> p_hsSplice splice HsProc _ p e -> do txt "proc" @@ -853,8 +852,6 @@ p_hsExpr' s = \case txt "static" breakpoint inci (located e p_hsExpr) - HsTick {} -> notImplemented "HsTick" - HsBinTick {} -> notImplemented "HsBinTick" HsPragE _ prag x -> case prag of HsPragSCC _ _ name -> do txt "{-# SCC " @@ -923,7 +920,7 @@ p_patSynBind PSB {..} = do inci (rhs conSpans) p_case :: - ( Anno (GRHS GhcPs (LocatedA body)) ~ SrcSpan, + ( Anno (GRHS GhcPs (LocatedA body)) ~ SrcAnn NoEpAnns, Anno (Match GhcPs (LocatedA body)) ~ SrcSpanAnnA ) => -- | Placer @@ -945,9 +942,11 @@ p_case placer render e mgroup = do inci (p_matchGroup' placer render Case mgroup) p_lamcase :: - ( Anno (GRHS GhcPs (LocatedA body)) ~ SrcSpan, + ( Anno (GRHS GhcPs (LocatedA body)) ~ SrcAnn NoEpAnns, Anno (Match GhcPs (LocatedA body)) ~ SrcSpanAnnA ) => + -- | Variant (@\\case@ or @\\cases@) + LamCaseVariant -> -- | Placer (body -> Placement) -> -- | Render @@ -955,8 +954,10 @@ p_lamcase :: -- | Expression MatchGroup GhcPs (LocatedA body) -> R () -p_lamcase placer render mgroup = do - txt "\\case" +p_lamcase variant placer render mgroup = do + txt $ case variant of + LamCase -> "\\case" + LamCases -> "\\cases" breakpoint inci (p_matchGroup' placer render LambdaCase mgroup) @@ -1014,7 +1015,7 @@ p_pat = \case p_rdrName name txt "@" located pat p_pat - ParPat _ pat -> + ParPat _ _ pat _ -> located pat (parens S . p_pat) BangPat _ pat -> do txt "!" @@ -1043,7 +1044,7 @@ p_pat = \case breakpoint let f = \case Nothing -> txt ".." - Just x -> located x p_pat_hsRecField + Just x -> located x p_pat_hsFieldBind inci . braces N . sep commaDel f $ case dotdot of Nothing -> Just <$> fields @@ -1081,14 +1082,14 @@ p_pat = \case located pat p_pat p_typeAscription (lhsTypeToSigType hsps_body) -p_pat_hsRecField :: HsRecField' (FieldOcc GhcPs) (LPat GhcPs) -> R () -p_pat_hsRecField HsRecField {..} = do - located hsRecFieldLbl $ p_rdrName . rdrNameFieldOcc - unless hsRecPun $ do +p_pat_hsFieldBind :: HsRecField GhcPs (LPat GhcPs) -> R () +p_pat_hsFieldBind HsFieldBind {..} = do + located hfbLHS p_fieldOcc + unless hfbPun $ do space equals breakpoint - inci (located hsRecFieldArg p_pat) + inci (located hfbRHS p_pat) p_unboxedSum :: BracketStyle -> ConTag -> Arity -> R () -> R () p_unboxedSum s tag arity m = do @@ -1136,8 +1137,8 @@ p_hsSpliceTH isTyped expr = \case where decoSymbol = if isTyped then "$$" else "$" -p_hsBracket :: EpAnn [AddEpAnn] -> HsBracket GhcPs -> R () -p_hsBracket epAnn = \case +p_hsQuote :: EpAnn [AddEpAnn] -> HsQuote GhcPs -> R () +p_hsQuote epAnn = \case ExpBr _ expr -> do let name | or [True | AddEpAnn AnnOpenEQ _ <- epAnnAnns epAnn] = "" @@ -1150,12 +1151,6 @@ p_hsBracket epAnn = \case VarBr _ isSingleQuote name -> do txt (bool "''" "'" isSingleQuote) p_rdrName name - TExpBr _ expr -> do - txt "[||" - breakpoint' - located expr p_hsExpr - breakpoint' - txt "||]" where quote :: Text -> R () -> R () quote name body = do @@ -1261,7 +1256,7 @@ cmdPlacement :: HsCmd GhcPs -> Placement cmdPlacement = \case HsCmdLam _ _ -> Hanging HsCmdCase _ _ _ -> Hanging - HsCmdLamCase _ _ -> Hanging + HsCmdLamCase _ _ _ -> Hanging HsCmdDo _ _ -> Hanging _ -> Normal @@ -1278,7 +1273,7 @@ exprPlacement = \case | isOneLineSpan (combineSrcSpans' $ fmap getLocA (x :| xs)) -> Hanging _ -> Normal - HsLamCase _ _ -> Hanging + HsLamCase _ _ _ -> Hanging HsCase _ _ _ -> Hanging HsDo _ (DoExpr _) _ -> Hanging HsDo _ (MDoExpr _) _ -> Hanging diff --git a/src/Ormolu/Printer/Meat/Declaration/Warning.hs b/src/Ormolu/Printer/Meat/Declaration/Warning.hs index f07e0e7c..583fd938 100644 --- a/src/Ormolu/Printer/Meat/Declaration/Warning.hs +++ b/src/Ormolu/Printer/Meat/Declaration/Warning.hs @@ -25,12 +25,12 @@ p_warnDecl :: WarnDecl GhcPs -> R () p_warnDecl (Warning _ functions warningTxt) = p_topLevelWarning functions warningTxt -p_moduleWarning :: WarningTxt -> R () +p_moduleWarning :: WarningTxt GhcPs -> R () p_moduleWarning wtxt = do let (pragmaText, lits) = warningText wtxt inci $ pragma pragmaText $ inci $ p_lits lits -p_topLevelWarning :: [LocatedN RdrName] -> WarningTxt -> R () +p_topLevelWarning :: [LocatedN RdrName] -> WarningTxt GhcPs -> R () p_topLevelWarning fnames wtxt = do let (pragmaText, lits) = warningText wtxt switchLayout (fmap getLocA fnames ++ fmap getLoc lits) $ @@ -39,10 +39,10 @@ p_topLevelWarning fnames wtxt = do breakpoint p_lits lits -warningText :: WarningTxt -> (Text, [Located StringLiteral]) +warningText :: WarningTxt GhcPs -> (Text, [Located StringLiteral]) warningText = \case - WarningTxt _ lits -> ("WARNING", lits) - DeprecatedTxt _ lits -> ("DEPRECATED", lits) + WarningTxt _ lits -> ("WARNING", fmap hsDocString <$> lits) + DeprecatedTxt _ lits -> ("DEPRECATED", fmap hsDocString <$> lits) p_lits :: [Located StringLiteral] -> R () p_lits = \case diff --git a/src/Ormolu/Printer/Meat/ImportExport.hs b/src/Ormolu/Printer/Meat/ImportExport.hs index c066b140..f13c2779 100644 --- a/src/Ormolu/Printer/Meat/ImportExport.hs +++ b/src/Ormolu/Printer/Meat/ImportExport.hs @@ -12,6 +12,7 @@ where import Control.Monad import GHC.Hs import GHC.LanguageExtensions.Type +import GHC.Types.PkgQual import GHC.Types.SrcLoc import GHC.Unit.Types import Ormolu.Printer.Combinators @@ -45,8 +46,8 @@ p_hsmodImport ImportDecl {..} = do (txt "qualified") space case ideclPkgQual of - Nothing -> return () - Just slit -> atom slit + NoRawPkgQual -> return () + RawPkgQual slit -> atom slit space inci $ do located ideclName atom @@ -112,9 +113,9 @@ p_lie encLayout relativePos = \case FirstPos -> return () MiddlePos -> newline LastPos -> newline - p_hsDocString (Asterisk n) False (noLoc str) + p_hsDoc (Asterisk n) False str IEDoc NoExtField str -> - p_hsDocString Pipe False (noLoc str) + p_hsDoc Pipe False str IEDocNamed NoExtField str -> p_hsDocName str where p_comma = diff --git a/src/Ormolu/Printer/Meat/Module.hs b/src/Ormolu/Printer/Meat/Module.hs index dde78817..b133dc56 100644 --- a/src/Ormolu/Printer/Meat/Module.hs +++ b/src/Ormolu/Printer/Meat/Module.hs @@ -45,7 +45,7 @@ p_hsModule mstackHeader pragmas HsModule {..} = do Nothing -> return () Just hsmodName' -> do located hsmodName' $ \name -> do - forM_ hsmodHaddockModHeader (p_hsDocString Pipe True) + forM_ hsmodHaddockModHeader (p_hsDoc Pipe True) p_hsmodName name breakpoint forM_ hsmodDeprecMessage $ \w -> do diff --git a/src/Ormolu/Printer/Meat/Type.hs b/src/Ormolu/Printer/Meat/Type.hs index 95bb863d..87bf64e9 100644 --- a/src/Ormolu/Printer/Meat/Type.hs +++ b/src/Ormolu/Printer/Meat/Type.hs @@ -22,7 +22,6 @@ module Ormolu.Printer.Meat.Type ) where -import Data.Foldable (for_) import GHC.Hs import GHC.Types.Basic hiding (isPromoted) import GHC.Types.SourceText @@ -54,12 +53,11 @@ p_hsType' multilineArgs docStyle = \case HsForAllVis _ bndrs -> p_forallBndrs ForAllVis p_hsTyVarBndr bndrs interArgBreak p_hsTypeR (unLoc t) - HsQualTy _ qs' t -> do - for_ qs' $ \qs -> do - located qs p_hsContext - space - txt "=>" - interArgBreak + HsQualTy _ qs t -> do + located qs p_hsContext + space + txt "=>" + interArgBreak case unLoc t of HsQualTy {} -> p_hsTypeR (unLoc t) HsFunTy {} -> p_hsTypeR (unLoc t) @@ -101,8 +99,8 @@ p_hsType' multilineArgs docStyle = \case space case arrow of HsUnrestrictedArrow _ -> txt "->" - HsLinearArrow _ _ -> txt "%1 ->" - HsExplicitMult _ _ mult -> do + HsLinearArrow _ -> txt "%1 ->" + HsExplicitMult _ mult _ -> do txt "%" p_hsTypeR (unLoc mult) space @@ -122,7 +120,7 @@ p_hsType' multilineArgs docStyle = \case HsSumTy _ xs -> parensHash N $ sep (space >> txt "|" >> breakpoint) (sitcc . located' p_hsType) xs - HsOpTy _ x op y -> do + HsOpTy _ _ x op y -> do fixityOverrides <- askFixityOverrides fixityMap <- askFixityMap let opTree = OpBranches [tyOpTree x, tyOpTree y] [op] @@ -147,12 +145,12 @@ p_hsType' multilineArgs docStyle = \case HsDocTy _ t str -> case docStyle of PipeStyle -> do - p_hsDocString Pipe True str + p_hsDoc Pipe True str located t p_hsType CaretStyle -> do located t p_hsType newline - p_hsDocString Caret False str + p_hsDoc Caret False str HsBangTy _ (HsSrcBang _ u s) t -> do case u of SrcUnpack -> txt "{-# UNPACK #-}" >> space @@ -243,11 +241,16 @@ p_hsTyVarBndr = \case data ForAllVisibility = ForAllInvis | ForAllVis -- | Render several @forall@-ed variables. -p_forallBndrs :: ForAllVisibility -> (a -> R ()) -> [LocatedA a] -> R () +p_forallBndrs :: + HasSrcSpan l => + ForAllVisibility -> + (a -> R ()) -> + [GenLocated l a] -> + R () p_forallBndrs ForAllInvis _ [] = txt "forall." p_forallBndrs ForAllVis _ [] = txt "forall ->" p_forallBndrs vis p tyvars = - switchLayout (getLocA <$> tyvars) $ do + switchLayout (getLoc' <$> tyvars) $ do txt "forall" breakpoint inci $ do @@ -262,11 +265,11 @@ p_conDeclFields xs = p_conDeclField :: ConDeclField GhcPs -> R () p_conDeclField ConDeclField {..} = do - mapM_ (p_hsDocString Pipe True) cd_fld_doc + mapM_ (p_hsDoc Pipe True) cd_fld_doc sitcc $ sep commaDel - (located' (p_rdrName . rdrNameFieldOcc)) + (located' (p_rdrName . foLabel)) cd_fld_names space txt "::" diff --git a/src/Ormolu/Utils.hs b/src/Ormolu/Utils.hs index 04c40555..391d888e 100644 --- a/src/Ormolu/Utils.hs +++ b/src/Ormolu/Utils.hs @@ -25,6 +25,7 @@ import qualified Data.List.NonEmpty as NE import Data.Maybe (fromMaybe) import Data.Text (Text) import qualified Data.Text as T +import qualified GHC.Data.Strict as Strict import GHC.Driver.Ppr import GHC.DynFlags (baseDynFlags) import GHC.Hs @@ -76,7 +77,7 @@ splitDocString docStr = . dropWhileEnd T.null . fmap (T.stripEnd . T.pack) . lines - $ unpackHDS docStr + $ renderHsDocString docStr -- We cannot have the first character to be a dollar because in that -- case it'll be a parse error (apparently collides with named docs -- syntax @-- $name@ somehow). @@ -110,7 +111,7 @@ incSpanLine i = \case line = srcLocLine x col = srcLocCol x in mkRealSrcLoc file (line + i) col - in RealSrcSpan (mkRealSrcSpan (incLine start) (incLine end)) Nothing + in RealSrcSpan (mkRealSrcSpan (incLine start) (incLine end)) Strict.Nothing UnhelpfulSpan x -> UnhelpfulSpan x -- | Do two declarations have a blank between them? diff --git a/stack.yaml b/stack.yaml index cf176579..2639fb2a 100644 --- a/stack.yaml +++ b/stack.yaml @@ -1,4 +1,4 @@ -resolver: lts-19.2 +resolver: lts-19.20 packages: - '.' @@ -6,8 +6,8 @@ packages: - extract-hackage-info extra-deps: -- Cabal-3.6.2.0 -- ghc-lib-parser-9.2.1.20211101 +- Cabal-syntax-3.8.1.0 +- ghc-lib-parser-9.4.1.20220807 nix: packages: diff --git a/tests/Ormolu/CabalInfoSpec.hs b/tests/Ormolu/CabalInfoSpec.hs index d82219e6..2eb7bd34 100644 --- a/tests/Ormolu/CabalInfoSpec.hs +++ b/tests/Ormolu/CabalInfoSpec.hs @@ -38,7 +38,7 @@ spec = do ciDynOpts `shouldBe` [DynOption "-XHaskell2010"] it "extracts correct dependencies from ormolu.cabal (src/Ormolu/Config.hs)" $ do CabalInfo {..} <- parseCabalInfo "ormolu.cabal" "src/Ormolu/Config.hs" - ciDependencies `shouldBe` Set.fromList ["Cabal", "Diff", "MemoTrie", "aeson", "ansi-terminal", "array", "base", "bytestring", "containers", "directory", "dlist", "exceptions", "file-embed", "filepath", "ghc-lib-parser", "megaparsec", "mtl", "syb", "template-haskell", "text", "th-lift-instances"] + ciDependencies `shouldBe` Set.fromList ["Cabal-syntax", "Diff", "MemoTrie", "aeson", "ansi-terminal", "array", "base", "bytestring", "containers", "directory", "dlist", "exceptions", "file-embed", "filepath", "ghc-lib-parser", "megaparsec", "mtl", "syb", "template-haskell", "text", "th-lift-instances"] it "extracts correct dependencies from ormolu.cabal (tests/Ormolu/PrinterSpec.hs)" $ do CabalInfo {..} <- parseCabalInfo "ormolu.cabal" "tests/Ormolu/PrinterSpec.hs" ciDependencies `shouldBe` Set.fromList ["QuickCheck", "base", "containers", "directory", "filepath", "ghc-lib-parser", "hspec", "hspec-megaparsec", "megaparsec", "ormolu", "path", "path-io", "temporary", "text"]