on effb5cd help sign in
.buildkite/pipeline.ymldeleted−18
since splitsnapshots
unifiedsplit
@@ -1,18 +0,0 @@
1−steps:
2− - label: Build and test with GHC 8.6.5
3− command: |
4− nix-build --keep-going --no-out-link --argstr ormoluCompiler ghc865
5− timeout: 100
6− - label: Build and test with GHC 8.8.4
7− command: |
8− nix-build --keep-going --no-out-link --argstr ormoluCompiler ghc884
9− timeout: 100
10− - label: Build and test with GHC 8.10.1
11− command: |
12− nix-build --keep-going --no-out-link --argstr ormoluCompiler ghc8101
13− timeout: 100
14− - wait
15− - label: Check formatting
16− command: |
17− ./format.sh
18− git diff --exit-code --color=always
.circleci/config.ymlnew file+44
@@ -0,0 +1,44 @@
1+version: 2
2+
3+jobs:
4+ build_ghc864:
5+ docker:
6+ - image: nixos/nix:2.1.3
7+ steps:
8+ - checkout
9+ - run:
10+ name: Add ca-certificates
11+ command: |
12+ apk --no-progress update
13+ apk --no-progress add ca-certificates
14+ - run:
15+ name: Setup Cachix
16+ command: |
17+ nix-env -f nix/nixpkgs/ -iA cachix
18+ USER=dummy cachix use tweag
19+ - run:
20+ name: Build environment
21+ command: |
22+ nix-shell --pure --run :
23+ - run:
24+ name: Push Cachix
25+ command: |
26+ if [ -n "$CACHIX_SIGNING_KEY" ];
27+ then nix-store -qR --include-outputs $(nix-instantiate default.nix) | cachix push tweag;
28+ fi
29+ - run:
30+ name: Build the package (includes running the tests)
31+ command: nix-build
32+ - run:
33+ name: Generate Haddocks
34+ command: nix-build --attr ormolu.doc
35+ - store_artifacts:
36+ path: result-doc/share/doc
37+ destination: haddock
38+
39+workflows:
40+ version: 2
41+ build:
42+ jobs:
43+ - build_ghc864:
44+ context: org-global
.github/workflows/binaries.ymldeleted−39
@@ -1,39 +0,0 @@
1−name: Build binaries
2−on:
3− release:
4− types: [published]
5−jobs:
6− build:
7− strategy:
8− fail-fast: false
9− matrix:
10− os: [ubuntu-latest, macOS-latest, windows-latest]
11− runs-on: ${{ matrix.os }}
12− steps:
13− - uses: actions/checkout@v2
14− - uses: actions/setup-haskell@v1
15− if: runner.os != 'Linux'
16− with:
17− ghc-version: '8.10.1'
18− cabal-version: '3.2'
19− - name: Build Linux binary
20− if: runner.os == 'Linux'
21− run: |
22− docker run \
23− -v $(pwd):/mnt -w /mnt \
24− utdemir/ghc-musl:v14-ghc8101 \
25− bash .github/workflows/build.sh
26− - name: Build ${{ runner.os }} binary
27− if: runner.os != 'Linux'
28− shell: bash
29− run: |
30− cabal build exe:ormolu
31− cp $(find dist-newstyle \( -name ormolu -o -name ormolu.exe \) -type f) ormolu
32− - uses: actions/upload-release-asset@v1
33− env:
34− GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
35− with:
36− upload_url: ${{ github.event.release.upload_url }}
37− asset_path: ormolu
38− asset_name: ormolu-${{ runner.os }}
39− asset_content_type: application/octet-stream
.github/workflows/build.shdeleted−7
@@ -1,7 +0,0 @@
1−set -e
2−
3−cabal update
4−cabal build exe:ormolu --enable-executable-static --ghc-options="-split-sections"
5−
6−cp $(find dist-newstyle -name ormolu -type f) .
7−strip -s ormolu
.gitignore−1
@@ -26,5 +26,4 @@ cabal.sandbox.config
26dist-*/
26dist-*/
27dist/
27dist/
28stack.yaml
28stack.yaml
29−stack.yaml.lock
30result*
29result*
CHANGELOG.md−231
@@ -1,234 +1,3 @@
1−## Unreleased
2−
3−* Ormolu no longer overwrites already formatted files. [PR
4− 649](https://github.com/tweag/ormolu/pull/649).
5−
6−## Ormolu 0.1.2.0
7−
8−* Fixed the bug when comments in different styles got glued together after
9− formatting. [Issue 589](https://github.com/tweag/ormolu/issues/589).
10−
11−* Added `-i` as a shortcut for `--mode inplace`. [Issue
12− 467](https://github.com/tweag/ormolu/issues/467).
13−
14−* Improved grouping of top-level declarations. [Issue
15− 466](https://github.com/tweag/ormolu/issues/466).
16−
17−## Ormolu 0.1.1.0
18−
19−* Imports in a import lists are now normalized: duplicate imports are
20− combined/eliminated intelligently.
21−
22−* Import declarations that can be merged are now automatically merged.
23− [Issue 414](https://github.com/tweag/ormolu/issues/414).
24−
25−* The magic comments for disabling and enabling Ormolu now can encompass any
26− fragment of code provided that the remaining code after exclusion of the
27− disabled part is still syntactically correct. [Issue
28− 601](https://github.com/tweag/ormolu/issues/601).
29−
30−* Improved sorting of operators in imports. [Issue
31− 602](https://github.com/tweag/ormolu/issues/602).
32−
33−* Fixed a bug related to trailing space in multiline comments in certain
34− cases. [Issue 603](https://github.com/tweag/ormolu/issues/602).
35−
36−* Added support for formatting linked lists with `(:)` as line terminator.
37− [Issue 478](https://github.com/tweag/ormolu/issues/478).
38−
39−* Fixed rendering of function arguments in multiline layout. [Issue
40− 609](https://github.com/tweag/ormolu/issues/609).
41−
42−* Blank lines between definitions in `let` and `while` bindings are now
43− preserved. [Issue 554](https://github.com/tweag/ormolu/issues/554).
44−
45−* Fixed the bug when type applications stuck to the `$` of TH splices that
46− followed them. [Issue 613](https://github.com/tweag/ormolu/issues/613).
47−
48−* Improved region formatting so that indented fragments—such as definitions
49− inside of `where` clauses—can be formatted. [Issue
50− 572](https://github.com/tweag/ormolu/issues/572).
51−
52−* Fixed the bug related to the de-association of pragma comments. [Issue
53− 619](https://github.com/tweag/ormolu/issues/619).
54−
55−## Ormolu 0.1.0.0
56−
57−* Fixed rendering of type signatures concerning several identifiers. [Issue
58− 566](https://github.com/tweag/ormolu/issues/566).
59−
60−* Fixed an idempotence issue with inline comments in tuples and parentheses.
61− [Issue 450](https://github.com/tweag/ormolu/issues/450).
62−
63−* Fixed an idempotence issue when certain comments were picked up as
64− “continuation” of a series of comments [Issue
65− 449](https://github.com/tweag/ormolu/issues/449).
66−
67−* Fixed an idempotence issue related to different indentation levels in a
68− comment series. [Issue 512](https://github.com/tweag/ormolu/issues/512).
69−
70−* Fixed an idempotence issue related to comments which may happen to be
71− separated from the elements they are attached to by the equality sign.
72− [Issue 340](https://github.com/tweag/ormolu/issues/340).
73−
74−* Fixed an idempotence issue with type synonym and data declarations where
75− the type has a Haddock. [Issue
76− 578](https://github.com/tweag/ormolu/issues/578).
77−
78−* Fix the false positive about AST differences in presence of comments with
79− multiple blank lines in a row. [Issue
80− 518](https://github.com/tweag/ormolu/issues/518).
81−
82−* Fixed rendering of comments around if expressions. [Issue
83− 458](https://github.com/tweag/ormolu/issues/458).
84−
85−* Unnamed fields of data constructors are now documented using the `-- ^`
86− syntax. [Issue 445](https://github.com/tweag/ormolu/issues/445) and [Issue
87− 428](https://github.com/tweag/ormolu/issues/428).
88−
89−* Fixed non-idempotent transformation of partly documented data definition.
90− [Issue 590](https://github.com/tweag/ormolu/issues/590).
91−
92−* Fixed an idempotence issue related to operators. [Issue
93− 522](https://github.com/tweag/ormolu/issues/522).
94−
95−* Renamed the `--check-idempotency` flag to `--check-idempotence`.
96− Apparently only the latter is correct.
97−
98−## Ormolu 0.0.5.0
99−
100−* Grouping of statements in `do`-blocks is now preserved. [Issue
101− 74](https://github.com/tweag/ormolu/issues/74).
102−
103−* Grouping of TH splices is now preserved. [Issue
104− 507](https://github.com/tweag/ormolu/issues/507).
105−
106−* Comments on pragmas are now preserved. [Issue
107− 216](https://github.com/tweag/ormolu/issues/216).
108−
109−* Ormolu can now be enabled and disabled via special comments. [Issue
110− 435](https://github.com/tweag/ormolu/issues/435).
111−
112−* Added experimental support for simple CPP. [Issue
113− 415](https://github.com/tweag/ormolu/issues/415).
114−
115−* Added two new options `--start-line` and `--end-line` that allow us to
116− select a region to format. [Issue
117− 516](https://github.com/tweag/ormolu/issues/516).
118−
119−* Fixed rendering of module headers in the presence of preceding comments or
120− Haddocks. [Issue 561](https://github.com/tweag/ormolu/issues/561).
121−
122−## Ormolu 0.0.4.0
123−
124−* When given several files to format, Ormolu does not stop on the first
125− failure, but tries to format all the files. [Issue
126− 502](https://github.com/tweag/ormolu/issues/502).
127−
128−* Made rendering of pattern matches involving operators consistent with
129− other cases of rendering of operators. [Issue
130− 500](https://github.com/tweag/ormolu/issues/500).
131−
132−* More compact rendering of type family injectivity constraints. [Issue
133− 482](https://github.com/tweag/ormolu/issues/482).
134−
135−* Improved rendering of the keyword `where` in class, data, and type family
136− declarations. When headers of these declarations are multi-line `where` is
137− now put on its own line. [Issue
138− 509](https://github.com/tweag/ormolu/issues/509).
139−
140−* Fixed the bug pertaining to rendering of arrow notation with multiline
141− expressions. [Issue 513](https://github.com/tweag/ormolu/issues/513).
142−
143−* Made rendering of data type definitions, value-level applications, and
144− application of types use the same style. Moreover, existential now doesn't
145− cause the data constructor be unconditionally rendered in multiline
146− layout. [Issue 427](https://github.com/tweag/ormolu/issues/427).
147−
148−* Records with a single data constructor are now formatted more compactly.
149− [Issue 425](https://github.com/tweag/ormolu/issues/425).
150−
151−* Switched to `ghc-lib-parser-8.10.1`.
152−
153−* Implemented support for the new language extensions `ImportQualifiedPost`
154− and `StandaloneKindSignatures`.
155−
156−## Ormolu 0.0.3.1
157−
158−* Fixed rendering of record updates with the record dot preprocessor syntax
159− [Issue 498](https://github.com/tweag/ormolu/issues/498).
160−
161−## Ormolu 0.0.3.0
162−
163−* Fixed an issue related to unnecessary use of curly braces. [Issue
164− 473](https://github.com/tweag/ormolu/issues/473).
165−
166−* Fixed the issue with formatting multi-way if when it happens to be a
167− function applied to arguments [Issue
168− 488](https://github.com/tweag/ormolu/issues/488). This changed the way
169− multi-line if is formatted in general.
170−
171−* Added support for record dot pre-processor when used via the plugin.
172− [Issue 486](https://github.com/tweag/ormolu/issues/486).
173−
174−* Stopped hanging record constructors and improved placing
175− potentially-hanging consturctions in the presence of comments. [Issue
176− 447](https://github.com/tweag/ormolu/issues/447).
177−
178−* Fixed indentation in presence of type applications. [Issue
179− 493](https://github.com/tweag/ormolu/issues/493).
180−
181−* Class and instance declarations now do not have a blank line after
182− `where`. Grouping of methods from the original input is also preserved
183− with some normalizations. [Issue
184− 431](https://github.com/tweag/ormolu/issues/431).
185−
186−## Ormolu 0.0.2.0
187−
188−* Switched to `ghc-lib-parser` instead of depending on the `ghc` package
189− directly. This should allow us to use newest features of GHC while not
190− necessarily depending on the newest version of the compiler. In addition
191− to that Ormolu is now GHCJS-compatible.
192−
193−* Now unrecognized GHC options passed with `--ghc-opt` cause Ormolu to fail
194− (exit code 7).
195−
196−* Fixed formatting of result type in closed type families. See [issue
197− 420](https://github.com/tweag/ormolu/issues/420).
198−
199−* Fixed a minor inconsistency between formatting of normal and foreign type
200− signatures. See [issue 408](https://github.com/tweag/ormolu/issues/408).
201−
202−* Fixed a bug when comment before module header with Haddock was moved
203− inside the export list. See [issue
204− 430](https://github.com/tweag/ormolu/issues/430).
205−
206−* Empty `forall`s are now correctly preserved. See [issue
207− 429](https://github.com/tweag/ormolu/issues/429).
208−
209−* Fixed [issue 446](https://github.com/tweag/ormolu/issues/446), which
210− involved braces and operators.
211−
212−* When there are comments between preceding Haddock (pipe-style) and its
213− corresponding declaration they are preserved like this in the output
214− instead of being shifted. To be clear, this is not a very good idea to
215− have comments in that position because the Haddock will end up not being
216− associated with the declarations. Issues
217− [440](https://github.com/tweag/ormolu/issues/440) and
218− [448](https://github.com/tweag/ormolu/issues/448).
219−
220−* Implemented correct handling of shebangs. [Issue
221− 377](https://github.com/tweag/ormolu/issues/377).
222−
223−* Implemented correct handling of stack headers. [Issue
224− 393](https://github.com/tweag/ormolu/issues/393).
225−
226−* Sorting language pragmas cannot not change meaning of the input program
227− anymore. [Issue 404](https://github.com/tweag/ormolu/issues/404).
228−
229−* Fixed formatting of applications where function is a complex expression.
230− [Issue 444](https://github.com/tweag/ormolu/issues/444).
231−
232## Ormolu 0.0.1.0
1## Ormolu 0.0.1.0
233
2
234* Initial release.
3* Initial release.
CONTRIBUTING.md+25−11
@@ -1,7 +1,8 @@
1# Contributing
1# Contributing
2
2
3Issues (bugs, feature requests or otherwise feedback) may be reported in
3Issues (bugs, feature requests or otherwise feedback) may be reported in
4−[the GitHub issue tracker for this project][issues]. Pull requests are also
4+[the GitHub issue tracker for this
5+project](https://github.com/tweag/ormolu/issues). Pull requests are also
5welcome.
6welcome.
6
7
7When contributing to this repository, please first discuss the change you
8When contributing to this repository, please first discuss the change you
@@ -17,6 +18,28 @@ messages and PR descriptions.
17
18
18* [Fixing bugs][bugs]. This is the main focus right now.
19* [Fixing bugs][bugs]. This is the main focus right now.
19
20
21+## Implementing rendering of AST
22+
23+The `Ormolu.Printer.Combinators` module provides a DSL for rendering of GHC
24+AST. You'll probably only need this one module for writing new rendering
25+functions. The module documents how to use the printing combinators it
26+provides. Consult the Haddocks to learn more about them.
27+
28+Create new modules corresponding to the things you want to render under
29+`Ormolu.Printer.Meat`. For example, there are `Ormolu.Printer.Meat.Type` and
30+`Ormolu.Printer.Meat.Declaration.Data`.
31+
32+Concrete rendering functions get their names by appending `p_` to the name
33+of the type which describes a particular part of AST. For example, the
34+function for rendering types is correspondingly:
35+
36+```haskell
37+p_hsType :: HsType GhcPs -> R ()
38+```
39+
40+In general rendering functions like this take 1 or more arguments and
41+produce `R ()` which is a rendering action.
42+
20### Testing
43### Testing
21
44
22Testing has been taken good care of and now it amounts to just adding
45Testing has been taken good care of and now it amounts to just adding
@@ -30,15 +53,12 @@ Testing is performed as following:
30* The result of printing is parsed back again and the AST is compared to the
53* The result of printing is parsed back again and the AST is compared to the
31 AST obtained from the original file. They should match.
54 AST obtained from the original file. They should match.
32* The output of printer is checked against the expected output.
55* The output of printer is checked against the expected output.
33−* Idempotence property is verified: formatting already formatted code
56+* Idempotency property is verified: formatting already formatted code
34 results in exactly the same output.
57 results in exactly the same output.
35
58
36Examples can be organized in sub-directories, see the existing ones for
59Examples can be organized in sub-directories, see the existing ones for
37inspiration.
60inspiration.
38
61
39−Please note that we try to keep individual files at most 25 lines long
40−because otherwise it's hard to figure out want went wrong when a test fails.
41−
42## CI
62## CI
43
63
44We use Circle CI. Some outside contributors may have problems, as in, CI
64We use Circle CI. Some outside contributors may have problems, as in, CI
@@ -55,10 +75,4 @@ User settings -> Account integrations -> Refresh permissions
55
75
56in Circle CI app.
76in Circle CI app.
57
77
58−## Formatting
59−
60−Use `format.sh` script to format Ormolu with current version of Ormolu. If
61−Ormolu is not formatted like this, the CI will fail.
62−
63−[issues]: https://github.com/tweag/ormolu/issues
64[bugs]: https://github.com/tweag/ormolu/issues?q=is%3Aissue+is%3Aopen+label%3Abug
78[bugs]: https://github.com/tweag/ormolu/issues?q=is%3Aissue+is%3Aopen+label%3Abug
DESIGN.md+21−24
@@ -1,8 +1,5 @@
1# Ormolu
1# Ormolu
2
2
3−*This document represents our discussions and plans at early stages of
4−development, it is no longer being updated.*
5−
6* [Analysis of the existing solutions](#analysis-of-the-existing-solutions)
3* [Analysis of the existing solutions](#analysis-of-the-existing-solutions)
7 * [Brittany](#brittany)
4 * [Brittany](#brittany)
8 * [Hindent](#hindent)
5 * [Hindent](#hindent)
@@ -24,7 +21,7 @@ It also includes recommendations for future implementers.
24
21
25We set for the following goals (mostly taken from
22We set for the following goals (mostly taken from
26[brittany](https://github.com/lspitzner/brittany)):
23[brittany](https://github.com/lspitzner/brittany)):
27−* Preserve the meaning of the formatted functions when no CPP is used;
24+* Preserve the meaning of the formatted functions;
28* Make reasonable use of screen space;
25* Make reasonable use of screen space;
29* Use linear space and computation time on the size of the input;
26* Use linear space and computation time on the size of the input;
30* Preserve comments;
27* Preserve comments;
@@ -140,10 +137,8 @@ impossible to guess what they'll be called on.
140
137
141### CPP
138### CPP
142
139
143−We allow CPP directives in the input, but we forgo the goal to preserve the
140+Formatting a module which uses CPP directives won't be supported. Instead,
144−meaning of the formatted functions in that case.
145−Instead of supporting CPP better, we hope for a solution to replace CPP to
146−do conditional compilation.
141+we hope for a solution to replace CPP to do conditional compilation.
147
142
148There are the following challenges when formatting a module with CPP:
143There are the following challenges when formatting a module with CPP:
149
144
@@ -182,15 +177,14 @@ True
182```
177```
183
178
184At the time of this writing, formatting this program with Hindent
179At the time of this writing, formatting this program with Hindent
185−or Ormolu produces the same output we would get if the CPP directives
180+produces the same output we would get if the CPP directives were
186−were considered comments:
181+considered comments:
187
182
188```
183```
189−$ ormolu --version
184+$ hindent --version
190−ormolu 0.0.5.0 HEAD fc64eada5c4da7a5b07d2872e253671b48aec115
185+hindent 5.2.7
191−using ghc-lib-parser 8.10.1.20200412
192
186
193−$ ormolu --mode inplace test.hs
187+$ hindent test.hs
194
188
195$ cat test.hs
189$ cat test.hs
196{-# LANGUAGE CPP #-}
190{-# LANGUAGE CPP #-}
@@ -230,6 +224,9 @@ to parse Haskell modules. If CPP is replaced with some language
230extension or mechanism to do conditional compilation, all tools
224extension or mechanism to do conditional compilation, all tools
231will benefit from it.
225will benefit from it.
232
226
227+Therefore, CPP won't be supported. If the CPP extension
228+is enabled, we should signal an error right away.
229+
233### Printing
230### Printing
234
231
235Just pretty-printing code (following the approach of Hindent) seems sane. It
232Just pretty-printing code (following the approach of Hindent) seems sane. It
@@ -285,22 +282,22 @@ map :: (a -> b) -> [a] -> [b]
285foldr :: (a -> b -> b) ->
282foldr :: (a -> b -> b) ->
286 b -> [a] -> [b]
283 b -> [a] -> [b]
287-- Is reformatted to:
284-- Is reformatted to:
288−foldr ::
285+foldr
289− (a -> b -> b) ->
286+ :: (a -> b -> b)
290− b ->
287+ -> b
291− [a] ->
288+ -> [a]
292− [b]
289+ -> [b]
293
290
294t = let x = foo bar
291t = let x = foo bar
295 baz
292 baz
296 in foo bar baz
293 in foo bar baz
297-- Is reformatted to:
294-- Is reformatted to:
298t =
295t =
299− let x =
296+ let x =
300− foo
297+ foo
301− bar
298+ bar
302− baz
299+ baz
303− in foo far baz
300+ in foo far baz
304```
301```
305
302
306Crucially, no effort is made to fit within reasonable line lengths. That's
303Crucially, no effort is made to fit within reasonable line lengths. That's
README.md+22−104
@@ -1,29 +1,26 @@
1# Ormolu
1# Ormolu
2
2
3−[![License BSD3](https://img.shields.io/badge/license-BSD3-brightgreen.svg)](http://opensource.org/licenses/BSD-3-Clause)
3+[![CircleCI](https://circleci.com/gh/tweag/ormolu/tree/master.svg?style=svg&circle-token=cfd37a39265561eb44e608f97cf953cb2a394c03)](https://circleci.com/gh/tweag/ormolu/tree/master)
4−[![Hackage](https://img.shields.io/hackage/v/ormolu.svg?style=flat)](https://hackage.haskell.org/package/ormolu)
5−[![Stackage Nightly](http://stackage.org/package/ormolu/badge/nightly)](http://stackage.org/nightly/package/ormolu)
6−[![Stackage LTS](http://stackage.org/package/ormolu/badge/lts)](http://stackage.org/lts/package/ormolu)
7−[![Build status](https://badge.buildkite.com/8e3b0951f3652b77e1c422b361904136a539b0522029156354.svg?branch=master)](https://buildkite.com/tweag-1/ormolu)
8
4
9Ormolu is a formatter for Haskell source code. The project was created with
5Ormolu is a formatter for Haskell source code. The project was created with
10the following goals in mind:
6the following goals in mind:
11
7
12* Using GHC's own parser to avoid parsing problems caused by
8* Using GHC's own parser to avoid parsing problems caused by
13 [`haskell-src-exts`][haskell-src-exts].
9 [`haskell-src-exts`][haskell-src-exts].
14−* Let some whitespace be programmable. The layout of the input influences
10+* Let some whitespace be programmable. The layout of the input
15− the layout choices in the output. This means that the choices between
11+ influence the layout choices in the output. This means that the
16− single-line/multi-line layouts in each particular situation are made by
12+ choices between single-line/multi-line layouts in each particular
17− the user, not by an algorithm. This makes the implementation simpler and
13+ situation are made by the user, not by an algorithm. This makes the
18− leaves some control to the user while still guaranteeing that the
14+ implementation simpler and leaves some control to the user while
19− formatted code is stylistically consistent.
15+ still guaranteeing that the formatted code is stylistically
16+ consistent.
20−* Writing code in such a way so it's easy to modify and maintain.
17+* Writing code in such a way so it's easy to modify and maintain. Roughly,
18+ it means that the project follows the path of [`hindent`][hindent] and is
19+ very much about printing AST in a particular way.
21* Implementing one “true” formatting style which admits no configuration.
20* Implementing one “true” formatting style which admits no configuration.
22* That formatting style aims to result in minimal diffs while still
21* That formatting style aims to result in minimal diffs while still
23 remaining very close to “conventional” Haskell formatting people use.
22 remaining very close to “conventional” Haskell formatting people use.
24−* Choose a style compatible with modern dialects of Haskell. As new Haskell
25− extensions enter broad use, we may change the style to accommodate them.
26−* Idempotence: formatting already formatted code doesn't change it.
23+* Idempotency: formatting already formatted code doesn't change it.
27* Be well-tested and robust to the point that it can be used in large
24* Be well-tested and robust to the point that it can be used in large
28 projects without exposing unfortunate, disappointing bugs here and there.
25 projects without exposing unfortunate, disappointing bugs here and there.
29
26
@@ -32,7 +29,7 @@ the following goals in mind:
32The easiest way to build the project is with Nix:
29The easiest way to build the project is with Nix:
33
30
34```console
31```console
35−$ nix-build -A ormolu
32+$ nix-build
36```
33```
37
34
38Or with `cabal-install` from the Nix shell:
35Or with `cabal-install` from the Nix shell:
@@ -45,36 +42,11 @@ Alternatively, `stack` could be used with a `stack.yaml` file as follows.
45
42
46```console
43```console
47$ cat stack.yaml
44$ cat stack.yaml
48−resolver: lts-16.0
45+resolver: lts-13.19
49packages:
46packages:
50- '.'
47- '.'
51
48
52−$ stack build # to build
49+$ stack build
53−$ stack install # to install
54−```
55−
56−To use Ormolu directly from GitHub with Nix, this snippet may come in handy:
57−
58−```nix
59−# This overlay adds Ormolu straight from GitHub.
60−self: super:
61−
62−let source = super.fetchFromGitHub {
63− owner = "tweag";
64− repo = "ormolu";
65− rev = "de279d80122b287374d4ed87c7b630db1f157642"; # update as necessary
66− sha256 = "0qrxfk62ww6b60ha9sqcgl4nb2n5fhf66a65wszjngwkybwlzmrv"; # as well
67− };
68− ormolu = import source { pkgs = self; };
69−in {
70− haskell = super.haskell // {
71− packages = super.haskell.packages // {
72− "${ormolu.ormoluCompiler}" = super.haskell.packages.${ormolu.ormoluCompiler}.override {
73− overrides = ormolu.ormoluOverlay;
74− };
75− };
76− };
77−}
78```
50```
79
51
80## Usage
52## Usage
@@ -92,48 +64,16 @@ formatted output.
92$ ormolu --mode inplace Module.hs
64$ ormolu --mode inplace Module.hs
93```
65```
94
66
95−Use `find` to format a tree recursively:
67+## Editor integration
96−
97−```console
98−$ ormolu --mode inplace $(find . -name '*.hs')
99−```
100−
101−## Magic comments
102−
103−Ormolu understands two magic comments:
104−
105−```haskell
106−{- ORMOLU_DISABLE -}
107−```
108−
109−and
110−
111−```haskell
112−{- ORMOLU_ENABLE -}
113−```
114−
115−This allows us to disable formatting selectively for code between these
116−markers or disable it for the entire file. To achieve the latter, just put
117−`{- ORMOLU_DISABLE -}` at the very top. Note that the source code should
118−still be parseable even without the “excluded” part. Because of that the
119−magic comments cannot be placed arbitrary, but should rather enclose
120−independent top-level definitions.
121
68
122−## Current limitations
69+We know of the following editor integrations:
123
70
124−* CPP support is experimental. CPP is virtually impossible to handle
71+* [For Emacs][emacs-package]
125− correctly, so we process them as a sort of unchangeable snippets. This
126− works only in simple cases when CPP conditionals surround top-level
127− declarations. See the [CPP][design-cpp] section in the design notes for
128− a discussion of the dangers.
129−* Input modules should be parsable by Haddock, which is a bit stricter
130− criterion than just being valid Haskell modules.
131−* Various minor idempotence issues, most of them are related to comments.
132
72
133## Running on Hackage
73## Running on Hackage
134
74
135It's possible to try Ormolu on arbitrary packages from Hackage. For that
75It's possible to try Ormolu on arbitrary packages from Hackage. For that
136−execute (from the root of the cloned repo):
76+execute (from root of clonned repo):
137
77
138```console
78```console
139$ nix-build -A hackage.<package>
79$ nix-build -A hackage.<package>
@@ -144,38 +84,16 @@ also contain formatted `.hs` files for inspection and original inputs with
144`.hs-original` extension (those are with CPP dropped, exactly what is fed
84`.hs-original` extension (those are with CPP dropped, exactly what is fed
145into Ormolu).
85into Ormolu).
146
86
147−## Editor integration
148−
149−We know of the following editor integrations:
150−
151−* [Emacs][emacs-package]
152−* [VS Code][vs-code-plugin]
153−* vim: [neoformat][neoformat], [vim-ormolu][vim-ormolu]
154−
155−## Arch Linux
156−
157−To install Ormolu on Arch Linux, one can use [the package on AUR][aur]:
158−
159−```console
160−yay -S ormolu
161−```
162−
163## Contributing
87## Contributing
164
88
165−See [CONTRIBUTING.md][contributing].
89+See [CONTRIBUTING.md](./CONTRIBUTING.md).
166
90
167## License
91## License
168
92
169−See [LICENSE.md][license].
93+See [LICENSE.md](./LICENSE.md).
170
94
171Copyright © 2018–present Tweag I/O
95Copyright © 2018–present Tweag I/O
172
96
173−[design-cpp]: https://github.com/tweag/ormolu/blob/master/DESIGN.md#cpp
174−[contributing]: https://github.com/tweag/ormolu/blob/master/CONTRIBUTING.md
175−[license]: https://github.com/tweag/ormolu/blob/master/LICENSE.md
176[haskell-src-exts]: https://hackage.haskell.org/package/haskell-src-exts
97[haskell-src-exts]: https://hackage.haskell.org/package/haskell-src-exts
98+[hindent]: https://hackage.haskell.org/package/hindent
177[emacs-package]: https://github.com/vyorkin/ormolu.el
99[emacs-package]: https://github.com/vyorkin/ormolu.el
178−[vs-code-plugin]: https://marketplace.visualstudio.com/items?itemName=sjurmillidahl.ormolu-vscode
179−[vim-ormolu]: https://github.com/sdiehl/vim-ormolu
180−[neoformat]: https://github.com/sbdchd/neoformat
181−[aur]: https://aur.archlinux.org/packages/ormolu
app/Main.hs+97−135
@@ -1,17 +1,12 @@
1−{-# LANGUAGE CPP #-}
1+{-# LANGUAGE CPP #-}
2−{-# LANGUAGE LambdaCase #-}
2+{-# LANGUAGE LambdaCase #-}
3{-# LANGUAGE RecordWildCards #-}
3{-# LANGUAGE RecordWildCards #-}
4{-# LANGUAGE TemplateHaskell #-}
4{-# LANGUAGE TemplateHaskell #-}
5−{-# LANGUAGE TypeApplications #-}
6
5
7module Main (main) where
6module Main (main) where
8
7
9−import Control.Exception (SomeException, displayException, try)
10import Control.Monad
8import Control.Monad
11−import Data.Bool (bool)
12−import Data.Either (lefts)
13−import Data.List (intercalate, sort)
9+import Data.List (intercalate)
14−import qualified Data.Text.IO as TIO
15import Data.Version (showVersion)
10import Data.Version (showVersion)
16import Development.GitRev
11import Development.GitRev
17import Options.Applicative
12import Options.Applicative
@@ -21,8 +16,10 @@ import Ormolu.Utils (showOutputable)
21import Paths_ormolu (version)
16import Paths_ormolu (version)
22import System.Exit (ExitCode (..), exitWith)
17import System.Exit (ExitCode (..), exitWith)
23import System.IO (hPutStrLn, stderr)
18import System.IO (hPutStrLn, stderr)
19+import qualified Data.Text.IO as TIO
24
20
25-- | Entry point of the program.
21-- | Entry point of the program.
22+
26main :: IO ()
23main :: IO ()
27main = withPrettyOrmoluExceptions $ do
24main = withPrettyOrmoluExceptions $ do
28 Opts {..} <- execParser optsParserInfo
25 Opts {..} <- execParser optsParserInfo
@@ -30,50 +27,35 @@ main = withPrettyOrmoluExceptions $ do
30 case optInputFiles of
27 case optInputFiles of
31 [] -> formatOne' Nothing
28 [] -> formatOne' Nothing
32 ["-"] -> formatOne' Nothing
29 ["-"] -> formatOne' Nothing
33− [x] -> formatOne' (Just x)
30+ xs -> mapM_ (formatOne' . Just) xs
34− xs -> do
35− -- It is possible to get IOException, error's and 'OrmoluException's
36− -- from 'formatOne', so we just catch everything.
37− errs <-
38− lefts <$> mapM (try @SomeException . formatOne' . Just) (sort xs)
39− unless (null errs) $ do
40− mapM_ (hPutStrLn stderr . displayException) errs
41− exitWith (ExitFailure 102)
42
31
43-- | Format a single input.
32-- | Format a single input.
33+
44−formatOne ::
34+formatOne
45− -- | Mode of operation
35+ :: Mode -- ^ Mode of operation
46− Mode ->
47− -- | Configuration
36+ -> Config -- ^ Configuration
48− Config RegionIndices ->
49− -- | File to format or stdin as 'Nothing'
37+ -> Maybe FilePath -- ^ File to format or stdin as 'Nothing'
50− Maybe FilePath ->
51− IO ()
38+ -> IO ()
52formatOne mode config = \case
39formatOne mode config = \case
53 Nothing -> do
40 Nothing -> do
54 r <- ormoluStdin config
41 r <- ormoluStdin config
55 case mode of
42 case mode of
56 Stdout -> TIO.putStr r
43 Stdout -> TIO.putStr r
57− _ -> do
44+ _ -> do
58− hPutStrLn
45+ hPutStrLn stderr
59− stderr
60 "This feature is not supported when input comes from stdin."
46 "This feature is not supported when input comes from stdin."
61− -- 101 is different from all the other exit codes we already use.
47+ -- 101 is different from all the other exit codes we already use.
62 exitWith (ExitFailure 101)
48 exitWith (ExitFailure 101)
63 Just inputFile -> do
49 Just inputFile -> do
64− originalInput <- TIO.readFile inputFile
65− formattedInput <- ormoluFile config inputFile
50+ r <- ormoluFile config inputFile
66 case mode of
51 case mode of
67 Stdout ->
52 Stdout ->
68− TIO.putStr formattedInput
53+ TIO.putStr r
69− InPlace -> do
54+ InPlace ->
70− -- Only write when the contents have changed, in order to avoid
71− -- updating the modified timestamp if the file was already correctly
72− -- formatted.
73− when (formattedInput /= originalInput) $
74− TIO.writeFile inputFile formattedInput
55+ TIO.writeFile inputFile r
75 Check -> do
56 Check -> do
76− when (formattedInput /= originalInput) $
57+ r' <- TIO.readFile inputFile
58+ when (r /= r') $
77 -- 100 is different to all the other exit code that are emitted
59 -- 100 is different to all the other exit code that are emitted
78 -- either from an 'OrmoluException' or from 'error' and
60 -- either from an 'OrmoluException' or from 'error' and
79 -- 'notImplemented'.
61 -- 'notImplemented'.
@@ -83,121 +65,101 @@ formatOne mode config = \case
83-- Command line options parsing.
65-- Command line options parsing.
84
66
85data Opts = Opts
67data Opts = Opts
68+ { optMode :: !Mode
86− { -- | Mode of operation
69+ -- ^ Mode of operation
87− optMode :: !Mode,
70+ , optConfig :: !Config
88− -- | Ormolu 'Config'
71+ -- ^ Ormolu 'Config'
89− optConfig :: !(Config RegionIndices),
72+ , optInputFiles :: ![FilePath]
90− -- | Haskell source files to format or stdin (when the list is empty)
73+ -- ^ Haskell source files to format or stdin (when the list is empty)
91− optInputFiles :: ![FilePath]
92 }
74 }
93
75
94-- | Mode of operation.
76-- | Mode of operation.
77+
95data Mode
78data Mode
96− = -- | Output formatted source code to stdout
79+ = Stdout -- ^ Output formatted source code to stdout
97− Stdout
98− | -- | Overwrite original file
80+ | InPlace -- ^ Overwrite original file
99− InPlace
100− | -- | Exit with non-zero status code if
81+ | Check -- ^ Exit with non-zero status code if
101− -- source is not already formatted
82+ -- source is not already formatted
102− Check
103 deriving (Eq, Show)
83 deriving (Eq, Show)
104
84
105optsParserInfo :: ParserInfo Opts
85optsParserInfo :: ParserInfo Opts
106−optsParserInfo =
107− info (helper <*> ver <*> exts <*> optsParser) . mconcat $
86+optsParserInfo = info (helper <*> ver <*> exts <*> optsParser) . mconcat $
108− [ fullDesc,
87+ [ fullDesc
109− progDesc "",
88+ , progDesc ""
110− header ""
89+ , header ""
111− ]
90+ ]
112 where
91 where
113 ver :: Parser (a -> a)
92 ver :: Parser (a -> a)
114− ver =
115− infoOption verStr . mconcat $
93+ ver = infoOption verStr . mconcat $
116− [ long "version",
94+ [ long "version"
117− short 'v',
95+ , short 'v'
118− help "Print version of the program"
96+ , help "Print version of the program"
119− ]
97+ ]
120− verStr =
121− intercalate
98+ verStr = intercalate "\n"
122− "\n"
123− [ unwords
99+ [ unwords
124− [ "ormolu",
100+ [ "ormolu"
125− showVersion version,
101+ , showVersion version
126− $gitBranch,
102+ , $gitBranch
127− $gitHash
103+ , $gitHash
128− ],
129− "using ghc-lib-parser " ++ VERSION_ghc_lib_parser
130 ]
104 ]
105+ , "using ghc " ++ VERSION_ghc
106+ ]
131 exts :: Parser (a -> a)
107 exts :: Parser (a -> a)
132− exts =
133− infoOption displayExts . mconcat $
108+ exts = infoOption displayExts . mconcat $
134− [ long "manual-exts",
109+ [ long "manual-exts"
135− help "Display extensions that need to be enabled manually"
110+ , help "Display extensions that need to be enabled manually"
136− ]
111+ ]
137− displayExts = unlines $ sort (showOutputable <$> manualExts)
112+ displayExts = unlines (showOutputable <$> manualExts)
138
113
139optsParser :: Parser Opts
114optsParser :: Parser Opts
140−optsParser =
115+optsParser = Opts
141− Opts
142− <$> ( (fmap (bool Stdout InPlace) . switch . mconcat)
143− [ short 'i',
144− help "A shortcut for --mode inplace"
145− ]
146− <|> (option parseMode . mconcat)
116+ <$> (option parseMode . mconcat)
147− [ long "mode",
117+ [ long "mode"
148− short 'm',
118+ , short 'm'
149− metavar "MODE",
119+ , metavar "MODE"
150− value Stdout,
120+ , value Stdout
151− help "Mode of operation: 'stdout' (default), 'inplace', or 'check'"
121+ , help "Mode of operation: 'stdout', 'inplace', or 'check'"
152− ]
122+ ]
153− )
154− <*> configParser
123+ <*> configParser
155− <*> (many . strArgument . mconcat)
124+ <*> (many . strArgument . mconcat)
156− [ metavar "FILE",
125+ [ metavar "FILE"
157− help "Haskell source files to format or stdin (default)"
126+ , help "Haskell source files to format or stdin (default)"
158− ]
127+ ]
159
128
160−configParser :: Parser (Config RegionIndices)
129+configParser :: Parser Config
161−configParser =
130+configParser = Config
162− Config
163− <$> (fmap (fmap DynOption) . many . strOption . mconcat)
131+ <$> (fmap (fmap DynOption) . many . strOption . mconcat)
164− [ long "ghc-opt",
132+ [ long "ghc-opt"
165− short 'o',
133+ , short 'o'
166− metavar "OPT",
134+ , metavar "OPT"
167− help "GHC options to enable (e.g. language extensions)"
135+ , help "GHC options to enable (e.g. language extensions)"
168− ]
136+ ]
169− <*> (switch . mconcat)
137+ <*> (switch . mconcat)
170− [ long "unsafe",
138+ [ long "unsafe"
171− short 'u',
139+ , short 'u'
172− help "Do formatting faster but without automatic detection of defects"
140+ , help "Do formatting faster but without automatic detection of defects"
173− ]
141+ ]
174− <*> (switch . mconcat)
142+ <*> (switch . mconcat)
175− [ long "debug",
143+ [ long "debug"
176− short 'd',
144+ , short 'd'
177− help "Output information useful for debugging"
145+ , help "Output information useful for debugging"
178− ]
146+ ]
147+ <*> (switch . mconcat)
148+ [ long "tolerate-cpp"
149+ , short 'p'
150+ , help "Do not fail if CPP pragma is present"
151+ ]
179− <*> (switch . mconcat)
152+ <*> (switch . mconcat)
180− [ long "check-idempotence",
153+ [ long "check-idempotency"
181− short 'c',
154+ , short 'c'
182− help "Fail if formatting is not idempotent"
155+ , help "Fail if formatting is not idempotent."
183− ]
184− <*> ( RegionIndices
185− <$> (optional . option auto . mconcat)
186− [ long "start-line",
187− metavar "START",
188− help "Start line of the region to format (starts from 1)"
189− ]
190− <*> (optional . option auto . mconcat)
191− [ long "end-line",
192− metavar "END",
193− help "End line of the region to format (inclusive)"
194− ]
156+ ]
195− )
196
157
197----------------------------------------------------------------------------
158----------------------------------------------------------------------------
198-- Helpers
159-- Helpers
199
160
200-- | Parse 'Mode'.
161-- | Parse 'Mode'.
162+
201parseMode :: ReadM Mode
163parseMode :: ReadM Mode
202parseMode = eitherReader $ \case
164parseMode = eitherReader $ \case
203 "stdout" -> Right Stdout
165 "stdout" -> Right Stdout
data/examples/declaration/annotation/annotation-out.hs+3−4
@@ -2,9 +2,9 @@
2
2
3{-# ANN
3{-# ANN
4 module
4 module
5− ( 5 ::
5+ ( 5
6− Int
6+ :: Int
7− )
7+ )
8 #-}
8 #-}
9
9
10{-# ANN foo "hey" #-}
10{-# ANN foo "hey" #-}
@@ -18,5 +18,4 @@ foo = 5
18
18
19data Foo = Foo Int
19data Foo = Foo Int
20{-# ANN type Foo ("HLint: ignore") #-}
20{-# ANN type Foo ("HLint: ignore") #-}
21−
22{- Comment -}
21{- Comment -}
data/examples/declaration/class/associated-data1-out.hs+1
@@ -4,6 +4,7 @@ class Foo a where data FooBar a
4
4
5-- | Something.
5-- | Something.
6class Bar a where
6class Bar a where
7+
7 -- | Bar bar
8 -- | Bar bar
8 data BarBar a
9 data BarBar a
9
10
data/examples/declaration/class/associated-data2-out.hs+1−2
@@ -1,9 +1,8 @@
1{-# LANGUAGE TypeFamilies #-}
1{-# LANGUAGE TypeFamilies #-}
2
2
3−module Main where
4−
5-- | Something more.
3-- | Something more.
6class Baz a where
4class Baz a where
5+
7 -- | Baz bar
6 -- | Baz bar
8 data
7 data
9 BazBar
8 BazBar
data/examples/declaration/class/associated-data2.hs−2
@@ -1,5 +1,3 @@
1−module Main where
2−
3{-# LANGUAGE TypeFamilies #-}
1{-# LANGUAGE TypeFamilies #-}
4
2
5-- | Something more.
3-- | Something more.
data/examples/declaration/class/associated-type-defaults-out.hs+2
@@ -4,6 +4,7 @@ class Foo a where type FooBar a = Int
4
4
5-- | Something.
5-- | Something.
6class Bar a where
6class Bar a where
7+
7 -- Define bar
8 -- Define bar
8 type
9 type
9 BarBar a =
10 BarBar a =
@@ -17,6 +18,7 @@ class Bar a where
17 a
18 a
18
19
19class Baz a where
20class Baz a where
21+
20 type
22 type
21 BazBar
23 BazBar
22 a
24 a
data/examples/declaration/class/associated-types1-out.hs+1
@@ -4,6 +4,7 @@ class Foo a where type FooBar a
4
4
5-- | Something.
5-- | Something.
6class Bar a where
6class Bar a where
7+
7 -- | Bar bar
8 -- | Bar bar
8 type BarBar a
9 type BarBar a
9
10
data/examples/declaration/class/associated-types2-out.hs+1−2
@@ -1,9 +1,8 @@
1{-# LANGUAGE TypeFamilies #-}
1{-# LANGUAGE TypeFamilies #-}
2
2
3−module Main where
4−
5-- | Something more.
3-- | Something more.
6class Baz a where
4class Baz a where
5+
7 -- | Baz bar
6 -- | Baz bar
8 type
7 type
9 BazBar
8 BazBar
data/examples/declaration/class/associated-types2.hs−2
@@ -1,5 +1,3 @@
1−module Main where
2−
3{-# LANGUAGE TypeFamilies #-}
1{-# LANGUAGE TypeFamilies #-}
4
2
5-- | Something more.
3-- | Something more.
data/examples/declaration/class/default-implementations-comments-out.hs+6−7
@@ -1,19 +1,18 @@
1−module Main where
2−
3-- | Baz
1-- | Baz
4class Baz a where
2class Baz a where
3+
5 foobar :: a -> a
4 foobar :: a -> a
6 foobar a =
5 foobar a =
7 barbaz (bazbar a)
6 barbaz (bazbar a)
8
7
9 -- | Bar baz
8 -- | Bar baz
10− barbaz ::
9+ barbaz
11− a -> a
10+ :: a -> a
12
11
13 -- | Baz bar
12 -- | Baz bar
14− bazbar ::
13+ bazbar
15− a ->
14+ :: a
16− a
15+ -> a
17
16
18 -- First comment
17 -- First comment
19 barbaz a =
18 barbaz a =
data/examples/declaration/class/default-implementations-comments.hs−2
@@ -1,5 +1,3 @@
1−module Main where
2−
3-- | Baz
1-- | Baz
4class Baz a where
2class Baz a where
5 foobar :: a -> a
3 foobar :: a -> a
data/examples/declaration/class/default-implementations-out.hs+3−5
@@ -1,5 +1,3 @@
1−module Main where
2−
3-- | Foo
1-- | Foo
4class Foo a where
2class Foo a where
5 foo :: a -> a
3 foo :: a -> a
@@ -7,7 +5,7 @@ class Foo a where
7
5
8-- | Bar
6-- | Bar
9class Bar a where
7class Bar a where
10− bar ::
8+ bar
11− a ->
9+ :: a
12− Int
10+ -> Int
13 bar = const 0
11 bar = const 0
data/examples/declaration/class/default-implementations.hs+1−2
@@ -1,5 +1,3 @@
1−module Main where
2−
3-- | Foo
1-- | Foo
4class Foo a where
2class Foo a where
5 foo :: a -> a
3 foo :: a -> a
@@ -11,3 +9,4 @@ class Bar a where
11 a
9 a
12 -> Int
10 -> Int
13 bar = const 0
11 bar = const 0
12+
data/examples/declaration/class/default-signatures-out.hs+13−13
@@ -1,22 +1,22 @@
1{-# LANGUAGE DefaultSignatures #-}
1{-# LANGUAGE DefaultSignatures #-}
2
2
3−module Main where
4−
5-- | Something else.
3-- | Something else.
6class Bar a where
4class Bar a where
5+
7 -- | Bar
6 -- | Bar
8− bar ::
7+ bar
9− String ->
8+ :: String
10− String ->
9+ -> String
11− a
10+ -> a
11+
12 -- Pointless comment
12 -- Pointless comment
13− default bar ::
13+ default bar
14− ( Read a,
14+ :: ( Read a,
15− Semigroup a
15+ Semigroup a
16− ) =>
16+ )
17− a ->
17+ => a
18− a ->
18+ -> a
19− a
19+ -> a
20 -- Even more pointless comment
20 -- Even more pointless comment
21 bar
21 bar
22 a
22 a
data/examples/declaration/class/default-signatures-simple-out.hs+2−2
@@ -1,8 +1,8 @@
1−module Main where
2−
3-- | Something.
1-- | Something.
4class Foo a where
2class Foo a where
3+
5 -- | Foo
4 -- | Foo
6 foo :: a -> String
5 foo :: a -> String
6+
7 default foo :: Show a => a -> String
7 default foo :: Show a => a -> String
8 foo = show
8 foo = show
data/examples/declaration/class/default-signatures-simple.hs+1−2
@@ -1,8 +1,7 @@
1−module Main where
2−
3-- | Something.
1-- | Something.
4class Foo a where
2class Foo a where
5 -- | Foo
3 -- | Foo
6 foo :: a -> String
4 foo :: a -> String
7 default foo :: Show a => a -> String
5 default foo :: Show a => a -> String
8 foo = show
6 foo = show
7+
data/examples/declaration/class/default-signatures.hs−2
@@ -1,5 +1,3 @@
1−module Main where
2−
3{-# LANGUAGE DefaultSignatures #-}
1{-# LANGUAGE DefaultSignatures #-}
4
2
5-- | Something else.
3-- | Something else.
data/examples/declaration/class/dependency-super-classes-out.hs+11−11
@@ -1,25 +1,25 @@
1{-# LANGUAGE FunctionalDependencies #-}
1{-# LANGUAGE FunctionalDependencies #-}
2
2
3−module Main where
4−
5-- | Something.
3-- | Something.
6class (MonadReader r s, MonadWriter w m) => MonadState s m | m -> s where
4class (MonadReader r s, MonadWriter w m) => MonadState s m | m -> s where
5+
7 get :: m s
6 get :: m s
7+
8 put :: s -> m ()
8 put :: s -> m ()
9
9
10-- | 'MonadParsec'
10-- | 'MonadParsec'
11class
11class
12 ( Stream s, -- Token streams
12 ( Stream s, -- Token streams
13 MonadPlus m -- Potential for failure
13 MonadPlus m -- Potential for failure
14− ) =>
14+ )
15− MonadParsec e s m
15+ => MonadParsec e s m
16− | m -> e s
17− where
16+ | m -> e s where
17+
18 -- | 'getState' returns state
18 -- | 'getState' returns state
19− getState ::
19+ getState
20− m s
20+ :: m s
21
21
22 -- | 'putState' sets state
22 -- | 'putState' sets state
23− putState ::
23+ putState
24− s ->
24+ :: s
25− m ()
25+ -> m ()
data/examples/declaration/class/dependency-super-classes.hs−2
@@ -1,5 +1,3 @@
1−module Main where
2−
3{-# LANGUAGE FunctionalDependencies #-}
1{-# LANGUAGE FunctionalDependencies #-}
4
2
5-- | Something.
3-- | Something.
data/examples/declaration/class/empty-classes-out.hs−2
@@ -1,5 +1,3 @@
1−module Main where
2−
3-- | Foo!
1-- | Foo!
4class Foo a
2class Foo a
5
3
data/examples/declaration/class/empty-classes.hs−2
@@ -1,5 +1,3 @@
1−module Main where
2−
3-- | Foo!
1-- | Foo!
4class Foo a where
2class Foo a where
5-- | Bar!
3-- | Bar!
data/examples/declaration/class/functional-dependencies-out.hs+1−4
@@ -1,7 +1,5 @@
1{-# LANGUAGE FunctionalDependencies #-}
1{-# LANGUAGE FunctionalDependencies #-}
2
2
3−module Main where
4−
5-- | Something.
3-- | Something.
6class Foo a b | a -> b
4class Foo a b | a -> b
7
5
@@ -14,6 +12,5 @@ class
14 b c -> a d, -- Bar
12 b c -> a d, -- Bar
15 a c -> b d, -- Baz
13 a c -> b d, -- Baz
16 a c d -> b,
14 a c d -> b,
17− a b d -> a b c d
15+ a b d -> a b c d where
18− where
19 baz :: a -> b
16 baz :: a -> b
data/examples/declaration/class/functional-dependencies.hs−2
@@ -1,5 +1,3 @@
1−module Main where
2−
3{-# LANGUAGE FunctionalDependencies #-}
1{-# LANGUAGE FunctionalDependencies #-}
4
2
5-- | Something.
3-- | Something.
data/examples/declaration/class/multi-parameters1-out.hs+5−5
@@ -4,11 +4,11 @@ class Foo a b where foo :: a -> b
4
4
5-- | Something.
5-- | Something.
6class Bar a b c d where
6class Bar a b c d where
7− bar ::
7+ bar
8− a ->
8+ :: a
9− b ->
9+ -> b
10− c ->
10+ -> c
11− d
11+ -> d
12
12
13class -- Before name
13class -- Before name
14 Baz where
14 Baz where
data/examples/declaration/class/multi-parameters2-out.hs+8−9
@@ -1,7 +1,5 @@
1{-# LANGUAGE MultiParamTypeClasses #-}
1{-# LANGUAGE MultiParamTypeClasses #-}
2
2
3−module Main where
4−
5-- | Something else.
3-- | Something else.
6class
4class
7 BarBaz
5 BarBaz
@@ -10,10 +8,11 @@ class
10 c -- Baz bar
8 c -- Baz bar
11 d -- Baz baz
9 d -- Baz baz
12 e -- Rest
10 e -- Rest
13− f
14− where
11+ f where
12+
15− barbaz ::
13+ barbaz
16− a -> f
14+ :: a -> f
15+
17− bazbar ::
16+ bazbar
18− e ->
17+ :: e
19− f
18+ -> f
data/examples/declaration/class/multi-parameters2.hs−2
@@ -1,5 +1,3 @@
1−module Main where
2−
3{-# LANGUAGE MultiParamTypeClasses #-}
1{-# LANGUAGE MultiParamTypeClasses #-}
4
2
5-- | Something else.
3-- | Something else.
data/examples/declaration/class/newlines-after-where-out.hsdeleted−5
@@ -1,5 +0,0 @@
1−class Num a where
2− (+) :: a -> a -> a
3−
4−class Num a where
5− (+) :: a -> a -> a
data/examples/declaration/class/newlines-after-where.hsdeleted−7
@@ -1,7 +0,0 @@
1−class Num a where
2− (+) :: a -> a -> a
3−
4−class Num a where
5−
6−
7− (+) :: a -> a -> a
data/examples/declaration/class/newlines-and-default-decls-out.hsdeleted−11
@@ -1,11 +0,0 @@
1−class Foo a where
2− foo :: a
3− default foo :: ()
4− foo = ()
5− bar :: a
6− default bar :: ()
7− bar = ()
8−
9− qux :: a
10− default qux :: ()
11− qux = ()
data/examples/declaration/class/newlines-and-default-decls.hsdeleted−13
@@ -1,13 +0,0 @@
1−class Foo a where
2− foo :: a
3− default foo :: ()
4− foo = ()
5− bar :: a
6− default bar :: ()
7− bar = ()
8−
9− qux :: a
10−
11− default qux :: ()
12−
13− qux = ()
data/examples/declaration/class/newlines-and-haddocks-out.hsdeleted−23
@@ -1,23 +0,0 @@
1−class Foo a where
2− -- | Haddock
3− foo :: a
4−
5− -- | Another Haddock
6− bar :: a
7−
8− baz :: a
9− -- ^ Post-Haddock
10−
11− raz :: a
12− -- ^ Another Post-Haddock
13−
14− -- | One more Haddock
15− qux :: a
16−
17− -- Comment before a Haddock
18−
19− -- | And one more Haddock
20− xyz :: a
21−
22− -- | Haddock followed by a blank line
23− abc :: a
data/examples/declaration/class/newlines-and-haddocks.hsdeleted−19
@@ -1,19 +0,0 @@
1−class Foo a where
2− -- | Haddock
3− foo :: a
4− -- | Another Haddock
5− bar :: a
6− baz :: a
7− -- ^ Post-Haddock
8− raz :: a
9− -- ^ Another Post-Haddock
10−
11− -- | One more Haddock
12− qux :: a
13− -- Comment before a Haddock
14− -- | And one more Haddock
15− xyz :: a
16−
17− -- | Haddock followed by a blank line
18−
19− abc :: a
data/examples/declaration/class/newlines-between-methods-out.hsdeleted−17
@@ -1,17 +0,0 @@
1−class Num a where
2− (+) :: a -> a -> a
3− (-) :: a -> a -> a
4− (*) :: a -> a -> a
5−
6− -- Comment before definition
7− negate :: a -> a
8−
9− -- Comment after definition
10−
11− -- Separator
12−
13− abs :: a -> a
14− signum :: a -> a
15−
16− -- Comment between unrelated definitions
17− fromInteger :: Integer -> a
data/examples/declaration/class/newlines-between-methods.hsdeleted−15
@@ -1,15 +0,0 @@
1−class Num a where
2− (+) :: a -> a -> a
3− (-) :: a -> a -> a
4− (*) :: a -> a -> a
5−
6− -- Comment before definition
7− negate :: a -> a
8− -- Comment after definition
9−
10− -- Separator
11−
12− abs :: a -> a
13− signum :: a -> a
14− -- Comment between unrelated definitions
15− fromInteger :: Integer -> a
data/examples/declaration/class/poly-kinded-classes-out.hs+3−3
@@ -4,6 +4,6 @@ class Foo (a :: k)
4
4
5class
5class
6 Bar
6 Bar
7− ( a :: -- Variable
7+ ( a -- Variable
8− * -- Star
8+ :: * -- Star
9− )
9+ )
data/examples/declaration/class/single-parameters-out.hs+10−13
@@ -1,5 +1,3 @@
1−module Main where
2−
3-- | Something.
1-- | Something.
4class Foo a where foo :: a
2class Foo a where foo :: a
5
3
@@ -10,17 +8,16 @@ class Bar a where
10
8
11class Baz a where
9class Baz a where
12 -- | Baz
10 -- | Baz
13− baz ::
11+ baz
14− -- | First argument
15− ( a,
12+ :: ( a,
16− a
13+ a -- ^ First argument
17− ) ->
14+ )
18− -- | Second argument
15+ -> a -- ^ Second argument
19− a ->
20− -- | Return value
16+ -> a -- ^ Return value
21− a
22
17
23class BarBaz a where
18class BarBaz a where
19+
24− barbaz ::
20+ barbaz
25− a -> b
21+ :: a -> b
22+
26 bazbar :: b -> a
23 bazbar :: b -> a
data/examples/declaration/class/single-parameters.hs−2
@@ -1,5 +1,3 @@
1−module Main where
2−
3-- | Something.
1-- | Something.
4class Foo a where foo :: a
2class Foo a where foo :: a
5
3
data/examples/declaration/class/super-classes-out.hs+4−4
@@ -3,12 +3,12 @@ class Foo a
3class Foo a => Bar a
3class Foo a => Bar a
4
4
5class
5class
6− (Foo a, Bar a) =>
6+ (Foo a, Bar a)
7− Baz a
7+ => Baz a
8
8
9class
9class
10 ( Foo a, -- Foo?
10 ( Foo a, -- Foo?
11 Bar a, -- Bar?
11 Bar a, -- Bar?
12 Baz a -- Baz
12 Baz a -- Baz
13− ) =>
13+ )
14− BarBar a
14+ => BarBar a
data/examples/declaration/class/type-operators1-out.hs+1−1
@@ -17,5 +17,5 @@ class
17class
17class
18 ( f
18 ( f
19 :. g
19 :. g
20− )
20+ )
21 a
21 a
data/examples/declaration/class/type-operators2-out.hs+1−1
@@ -12,5 +12,5 @@ class (f `Product` g) a
12class
12class
13 ( f
13 ( f
14 `Sum` g
14 `Sum` g
15− )
15+ )
16 a
16 a
data/examples/declaration/class/type-operators3-out.hsdeleted−10
@@ -1,10 +0,0 @@
1−{-# LANGUAGE PolyKinds #-}
2−{-# LANGUAGE TypeFamilies #-}
3−{-# LANGUAGE TypeOperators #-}
4−{-# LANGUAGE NoStarIsType #-}
5−
6−class PNum x where
7− type (a :: x) * (b :: x)
8−
9−instance PNum Nat where
10− type a * b = ()
data/examples/declaration/class/type-operators3.hsdeleted−7
@@ -1,7 +0,0 @@
1−{-# LANGUAGE TypeFamilies, TypeOperators, NoStarIsType, PolyKinds #-}
2−
3−class PNum x where
4− type (a :: x) * (b :: x)
5−
6−instance PNum Nat where
7− type a * b = ()
data/examples/declaration/data/deriving-strategies-out.hs+1−3
@@ -1,12 +1,10 @@
1−module Main where
2−
3-- | Something.
1-- | Something.
4newtype Foo = Foo Int
2newtype Foo = Foo Int
5 deriving stock (Eq, Show, Generic)
3 deriving stock (Eq, Show, Generic)
6 deriving anyclass
4 deriving anyclass
7 ( ToJSON,
5 ( ToJSON,
8 FromJSON
6 FromJSON
9− )
7+ )
10 deriving newtype (Num)
8 deriving newtype (Num)
11 deriving (Monoid) via (Sum Int)
9 deriving (Monoid) via (Sum Int)
12 deriving
10 deriving
data/examples/declaration/data/deriving-strategies.hs−2
@@ -1,5 +1,3 @@
1−module Main where
2−
3-- | Something.
1-- | Something.
4
2
5newtype Foo = Foo Int
3newtype Foo = Foo Int
data/examples/declaration/data/existential-multiline-out.hs−12
@@ -3,15 +3,3 @@
3data Foo
3data Foo
4 = forall a. MkFoo a (a -> Bool)
4 = forall a. MkFoo a (a -> Bool)
5 | forall a. Eq a => MkBar a
5 | forall a. Eq a => MkBar a
6−
7−data Bar
8− = forall x y.
9− Bar x y x y
10−
11−data Baz
12− = forall x y.
13− Baz
14− x
15− y
16− x
17− y
data/examples/declaration/data/existential-multiline.hs−7
@@ -3,10 +3,3 @@
3data Foo
3data Foo
4 = forall a. MkFoo a (a -> Bool)
4 = forall a. MkFoo a (a -> Bool)
5 | forall a. Eq a => MkBar a
5 | forall a. Eq a => MkBar a
6−
7−data Bar = forall x y.
8− Bar x y x y
9−
10−data Baz = forall x y.
11− Baz x y x
12− y
data/examples/declaration/data/existential-out.hs−2
@@ -1,5 +1,3 @@
1{-# LANGUAGE ExistentialQuantification #-}
1{-# LANGUAGE ExistentialQuantification #-}
2
2
3data Foo = forall a. MkFoo a (a -> Bool)
3data Foo = forall a. MkFoo a (a -> Bool)
4−
5−data Bar = forall a b. a + b => Bar a b
data/examples/declaration/data/existential.hs−2
@@ -1,5 +1,3 @@
1{-# LANGUAGE ExistentialQuantification #-}
1{-# LANGUAGE ExistentialQuantification #-}
2
2
3data Foo = forall a. MkFoo a (a -> Bool)
3data Foo = forall a. MkFoo a (a -> Bool)
4−
5−data Bar = forall a b. a + b => Bar a b
data/examples/declaration/data/fat-multiline-out.hs+4−6
@@ -1,12 +1,10 @@
1−module Main where
2−
3-- | Something.
1-- | Something.
4data Foo
2data Foo
5− = -- | Foo
6− Foo
3+ = Foo
7 Int
4 Int
8 Int
5 Int
9− | -- | Bar
6+ -- ^ Foo
10− Bar
7+ | Bar
11 Bool
8 Bool
12 Bool
9 Bool
10+ -- ^ Bar
data/examples/declaration/data/fat-multiline.hs−2
@@ -1,5 +1,3 @@
1−module Main where
2−
3-- | Something.
1-- | Something.
4
2
5data Foo
3data Foo
data/examples/declaration/data/field-layout/gadt-out.hsdeleted−11
@@ -1,11 +0,0 @@
1−module Main where
2−
3−-- | Foo.
4−data Foo a b where
5− -- | Something
6− Foo :: Foo Int Int
7− -- | Something else
8− Bar ::
9− Foo
10− Char
11− Char
data/examples/declaration/data/field-layout/gadt.hsdeleted−10
@@ -1,10 +0,0 @@
1−module Main where
2−
3−-- | Foo.
4−
5−data Foo a b where
6− -- | Something
7− Foo :: Foo Int Int
8− -- | Something else
9− Bar :: Foo Char
10− Char
data/examples/declaration/data/field-layout/record-out.hsdeleted−12
@@ -1,12 +0,0 @@
1−module Main where
2−
3−-- | Foo.
4−data Foo = Foo
5− { -- | Something
6− foo :: Foo Int Int,
7− -- | Something else
8− bar ::
9− Bar
10− Char
11− Char
12− }
data/examples/declaration/data/field-layout/record.hsdeleted−11
@@ -1,11 +0,0 @@
1−module Main where
2−
3−-- | Foo.
4−
5−data Foo = Foo
6− { foo :: Foo Int Int
7− -- ^ Something
8− , bar :: Bar Char
9− Char
10− -- ^ Something else
11− }
data/examples/declaration/data/field-layout/variants-out.hsdeleted−10
@@ -1,10 +0,0 @@
1−module Main where
2−
3−-- | Foo.
4−data Foo
5− = -- | Something
6− Foo Int Int
7− | -- | Something else
8− Bar
9− Char
10− Char
data/examples/declaration/data/field-layout/variants.hsdeleted−10
@@ -1,10 +0,0 @@
1−module Main where
2−
3−-- | Foo.
4−
5−data Foo =
6− Foo Int Int
7− -- ^ Something
8− | Bar Char
9− Char
10− -- ^ Something else
data/examples/declaration/data/gadt-syntax-out.hs+1−2
@@ -1,3 +1,2 @@
1−{-# LANGUAGE GADTSyntax #-}
1+{-# LANUGAGE GADTSyntax #-}
2−
3data Foo where MKFoo :: a -> (a -> Bool) -> Foo
2data Foo where MKFoo :: a -> (a -> Bool) -> Foo
data/examples/declaration/data/gadt-syntax.hs+1−1
@@ -1,3 +1,3 @@
1−{-# LANGUAGE GADTSyntax #-}
1+{-# LANUGAGE GADTSyntax #-}
2
2
3data Foo where { MKFoo :: a -> (a->Bool) -> Foo }
3data Foo where { MKFoo :: a -> (a->Bool) -> Foo }
data/examples/declaration/data/gadt/multiline-out.hs+13−17
@@ -1,25 +1,21 @@
1{-# LANGUAGE ExplicitForAll #-}
1{-# LANGUAGE ExplicitForAll #-}
2
2
3−module Main where
4−
5-- | Here goes a comment.
3-- | Here goes a comment.
6data Foo a where
4data Foo a where
7 -- | 'Foo' is wonderful.
5 -- | 'Foo' is wonderful.
8− Foo ::
6+ Foo
9− forall a b.
10− (Show a, Eq b) => -- foo
7+ :: forall a b. (Show a, Eq b) -- foo
11− -- bar
8+ -- bar
12− a ->
9+ => a
13− b ->
10+ -> b
14− Foo 'Int
11+ -> Foo 'Int
15 -- | But 'Bar' is also not too bad.
12 -- | But 'Bar' is also not too bad.
16− Bar ::
13+ Bar
17− Int ->
14+ :: Int
18− Maybe Text ->
15+ -> Maybe Text
19− Foo 'Bool
16+ -> Foo 'Bool
20 -- | So is 'Baz'.
17 -- | So is 'Baz'.
21− Baz ::
18+ Baz
22− forall a.
19+ :: forall a. a
23− a ->
24− Foo 'String
20+ -> Foo 'String
25 (:~>) :: Foo a -> Foo a -> Foo a
21 (:~>) :: Foo a -> Foo a -> Foo a
data/examples/declaration/data/gadt/multiline-where-out.hsdeleted−7
@@ -1,7 +0,0 @@
1−data
2− Foo
3− a
4− b
5− c
6− where
7− Foo :: a -> b -> c -> Foo a b c
data/examples/declaration/data/gadt/multiline-where.hsdeleted−6
@@ -1,6 +0,0 @@
1−data
2− Foo
3− a
4− b
5− c where
6− Foo :: a -> b -> c -> Foo a b c
data/examples/declaration/data/gadt/multiline.hs−2
@@ -1,5 +1,3 @@
1−module Main where
2−
3{-# LANGUAGE ExplicitForAll #-}
1{-# LANGUAGE ExplicitForAll #-}
4
2
5-- | Here goes a comment.
3-- | Here goes a comment.
data/examples/declaration/data/gadt/multiple-declaration-out.hs+6−6
@@ -3,13 +3,13 @@ data GADT0 a where
3
3
4data GADT1 a where
4data GADT1 a where
5 GADT11,
5 GADT11,
6− GADT12 ::
6+ GADT12
7− Int ->
7+ :: Int
8− GADT1 a
8+ -> GADT1 a
9
9
10data GADT2 a where
10data GADT2 a where
11 GADT21,
11 GADT21,
12 GADT21,
12 GADT21,
13− GADT22 ::
13+ GADT22
14− Int ->
14+ :: Int
15− GADT2 a
15+ -> GADT2 a
data/examples/declaration/data/gadt/record-out.hs+9−11
@@ -1,14 +1,12 @@
1−module Main where
2−
3-- | Something.
1-- | Something.
4data Foo where
2data Foo where
5 Foo :: {fooX :: Int} -> Foo
3 Foo :: {fooX :: Int} -> Foo
6− Bar ::
4+ Bar
7− { fooY :: Int,
5+ :: { fooY :: Int,
8− fooBar, fooBaz :: Bool,
6+ fooBar, fooBaz :: Bool,
9− fooFoo,
7+ fooFoo,
10− barBar,
8+ barBar,
11− bazBaz ::
9+ bazBaz
12− Int
10+ :: Int
13− } ->
11+ }
14− Foo
12+ -> Foo
data/examples/declaration/data/gadt/record.hs−2
@@ -1,5 +1,3 @@
1−module Main where
2−
3-- | Something.
1-- | Something.
4
2
5data Foo where
3data Foo where
data/examples/declaration/data/gadt/simple-out.hs+2−12
@@ -1,18 +1,8 @@
1{-# LANGUAGE ExplicitForAll #-}
1{-# LANGUAGE ExplicitForAll #-}
2
2
3−module Main where
4−
5-- | Here goes a comment.
3-- | Here goes a comment.
6data Foo a where
4data Foo a where
7 -- | 'Foo' is wonderful.
5 -- | 'Foo' is wonderful.
8 Foo :: forall a b. (Show a, Eq b) => a -> b -> Foo 'Int
6 Foo :: forall a b. (Show a, Eq b) => a -> b -> Foo 'Int
9− Bar ::
10− Int ->
11− Text ->
12− -- | But 'Bar' is also not too bad.
7+ Bar :: Int -> Text -> Foo 'Bool -- ^ But 'Bar' is also not too bad.
13− Foo 'Bool
14− Baz ::
15− forall a.
8+ Baz :: forall a. a -> Foo 'String -- ^ So is 'Baz'.
16− a ->
17− -- | So is 'Baz'.
18− Foo 'String
data/examples/declaration/data/gadt/simple.hs−2
@@ -1,5 +1,3 @@
1−module Main where
2−
3{-# LANGUAGE ExplicitForAll #-}
1{-# LANGUAGE ExplicitForAll #-}
4
2
5-- | Here goes a comment.
3-- | Here goes a comment.
data/examples/declaration/data/gadt/strictness-out.hs+1−2
@@ -1,3 +1,2 @@
1data Foo a where
1data Foo a where
2− Foo1 :: !Int -> {-# UNPACK #-} !Bool -> Foo Int
2+ Foo :: !Int -> {-# UNPACK #-} !Bool -> Foo Int
3− Foo2 :: {-# UNPACK #-} Maybe Int && Bool -> Foo Int
data/examples/declaration/data/gadt/strictness.hs+1−2
@@ -1,3 +1,2 @@
1data Foo a where
1data Foo a where
2− Foo1 :: !Int -> {-# UNPACK #-} !Bool -> Foo Int
2+ Foo :: !Int -> {-# UNPACK #-} !Bool -> Foo Int
3− Foo2 :: {-# UNPACK #-} Maybe Int && Bool -> Foo Int
data/examples/declaration/data/kind-annotations-out.hs−10
@@ -1,11 +1 @@
1data Something (n :: Nat) = Something
1data Something (n :: Nat) = Something
2−
3−data Format (k :: *) (k' :: *) (k'' :: *)
4−
5−type Parens1 = Proxy '(a :: A, b :: (B :: *))
6−
7−type Parens2 = Proxy '((a :: A), (b :: B))
8−
9−type family Foo a where
10− Foo '(a :: Int, b :: Bool) = Int
11− Foo '((a :: Int), (b :: Bool)) = Int
data/examples/declaration/data/kind-annotations.hs−9
@@ -1,10 +1 @@
1data Something (n :: Nat) = Something
1data Something (n :: Nat) = Something
2−
3−data Format (k :: *) (k' :: *) (k'' :: *)
4−
5−type Parens1 = Proxy '(a :: A, b :: (B :: *))
6−type Parens2 = Proxy '((a :: A), (b :: B))
7−
8−type family Foo a where
9− Foo '(a :: Int, b :: Bool) = Int
10− Foo '((a :: Int), (b :: Bool)) = Int
data/examples/declaration/data/multiline-arg-parens-out.hs+1−3
@@ -1,10 +1,8 @@
1−module Main where
2−
3-- | Something.
1-- | Something.
4data Foo
2data Foo
5 = Foo
3 = Foo
6 Bar
4 Bar
7 (Set Baz) -- and here we go
5 (Set Baz) -- and here we go
8− -- and that's it
6+ -- and that's it
9 Text
7 Text
10 deriving (Eq)
8 deriving (Eq)
data/examples/declaration/data/multiline-arg-parens.hs−2
@@ -1,5 +1,3 @@
1−module Main where
2−
3-- | Something.
1-- | Something.
4
2
5data Foo
3data Foo
data/examples/declaration/data/multiline-names-out.hs+2−2
@@ -11,7 +11,7 @@ data (f :* g) a = f a :* g a
11data
11data
12 ( f
12 ( f
13 :+ g
13 :+ g
14− )
14+ )
15 a
15 a
16 = L (f a)
16 = L (f a)
17 | R (g a)
17 | R (g a)
@@ -23,7 +23,7 @@ data (f `Product` g) a = f a `Product` g a
23data
23data
24 ( f
24 ( f
25 `Sum` g
25 `Sum` g
26− )
26+ )
27 a
27 a
28 = L' (f a)
28 = L' (f a)
29 | R' (g a)
29 | R' (g a)
data/examples/declaration/data/multiline-out.hs+3−8
@@ -1,12 +1,7 @@
1−module Main where
2−
3-- | Here we have 'Foo'.
1-- | Here we have 'Foo'.
4data Foo
2data Foo
5− = -- | One
6− Foo
3+ = Foo -- ^ One
7− | -- | Two
8− Bar Int
4+ | Bar Int -- ^ Two
9− | -- | Three
10− Baz
5+ | Baz -- ^ Three
11 deriving
6 deriving
12 (Eq, Show)
7 (Eq, Show)
data/examples/declaration/data/multiline.hs−2
@@ -1,5 +1,3 @@
1−module Main where
2−
3-- | Here we have 'Foo'.
1-- | Here we have 'Foo'.
4
2
5data Foo
3data Foo
data/examples/declaration/data/newtype-out.hs−2
@@ -1,5 +1,3 @@
1−module Main where
2−
3-- | Something.
1-- | Something.
4newtype Foo = Foo Int
2newtype Foo = Foo Int
5 deriving (Eq, Show)
3 deriving (Eq, Show)
data/examples/declaration/data/newtype.hs−2
@@ -1,5 +1,3 @@
1−module Main where
2−
3-- | Something.
1-- | Something.
4
2
5newtype Foo = Foo Int
3newtype Foo = Foo Int
data/examples/declaration/data/operators-out.hsdeleted−12
@@ -1,12 +0,0 @@
1−data ErrorMessage' s
2− = -- | Show the text as is.
3− Text s
4− | -- | Pretty print the type.
5− -- @ShowType :: k -> ErrorMessage@
6− forall t. ShowType t
7− | -- | Put two pieces of error message next
8− -- to each other.
9− ErrorMessage' s :<>: ErrorMessage' s
10− | -- | Stack two pieces of error message on top
11− -- of each other.
12− ErrorMessage' s :$$: ErrorMessage' s
data/examples/declaration/data/operators.hsdeleted−12
@@ -1,12 +0,0 @@
1−data ErrorMessage' s
2− = -- | Show the text as is.
3− Text s
4− | -- | Pretty print the type.
5− -- @ShowType :: k -> ErrorMessage@
6− forall t. ShowType t
7− | -- | Put two pieces of error message next
8− -- to each other.
9− ErrorMessage' s :<>: ErrorMessage' s
10− | -- | Stack two pieces of error message on top
11− -- of each other.
12− ErrorMessage' s :$$: ErrorMessage' s
data/examples/declaration/data/partly-documented-out.hsdeleted−5
@@ -1,5 +0,0 @@
1−data Optimisation
2− = PETransform
3− | -- | partial eval and associated transforms
4− GeneralisedNatHack
5− deriving (Show, Eq, Generic)
data/examples/declaration/data/partly-documented.hsdeleted−2
@@ -1,2 +0,0 @@
1−data Optimisation = PETransform | GeneralisedNatHack -- ^ partial eval and associated transforms
2− deriving (Show, Eq, Generic)
data/examples/declaration/data/record-multi-const-out.hsdeleted−17
@@ -1,17 +0,0 @@
1−module Main where
2−
3−-- | Something.
4−data Foo
5− = Foo
6− { -- | X
7− fooX :: Int,
8− -- | Y
9− fooY :: Int
10− }
11− | Bar
12− { -- | X
13− barX :: Int,
14− -- | Y
15− barY :: Int
16− }
17− deriving (Eq, Show)
data/examples/declaration/data/record-multi-const.hsdeleted−13
@@ -1,13 +0,0 @@
1−module Main where
2−
3−-- | Something.
4−
5−data Foo = Foo
6− { fooX :: Int -- ^ X
7− , fooY :: Int -- ^ Y
8− } |
9− Bar
10− { barX :: Int -- ^ X
11− , barY :: Int -- ^ Y
12− }
13− deriving (Eq, Show)
data/examples/declaration/data/record-out.hs+16−21
@@ -1,23 +1,18 @@
1−module Main where
2−
3-- | Something.
1-- | Something.
4−data Foo = Foo
2+data Foo
5− { -- | X
3+ = Foo
6− fooX :: Int,
4+ { fooX :: Int, -- ^ X
7− -- | Y
8− fooY :: Int,
5+ fooY :: Int, -- ^ Y
9− -- | BarBaz
10− fooBar, fooBaz :: NonEmpty (Identity Bool),
6+ fooBar, fooBaz :: NonEmpty (Identity Bool), -- ^ BarBaz
11− -- | GagGog
12− fooGag,
7+ fooGag,
13− fooGog ::
8+ fooGog
14− NonEmpty
9+ :: NonEmpty
15− ( Indentity
10+ ( Indentity
16− Bool
11+ Bool
17− ),
12+ ),
18− -- | Huh!
13+ -- ^ GagGog
19− fooFoo,
14+ fooFoo,
20− barBar ::
15+ barBar
21− Int
16+ :: Int -- ^ Huh!
22− }
17+ }
23 deriving (Eq, Show)
18 deriving (Eq, Show)
data/examples/declaration/data/record-singleline-out.hs−2
@@ -1,5 +1,3 @@
1−module Main where
2−
3-- | Something.
1-- | Something.
4data Foo = Foo {fooX :: Int, fooY :: Int}
2data Foo = Foo {fooX :: Int, fooY :: Int}
5 deriving (Eq, Show)
3 deriving (Eq, Show)
data/examples/declaration/data/record-singleline.hs−2
@@ -1,5 +1,3 @@
1−module Main where
2−
3-- | Something.
1-- | Something.
4
2
5data Foo = Foo { fooX :: Int , fooY :: Int }
3data Foo = Foo { fooX :: Int , fooY :: Int }
data/examples/declaration/data/record.hs−2
@@ -1,5 +1,3 @@
1−module Main where
2−
3-- | Something.
1-- | Something.
4
2
5data Foo = Foo
3data Foo = Foo
data/examples/declaration/data/simple-broken-out.hs+2−3
@@ -1,7 +1,6 @@
1−module Main where
2−
3-- | Here we go.
1-- | Here we go.
2+data Foo
4−data Foo = Foo {unFoo :: Int}
3+ = Foo {unFoo :: Int}
5 deriving (Eq)
4 deriving (Eq)
6
5
7-- | And once again.
6-- | And once again.
data/examples/declaration/data/simple-broken.hs−2
@@ -1,5 +1,3 @@
1−module Main where
2−
3-- | Here we go.
1-- | Here we go.
4
2
5data Foo
3data Foo
data/examples/declaration/data/simple-out.hs−2
@@ -1,5 +1,3 @@
1−module Main where
2−
3-- | And here we have 'Foo'.
1-- | And here we have 'Foo'.
4data Foo = Foo | Bar Int | Baz
2data Foo = Foo | Bar Int | Baz
5 deriving (Eq, Show)
3 deriving (Eq, Show)
data/examples/declaration/data/simple.hs−2
@@ -1,5 +1,3 @@
1−module Main where
2−
3-- | And here we have 'Foo'.
1-- | And here we have 'Foo'.
4
2
5data Foo = Foo | Bar Int | Baz
3data Foo = Foo | Bar Int | Baz
data/examples/declaration/data/strictness-out.hs+1−5
@@ -1,6 +1,2 @@
1−module Main where
2−
3-- | Something.
1-- | Something.
4−data Foo
5− = Foo1 !Int {-# UNPACK #-} !Bool {-# NOUNPACK #-} !String
2+data Foo = Foo !Int {-# UNPACK #-} !Bool {-# NOUNPACK #-} !String
6− | Foo2 {a :: {-# UNPACK #-} Maybe Int && Bool}
data/examples/declaration/data/strictness.hs+1−5
@@ -1,7 +1,3 @@
1−module Main where
2−
3-- | Something.
1-- | Something.
4
2
5−data Foo
6− = Foo1 !Int {-# UNPACK #-} !Bool {-# NOUNPACK #-} !String
3+data Foo = Foo !Int {-# UNPACK #-} !Bool {-# NOUNPACK #-} !String
7− | Foo2 { a :: {-# UNPACK #-} Maybe Int && Bool }
data/examples/declaration/data/unnamed-field-comment-0-out.hsdeleted−7
@@ -1,7 +0,0 @@
1−data Foo
2− = -- | Bar
3− Bar
4− Field1
5− -- ^ Field 1
6− Field2
7− -- ^ Field 2
data/examples/declaration/data/unnamed-field-comment-0.hsdeleted−5
@@ -1,5 +0,0 @@
1−data Foo
2− = -- | Bar
3− Bar
4− Field1 -- ^ Field 1
5− Field2 -- ^ Field 2
data/examples/declaration/data/unnamed-field-comment-1-out.hsdeleted−5
@@ -1,5 +0,0 @@
1−data X
2− = B
3− !Int
4− -- ^ y
5− C
data/examples/declaration/data/unnamed-field-comment-1.hsdeleted−4
@@ -1,4 +0,0 @@
1−data X
2− = B
3− !Int -- ^ y
4− C
data/examples/declaration/data/with-comment-out.hsdeleted−4
@@ -1,4 +0,0 @@
1−data A
2− = B -- C
3− | -- D
4− E
data/examples/declaration/data/with-comment.hsdeleted−5
@@ -1,5 +0,0 @@
1−data A =
2− B -- C
3−
4− -- D
5− | E
data/examples/declaration/data/with-weird-haddock-out.hsdeleted−4
@@ -1,4 +0,0 @@
1−data PlusLevel' t
2− = -- | @n + ℓ@.
3− Plus Integer (LevelAtom' t)
4− deriving (Show, Data)
data/examples/declaration/data/with-weird-haddock.hsdeleted−2
@@ -1,2 +0,0 @@
1−data PlusLevel' t = Plus Integer (LevelAtom' t) -- ^ @n + ℓ@.
2− deriving (Show, Data)
data/examples/declaration/default/default-out.hs+1−1
@@ -4,4 +4,4 @@ default
4 ( Int,
4 ( Int,
5 Foo,
5 Foo,
6 Bar
6 Bar
7− )
7+ )
data/examples/declaration/foreign/foreign-export-out.hs+1−2
@@ -2,8 +2,7 @@ foreign export ccall foo :: Int -> IO Int
2
2
3-- | 'foreignTomFun' is a very important thing
3-- | 'foreignTomFun' is a very important thing
4foreign export ccall "tomography"
4foreign export ccall "tomography"
5− foreignTomFun ::
6− StablePtr Storage {- Storage is bad -} -> TomForegin
5+ foreignTomFun :: StablePtr Storage -> TomForegin {- Storage is bad -}
7
6
8foreign export {- We can't use capi here -} ccall "dynamic"
7foreign export {- We can't use capi here -} ccall "dynamic"
9 export_nullaryMeth :: (IO HRESULT) -> IO (Ptr ())
8 export_nullaryMeth :: (IO HRESULT) -> IO (Ptr ())
data/examples/declaration/foreign/foreign-import-out.hs+10−10
@@ -10,16 +10,16 @@ foreign import stdcall unsafe "boo"
10 boo :: Int -> Text -> IO Array
10 boo :: Int -> Text -> IO Array
11
11
12foreign import javascript
12foreign import javascript
13− baz ::
13+ baz
14− String ->
14+ :: String
15− Int ->
15+ -> Int
16− IO Foo
16+ -> IO Foo
17
17
18foreign import {- We use capi here -} capi "pi.h value pi" c_pi :: CDouble
18foreign import {- We use capi here -} capi "pi.h value pi" c_pi :: CDouble
19
19
20−foreign import stdcall {- This is a bad place for a comment -} "dynamic"
20+foreign import stdcall "dynamic" {- This is a bad place for a comment -}
21− dyn_gluBeginSurface ::
21+ dyn_gluBeginSurface
22+ :: FunPtr (Ptr GLUnurbs -> IO ())
22− -- | This 'FunPtr' is extremely dangerous, beware
23+ -- ^ This 'FunPtr' is extremely dangerous, beware
23− FunPtr (Ptr GLUnurbs -> IO ()) ->
24+ -> Ptr GLUnurbs
24− Ptr GLUnurbs ->
25− IO ()
25+ -> IO ()
data/examples/declaration/instance/associated-data-out.hs+2
@@ -11,7 +11,9 @@ instance Foo Double where
11 Double
11 Double
12
12
13instance Foo [a] where
13instance Foo [a] where
14+
14 data Bar [a]
15 data Bar [a]
15 = ListBar [Bar a]
16 = ListBar [Bar a]
17+
16 data Baz [a]
18 data Baz [a]
17 = ListBaz
19 = ListBaz
data/examples/declaration/instance/associated-data.hs−1
@@ -13,7 +13,6 @@ instance Foo Double where
13
13
14instance Foo [a]
14instance Foo [a]
15 where
15 where
16−
17 data Bar [a] =
16 data Bar [a] =
18 ListBar [Bar a]
17 ListBar [Bar a]
19 data Baz [a] =
18 data Baz [a] =
data/examples/declaration/instance/associated-types-out.hs+1
@@ -3,6 +3,7 @@
3instance Foo Int where type Bar Int = Double
3instance Foo Int where type Bar Int = Double
4
4
5instance Foo Double where
5instance Foo Double where
6+
6 type
7 type
7 Bar
8 Bar
8 Double =
9 Double =
data/examples/declaration/instance/associated-types.hs−2
@@ -9,7 +9,5 @@ instance Foo Double
9 Double
9 Double
10 =
10 =
11 [Double]
11 [Double]
12−
13−
14 type instance Baz Double
12 type instance Baz Double
15 = [Double]
13 = [Double]
data/examples/declaration/instance/contexts-comments-out.hs+8−8
@@ -4,14 +4,14 @@ instance
4 Read
4 Read
5 ( c, -- Bar
5 ( c, -- Bar
6 d
6 d
7− )
8− ) =>
9− Read
10− ( a, -- Baz
11− b,
12− ( c, -- Quux
13− d
14− )
7+ )
15 )
8 )
9+ => Read
10+ ( a, -- Baz
11+ b,
12+ ( c, -- Quux
13+ d
14+ )
15+ )
16 where
16 where
17 readsPrec = undefined
17 readsPrec = undefined
data/examples/declaration/instance/contexts-out.hs+7−7
@@ -3,16 +3,16 @@ instance Eq a => Eq [a] where (==) _ _ = False
3instance
3instance
4 ( Ord a,
4 ( Ord a,
5 Ord b
5 Ord b
6− ) =>
6+ )
7− Ord (a, b)
7+ => Ord (a, b)
8 where
8 where
9 compare _ _ = GT
9 compare _ _ = GT
10
10
11instance
11instance
12− (Show a, Show b) =>
12+ (Show a, Show b)
13− Show
13+ => Show
14− ( a,
14+ ( a,
15− b
15+ b
16− )
16+ )
17 where
17 where
18 showsPrec _ _ = showString ""
18 showsPrec _ _ = showString ""
data/examples/declaration/instance/data-family-instances-gadt-out.hs+6−8
@@ -2,12 +2,10 @@
2{-# LANGUAGE TypeFamilies #-}
2{-# LANGUAGE TypeFamilies #-}
3
3
4data instance Bar Int a where
4data instance Bar Int a where
5− SameBar ::
5+ SameBar
6− Bar
6+ :: Bar Int
7− Int
8− Int
7+ Int
9 CloseBar :: Bar Int Double
8 CloseBar :: Bar Int Double
10− OtherBar ::
9+ OtherBar
11− Bar
10+ :: Bar Int
12− Int
13− a
11+ a
data/examples/declaration/instance/data-family-instances-newtype-out.hs+4−3
@@ -1,6 +1,7 @@
1{-# LANGUAGE GADTSyntax #-}
1{-# LANGUAGE GADTSyntax #-}
2{-# LANGUAGE TypeFamilies #-}
2{-# LANGUAGE TypeFamilies #-}
3
3
4−newtype instance Foo [Double] = DoubleListFoo
4+newtype instance Foo [Double]
5+ = DoubleListFoo
5− { unDoubleListFoo :: Double
6+ { unDoubleListFoo :: Double
6− }
7+ }
data/examples/declaration/instance/data-family-instances-out.hs+2−2
@@ -9,10 +9,10 @@ data instance
9 = IntListFoo
9 = IntListFoo
10 ( Int,
10 ( Int,
11 Int
11 Int
12− )
12+ )
13 ( Double,
13 ( Double,
14 Double
14 Double
15− )
15+ )
16
16
17data instance Bar Double a
17data instance Bar Double a
18 = DoubleBar
18 = DoubleBar
data/examples/declaration/instance/instance-sigs-multiple-out.hs+7−5
@@ -1,10 +1,12 @@
1{-# LANGUAGE InstanceSigs #-}
1{-# LANGUAGE InstanceSigs #-}
2
2
3instance Applicative [] where
3instance Applicative [] where
4+
4− pure ::
5+ pure
5− a ->
6+ :: a
6− [a]
7+ -> [a]
7 pure a = [a]
8 pure a = [a]
9+
8− (<*>) ::
10+ (<*>)
9− [a] -> [a] -> [a]
11+ :: [a] -> [a] -> [a]
10 (<*>) _ _ = []
12 (<*>) _ _ = []
data/examples/declaration/instance/instance-sigs-out.hs+4−4
@@ -5,10 +5,10 @@ instance Eq Int where
5 (==) _ _ = False
5 (==) _ _ = False
6
6
7instance Ord Int where
7instance Ord Int where
8− compare ::
8+ compare
9− Int ->
9+ :: Int
10− Int ->
10+ -> Int
11− Ordering
11+ -> Ordering
12 compare
12 compare
13 _
13 _
14 _ =
14 _ =
data/examples/declaration/instance/multi-parameter-out.hs+2
@@ -1,5 +1,7 @@
1instance MonadReader a ((->) a) where ask = id
1instance MonadReader a ((->) a) where ask = id
2
2
3instance MonadState s (State s) where
3instance MonadState s (State s) where
4+
4 get = State.get
5 get = State.get
6+
5 put = State.put
7 put = State.put
data/examples/declaration/instance/newlines-after-where-out.hsdeleted−5
@@ -1,5 +0,0 @@
1−instance Num X where
2− (+) = undefined
3−
4−instance Num Y where
5− (+) = undefined
data/examples/declaration/instance/newlines-after-where.hsdeleted−7
@@ -1,7 +0,0 @@
1−instance Num X where
2− (+) = undefined
3−
4−instance Num Y where
5−
6−
7− (+) = undefined
data/examples/declaration/instance/newlines-between-methods-out.hsdeleted−18
@@ -1,18 +0,0 @@
1−instance Num a => Num (Diff a) where
2− D u dudx + D v dvdx = D (u + v) (dudx + dvdx)
3− D u dudx - D v dvdx = D (u - v) (dudx - dvdx)
4− D u dudx * D v dvdx = D (u * v) (u * dvdx + v * dudx)
5−
6− -- Comment before definition
7− negate (D u dudx) = D (- u) (- dudx)
8− negate (Z u dudx) = undefined
9−
10− -- Comment after definition
11−
12− -- Separator
13−
14− abs (D u _) = D (abs u) (signum u)
15− signum (D u _) = D (signum u) 0
16−
17− -- Comment between unrelated definitions
18− fromInteger n = D (fromInteger n) 0
data/examples/declaration/instance/newlines-between-methods.hsdeleted−16
@@ -1,16 +0,0 @@
1−instance Num a => Num (Diff a) where
2− D u dudx + D v dvdx = D (u + v) (dudx + dvdx)
3− D u dudx - D v dvdx = D (u - v) (dudx - dvdx)
4− D u dudx * D v dvdx = D (u * v) (u * dvdx + v * dudx)
5−
6− -- Comment before definition
7− negate (D u dudx) = D (-u) (-dudx)
8− negate (Z u dudx) = undefined
9− -- Comment after definition
10−
11− -- Separator
12−
13− abs (D u _) = D (abs u) (signum u)
14− signum (D u _) = D (signum u) 0
15− -- Comment between unrelated definitions
16− fromInteger n = D (fromInteger n) 0
data/examples/declaration/instance/single-parameter-out.hs+2
@@ -1,7 +1,9 @@
1instance Monoid Int where (<>) x y = x + y
1instance Monoid Int where (<>) x y = x + y
2
2
3instance Enum Int where
3instance Enum Int where
4+
4 fromEnum x = x
5 fromEnum x = x
6+
5 toEnum =
7 toEnum =
6 \x ->
8 \x ->
7 x
9 x
data/examples/declaration/instance/type-family-instances-out.hs+2−2
@@ -7,7 +7,7 @@ type instance
7 [Int] =
7 [Int] =
8 ( Int,
8 ( Int,
9 Int
9 Int
10− )
10+ )
11
11
12type instance Bar Int [Int] Double = (Int, Double)
12type instance Bar Int [Int] Double = (Int, Double)
13
13
@@ -18,4 +18,4 @@ type instance
18 Double =
18 Double =
19 ( Int,
19 ( Int,
20 Double
20 Double
21− )
21+ )
data/examples/declaration/rewrite-rule/basic1-out.hs+1−2
@@ -10,8 +10,7 @@
10
10
11{-# RULES
11{-# RULES
12"map/map"
12"map/map"
13− map
13+ map f
14− f
15 (map g xs) =
14 (map g xs) =
16 map
15 map
17 (f . g)
16 (f . g)
data/examples/declaration/rewrite-rule/forall-1-out.hsdeleted−23
@@ -1,23 +0,0 @@
1−{-# RULES "rd_tyvs" forall a. forall (x :: a). id x = x #-}
2−
3−{-# RULES "rd_tyvs'" forall f a. forall (x :: f a). id x = x #-}
4−
5−{-# RULES "rd_tyvs''" forall (a :: *). forall (x :: a). id x = x #-}
6−
7−{-# RULES
8−"rd_tyvs_multiline1" forall (a :: *). forall (x :: a).
9− id x =
10− x
11− #-}
12−
13−{-# RULES
14−"rd_tyvs_multiline2" forall
15− ( a ::
16− *
17− ). forall
18− ( x ::
19− a
20− ).
21− id x =
22− x
23− #-}
data/examples/declaration/rewrite-rule/forall-1.hsdeleted−17
@@ -1,17 +0,0 @@
1−{-# RULES "rd_tyvs" forall a. forall (x :: a). id x = x #-}
2−
3−{-# RULES "rd_tyvs'" forall f a. forall (x :: f a). id x = x #-}
4−
5−{-# RULES "rd_tyvs''" forall (a :: *). forall (x :: a). id x = x #-}
6−
7−{-# RULES "rd_tyvs_multiline1"
8− forall (a :: *).
9− forall (x :: a).
10− id x = x #-}
11−
12−{-# RULES "rd_tyvs_multiline2"
13− forall (a ::
14− *).
15− forall (x ::
16− a).
17− id x = x #-}
data/examples/declaration/rewrite-rule/forall-0-out.hs → data/examples/declaration/rewrite-rule/forall-out.hsrenamed

The content is the same.

data/examples/declaration/rewrite-rule/forall-0.hs → data/examples/declaration/rewrite-rule/forall.hsrenamed

The content is the same.

data/examples/declaration/rewrite-rule/phase-out.hs+2−4
@@ -1,7 +1,6 @@
1{-# RULES
1{-# RULES
2"map/map" [2]
2"map/map" [2]
3− map
3+ map f
4− f
5 (map g xs) =
4 (map g xs) =
6 map
5 map
7 (f . g)
6 (f . g)
@@ -10,8 +9,7 @@
10
9
11{-# RULES
10{-# RULES
12"map/map" [1] forall x y z.
11"map/map" [1] forall x y z.
13− map
12+ map f
14− f
15 (map g xs) =
13 (map g xs) =
16 map
14 map
17 (f . g)
15 (f . g)
data/examples/declaration/rewrite-rule/prelude2-out.hs−1
@@ -17,7 +17,6 @@
17-- So I've disabled it for now. We could have special cases
17-- So I've disabled it for now. We could have special cases
18-- for short lists, I suppose.
18-- for short lists, I suppose.
19-- "foldr/cons" forall k z x xs. foldr k z (x:xs) = k x (foldr k z xs)
19-- "foldr/cons" forall k z x xs. foldr k z (x:xs) = k x (foldr k z xs)
20−
21"foldr/single" forall k z x. foldr k z [x] = k x z
20"foldr/single" forall k z x. foldr k z [x] = k x z
22"foldr/nil" forall k z. foldr k z [] = z
21"foldr/nil" forall k z. foldr k z [] = z
23"augment/build" forall
22"augment/build" forall
data/examples/declaration/rewrite-rule/prelude2.hs+1
@@ -27,3 +27,4 @@
27"augment/nil" forall (g::forall b. (a->b->b) -> b -> b) .
27"augment/nil" forall (g::forall b. (a->b->b) -> b -> b) .
28 augment g [] = build g
28 augment g [] = build g
29 #-}
29 #-}
30+
data/examples/declaration/rewrite-rule/prelude4-out.hs+1−1
@@ -2,6 +2,6 @@
2"unpack" [~1] forall a. unpackCString # a = build (unpackFoldrCString # a)
2"unpack" [~1] forall a. unpackCString # a = build (unpackFoldrCString # a)
3"unpack-list" [1] forall a. unpackFoldrCString # a (:) [] = unpackCString # a
3"unpack-list" [1] forall a. unpackFoldrCString # a (:) [] = unpackCString # a
4"unpack-append" forall a n. unpackFoldrCString # a (:) n = unpackAppendCString # a n
4"unpack-append" forall a n. unpackFoldrCString # a (:) n = unpackAppendCString # a n
5+ #-}
5-- There's a built-in rule (in PrelRules.lhs) for
6-- There's a built-in rule (in PrelRules.lhs) for
6-- unpackFoldr "foo" c (unpackFoldr "baz" c n) = unpackFoldr "foobaz" c n
7-- unpackFoldr "foo" c (unpackFoldr "baz" c n) = unpackFoldr "foobaz" c n
7− #-}
data/examples/declaration/rewrite-rule/type-signature-out.hs+5−6
@@ -6,12 +6,11 @@
6"fold/build" forall
6"fold/build" forall
7 k
7 k
8 z
8 z
9− ( g ::
9+ ( g
10− forall b.
10+ :: forall b. (a -> b -> b)
11− (a -> b -> b) ->
11+ -> b
12− b ->
13− b
12+ -> b
14− ).
13+ ).
15 foldr k z (build g) =
14 foldr k z (build g) =
16 g k z
15 g k z
17 #-}
16 #-}
data/examples/declaration/signature/complete/complete-out.hs+2−2
@@ -5,6 +5,6 @@
5{-# COMPLETE
5{-# COMPLETE
6 A,
6 A,
7 B,
7 B,
8− C ::
8+ C
9− Foo
9+ :: Foo
10 #-}
10 #-}
data/examples/declaration/signature/inline/inline-out.hs−4
@@ -9,7 +9,3 @@ bar = id
9baz :: Int -> Int
9baz :: Int -> Int
10baz = id
10baz = id
11{-# INLINE [~2] baz #-}
11{-# INLINE [~2] baz #-}
12−
13−reVector :: Bundle u a -> Bundle v a
14−{-# INLINE reVector #-}
15−reVector = M.reVector
data/examples/declaration/signature/inline/inline.hs−5
@@ -11,8 +11,3 @@ bar = id
11baz :: Int -> Int
11baz :: Int -> Int
12baz = id
12baz = id
13{-# INLINE [~2] baz #-}
13{-# INLINE [~2] baz #-}
14−
15−reVector :: Bundle u a -> Bundle v a
16−
17−{-# INLINE reVector #-}
18−reVector = M.reVector
data/examples/declaration/signature/minimal/minimal-out.hs+3−1
@@ -1,4 +1,5 @@
1class Foo a where
1class Foo a where
2+
2 {-# MINIMAL (==) | ((/=), foo) #-}
3 {-# MINIMAL (==) | ((/=), foo) #-}
3
4
4 {-# MINIMAL
5 {-# MINIMAL
@@ -6,9 +7,10 @@ class Foo a where
6 | ( b, c, d
7 | ( b, c, d
7 | e,
8 | e,
8 f
9 f
9− )
10+ )
10 | g
11 | g
11 #-}
12 #-}
12
13
13 (==) :: a -> a -> Bool
14 (==) :: a -> a -> Bool
15+
14 (/=) :: a -> a -> Bool
16 (/=) :: a -> a -> Bool
data/examples/declaration/signature/pattern/multiline-out.hs+4−17
@@ -1,19 +1,6 @@
1{-# LANGUAGE PatternSynonyms #-}
1{-# LANGUAGE PatternSynonyms #-}
2
2
3−pattern Arrow ::
3+pattern Arrow
4− Type ->
5− Type ->
6− Type
4+ :: Type
7−
8−pattern
9− Foo,
10− Bar ::
11− Type -> Type -> Type
5+ -> Type
12−
6+ -> Type
13−pattern
14− TypeSignature,
15− FunctionBody,
16− PatternSignature,
17− WarningPragma ::
18− [RdrName] ->
19− HsDecl GhcPs
data/examples/declaration/signature/pattern/multiline.hs−10
@@ -1,13 +1,3 @@
1{-# LANGUAGE PatternSynonyms #-}
1{-# LANGUAGE PatternSynonyms #-}
2−
3pattern Arrow :: Type
2pattern Arrow :: Type
4 -> Type -> Type
3 -> Type -> Type
5−
6−pattern Foo, Bar ::
7− Type -> Type -> Type
8−
9−pattern TypeSignature
10− , FunctionBody
11− , PatternSignature
12− , WarningPragma :: [RdrName]
13− -> HsDecl GhcPs
data/examples/declaration/signature/pattern/single-line-out.hs−2
@@ -1,5 +1,3 @@
1{-# LANGUAGE PatternSynonyms #-}
1{-# LANGUAGE PatternSynonyms #-}
2
2
3pattern Arrow :: Type -> Type -> Type
3pattern Arrow :: Type -> Type -> Type
4−
5−pattern Foo, Bar :: Type -> Type -> Type
data/examples/declaration/signature/pattern/single-line.hs−2
@@ -1,5 +1,3 @@
1{-# LANGUAGE PatternSynonyms #-}
1{-# LANGUAGE PatternSynonyms #-}
2
2
3pattern Arrow :: Type -> Type -> Type
3pattern Arrow :: Type -> Type -> Type
4−
5−pattern Foo, Bar :: Type -> Type -> Type
data/examples/declaration/signature/specialize/specialize-instance-out.hs+5−1
@@ -3,12 +3,16 @@ data Foo a = Foo a
3data VT v m r = VT v m r
3data VT v m r = VT v m r
4
4
5instance (Eq a) => Eq (Foo a) where
5instance (Eq a) => Eq (Foo a) where
6+
6 {-# SPECIALIZE instance Eq (Foo [(Int, Bar)]) #-}
7 {-# SPECIALIZE instance Eq (Foo [(Int, Bar)]) #-}
8+
7 (==) (Foo a) (Foo b) = (==) a b
9 (==) (Foo a) (Foo b) = (==) a b
8
10
9instance (Num r, V.Vector v r, Factored m r) => Num (VT v m r) where
11instance (Num r, V.Vector v r, Factored m r) => Num (VT v m r) where
12+
10 {-# SPECIALIZE instance
13 {-# SPECIALIZE instance
11 ( Factored m Int => Num (VT U.Vector m Int)
14 ( Factored m Int => Num (VT U.Vector m Int)
12− )
15+ )
13 #-}
16 #-}
17+
14 VT x + VT y = VT $ V.zipWith (+) x y
18 VT x + VT y = VT $ V.zipWith (+) x y
data/examples/declaration/signature/specialize/specialize-out.hs+6−6
@@ -9,15 +9,15 @@ bar = id
9
9
10baz :: Num a => a -> a
10baz :: Num a => a -> a
11baz = id
11baz = id
12−{-# SPECIALIZE [~2] baz ::
12+{-# SPECIALIZE [~2] baz
13− Int ->
13+ :: Int
14− Int
14+ -> Int
15 #-}
15 #-}
16
16
17{-# SPECIALIZE fits13Bits :: Int -> Bool, Integer -> Bool #-}
17{-# SPECIALIZE fits13Bits :: Int -> Bool, Integer -> Bool #-}
18−{-# SPECIALIZE fits13Bits ::
18+{-# SPECIALIZE fits13Bits
19− Int ->
19+ :: Int
20− Bool,
20+ -> Bool,
21 Integer -> Bool
21 Integer -> Bool
22 #-}
22 #-}
23fits13Bits :: Integral a => a -> Bool
23fits13Bits :: Integral a => a -> Bool
data/examples/declaration/signature/standalone-kind-out.hsdeleted−13
@@ -1,13 +0,0 @@
1−{-# LANGUAGE StandaloneKindSignatures #-}
2−
3−type T ::
4− (k -> Type) ->
5− k ->
6− Type
7−data T m a = MkT (m a) (T Maybe (m a))
8−
9−type C1 :: Type -> Constraint
10−class C1 a
11−
12−type F :: Type -> Type
13−type family F
data/examples/declaration/signature/standalone-kind.hsdeleted−13
@@ -1,13 +0,0 @@
1−{-# LANGUAGE StandaloneKindSignatures #-}
2−
3−type T :: (k -> Type)
4− -> k
5− -> Type
6−
7−data T m a = MkT (m a) (T Maybe (m a))
8−
9−type C1 :: Type -> Constraint
10−class C1 a
11−
12−type F :: Type -> Type
13−type family F
data/examples/declaration/signature/type/arguments-out.hs+13−14
@@ -1,16 +1,15 @@
1{-# LANGUAGE RankNTypes #-}
1{-# LANGUAGE RankNTypes #-}
2
2
3−functionName ::
3+functionName
4− (C1, C2, C3, C4, C5) =>
4+ :: (C1, C2, C3, C4, C5)
5− a ->
5+ => a
6− b ->
6+ -> b
7− ( forall a.
7+ -> ( forall a. (C6, C7)
8− (C6, C7) =>
9− LongDataTypeName ->
8+ => LongDataTypeName
10− a ->
9+ -> a
11− AnotherLongDataTypeName ->
10+ -> AnotherLongDataTypeName
12− b ->
11+ -> b
13− c
12+ -> c
14− ) ->
13+ )
15− (c -> d) ->
14+ -> (c -> d)
16− (a, b, c, d)
15+ -> (a, b, c, d)
data/examples/declaration/signature/type/context-multi-line-out.hs+10−10
@@ -1,10 +1,10 @@
1−functionName ::
1+functionName
2− ( C1,
2+ :: ( C1,
3− C2,
3+ C2,
4− C3
4+ C3
5+ )
5− ) =>
6+ => a
6− a ->
7− b ->
7+ -> b
8− c ->
8+ -> c
9− d ->
9+ -> d
10− (a, b, c, d)
10+ -> (a, b, c, d)
data/examples/declaration/signature/type/context-single-line-out.hs+7−7
@@ -1,7 +1,7 @@
1−functionName ::
1+functionName
2− (C1, C2, C3) =>
2+ :: (C1, C2, C3)
3− a ->
3+ => a
4− b ->
4+ -> b
5− c ->
5+ -> c
6− d ->
6+ -> d
7− (a, b, c, d)
7+ -> (a, b, c, d)
data/examples/declaration/signature/type/infix-promoted-type-constructor-out.hs+1
@@ -1,2 +1,3 @@
1fun1 :: Def ('[Ref s (Stored Uint32), IBool] 'T.:-> IBool)
1fun1 :: Def ('[Ref s (Stored Uint32), IBool] 'T.:-> IBool)
2+
2fun2 :: Def ('[Ref s (Stored Uint32), IBool] ':-> IBool)
3fun2 :: Def ('[Ref s (Stored Uint32), IBool] ':-> IBool)
data/examples/declaration/signature/type/long-function-name-out.hs+6−6
@@ -1,6 +1,6 @@
1−longFunctionName ::
1+longFunctionName
2− a ->
2+ :: a
3− b ->
3+ -> b
4− c ->
4+ -> c
5− d ->
5+ -> d
6− (a, b, c, d)
6+ -> (a, b, c, d)
data/examples/declaration/signature/type/long-multiline-applications-out.hs+15−16
@@ -1,16 +1,15 @@
1−functionName ::
1+functionName
2− (C1, C2, C3, C4, C5) =>
2+ :: (C1, C2, C3, C4, C5)
3− forall a b c.
3+ => a
4− a ->
4+ -> b
5− b ->
6− ( LongDataTypeName
5+ -> ( LongDataTypeName
7− AnotherLongDataTypeName
6+ AnotherLongDataTypeName
8− AnotherLongDataTypeName2
7+ AnotherLongDataTypeName2
9− AnotherLongDataTypeName3 ->
8+ AnotherLongDataTypeName3
10− a ->
9+ -> a
11− AnotherLongDataTypeName4 ->
10+ -> AnotherLongDataTypeName4
12− b ->
11+ -> b
13− c
12+ -> c
14− ) ->
13+ )
15− (c -> d) ->
14+ -> (c -> d)
16− (a, b, c, d)
15+ -> (a, b, c, d)
data/examples/declaration/signature/type/long-multiline-applications.hs+1−2
@@ -1,7 +1,6 @@
1functionName
1functionName
2 :: (C1, C2, C3, C4, C5)
2 :: (C1, C2, C3, C4, C5)
3− => forall a b c
4− . a
3+ => a
5 -> b
4 -> b
6 -> ( LongDataTypeName
5 -> ( LongDataTypeName
7 AnotherLongDataTypeName
6 AnotherLongDataTypeName
data/examples/declaration/signature/type/multi-value-out.hs+2−7
@@ -2,14 +2,9 @@ foo, bar :: Int
2foo = 1
2foo = 1
3bar = 2
3bar = 2
4
4
5−a, b, c :: Int
6−a = 1
7−b = 2
8−c = 3
9−
10foo,
5foo,
11 bar,
6 bar,
12− baz ::
7+ baz
13− Int
8+ :: Int
14bar = 2
9bar = 2
15baz = 3
10baz = 3
data/examples/declaration/signature/type/multi-value.hs−5
@@ -2,11 +2,6 @@ foo, bar :: Int
2foo = 1
2foo = 1
3bar = 2
3bar = 2
4
4
5−a, b, c :: Int
6−a = 1
7−b = 2
8−c = 3
9−
10foo,
5foo,
11 bar,
6 bar,
12 baz :: Int
7 baz :: Int
data/examples/declaration/signature/type/unicode-out.hsdeleted−4
@@ -1,4 +0,0 @@
1−{-# LANGUAGE UnicodeSyntax #-}
2−
3−foo :: forall a. Show a => a -> String
4−foo = const ()
data/examples/declaration/signature/type/unicode.hsdeleted−4
@@ -1,4 +0,0 @@
1−{-# LANGUAGE UnicodeSyntax #-}
2−
3−foo ∷ ∀a. Show a ⇒ a → String
4−foo = const ()
data/examples/declaration/signature/type/unrelated-out.hsdeleted−4
@@ -1,4 +0,0 @@
1−clientFunc1 :: SomeType1
2−clientFunc2 :: SomeType2
3−clientFunc3 :: SomeType3
4−clientFunc1 :<|> clientFunc2 :<|> clientFunc3 = hoistClient foo bar baz
data/examples/declaration/signature/type/unrelated.hsdeleted−4
@@ -1,4 +0,0 @@
1−clientFunc1 :: SomeType1
2−clientFunc2 :: SomeType2
3−clientFunc3 :: SomeType3
4−clientFunc1 :<|> clientFunc2 :<|> clientFunc3 = hoistClient foo bar baz
data/examples/declaration/splice/bracket-declaration-out.hs+1−1
@@ -23,4 +23,4 @@ $( singletons
23 data T = T
23 data T = T
24 deriving (Eq, Ord, Enum, Bounded, Show)
24 deriving (Eq, Ord, Enum, Bounded, Show)
25 |]
25 |]
26− )
26+ )
data/examples/declaration/splice/grouped-splices-out.hsdeleted−3
@@ -1,3 +0,0 @@
1−$(deriveJSON fieldLabelMod ''A)
2−$(deriveJSON fieldLabelMod ''B)
3−$(deriveJSON fieldLabelMod ''C)
data/examples/declaration/splice/grouped-splices.hsdeleted−3
@@ -1,3 +0,0 @@
1−$(deriveJSON fieldLabelMod ''A)
2−$(deriveJSON fieldLabelMod ''B)
3−$(deriveJSON fieldLabelMod ''C)
data/examples/declaration/splice/splice-decl.hs+1
@@ -15,3 +15,4 @@ foo bar
15-- TemplateHaskell allows Q () at the top level
15-- TemplateHaskell allows Q () at the top level
16do
16do
17 pure []
17 pure []
18+
data/examples/declaration/splice/typed-splice-out.hs+1−1
@@ -2,6 +2,6 @@
2
2
3x =
3x =
4 $$( foo bar
4 $$( foo bar
5− )
5+ )
6
6
7x = $$foo
7x = $$foo
data/examples/declaration/splice/untyped-splice-out.hs+1−1
@@ -5,6 +5,6 @@ x = $(foo bar)
5x =
5x =
6 $( foo
6 $( foo
7 bar
7 bar
8− )
8+ )
9
9
10x = $foo
10x = $foo
data/examples/declaration/type-families/closed-type-family/multi-line-out.hs+8−9
@@ -1,7 +1,7 @@
1type family
1type family
2− Id a =
2+ Id a
3− result | result -> a
3+ = result
4− where
4+ | result -> a where
5 Id a =
5 Id a =
6 a
6 a
7
7
@@ -9,16 +9,15 @@ type family
9 G
9 G
10 (a :: k)
10 (a :: k)
11 b
11 b
12− c =
12+ c
13− foo | foo -> k b
13+ = foo
14− where
14+ | foo -> k b where
15 G a b c =
15 G a b c =
16 (a, b)
16 (a, b)
17
17
18type family
18type family
19− F a ::
19+ F a
20− * -> *
21− where
20+ :: * -> * where
22 F Int = Double
21 F Int = Double
23 F Bool =
22 F Bool =
24 Char
23 Char
data/examples/declaration/type-families/closed-type-family/simple-out.hs−2
@@ -1,5 +1,3 @@
1−module Main where
2−
3-- | Documentation.
1-- | Documentation.
4type family F a :: * -> * where
2type family F a :: * -> * where
5 F Int = Double
3 F Int = Double
data/examples/declaration/type-families/closed-type-family/simple.hs−2
@@ -1,5 +1,3 @@
1−module Main where
2−
3-- | Documentation.
1-- | Documentation.
4
2
5type family F a :: * -> * where
3type family F a :: * -> * where
data/examples/declaration/type-families/closed-type-family/with-equal-sign-out.hsdeleted−2
@@ -1,2 +0,0 @@
1−type family TF a b = result where
2− TF a b = Int
data/examples/declaration/type-families/closed-type-family/with-equal-sign.hsdeleted−2
@@ -1,2 +0,0 @@
1−type family TF a b = result where
2− TF a b = Int
data/examples/declaration/type-families/closed-type-family/with-forall-out.hsdeleted−3
@@ -1,3 +0,0 @@
1−type family G a b where
2− forall x y. G [x] (Proxy y) = Double
3− forall z. z `G` z = Bool
data/examples/declaration/type-families/closed-type-family/with-forall.hsdeleted−3
@@ -1,3 +0,0 @@
1−type family G a b where
2− forall x y. G [x] (Proxy y) = Double
3− forall z. z `G` z = Bool
data/examples/declaration/type-families/data-family/no-annotation-out.hs−2
@@ -1,4 +1,2 @@
1−module Main where
2−
3-- | Documentation.
1-- | Documentation.
4data family Array e
2data family Array e
data/examples/declaration/type-families/data-family/no-annotation.hs−2
@@ -1,5 +1,3 @@
1−module Main where
2−
3-- | Documentation.
1-- | Documentation.
4
2
5data family Array e
3data family Array e
data/examples/declaration/type-families/data-family/simple-out.hs−2
@@ -1,4 +1,2 @@
1−module Main where
2−
3-- | Documentation.
1-- | Documentation.
4data family GMap k :: Type -> Type
2data family GMap k :: Type -> Type
data/examples/declaration/type-families/data-family/simple.hs−2
@@ -1,5 +1,3 @@
1−module Main where
2−
3-- | Documentation.
1-- | Documentation.
4
2
5data family GMap k :: Type -> Type
3data family GMap k :: Type -> Type
data/examples/declaration/type-families/type-family/no-annotation-out.hs−2
@@ -1,4 +1,2 @@
1−module Main where
2−
3-- | Documentation.
1-- | Documentation.
4type family F a b :: Type -> Type
2type family F a b :: Type -> Type
data/examples/declaration/type-families/type-family/no-annotation.hs−2
@@ -1,5 +1,3 @@
1−module Main where
2−
3-- | Documentation.
1-- | Documentation.
4
2
5type family F a b :: Type -> Type
3type family F a b :: Type -> Type
data/examples/declaration/type-families/type-family/operator-out.hsdeleted−3
@@ -1,3 +0,0 @@
1−type family a ! b
2−
3−type family a . b
data/examples/declaration/type-families/type-family/operator.hsdeleted−2
@@ -1,2 +0,0 @@
1−type family a ! b
2−type family a . b
data/examples/declaration/type-families/type-family/simple-out.hs−2
@@ -1,4 +1,2 @@
1−module Main where
2−
3-- | Documentation.
1-- | Documentation.
4type family Elem c :: Type
2type family Elem c :: Type
data/examples/declaration/type-families/type-family/simple.hs−2
@@ -1,5 +1,3 @@
1−module Main where
2−
3-- | Documentation.
1-- | Documentation.
4
2
5type family Elem c :: Type
3type family Elem c :: Type
data/examples/declaration/type-synonyms/multi-line-out.hs+15−12
@@ -1,18 +1,21 @@
1−type Foo a b c =
1+type Foo a b c
2− Bar c a b
2+ = Bar c a b
3
3
4type Foo
4type Foo
5 a
5 a
6 b
6 b
7− c =
7+ c
8− Bar c a b
8+ = Bar c a b
9
9
10−type Foo =
10+type Foo
11− Bar
11+ = Bar
12− Baz
12+ Baz
13− Quux
13+ Quux
14
14
15−type API =
15+type API
16− "route1" :> ApiRoute1
16+ = "route1" :> ApiRoute1
17+ :<|> "route2"
17− :<|> "route2" :> ApiRoute2 -- comment here
18+ :> ApiRoute2 -- comment here
19+ :<|> OmitDocs
20+ :> "i"
18− :<|> OmitDocs :> "i" :> ASomething API
21+ :> ASomething API
data/examples/declaration/type-synonyms/multi-line.hs+3
@@ -15,3 +15,6 @@ type API
15 = "route1" :> ApiRoute1
15 = "route1" :> ApiRoute1
16 :<|> "route2" :> ApiRoute2 -- comment here
16 :<|> "route2" :> ApiRoute2 -- comment here
17 :<|> OmitDocs :> "i" :> ASomething API
17 :<|> OmitDocs :> "i" :> ASomething API
18+
19+
20+
data/examples/declaration/type-synonyms/simple-out.hs−2
@@ -1,5 +1,3 @@
1−module Main where
2−
3-- | Documentation.
1-- | Documentation.
4type Foo a b c = Bar c a b
2type Foo a b c = Bar c a b
5
3
data/examples/declaration/type-synonyms/simple.hs−2
@@ -1,5 +1,3 @@
1−module Main where
2−
3-- | Documentation.
1-- | Documentation.
4
2
5type Foo a b c = Bar c a b
3type Foo a b c = Bar c a b
data/examples/declaration/type-synonyms/with-weird-haddock-out.hsdeleted−3
@@ -1,3 +0,0 @@
1−type Elims =
2− -- | eliminations ordered left-to-right.
3− [Elim]
data/examples/declaration/type-synonyms/with-weird-haddock.hsdeleted−1
@@ -1 +0,0 @@
1−type Elims = [Elim] -- ^ eliminations ordered left-to-right.
data/examples/declaration/type/forall-out.hsdeleted−4
@@ -1,4 +0,0 @@
1−type CoerceLocalSig m m' =
2− forall r a.
3− LocalSig m r a ->
4− LocalSig m' r a
data/examples/declaration/type/forall.hsdeleted−4
@@ -1,4 +0,0 @@
1−type CoerceLocalSig m m' =
2− forall r a.
3− LocalSig m r a ->
4− LocalSig m' r a
data/examples/declaration/type/lits-out.hsdeleted−6
@@ -1,6 +0,0 @@
1−type A = "foo"
2−
3−type B =
4− "foo\
5− \bar" ->
6− ()
data/examples/declaration/type/lits.hsdeleted−4
@@ -1,4 +0,0 @@
1−type A = "foo"
2−
3−type B = "foo\
4− \bar" -> ()
data/examples/declaration/type/type-applications-out.hsdeleted−3
@@ -1,3 +0,0 @@
1−{-# LANGUAGE TypeApplications #-}
2−
3−type P = K @Bool @(Bool :: *) 'True 'False
data/examples/declaration/type/type-applications.hsdeleted−3
@@ -1,3 +0,0 @@
1−{-# LANGUAGE TypeApplications #-}
2−
3−type P = K @Bool @(Bool :: *) 'True 'False
data/examples/declaration/type/visible-forall-out.hsdeleted−2
@@ -1,2 +0,0 @@
1−-- source: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0081-forall-arrow.rst
2−data T :: forall k -> k -> Type
data/examples/declaration/type/visible-forall.hsdeleted−2
@@ -1,2 +0,0 @@
1−-- source: https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0081-forall-arrow.rst
2−data T :: forall k -> k -> Type
data/examples/declaration/value/function/application-0-out.hsdeleted−17
@@ -1,17 +0,0 @@
1−foo =
2− f1
3− p1
4− p2
5− p3
6−
7−foo' =
8− f2
9− p1
10− p2
11− p3
12−
13−foo'' =
14− f3
15− p1
16− p2
17− p3
data/examples/declaration/value/function/application-0.hsdeleted−12
@@ -1,12 +0,0 @@
1−foo =
2− f1
3− p1
4− p2 p3
5−
6−foo' = f2 p1
7− p2
8− p3
9−
10−foo'' =
11− f3 p1 p2
12− p3
data/examples/declaration/value/function/application-1-out.hsdeleted−19
@@ -1,19 +0,0 @@
1−main =
2− do
3− x
4− y
5− z
6−
7−main =
8− case foo of
9− x -> a
10− foo
11− a
12− b
13−
14−main =
15− do
16− if x then y else z
17− foo
18− a
19− b
data/examples/declaration/value/function/application-1.hsdeleted−14
@@ -1,14 +0,0 @@
1−main =
2− do
3− x
4− y
5− z
6−
7−main =
8− case foo of
9− x -> a
10− foo a b
11−
12−main = do
13− if x then y else z
14− foo a b
data/examples/declaration/value/function/arg-breakpoints-out.hsdeleted−3
@@ -1,3 +0,0 @@
1−foo
2− bar =
3− body
data/examples/declaration/value/function/arg-breakpoints.hsdeleted−3
@@ -1,3 +0,0 @@
1−foo
2− bar =
3− body
data/examples/declaration/value/function/arithmetic-sequences-out.hs+2−2
@@ -5,13 +5,13 @@ foo' = [0 .. 5]
5bar x =
5bar x =
6 [ 0
6 [ 0
7 .. x
7 .. x
8− ]
8+ ]
9
9
10baz x =
10baz x =
11 [ 1,
11 [ 1,
12 3
12 3
13 .. x
13 .. x
14− ]
14+ ]
15
15
16barbaz x = [0, 1 ..]
16barbaz x = [0, 1 ..]
17
17
data/examples/declaration/value/function/arrow/expression-applications-out.hsnew file+9
@@ -0,0 +1,9 @@
1+{-# LANGUAGE Arrows #-}
2+
3+foo x y = x -< y
4+
5+bar f x =
6+ f x -< -- Hello
7+ x -- World
8+
9+baz x y = x -<< y
data/examples/declaration/value/function/arrow/expression-applications.hsnew file+9
@@ -0,0 +1,9 @@
1+{-# LANGUAGE Arrows #-}
2+
3+foo x y = x -< y
4+
5+bar f x
6+ = f x -- Hello
7+ -< x -- World
8+
9+baz x y = x -<< y
data/examples/declaration/value/function/arrow/expression-forms-out.hsnew file+13
@@ -0,0 +1,13 @@
1+{-# LANGUAGE Arrows #-}
2+
3+foo f g x y = (|test (f -< x) (g -< y)|)
4+
5+bar f g x y =
6+ (| test
7+ ( f -<
8+ x
9+ )
10+ ( g -<
11+ y
12+ )
13+ |)
data/examples/declaration/value/function/arrow/expression-forms.hsnew file+11
@@ -0,0 +1,11 @@
1+{-# LANGUAGE Arrows #-}
2+
3+foo f g x y = (| test (f -< x) (g -< y) |)
4+
5+bar f g x y = (|
6+ test
7+ (f
8+ -< x)
9+ (g
10+ -< y)
11+ |)
data/examples/declaration/value/function/arrow/multiline-case-out.hsdeleted−8
@@ -1,8 +0,0 @@
1−{-# LANGUAGE Arrows #-}
2−
3−f = proc x -> do
4− x <-
5− case x of X -> x
6− -<
7− y
8− a -< b
data/examples/declaration/value/function/arrow/multiline-case.hsdeleted−7
@@ -1,7 +0,0 @@
1−{-# LANGUAGE Arrows #-}
2−
3−f = proc x -> do
4− x
5− <- case x of X -> x
6− -< y
7− a -< b
data/examples/declaration/value/function/arrow/proc-applications-out.hs+4−5
@@ -9,11 +9,10 @@ bar f x =
9 w
9 w
10 )
10 )
11 ->
11 ->
12− f -- The value
12+ f -< -- The value
13− -<
14− ( x, -- Foo
13+ ( x, -- Foo
15− w, -- Bar
14+ w, -- Bar
16− z -- Baz
15+ z -- Baz
17 )
16 )
18
17
19baz x = proc a -> a -<< x
18baz x = proc a -> a -<< x
data/examples/declaration/value/function/arrow/proc-do-complex-out.hs+26−27
@@ -16,16 +16,16 @@ foo
16 f -- Call into f
16 f -- Call into f
17 ( a,
17 ( a,
18 c -- Tuple together arguments
18 c -- Tuple together arguments
19− )
19+ )
20 ( b,
20 ( b,
21 d
21 d
22− )
23− -<
22+ ) -<
24− ( b + 1, -- Funnel into arrow
23+ ( b + 1, -- Funnel into arrow
25− d * b
24+ d * b
26 )
25 )
27 if x `mod` y == 0 -- Basic condition
26 if x `mod` y == 0 -- Basic condition
27+ then
28− then case e of -- Only left case is relevant
28+ case e of -- Only left case is relevant
29 Left
29 Left
30 ( z,
30 ( z,
31 w
31 w
@@ -33,30 +33,29 @@ foo
33 let v =
33 let v =
34 u -- Actually never used
34 u -- Actually never used
35 ^ 2
35 ^ 2
36− in ( returnA
36+ in ( returnA -<
37− -<
38− -- Just do the calculation
37+ -- Just do the calculation
39− (x + y * z)
38+ (x + y * z)
40− )
39+ )
40+ else
41− else do
41+ do
42 let u = x -- Let bindings bind expressions, not commands
42 let u = x -- Let bindings bind expressions, not commands
43− -- Could pattern match directly on x
43+ -- Could pattern match directly on x
44+ i <-
44− i <- case u of
45+ case u of
45− 0 -> (g . h -< u)
46+ 0 -> (g . h -< u)
46− n ->
47+ n ->
47− ( ( h . g
48+ ( ( h . g -<
48− -<
49 y -- First actual use of y
49 y -- First actual use of y
50− )
50+ )
51− )
51+ )
52 returnA -< ()
52 returnA -< ()
53 -- Sometimes execute effects
53 -- Sometimes execute effects
54 if i > 0
54 if i > 0
55− then ma -< ()
55+ then ma -< ()
56− else returnA -< ()
56+ else returnA -< ()
57− returnA
57+ returnA -<
58− -<
59− ( i
58+ ( i
60− + x
59+ + x
61− * y -- Just do the calculation
60+ * y -- Just do the calculation
62 )
61 )
data/examples/declaration/value/function/arrow/proc-do-simple1-out.hs+2−3
@@ -13,6 +13,5 @@ barbaz f g = proc (a, b) -> do
13
13
14bazbar f = proc a -> do
14bazbar f = proc a -> do
15 a <-
15 a <-
16− f
16+ f -<
17− -<
18− a
17+ a
data/examples/declaration/value/function/arrow/proc-do-simple2-out.hs+6−8
@@ -11,12 +11,10 @@ bazbaz f g h = proc (a, b, c) -> do
11 z <-
11 z <-
12 h
12 h
13 x
13 x
14− y
14+ y -<
15− -<
16− ( a,
15+ ( a,
17− b,
16+ b,
18− c
17+ c
19 )
18 )
20− returnA
19+ returnA -<
21− -<
22− (x, y, z)
20+ (x, y, z)
data/examples/declaration/value/function/arrow/proc-forms1-out.hs+13−16
@@ -1,21 +1,18 @@
1{-# LANGUAGE Arrows #-}
1{-# LANGUAGE Arrows #-}
2
2
3−foo0 f g x y = proc _ -> (| f (g -< (x, y)) |)
3+foo0 f g x y = proc _ -> (|f (g -< (x, y))|)
4
4
5foo1 f g h x =
5foo1 f g h x =
6 proc (y, z) ->
6 proc (y, z) ->
7− (|
8− test
7+ (| test
9− ( h f
8+ ( h f
10− . h g
9+ . h g -<
11− -<
12− y x
10+ y x
13− . y z
11+ . y z
14− )
12+ )
15− ( h g
13+ ( h g
16− . h f
14+ . h f -<
17− -<
18− y z
15+ y z
19− . y x
16+ . y x
20− )
17+ )
21− |)
18+ |)
data/examples/declaration/value/function/arrow/proc-forms2-out.hs+7−11
@@ -2,21 +2,17 @@
2
2
3bar0 f g h x =
3bar0 f g h x =
4 proc (y, z) ->
4 proc (y, z) ->
5− (| test (h f . (h g) -< (y x) . y z) ((h g) . h f -< y z . (y x)) |)
5+ (|test (h f . (h g) -< (y x) . y z) ((h g) . h f -< y z . (y x))|)
6
6
7−bar1 f g x y = proc _ -> (f -< x) &&& (g -< y)
7+bar1 f g x y = proc _ -> f -< x &&& g -< y
8
8
9bar2 f g h x =
9bar2 f g h x =
10 proc (y, z) ->
10 proc (y, z) ->
11− (h f . (h g) -< (y x) . y z) ||| ((h g) . h f -< y z . (y x))
11+ h f . (h g) -< (y x) . y z ||| (h g) . h f -< y z . (y x)
12
12
13bar3 f g h x =
13bar3 f g h x =
14 proc (y, z) ->
14 proc (y, z) ->
15− ( (h f . h g)
15+ (h f . h g) -<
16− -<
17− (y x) . y z
16+ (y x) . y z
18− ) |||
19− ( (h g . h f)
17+ ||| (h g . h f) -<
20− -<
21− y z . (y x)
18+ y z . (y x)
22− )
data/examples/declaration/value/function/arrow/proc-forms2.hs+6−6
@@ -4,16 +4,16 @@ bar0 f g h x =
4 proc (y, z) ->
4 proc (y, z) ->
5 (| test (h f.(h g) -< (y x).y z)((h g) . h f-<y z . (y x)) |)
5 (| test (h f.(h g) -< (y x).y z)((h g) . h f-<y z . (y x)) |)
6
6
7−bar1 f g x y = proc _ -> (f -< x)&&&(g -< y)
7+bar1 f g x y = proc _ -> f -< x&&&g -< y
8
8
9bar2 f g h x =
9bar2 f g h x =
10 proc (y, z) ->
10 proc (y, z) ->
11− (h f.(h g) -< (y x).y z) ||| ((h g) . h f-<y z . (y x))
11+ h f.(h g) -< (y x).y z ||| (h g) . h f-<y z . (y x)
12
12
13bar3 f g h x =
13bar3 f g h x =
14 proc (y, z) ->
14 proc (y, z) ->
15− ((h f.h g)
15+ (h f.h g)
16− -< (y x).y z)
16+ -< (y x).y z
17 |||
17 |||
18− ((h g . h f)
18+ (h g . h f)
19− -<y z . (y x))
19+ -<y z . (y x)
data/examples/declaration/value/function/arrow/proc-ifs-out.hs+7−9
@@ -4,12 +4,10 @@ foo f = proc a -> if a then f -< 0 else f -< 1
4
4
5bar f g = proc a ->
5bar f g = proc a ->
6 if f a
6 if f a
7− then
7+ then
8− f
8+ f
9− . g
9+ . g -<
10− -<
11− a
10+ a
12− else
11+ else
13− g
12+ g -<
14− -<
15− b
13+ b
data/examples/declaration/value/function/arrow/proc-lets-out.hs+1−1
@@ -9,4 +9,4 @@ bar f g = proc a ->
9 j =
9 j =
10 g
10 g
11 . h
11 . h
12− in id -< (h, j)
12+ in id -< (h, j)
data/examples/declaration/value/function/arrow/proc-parentheses-out.hs+5−6
@@ -5,15 +5,14 @@ foo f = proc a -> (f -< a)
5bar f g = proc a ->
5bar f g = proc a ->
6 ( ( (f)
6 ( ( (f)
7 ( g
7 ( g
8− )
9− )
8+ )
10− -<
9+ ) -<
11− ( ( ( ( ( ( g
10+ ( ( ( ( ( ( g
12− a
11+ a
13 )
12 )
14 )
13 )
15 )
14 )
16 )
15 )
17 )
16 )
18 )
17 )
19− )
18+ )
data/examples/declaration/value/function/arrow/recursive-procs-out.hs+9−13
@@ -3,21 +3,17 @@
3foo f g = proc (x, y) -> do
3foo f g = proc (x, y) -> do
4 rec a <- f y -< x
4 rec a <- f y -< x
5 b <-
5 b <-
6− g x
6+ g x -<
7− -<
8− y
7+ y
9− bar
8+ bar -<
10− -<
11− ( a,
9+ ( a,
12− b
10+ b
13 )
11 )
14 rec p <-
12 rec p <-
15 f
13 f
16− p
14+ p -<
17− -<
18− a
15+ a
19 rec q <-
16 rec q <-
20 g
17 g
21− q
18+ q -<
22− -<
23− b
19+ b
data/examples/declaration/value/function/awkward-comment-0-out.hsdeleted−6
@@ -1,6 +0,0 @@
1−mergeErrorReply :: ParseError -> Reply s u a -> Reply s u a
2−mergeErrorReply err1 reply -- XXX where to put it?
3− =
4− case reply of
5− Ok x state err2 -> Ok x state (mergeError err1 err2)
6− Error err2 -> Error (mergeError err1 err2)
data/examples/declaration/value/function/awkward-comment-0.hsdeleted−5
@@ -1,5 +0,0 @@
1−mergeErrorReply :: ParseError -> Reply s u a -> Reply s u a
2−mergeErrorReply err1 reply -- XXX where to put it?
3− = case reply of
4− Ok x state err2 -> Ok x state (mergeError err1 err2)
5− Error err2 -> Error (mergeError err1 err2)
data/examples/declaration/value/function/awkward-comment-1-out.hsdeleted−9
@@ -1,9 +0,0 @@
1−doForeign :: Vars -> [Name] -> [Term] -> Idris LExp
2−doForeign x = x
3− where
4− splitArg tm | (_, [_, _, l, r]) <- unApply tm -- pair, two implicits
5− =
6− do
7− let l' = toFDesc l
8− r' <- irTerm (sMN 0 "__foreignCall") vs env r
9− return (l', r')
data/examples/declaration/value/function/awkward-comment-1.hsdeleted−7
@@ -1,7 +0,0 @@
1−doForeign :: Vars -> [Name] -> [Term] -> Idris LExp
2−doForeign x = x
3− where
4− splitArg tm | (_, [_,_,l,r]) <- unApply tm -- pair, two implicits
5− = do let l' = toFDesc l
6− r' <- irTerm (sMN 0 "__foreignCall") vs env r
7− return (l', r')
data/examples/declaration/value/function/blank-lines-let-out.hsdeleted−6
@@ -1,6 +0,0 @@
1−foo =
2− let x = 10
3−
4− y = 11
5− z = 12
6− in x + y + z
data/examples/declaration/value/function/blank-lines-let.hsdeleted−9
@@ -1,9 +0,0 @@
1−foo =
2− let
3−
4− x = 10
5−
6− y = 11
7− z = 12
8−
9− in x + y + z
data/examples/declaration/value/function/blank-lines-where-out.hsdeleted−6
@@ -1,6 +0,0 @@
1−foo = x + y + z
2− where
3− x = 10
4−
5− y = 11
6− z = 12
data/examples/declaration/value/function/blank-lines-where.hsdeleted−7
@@ -1,7 +0,0 @@
1−foo = x + y + z
2− where
3−
4− x = 10
5−
6− y = 11
7− z = 12
data/examples/declaration/value/function/block-arguments-out.hs+10−14
@@ -1,11 +1,13 @@
1f1 = foo do bar
1f1 = foo do bar
2
2
3+f2 =
3−f2 = foo do
4+ foo do
4− bar
5+ bar
5
6
7+f3 =
6−f3 = foo case True of
8+ foo case True of
7− True -> bar
9+ True -> bar
8− False -> baz
10+ False -> baz
9
11
10f4 = foo let a = 3 in b
12f4 = foo let a = 3 in b
11
13
@@ -23,12 +25,6 @@ f6 =
23
25
24f7 = foo \x -> y
26f7 = foo \x -> y
25
27
28+f8 =
26−f8 = foo \x ->
29+ foo \x ->
27− y
30+ y
28−
29−f9 = foo do { bar } baz
30−
31−f10 = foo
32− do a
33− do b
34− do c
data/examples/declaration/value/function/block-arguments.hs−7
@@ -21,10 +21,3 @@ f7 = foo \x -> y
21
21
22f8 = foo \x ->
22f8 = foo \x ->
23 y
23 y
24−
25−f9 = foo do { bar } baz
26−
27−f10 = foo
28− do { a }
29− do { b }
30− do c
data/examples/declaration/value/function/case-multi-line-guards-out.hs+2−4
@@ -9,8 +9,6 @@ withGuards x =
9 _ -> 20
9 _ -> 20
10
10
11case x of
11case x of
12− '-' | not isUrl -> case xs of
12+ '-' | not isUrl ->
13− _ -> emitc '-'
14− '*' | not isUrl ->
15 case xs of
13 case xs of
16− _ -> emitc '*'
14+ _ -> emitc '-'
data/examples/declaration/value/function/case-multi-line-guards.hs−3
@@ -10,6 +10,3 @@ withGuards x =
10case x of
10case x of
11 '-' | not isUrl -> case xs of
11 '-' | not isUrl -> case xs of
12 _ -> emitc '-'
12 _ -> emitc '-'
13− '*' | not isUrl ->
14− case xs of
15− _ -> emitc '*'
data/examples/declaration/value/function/complex-list-out.hs+2−2
@@ -4,7 +4,7 @@ handleStuff =
4 something,
4 something,
5 \ExceptionB ->
5 \ExceptionB ->
6 somethingElse
6 somethingElse
7− ]
7+ ]
8
8
9handleStuff =
9handleStuff =
10 handle
10 handle
@@ -12,4 +12,4 @@ handleStuff =
12 bar,
12 bar,
13 baz
13 baz
14 qux
14 qux
15− ]
15+ ]
data/examples/declaration/value/function/comprehension/transform-multi-line1-out.hs+4−5
@@ -3,10 +3,9 @@
3foo' xs ys =
3foo' xs ys =
4 [ ( x,
4 [ ( x,
5 y
5 y
6− )
6+ )
7 | x <- xs,
7 | x <- xs,
8 y <- ys,
8 y <- ys,
9− then
10− -- First comment
9+ -- First comment
11− reverse -- Second comment
10+ then reverse -- Second comment
12− ]
11+ ]
data/examples/declaration/value/function/comprehension/transform-multi-line2-out.hs+5−6
@@ -3,14 +3,13 @@
3bar' xs ys =
3bar' xs ys =
4 [ ( x,
4 [ ( x,
5 y
5 y
6− )
6+ )
7 | x <- xs,
7 | x <- xs,
8 y <- ys,
8 y <- ys,
9− then
10− -- First comment
9+ -- First comment
11− sortWith
10+ then sortWith
12 by
11 by
13 ( x
12 ( x
14 + y -- Second comment
13 + y -- Second comment
15− )
14+ )
16− ]
15+ ]
data/examples/declaration/value/function/comprehension/transform-multi-line3-out.hs+4−5
@@ -3,10 +3,9 @@
3baz' xs ys =
3baz' xs ys =
4 [ ( x,
4 [ ( x,
5 y
5 y
6− )
6+ )
7 | x <- xs,
7 | x <- xs,
8 y <- ys,
8 y <- ys,
9− then group using
9+ -- First comment
10− -- First comment
11− permutations -- Second comment
10+ then group using permutations -- Second comment
12− ]
11+ ]
data/examples/declaration/value/function/comprehension/transform-multi-line3.hs+1
@@ -10,3 +10,4 @@ baz' xs ys = [
10 using -- First comment
10 using -- First comment
11 permutations -- Second comment
11 permutations -- Second comment
12 ]
12 ]
13+
data/examples/declaration/value/function/comprehension/transform-multi-line4-out.hs+6−7
@@ -3,15 +3,14 @@
3quux' xs ys =
3quux' xs ys =
4 [ ( x,
4 [ ( x,
5 y
5 y
6− )
6+ )
7 | x <- xs,
7 | x <- xs,
8 y <- ys,
8 y <- ys,
9+ -- First comment
9 then group by
10 then group by
10− -- First comment
11 ( x
11 ( x
12 + y
12 + y
13− )
13+ )
14− using
14+ -- Second comment
15− -- Second comment
16− groupWith -- Third comment
15+ using groupWith -- Third comment
17− ]
16+ ]
data/examples/declaration/value/function/do/applications-and-parens-out.hsdeleted−9
@@ -1,9 +0,0 @@
1−warningFor var place = do
2− guard $ isVariableName var
3− guard . not $ isInArray var place || isGuarded place
4− ( if includeGlobals || isLocal var
5− then warningForLocals
6− else warningForGlobals
7− )
8− var
9− place
data/examples/declaration/value/function/do/applications-and-parens.hsdeleted−6
@@ -1,6 +0,0 @@
1−warningFor var place = do
2− guard $ isVariableName var
3− guard . not $ isInArray var place || isGuarded place
4− (if includeGlobals || isLocal var
5− then warningForLocals
6− else warningForGlobals) var place
data/examples/declaration/value/function/do/blocks-out.hs−1
@@ -15,5 +15,4 @@ readInClause = do
15 <|> do
15 <|> do
16 optional g_Semi
16 optional g_Semi
17 void allspacing
17 void allspacing
18−
19 return things
18 return things
data/examples/declaration/value/function/do/comment-alignment-out.hsdeleted−9
@@ -1,9 +0,0 @@
1−main = do
2− case blah of
3− Nothing -> return ()
4− Just xs -> do
5− forM_ xs foo
6− bar
7− -- and here it goes
8− unless bobla $
9− quux
data/examples/declaration/value/function/do/comment-alignment.hsdeleted−9
@@ -1,9 +0,0 @@
1−main = do
2− case blah of
3− Nothing -> return ()
4− Just xs -> do
5− forM_ xs foo
6− bar
7− -- and here it goes
8− unless bobla $
9− quux
data/examples/declaration/value/function/do/comment-spacing-out.hsdeleted−7
@@ -1,7 +0,0 @@
1−foo = do
2− bar
3− -- foo
4− baz
5−
6− -- foo
7− quux
data/examples/declaration/value/function/do/comment-spacing.hsdeleted−7
@@ -1,7 +0,0 @@
1−foo = do
2− bar
3− -- foo
4− baz
5−
6− -- foo
7− quux
data/examples/declaration/value/function/do/expr.hs+1
@@ -8,3 +8,4 @@ quux = something $ do
8 then x
8 then x
9 else y
9 else y
10 baz
10 baz
11+
data/examples/declaration/value/function/do/hang-rhs-arrow-out.hsdeleted−9
@@ -1,9 +0,0 @@
1−foo = do
2− something <- case bar of
3− Foo -> return 1
4− Bar -> return 2
5− somethingElse <-
6− case boom of
7− Foo -> return 1
8− Bar -> return 2
9− quux something somethingElse
data/examples/declaration/value/function/do/hang-rhs-arrow.hsdeleted−9
@@ -1,9 +0,0 @@
1−foo = do
2− something <- case bar of
3− Foo -> return 1
4− Bar -> return 2
5− somethingElse <-
6− case boom of
7− Foo -> return 1
8− Bar -> return 2
9− quux something somethingElse
data/examples/declaration/value/function/do/hanging-out.hsnew file

No changes to the content.

data/examples/declaration/value/function/do/hanging.hsnew file

No changes to the content.

data/examples/declaration/value/function/do/operator-and-parens-out.hsdeleted−7
@@ -1,7 +0,0 @@
1−scientifically :: (Scientific -> a) -> Parser a
2−scientifically h = do
3− something
4− ( I.satisfy (\w -> w == 'e' || w == 'E')
5− *> fmap (h . Sci.scientific signedCoeff . (e +)) (signed decimal)
6− )
7− <|> return (h $ Sci.scientific signedCoeff e)
data/examples/declaration/value/function/do/operator-and-parens.hsdeleted−7
@@ -1,7 +0,0 @@
1−scientifically :: (Scientific -> a) -> Parser a
2−scientifically h = do
3− something
4− ( I.satisfy (\w -> w == 'e' || w == 'E')
5− *> fmap (h . Sci.scientific signedCoeff . (e +)) (signed decimal)
6− )
7− <|> return (h $ Sci.scientific signedCoeff e)
data/examples/declaration/value/function/do/recursive-do-rec-out.hs−5
@@ -2,18 +2,13 @@
2
2
3foo = do
3foo = do
4 rec a <- b + 5
4 rec a <- b + 5
5−
6 let d = c
5 let d = c
7−
8 b <- a * 5
6 b <- a * 5
9−
10 something
7 something
11−
12 c <- a + b
8 c <- a + b
13 print c
9 print c
14 rec something $ do
10 rec something $ do
15 x <- a
11 x <- a
16 print x
12 print x
17−
18 y <- c
13 y <- c
19 print y
14 print y
data/examples/declaration/value/function/explicit-type-out.hs+2−2
@@ -1,5 +1,5 @@
1foo = 5 :: Int
1foo = 5 :: Int
2
2
3bar =
3bar =
4− 5 ::
4+ 5
5− Int
5+ :: Int
data/examples/declaration/value/function/fancy-forall-0-out.hsdeleted−10
@@ -1,10 +0,0 @@
1−wrapError ::
2− forall outertag innertag t outer inner m a.
3− ( forall x. Coercible (t m x) (m x),
4− forall m'.
5− HasCatch outertag outer m' =>
6− HasCatch innertag inner (t m'),
7− HasCatch outertag outer m
8− ) =>
9− (forall m'. HasCatch innertag inner m' => m' a) ->
10− m a
data/examples/declaration/value/function/fancy-forall-0.hsdeleted−6
@@ -1,6 +0,0 @@
1−wrapError :: forall outertag innertag t outer inner m a.
2− ( forall x. Coercible (t m x) (m x)
3− , forall m'. HasCatch outertag outer m'
4− => HasCatch innertag inner (t m')
5− , HasCatch outertag outer m )
6− => (forall m'. HasCatch innertag inner m' => m' a) -> m a
data/examples/declaration/value/function/fancy-forall-1-out.hsdeleted−10
@@ -1,10 +0,0 @@
1−magnify ::
2− forall outertag innertag t outer inner m a.
3− ( forall x. Coercible (t m x) (m x),
4− forall m'.
5− HasReader outertag outer m' =>
6− HasReader innertag inner (t m'),
7− HasReader outertag outer m
8− ) =>
9− (forall m'. HasReader innertag inner m' => m' a) ->
10− m a
data/examples/declaration/value/function/fancy-forall-1.hsdeleted−6
@@ -1,6 +0,0 @@
1−magnify :: forall outertag innertag t outer inner m a.
2− ( forall x. Coercible (t m x) (m x)
3− , forall m'. HasReader outertag outer m'
4− => HasReader innertag inner (t m')
5− , HasReader outertag outer m )
6− => (forall m'. HasReader innertag inner m' => m' a) -> m a
data/examples/declaration/value/function/if-with-comment-out.hsdeleted−8
@@ -1,8 +0,0 @@
1−foo =
2− if undefined
3− then -- then comment
4− undefined
5− else -- else comment
6−
7− do
8− undefined
data/examples/declaration/value/function/if-with-comment.hsdeleted−8
@@ -1,8 +0,0 @@
1−foo =
2− if undefined
3− -- then comment
4− then undefined
5− -- else comment
6− else
7− do
8− undefined
data/examples/declaration/value/function/implicit-params-out.hs+7−8
@@ -1,16 +1,15 @@
1{-# LANGUAGE ImplicitParams #-}
1{-# LANGUAGE ImplicitParams #-}
2
2
3sortBy :: (a -> a -> Bool) -> [a] -> [a]
3sortBy :: (a -> a -> Bool) -> [a] -> [a]
4−sortBy = undefined
5
4
6sort :: (?cmp :: a -> a -> Bool) => [a] -> [a]
5sort :: (?cmp :: a -> a -> Bool) => [a] -> [a]
7sort = sortBy ?cmp
6sort = sortBy ?cmp
8
7
9−sort' ::
8+sort'
10− ( ?cmp ::
9+ :: ( ?cmp
11− a -> a -> Bool,
10+ :: a -> a -> Bool,
12− ?foo :: Int
11+ ?foo :: Int
13− ) =>
12+ )
14− [a] ->
13+ => [a]
15− [a]
14+ -> [a]
16sort' = sort
15sort' = sort
data/examples/declaration/value/function/implicit-params.hs−2
@@ -1,8 +1,6 @@
1{-# LANGUAGE ImplicitParams #-}
1{-# LANGUAGE ImplicitParams #-}
2sortBy :: (a -> a -> Bool) -> [a] -> [a]
2sortBy :: (a -> a -> Bool) -> [a] -> [a]
3
3
4−sortBy = undefined
5−
6sort :: (?cmp :: a -> a -> Bool) => [a] -> [a]
4sort :: (?cmp :: a -> a -> Bool) => [a] -> [a]
7sort = sortBy ?cmp
5sort = sortBy ?cmp
8
6
data/examples/declaration/value/function/infix/applicative.hs+2
@@ -1,4 +1,6 @@
1+
1f =
2f =
2 Foo <$> bar
3 Foo <$> bar
3 <*> baz
4 <*> baz
4 <*> baz'
5 <*> baz'
6+
data/examples/declaration/value/function/infix/comments-out.hs+6−5
@@ -1,8 +1,9 @@
1main =
1main =
2− bar $ -- bar
2+ bar
3+ $ baz -- bar
3− baz -- baz
4+ -- baz
4
5
5−bar $
6+bar
6− {- foo
7+ $ {- foo
7− -}
8+ -}
8 bar
9 bar
data/examples/declaration/value/function/infix/comments.hs+3
@@ -6,3 +6,6 @@ bar $
6 {- foo
6 {- foo
7 -}
7 -}
8 bar
8 bar
9+
10+
11+
data/examples/declaration/value/function/infix/dollar-chains-out.hsdeleted−22
@@ -1,22 +0,0 @@
1−module Main where
2−
3−foo =
4− fmap escapeLeadingDollar
5− . dropPaddingSpace
6− . dropWhileEnd T.null
7− . fmap (T.stripEnd . T.pack)
8− . lines
9− $ unpackHDS docStr
10−
11−foo =
12− when (GHC.xopt Cpp dynFlags && not cfgTolerateCpp) $
13− throwIO (OrmoluCppEnabled path)
14−
15−foo =
16− bar $
17− baz $
18− quux
19−
20−x =
21− case l of { A -> B } $
22− case q of r -> s
data/examples/declaration/value/function/infix/dollar-chains.hsdeleted−22
@@ -1,22 +0,0 @@
1−module Main where
2−
3−foo =
4− fmap escapeLeadingDollar
5− . dropPaddingSpace
6− . dropWhileEnd T.null
7− . fmap (T.stripEnd . T.pack)
8− . lines
9− $ unpackHDS docStr
10−
11−foo =
12− when (GHC.xopt Cpp dynFlags && not cfgTolerateCpp) $
13− throwIO (OrmoluCppEnabled path)
14−
15−foo =
16− bar
17− $ baz
18− $ quux
19−
20−x =
21− case l of { A -> B } $
22− case q of r -> s
data/examples/declaration/value/function/infix/hanging-out.hs+6−7
@@ -4,9 +4,9 @@ f = unFoo . foo bar baz 3 $ do
4
4
5g = unFoo
5g = unFoo
6 . foo
6 . foo
7− bar
7+ bar
8− baz
8+ baz
9− 3
9+ 3
10 $ do
10 $ do
11 act
11 act
12 ret
12 ret
@@ -17,7 +17,6 @@ update =
17 `catch` \case
17 `catch` \case
18 a -> a
18 a -> a
19
19
20−foo =
20+foo = bar
21− bar
22− ++ case foo of
21+ ++ case foo of
23− a -> a
22+ a -> a
data/examples/declaration/value/function/infix/lenses-out.hs+10−20
@@ -1,21 +1,11 @@
1lenses =
1lenses =
2− Just $
3− M.fromList $
2+ Just $ M.fromList
3+ $ "type"
4− "type" .= ("user.connection" :: Text)
4+ .= ("user.connection" :: Text)
5− # "connection" .= uc
5+ # "connection"
6+ .= uc
7+ # "user"
6− # "user" .= case name of
8+ .= case name of
7− Just n -> Just $ object ["name" .= n]
9+ Just n -> Just $ object ["name" .= n]
8− Nothing -> Nothing
10+ Nothing -> Nothing
9− # []
11+ # []
10−
11−foo =
12− a
13− & b .~ 2
14− & c .~ 3
15−
16−wreq =
17− let opts =
18− defaults & auth ?~ awsAuth AWSv4 "key" "secret"
19− & header "Accept" .~ ["application/json"]
20− & header "Runscope-Bucket-Auth" .~ ["1example-1111-4yyyy-zzzz-xxxxxxxx"]
21− in getWith opts
data/examples/declaration/value/function/infix/lenses.hs−9
@@ -5,12 +5,3 @@ lenses = Just $ M.fromList
5 Just n -> Just $ object ["name" .= n]
5 Just n -> Just $ object ["name" .= n]
6 Nothing -> Nothing
6 Nothing -> Nothing
7 # []
7 # []
8−
9−foo = a
10− & b .~ 2 & c .~ 3
11−
12−wreq =
13− let opts = defaults & auth ?~ awsAuth AWSv4 "key" "secret"
14− & header "Accept" .~ ["application/json"]
15− & header "Runscope-Bucket-Auth" .~ ["1example-1111-4yyyy-zzzz-xxxxxxxx"]
16− in getWith opts
data/examples/declaration/value/function/infix/unicode-out.hsdeleted−3
@@ -1,3 +0,0 @@
1−main = print ('a' → 'a')
2− where
3− (→) = (,)
data/examples/declaration/value/function/infix/unicode.hsdeleted−3
@@ -1,3 +0,0 @@
1−main = print ('a' → 'a')
2− where
3− (→) = (,)
data/examples/declaration/value/function/lambda-case-out.hs−2
@@ -1,7 +1,5 @@
1{-# LANGUAGE LambdaCase #-}
1{-# LANGUAGE LambdaCase #-}
2
2
3−foo = bar (\case JKey {} -> True; _ -> False)
4−
5foo :: Int -> Int
3foo :: Int -> Int
6foo = \case
4foo = \case
7 5 -> 10
5 5 -> 10
data/examples/declaration/value/function/lambda-case.hs−2
@@ -1,7 +1,5 @@
1{-# LANGUAGE LambdaCase #-}
1{-# LANGUAGE LambdaCase #-}
2
2
3−foo = bar (\case JKey{} -> True; _ -> False)
4−
5foo :: Int -> Int
3foo :: Int -> Int
6foo = \case
4foo = \case
7 5 -> 10
5 5 -> 10
data/examples/declaration/value/function/lambda-multi-line1-out.hs+3−3
@@ -9,7 +9,7 @@ bar x = \y ->
9 else 12
9 else 12
10
10
11foo =
11foo =
12− prop "is inverse to closure" $
12+ prop "is inverse to closure"
13− \(f :: StaticPtr (Int -> Int))
13+ $ \(f :: StaticPtr (Int -> Int))
14− (x :: Int) ->
14+ (x :: Int) ->
15 (unclosure . closure) f x == deRefStaticPtr f x
15 (unclosure . closure) f x == deRefStaticPtr f x
data/examples/declaration/value/function/lambda-multi-line2-out.hs+4−4
@@ -3,10 +3,10 @@ tricky0 =
3 canUnify poly_given_ok wt gt || go False wt gt
3 canUnify poly_given_ok wt gt || go False wt gt
4
4
5tricky1 =
5tricky1 =
6− flip all (zip ws gs) $
6+ flip all (zip ws gs)
7− \(wt, gt) -> canUnify poly_given_ok wt gt || go False wt gt
7+ $ \(wt, gt) -> canUnify poly_given_ok wt gt || go False wt gt
8
8
9tricky2 =
9tricky2 =
10− flip all (zip ws gs) $
10+ flip all (zip ws gs)
11− \(wt, gt) ->
11+ $ \(wt, gt) ->
12 canUnify poly_given_ok wt gt || go False wt gt
12 canUnify poly_given_ok wt gt || go False wt gt
data/examples/declaration/value/function/lambda-single-line-out.hs−2
@@ -1,5 +1,3 @@
1−{-# LANGUAGE BangPatterns #-}
2−
3foo :: a -> a -> a
1foo :: a -> a -> a
4foo x = \y -> x
2foo x = \y -> x
5
3
data/examples/declaration/value/function/lambda-single-line.hs−2
@@ -1,5 +1,3 @@
1−{-# LANGUAGE BangPatterns #-}
2−
3foo :: a -> a -> a
1foo :: a -> a -> a
4foo x = \y -> x
2foo x = \y -> x
5
3
data/examples/declaration/value/function/let-multi-line-out.hs−5
@@ -21,8 +21,3 @@ implicitParams :: HasCallStack => Int
21implicitParams =
21implicitParams =
22 let ?cs = ?callstack
22 let ?cs = ?callstack
23 in foo cs
23 in foo cs
24−
25−sitting =
26− foo $
27− let x = 20
28− in x
data/examples/declaration/value/function/let-multi-line.hs−4
@@ -21,7 +21,3 @@ implicitParams :: HasCallStack => Int
21implicitParams =
21implicitParams =
22 let ?cs = ?callstack
22 let ?cs = ?callstack
23 in foo cs
23 in foo cs
24−
25−sitting =
26− foo $ let x = 20
27− in x
data/examples/declaration/value/function/let-single-line-out.hs+1
@@ -5,6 +5,7 @@ foo x = let x = z where { z = 2 }; a = 3 in x
5foo x = let g :: Int -> Int; g = id in ()
5foo x = let g :: Int -> Int; g = id in ()
6
6
7let a = b; c = do { foo; bar }; d = baz in b
7let a = b; c = do { foo; bar }; d = baz in b
8+
8let a = case True of { True -> foo; False -> bar }; b = foo a in b
9let a = case True of { True -> foo; False -> bar }; b = foo a in b
9
10
10foo x = let ?g = id; ?f = g in x
11foo x = let ?g = id; ?f = g in x
data/examples/declaration/value/function/list-comprehensions-out.hs+4−3
@@ -10,7 +10,8 @@ barbaz x y z w =
10 any even [a, b],
10 any even [a, b],
11 c <-
11 c <-
12 z
12 z
13+ * z
13− * z ^ 2, -- Bar baz
14+ ^ 2, -- Bar baz
14 d <-
15 d <-
15 w
16 w
16 + w, -- Baz bar
17 + w, -- Baz bar
@@ -20,5 +21,5 @@ barbaz x y z w =
20 b,
21 b,
21 c,
22 c,
22 d
23 d
23− ]
24+ ]
24− ]
25+ ]
data/examples/declaration/value/function/list-notation-0-out.hsdeleted−5
@@ -1,5 +0,0 @@
1−foo =
2− testCase "Foo" testFoo :
3− testCase "Bar" testBar :
4− testCase "Baz" testBaz :
5− []
data/examples/declaration/value/function/list-notation-0.hsdeleted−5
@@ -1,5 +0,0 @@
1−foo =
2− testCase "Foo" testFoo :
3− testCase "Bar" testBar :
4− testCase "Baz" testBaz :
5− []
data/examples/declaration/value/function/list-notation-1-out.hsdeleted−8
@@ -1,8 +0,0 @@
1−instance A.ToJSON UpdateTable where
2− toJSON a =
3− A.object $
4− "TableName" .= updateTableName a :
5− "ProvisionedThroughput" .= updateProvisionedThroughput a :
6− case updateGlobalSecondaryIndexUpdates a of
7− [] -> []
8− l -> ["GlobalSecondaryIndexUpdates" .= l]
data/examples/declaration/value/function/list-notation-1.hsdeleted−7
@@ -1,7 +0,0 @@
1−instance A.ToJSON UpdateTable where
2− toJSON a = A.object
3− $ "TableName" .= updateTableName a
4− : "ProvisionedThroughput" .= updateProvisionedThroughput a
5− : case updateGlobalSecondaryIndexUpdates a of
6− [] -> []
7− l -> [ "GlobalSecondaryIndexUpdates" .= l ]
data/examples/declaration/value/function/list-notation-2-out.hsdeleted−6
@@ -1,6 +0,0 @@
1−-- A list of the element and all its parents up to the root node.
2−getPath tree t =
3− t :
4− case Map.lookup (getId t) tree of
5− Nothing -> []
6− Just parent -> getPath tree parent
data/examples/declaration/value/function/list-notation-2.hsdeleted−5
@@ -1,5 +0,0 @@
1−-- A list of the element and all its parents up to the root node.
2−getPath tree t = t :
3− case Map.lookup (getId t) tree of
4− Nothing -> []
5− Just parent -> getPath tree parent
data/examples/declaration/value/function/list-notation-3-out.hsdeleted−12
@@ -1,12 +0,0 @@
1−foo =
2− reportSDoc "tc.cc" 30 $
3− sep $ do
4− (prettyTCM q <+> " before compilation") : do
5− map (prettyTCM . map unArg . clPats) cls
6−
7−foo =
8− reportSDoc "tc.cc" 30 $
9− sep $ do
10− (prettyTCM q <+> " before compilation") :
11− do
12− map (prettyTCM . map unArg . clPats) cls
data/examples/declaration/value/function/list-notation-3.hsdeleted−10
@@ -1,10 +0,0 @@
1−foo =
2− reportSDoc "tc.cc" 30 $ sep $ do
3− (prettyTCM q <+> " before compilation") : do
4− map (prettyTCM . map unArg . clPats) cls
5−
6−foo =
7− reportSDoc "tc.cc" 30 $ sep $ do
8− (prettyTCM q <+> " before compilation") :
9− do
10− map (prettyTCM . map unArg . clPats) cls
data/examples/declaration/value/function/multi-way-if-out.hs+4−10
@@ -4,13 +4,7 @@ foo x = if | x == 5 -> 5
4
4
5bar x y =
5bar x y =
6 if
6 if
7− | x > y -> x
7+ | x > y -> x
8− | x < y ->
8+ | x < y ->
9− y
9+ y
10− | otherwise -> x
11−
12−baz =
13− if
14− | p -> f
15− | otherwise -> g
10+ | otherwise -> x
16− x
data/examples/declaration/value/function/multi-way-if.hs−5
@@ -7,8 +7,3 @@ bar x y = if
7 | x < y
7 | x < y
8 -> y
8 -> y
9 | otherwise -> x
9 | otherwise -> x
10−
11−baz =
12− if | p -> f
13− | otherwise -> g
14− x
data/examples/declaration/value/function/operator-comments-0-out.hsdeleted−16
@@ -1,16 +0,0 @@
1−foo =
2− bar
3− ++
4− {- some comment -}
5− case foo of
6− a -> a
7−
8−foo =
9− bar
10− ++ {- some comment -} case foo of
11− a -> a
12−
13−foo =
14− bar
15− ++ case foo {- some comment -} of
16− a -> a
data/examples/declaration/value/function/operator-comments-0.hsdeleted−17
@@ -1,17 +0,0 @@
1−foo =
2− bar
3− ++
4− {- some comment -}
5− case foo of
6− a -> a
7−
8−foo =
9− bar
10− ++ {- some comment -}
11− case foo of
12− a -> a
13−
14−foo =
15− bar
16− ++ case foo of {- some comment -}
17− a -> a
data/examples/declaration/value/function/operator-comments-1-out.hsdeleted−16
@@ -1,16 +0,0 @@
1−foo =
2− bar
3− ++
4− -- some comment
5− case foo of
6− a -> a
7−
8−foo =
9− bar
10− ++ case foo of -- some comment
11− a -> a
12−
13−foo =
14− bar
15− ++ case foo of -- some comment
16− a -> a
data/examples/declaration/value/function/operator-comments-1.hsdeleted−17
@@ -1,17 +0,0 @@
1−foo =
2− bar
3− ++
4− -- some comment
5− case foo of
6− a -> a
7−
8−foo =
9− bar
10− ++ -- some comment
11− case foo of
12− a -> a
13−
14−foo =
15− bar
16− ++ case foo of -- some comment
17− a -> a
data/examples/declaration/value/function/operator-comments-2-out.hsdeleted−5
@@ -1,5 +0,0 @@
1−x =
2− y
3− ++ f g -- commentA
4− -- commentB
5− -- commentC
data/examples/declaration/value/function/operator-comments-2.hsdeleted−4
@@ -1,4 +0,0 @@
1−x =
2− y ++ -- commentA
3−-- commentB
4− f g -- commentC
data/examples/declaration/value/function/operator-sections-out.hs+2−2
@@ -5,9 +5,9 @@ bar = (<> "hello")
5baz =
5baz =
6 ( 1 * 2
6 ( 1 * 2
7 +
7 +
8− )
8+ )
9 ( *
9 ( *
10 3 ^ 5
10 3 ^ 5
11− )
11+ )
12
12
13quux = (,) <$> foo <$> bar
13quux = (,) <$> foo <$> bar
data/examples/declaration/value/function/operators-0-out.hsdeleted−5
@@ -1,5 +0,0 @@
1−a =
2− b & c .~ d
3− & e
4− %~ f
5− g
data/examples/declaration/value/function/operators-0.hsdeleted−4
@@ -1,4 +0,0 @@
1−a =
2− b & c .~ d
3− & e %~ f
4− g
data/examples/declaration/value/function/operators-1-out.hsdeleted−4
@@ -1,4 +0,0 @@
1−foo =
2− f
3− . g
4− =<< h . i
data/examples/declaration/value/function/operators-1.hsdeleted−3
@@ -1,3 +0,0 @@
1−foo = f
2− . g
3− =<< h . i
data/examples/declaration/value/function/operators-2-out.hsdeleted−4
@@ -1,4 +0,0 @@
1−foo n
2− | x || y && z || n ** x
3− || x && n =
4− 42
data/examples/declaration/value/function/operators-2.hsdeleted−4
@@ -1,4 +0,0 @@
1−foo n
2− | x || y && z || n ** x
3− || x && n =
4− 42
data/examples/declaration/value/function/operators-3-out.hsdeleted−3
@@ -1,3 +0,0 @@
1−foo =
2− op <> n <+> colon <+> prettySe <+> text "="
3− <+> prettySe <> text sc
data/examples/declaration/value/function/operators-3.hsdeleted−3
@@ -1,3 +0,0 @@
1−foo =
2− op <> n <+> colon <+> prettySe <+> text "=" <+>
3− prettySe <> text sc
data/examples/declaration/value/function/operators-4-out.hsdeleted−3
@@ -1,3 +0,0 @@
1−foo =
2− line <> bindingOf <+> text "=" <+> tPretty <+> colon
3− <+> align <> prettyPs
data/examples/declaration/value/function/operators-4.hsdeleted−3
@@ -1,3 +0,0 @@
1−foo =
2− line <> bindingOf <+> text "=" <+> tPretty <+> colon <+>
3− align <> prettyPs
data/examples/declaration/value/function/operators-5-out.hsdeleted−5
@@ -1,5 +0,0 @@
1−foo =
2− map bar $
3− [ baz
4− ]
5− ++ quux
data/examples/declaration/value/function/operators-5.hsdeleted−4
@@ -1,4 +0,0 @@
1−foo =
2− map bar $
3− [ baz
4− ] ++ quux
data/examples/declaration/value/function/operators-6-out.hsdeleted−9
@@ -1,9 +0,0 @@
1−type PermuteRef =
2− "a"
3− :> ( "b" :> "c" :> End
4− :<|> "c" :> "b" :> End
5− )
6− :<|> "b"
7− :> ( "a" :> "c" :> End
8− :<|> "c" :> "a" :> End
9− )
data/examples/declaration/value/function/operators-6.hsdeleted−7
@@ -1,7 +0,0 @@
1−type PermuteRef =
2− "a" :> ( "b" :> "c" :> End
3− :<|> "c" :> "b" :> End
4− )
5− :<|> "b" :> ( "a" :> "c" :> End
6− :<|> "c" :> "a" :> End
7− )
data/examples/declaration/value/function/overindentation-out.hsdeleted−11
@@ -1,11 +0,0 @@
1−reallyincrediblyLongName =
2− f
3− a
4− A
5− { reallyincrediblyLongName =
6− f
7− a
8− A
9− { reallyincrediblyLongName
10− }
11− }
data/examples/declaration/value/function/overindentation.hsdeleted−9
@@ -1,9 +0,0 @@
1−reallyincrediblyLongName = f
2− a
3− A
4− { reallyincrediblyLongName = f
5− a
6− A
7− { reallyincrediblyLongName
8− }
9− }
data/examples/declaration/value/function/parallel-comprehensions-complex-out.hs+2−2
@@ -9,7 +9,7 @@ baz x y z w =
9 h,
9 h,
10 i,
10 i,
11 j
11 j
12− )
12+ )
13 | a <- -- Foo 1
13 | a <- -- Foo 1
14 x, -- Foo 2
14 x, -- Foo 2
15 b <- -- Bar 1
15 b <- -- Bar 1
@@ -32,4 +32,4 @@ baz x y z w =
32 -- Bar bar 3
32 -- Bar bar 3
33 j <- -- Bar baz 1
33 j <- -- Bar baz 1
34 a + b -- Bar baz 2
34 a + b -- Bar baz 2
35− ]
35+ ]
data/examples/declaration/value/function/parens-out.hsdeleted−1
@@ -1 +0,0 @@
1−f = p (do foo; bar) baz
data/examples/declaration/value/function/parens.hsdeleted−1
@@ -1 +0,0 @@
1−f = p (do foo; bar) baz
data/examples/declaration/value/function/pattern/as-pattern-out.hsdeleted−3
@@ -1,3 +0,0 @@
1−main = case [1] of
2− xs@(x : _) -> print (x, xs)
3− xs@[] -> print xs
data/examples/declaration/value/function/pattern/as-pattern.hsdeleted−3
@@ -1,3 +0,0 @@
1−main = case [1] of
2− xs @ (x:_) -> print (x, xs)
3− xs@[] -> print xs
data/examples/declaration/value/function/pattern/famous-cardano-pattern-out.hs+8−8
@@ -1,8 +1,8 @@
1−( getNodeSettingsR
1+( getNodeSettingsR :<|>
2− :<|> getNodeInfoR
2+ getNodeInfoR :<|>
3− :<|> getNextUpdateR
3+ getNextUpdateR :<|>
4− :<|> restartNodeR
4+ restartNodeR
5− )
5+ ) :<|>
6− :<|> ( getUtxoR
6+ ( getUtxoR :<|>
7− :<|> getConfirmedProposalsR
7+ getConfirmedProposalsR
8− ) = client nodeV1Api
8+ ) = client nodeV1Api
data/examples/declaration/value/function/pattern/multiline-case-pattern-out.hs+2−2
@@ -10,6 +10,6 @@ f xs = case xs of
10 ] -> a + b
10 ] -> a + b
11
11
12g xs = case xs of
12g xs = case xs of
13− ( a
13+ ( a :
14− : bs
14+ bs
15 ) -> a + b
15 ) -> a + b
data/examples/declaration/value/function/pattern/record-patterns-out.hs+1−1
@@ -16,4 +16,4 @@ quux
16 { boom = a,
16 { boom = a,
17 foom = b,
17 foom = b,
18 ..
18 ..
19− } = a + b
19+ } = a + b
data/examples/declaration/value/function/pattern/sig-pattern-out.hs+2−2
@@ -2,6 +2,6 @@ f = do
2 x :: a <- g
2 x :: a <- g
3
3
4f = do
4f = do
5− (x, y) ::
5+ (x, y)
6− (a, b) <-
6+ :: (a, b) <-
7 g
7 g
data/examples/declaration/value/function/pattern/splice-pattern-out.hs+2−2
@@ -7,7 +7,7 @@ singleLine = case () of
7multiline = case () of
7multiline = case () of
8 $( x
8 $( x
9 + y
9 + y
10− ) -> ()
10+ ) -> ()
11 $( y
11 $( y
12 "something"
12 "something"
13− ) -> ()
13+ ) -> ()
data/examples/declaration/value/function/pattern/strictness-out.hs−2
@@ -1,5 +1,3 @@
1−{-# LANGUAGE BangPatterns #-}
2−
3!a = ()
1!a = ()
4
2
5~b = ()
3~b = ()
data/examples/declaration/value/function/pattern/strictness.hs−2
@@ -1,4 +1,2 @@
1−{-# LANGUAGE BangPatterns #-}
2−
3!a = ()
1!a = ()
4~b = ()
2~b = ()
data/examples/declaration/value/function/pattern/unboxed-sum-pattern-out.hs+3−5
@@ -18,9 +18,7 @@ z = True
18
18
19z_multiline = True
19z_multiline = True
20 where
20 where
21− (#
22− | | _x
21+ (# | | _x
23 #) =
22 #) =
24− (#
23+ (# | | True
25− | | True
26− #)
24+ #)
data/examples/declaration/value/function/record-constructors-out.hsnew file+26
@@ -0,0 +1,26 @@
1+foo = Foo {a = 3}
2+
3+bar = Bar
4+ { abc = foo,
5+ def = Foo {a = 10}
6+ }
7+
8+baz = Baz {}
9+
10+aLongVariableName =
11+ ALongRecordName
12+ { short = baz,
13+ aLongRecordFieldName = YetAnotherLongRecordName
14+ { yetAnotherLongRecordFieldName = "a long string"
15+ },
16+ aLongRecordFieldName2 =
17+ Just YetAnotherLongRecordName
18+ { yetAnotherLongRecordFieldName = "a long string",
19+ yetAnotherLongRecordFieldName =
20+ Just
21+ "a long string"
22+ },
23+ aLongRecordFieldName3 = do
24+ foo
25+ bar
26+ }
data/examples/declaration/value/function/record/constructors.hs → data/examples/declaration/value/function/record-constructors.hsrenamed+1−1
@@ -4,7 +4,7 @@ bar = Bar {
4 def = Foo {a = 10}
4 def = Foo {a = 10}
5}
5}
6baz = Baz{ }
6baz = Baz{ }
7−sym = Foo { (+) = 3 }
7+
8aLongVariableName =
8aLongVariableName =
9 ALongRecordName
9 ALongRecordName
10 { short = baz,
10 { short = baz,
data/examples/declaration/value/function/record/updaters-out.hs → data/examples/declaration/value/function/record-updaters-out.hsrenamed+1−3
@@ -4,8 +4,6 @@ bar x =
4 x
4 x
5 { abc = foo,
5 { abc = foo,
6 def = Foo {a = 10}
6 def = Foo {a = 10}
7− }
7+ }
8
8
9baz x = x {}
9baz x = x {}
10−
11−sym x = x {(+) = 4}
data/examples/declaration/value/function/record/updaters.hs → data/examples/declaration/value/function/record-updaters.hsrenamed−1
@@ -4,4 +4,3 @@ bar x = x {
4 def = Foo {a = 10}
4 def = Foo {a = 10}
5}
5}
6baz x = x{ }
6baz x = x{ }
7−sym x = x { (+) = 4 }
data/examples/declaration/value/function/record/wildcards-out.hs → data/examples/declaration/value/function/record-wildcards-out.hsrenamed+5−6
@@ -3,12 +3,11 @@
3
3
4foo x y = Foo {x, y}
4foo x y = Foo {x, y}
5
5
6−bar x y z =
6+bar x y z = Bar
7− Bar
8− { x,
7+ { x,
9− y,
8+ y,
10− z,
9+ z,
11− ..
10+ ..
12 }
11 }
13
12
14baz = Baz {..}
13baz = Baz {..}
data/examples/declaration/value/function/record/wildcards.hs → data/examples/declaration/value/function/record-wildcards.hsrenamed

The content is the same.

data/examples/declaration/value/function/record/constructors-out.hsdeleted−31
@@ -1,31 +0,0 @@
1−foo = Foo {a = 3}
2−
3−bar =
4− Bar
5− { abc = foo,
6− def = Foo {a = 10}
7− }
8−
9−baz = Baz {}
10−
11−sym = Foo {(+) = 3}
12−
13−aLongVariableName =
14− ALongRecordName
15− { short = baz,
16− aLongRecordFieldName =
17− YetAnotherLongRecordName
18− { yetAnotherLongRecordFieldName = "a long string"
19− },
20− aLongRecordFieldName2 =
21− Just
22− YetAnotherLongRecordName
23− { yetAnotherLongRecordFieldName = "a long string",
24− yetAnotherLongRecordFieldName =
25− Just
26− "a long string"
27− },
28− aLongRecordFieldName3 = do
29− foo
30− bar
31− }
data/examples/declaration/value/function/record/dot-out.hsdeleted−15
@@ -1,15 +0,0 @@
1−{-# OPTIONS_GHC -fplugin=RecordDotPreprocessor #-}
2−
3−data Foo = Foo {bar :: Int}
4−
5−mfoo = fmap (.bar) $ Nothing
6−
7−bar = (Foo 1).bar
8−
9−fooplus f n = f{foo = f.bar + n}
10−
11−fooplus' f n = f {foo = f.bar + n}
12−
13−fooplus'' f n = f {foo = f.bar + n}
14−
15−fooplus''' f n = f {foo = f.bar + n}
data/examples/declaration/value/function/record/dot.hsdeleted−14
@@ -1,14 +0,0 @@
1−{-# OPTIONS_GHC -fplugin=RecordDotPreprocessor #-}
2−data Foo = Foo { bar :: Int }
3−
4−mfoo = fmap (.bar) $ Nothing
5−
6−bar = ( Foo 1).bar
7−
8−fooplus f n = f{foo = f.bar + n}
9−
10−fooplus' f n = f { foo = f.bar + n}
11−
12−fooplus'' f n = f {foo = f.bar + n}
13−
14−fooplus''' f n = f{ foo = f.bar + n}
data/examples/declaration/value/function/record/hanging-after-equal-con-out.hsdeleted−8
@@ -1,8 +0,0 @@
1−foo =
2− Foo
3− { foo =
4− -- Blah blah
5− case x of
6− Blah -> 1
7− Blim -> 2
8− }
data/examples/declaration/value/function/record/hanging-after-equal-con.hsdeleted−7
@@ -1,7 +0,0 @@
1−foo = Foo
2− { foo =
3− -- Blah blah
4− case x of
5− Blah -> 1
6− Blim -> 2
7− }
data/examples/declaration/value/function/record/hanging-after-equal-update-out.hsdeleted−8
@@ -1,8 +0,0 @@
1−foo =
2− foo
3− { foo =
4− -- Blah blah
5− case x of
6− Blah -> 1
7− Blim -> 2
8− }
data/examples/declaration/value/function/record/hanging-after-equal-update.hsdeleted−7
@@ -1,7 +0,0 @@
1−foo = foo
2− { foo =
3− -- Blah blah
4− case x of
5− Blah -> 1
6− Blim -> 2
7− }
data/examples/declaration/value/function/record/inter-comments-out.hsdeleted−13
@@ -1,13 +0,0 @@
1−x =
2− Just
3− -- comment
4− A
5− { x
6− }
7−
8−x =
9− Just
10− -- comment
11− a
12− { x
13− }
data/examples/declaration/value/function/record/inter-comments.hsdeleted−11
@@ -1,11 +0,0 @@
1−x = Just
2− -- comment
3− A
4− { x
5− }
6−
7−x = Just
8− -- comment
9− a
10− { x
11− }
data/examples/declaration/value/function/static-pointers-out.hs+3−4
@@ -9,12 +9,11 @@ bar =
9 [ 1,
9 [ 1,
10 2,
10 2,
11 3
11 3
12− ]
12+ ]
13
13
14baz :: StaticPtr Bool
14baz :: StaticPtr Bool
15baz =
15baz =
16 static
16 static
17− ( fun
17+ ( fun 1
18− 1
19 2
18 2
20− )
19+ )
data/examples/declaration/value/function/strings-out.hsdeleted−10
@@ -1,10 +0,0 @@
1−{-# LANGUAGE MagicHash #-}
2−
3−foo = "foobar"
4−
5−bar = "foo\&barbaz"
6−
7−baz =
8− "foo\
9− \bar\
10− \baz"
data/examples/declaration/value/function/strings.hsdeleted−7
@@ -1,7 +0,0 @@
1−{-# LANGUAGE MagicHash #-}
2−
3−foo = "foobar"
4−bar = "foo\&bar\ \baz"
5−baz = "foo\
6− \bar\
7− \baz"
data/examples/declaration/value/function/tricky-parens-out.hs+1−1
@@ -1,4 +1,4 @@
1handleStuff =
1handleStuff =
2 ( let foo = foo
2 ( let foo = foo
3 in foo
3 in foo
4− )
4+ )
data/examples/declaration/value/function/tuples-out.hs+2−2
@@ -4,11 +4,11 @@ bar =
4 ( 1,
4 ( 1,
5 2,
5 2,
6 3
6 3
7− )
7+ )
8
8
9handleStuff =
9handleStuff =
10 ( let foo = foo
10 ( let foo = foo
11 in foo,
11 in foo,
12 let bar = bar
12 let bar = bar
13 in bar
13 in bar
14− )
14+ )
data/examples/declaration/value/function/type-applications-and-splice-out.hsdeleted−4
@@ -1,4 +0,0 @@
1−{-# LANGUAGE TemplateHaskell #-}
2−{-# LANGUAGE TypeApplications #-}
3−
4−staticKey name = [|sing @ $(symFQN name)|]
data/examples/declaration/value/function/type-applications-and-splice.hsdeleted−4
@@ -1,4 +0,0 @@
1−{-# LANGUAGE TemplateHaskell #-}
2−{-# LANGUAGE TypeApplications #-}
3−
4−staticKey name = [| sing @ $(symFQN name) |]
data/examples/declaration/value/function/type-applications-out.hs−6
@@ -8,9 +8,3 @@ baz =
8 f @Int @String
8 f @Int @String
9 a
9 a
10 b
10 b
11−
12−goo =
13− hash
14− @(HASH TPraosStandardCrypto)
15− @ByteString
16− "And the lamb lies down on Broadway"
data/examples/declaration/value/function/type-applications.hs−5
@@ -6,8 +6,3 @@ bar = f @(Maybe Int) a b
6
6
7baz = f @Int @String
7baz = f @Int @String
8 a b
8 a b
9−
10−goo = hash
11− @(HASH TPraosStandardCrypto)
12− @ByteString
13− "And the lamb lies down on Broadway"
data/examples/declaration/value/function/typed-expressions-out.hs+2−2
@@ -1,5 +1,5 @@
1foo x = x :: Int
1foo x = x :: Int
2
2
3bar x =
3bar x =
4− Just x ::
4+ Just x
5− Maybe String
5+ :: Maybe String
data/examples/declaration/value/function/unboxed-sums-out.hs+2−3
@@ -5,6 +5,5 @@ foo = (# 1 | #)
5bar = (# | | 2 | #)
5bar = (# | | 2 | #)
6
6
7baz =
7baz =
8− (#
8+ (# | | | 10 | | | | |
9− | | | 10 | | | | |
10− #)
9+ #)
data/examples/declaration/value/function/unboxed-tuples-out.hs+4−5
@@ -3,8 +3,7 @@
3foo = (# 1, 2, 3 #)
3foo = (# 1, 2, 3 #)
4
4
5bar =
5bar =
6− (#
7− 1,
6+ (# 1,
8− 2,
7+ 2,
9− 3
8+ 3
10− #)
9+ #)
data/examples/declaration/value/function/where-nested.hs+1
@@ -10,3 +10,4 @@ foo = bar
10foo2 = bar
10foo2 = bar
11 where
11 where
12 { f1 = f1 where { f1 = 3; f1' = 4 }; f2 = f2 where { f2 = 3; f2' = 4 } }
12 { f1 = f1 where { f1 = 3; f1' = 4 }; f2 = f2 where { f2 = 3; f2' = 4 } }
13+
data/examples/declaration/value/other/comments-get-before-op-out.hs+1−1
@@ -6,5 +6,5 @@ main = do
6 migration3
6 migration3
7 -- When adding migrations here, don't forget to update
7 -- When adding migrations here, don't forget to update
8 -- 'schemaVersion' in Galley.Data
8 -- 'schemaVersion' in Galley.Data
9− ]
9+ ]
10 `finally` Log.close
10 `finally` Log.close
data/examples/declaration/value/other/line-multi-line-out.hs+1−1
@@ -3,4 +3,4 @@ x =
3 [ 1,
3 [ 1,
4 2,
4 2,
5 somethingSomething 3
5 somethingSomething 3
6− ]
6+ ]
data/examples/declaration/value/pattern-synonyms/bidirectional-out.hs+1−4
@@ -8,7 +8,7 @@ pattern Arrow {t1, t2} = App "->" [t1, t2]
8pattern Arrow
8pattern Arrow
9 { t1,
9 { t1,
10 t2
10 t2
11− } =
11+ } =
12 App "->" [t1, t2]
12 App "->" [t1, t2]
13
13
14pattern Int =
14pattern Int =
@@ -23,6 +23,3 @@ pattern Maybe t =
23 App
23 App
24 "Maybe"
24 "Maybe"
25 [t]
25 [t]
26−
27−pattern a :< b <-
28− (a, b)
data/examples/declaration/value/pattern-synonyms/bidirectional.hs−4
@@ -15,7 +15,3 @@ pattern Maybe t =
15 App
15 App
16 "Maybe"
16 "Maybe"
17 [t]
17 [t]
18−
19−pattern a :< b <-
20− (a , b)
21−
data/examples/declaration/value/pattern-synonyms/explicitely-bidirectional-out.hs−5
@@ -14,8 +14,3 @@ pattern Simple <-
14 "Simple"
14 "Simple"
15 where
15 where
16 Simple = "Complicated"
16 Simple = "Complicated"
17−
18−pattern a :< b <-
19− (a, b)
20− where
21− a :< b = (a, b)
data/examples/declaration/value/pattern-synonyms/explicitely-bidirectional.hs−6
@@ -11,9 +11,3 @@ pattern HeadC' x <-
11pattern Simple <- "Simple"
11pattern Simple <- "Simple"
12 where
12 where
13 Simple = "Complicated"
13 Simple = "Complicated"
14−
15−pattern a :< b <-
16− (a , b)
17− where
18− a :< b = (a, b)
19−
data/examples/declaration/value/pattern-synonyms/unidirectional-out.hs+1−1
@@ -14,7 +14,7 @@ pattern FirstTwo {x, y} <-
14pattern FirstTwo'
14pattern FirstTwo'
15 { x,
15 { x,
16 y
16 y
17− } <-
17+ } <-
18 x : (y : xs)
18 x : (y : xs)
19
19
20pattern Simple <- "Simple"
20pattern Simple <- "Simple"
data/examples/declaration/warning/warning-multiline-out.hs+1−1
@@ -3,7 +3,7 @@
3 foo
3 foo
4 [ "These are bad functions",
4 [ "These are bad functions",
5 "Really bad!"
5 "Really bad!"
6− ]
6+ ]
7 #-}
7 #-}
8test :: IO ()
8test :: IO ()
9test = pure ()
9test = pure ()
data/examples/import/comments-inside-imports-out.hsdeleted−7
@@ -1,7 +0,0 @@
1−-- x
2−
3−import qualified -- x
4− Bar
5−import qualified -- x
6− Baz
7−import Foo
data/examples/import/comments-inside-imports.hsdeleted−9
@@ -1,9 +0,0 @@
1−import -- x
2− Foo
3−
4−import -- x
5− qualified Bar
6−
7−import qualified
8− -- x
9− Baz
data/examples/import/deduplication-bug-out.hsdeleted−6
@@ -1,6 +0,0 @@
1−import Foo1 (Bar1 (..), Baz1)
2−import Foo2 (Bar2 (..), Baz2)
3−import Foo3 (Bar3 (x1, x2, x3))
4−import Foo4 (Bar4 (x1, x2))
5−import Foo5 (Bar5 (x1))
6−import Foo6 (Bar6 (..))
data/examples/import/deduplication-bug.hsdeleted−6
@@ -1,6 +0,0 @@
1−import Foo1 (Bar1, Baz1, Bar1(..))
2−import Foo2 (Bar2(..), Baz2, Bar2)
3−import Foo3 (Bar3(x1,x3), Bar3(x1, x2))
4−import Foo4 (Bar4(x1), Bar4(x2))
5−import Foo5 (Bar5, Bar5(x1))
6−import Foo6 (Bar6(x1), Bar6(..))
data/examples/import/explicit-imports-out.hs+6−6
@@ -1,12 +1,12 @@
1import qualified MegaModule as M
1import qualified MegaModule as M
2+ ( (<<<),
3+ (>>>),
2− ( Either,
4+ Either,
3 Maybe (Just, Nothing),
5 Maybe (Just, Nothing),
4 MaybeT (..),
6 MaybeT (..),
5− Monad (return, (>>), (>>=)),
7+ Monad ((>>), (>>=), return),
6 MonadBaseControl,
8 MonadBaseControl,
7 join,
9 join,
8 liftIO,
10 liftIO,
9− void,
11+ void
10− (<<<),
11− (>>>),
12− )
12+ )
data/examples/import/explicit-imports-with-comments-out.hs+3−4
@@ -1,7 +1,6 @@
1import qualified MegaModule as M
1import qualified MegaModule as M
2 ( -- (1)
2 ( -- (1)
3− -- (2)
4− Either, -- (3)
5− (<<<),
3+ (<<<), -- (2)
6 (>>>),
4 (>>>),
5+ Either -- (3)
7− )
6+ )
data/examples/import/merging-0-out.hsdeleted−3
@@ -1,3 +0,0 @@
1−import Foo
2−import Foo (bar, foo)
3−import Foo as F
data/examples/import/merging-0.hsdeleted−4
@@ -1,4 +0,0 @@
1−import Foo
2−import Foo (foo)
3−import Foo (bar)
4−import Foo as F
data/examples/import/merging-1-out.hsdeleted−2
@@ -1,2 +0,0 @@
1−import "bar" Foo (bar)
2−import "foo" Foo (baz, foo)
data/examples/import/merging-1.hsdeleted−3
@@ -1,3 +0,0 @@
1−import "foo" Foo (foo)
2−import "bar" Foo (bar)
3−import "foo" Foo (baz)
data/examples/import/merging-2-out.hsdeleted−2
@@ -1,2 +0,0 @@
1−import Foo hiding (bar4, foo2)
2−import qualified Foo (bar3, foo1)
data/examples/import/merging-2.hsdeleted−4
@@ -1,4 +0,0 @@
1−import qualified Foo (foo1)
2−import Foo hiding (foo2)
3−import qualified Foo (bar3)
4−import Foo hiding (bar4)
data/examples/import/misc-out.hs+7−1
@@ -1,5 +1,11 @@
1import A hiding
1import A hiding
2 ( foobarbazqux,
2 ( foobarbazqux,
3+ foobarbazqux,
4+ foobarbazqux,
5+ foobarbazqux,
6+ foobarbazqux,
7+ foobarbazqux,
8+ foobarbazqux
3− )
9+ )
4import {-# SOURCE #-} safe qualified Module as M hiding (a, b, c, d, e, f)
10import {-# SOURCE #-} safe qualified Module as M hiding (a, b, c, d, e, f)
5import Name hiding ()
11import Name hiding ()
data/examples/import/nested-explicit-imports-out.hs+8−8
@@ -1,10 +1,10 @@
1import qualified MegaModule as M
1import qualified MegaModule as M
2− ( Either,
3− Monad
4− ( return,
5− (>>),
6− (>>=)
7− ),
8− (<<<),
2+ ( (<<<),
9 (>>>),
3 (>>>),
4+ Either,
5+ Monad
6+ ( (>>),
7+ (>>=),
8+ return
9+ )
10− )
10+ )
data/examples/import/qualified-post-out.hsdeleted−5
@@ -1,5 +0,0 @@
1−{-# LANGUAGE ImportQualifiedPost #-}
2−
3−import Data.Text qualified (a, b, c)
4−import Data.Text qualified hiding (a, b, c)
5−import Data.Text qualified as T
data/examples/import/qualified-post.hsdeleted−5
@@ -1,5 +0,0 @@
1−{-# LANGUAGE ImportQualifiedPost #-}
2−
3−import qualified Data.Text as T
4−import qualified Data.Text (a, c, b)
5−import Data.Text qualified hiding (c, b, a)
data/examples/import/qualified-prelude-out.hs+1−1
@@ -1,4 +1,4 @@
1module P where
1module P where
2
2
3−import Prelude hiding (id, (.))
3+import Prelude hiding ((.), id)
4import qualified Prelude
4import qualified Prelude
data/examples/import/simple-out.hs+3−2
@@ -1,5 +1,6 @@
1import Data.Text
1import Data.Text
2+import Data.Text
3+import qualified Data.Text as T
4+import qualified Data.Text (a, b, c)
2import Data.Text (a, b, c)
5import Data.Text (a, b, c)
3import Data.Text hiding (a, b, c)
6import Data.Text hiding (a, b, c)
4−import qualified Data.Text (a, b, c)
5−import qualified Data.Text as T
data/examples/import/simple.hs−2
@@ -4,5 +4,3 @@ import qualified Data.Text as T
4import qualified Data.Text (a, c, b)
4import qualified Data.Text (a, c, b)
5import Data.Text (a, b, c)
5import Data.Text (a, b, c)
6import Data.Text hiding (c, b, a)
6import Data.Text hiding (c, b, a)
7−import Data.Text (a, b, c, b, a)
8−import Data.Text hiding (c, b, a, b, c)
data/examples/import/sorted-export-list-out.hsdeleted−1
@@ -1 +0,0 @@
1−import Linear.Vector (Additive (..), (*^), (^*))
data/examples/import/sorted-export-list.hsdeleted−1
@@ -1 +0,0 @@
1−import Linear.Vector (Additive (..), (*^), (^*))
data/examples/module-header/double-dot-with-names-out.hs+6−1
@@ -1,6 +1,11 @@
1{-# LANGUAGE PatternSynonyms #-}
1{-# LANGUAGE PatternSynonyms #-}
2
2
3−module ExportSyntax (A (.., NoA), Q (F, ..), G (T, .., U)) where
3+module ExportSyntax
4+ ( A (.., NoA),
5+ Q (F, ..),
6+ G (T, .., U)
7+ )
8+where
4
9
5data A = A | B
10data A = A | B
6
11
data/examples/module-header/leading-empty-line-out.hsdeleted−11
@@ -1,11 +0,0 @@
1−-- |
2−-- Module : Text.Megaparsec
3−-- Copyright : © 2015–2019 Megaparsec contributors
4−-- © 2007 Paolo Martini
5−-- © 1999–2001 Daan Leijen
6−-- License : FreeBSD
7−--
8−-- Maintainer : Mark Karpov <markkarpov92@gmail.com>
9−-- Stability : experimental
10−-- Portability : portable
11−module Main where
data/examples/module-header/leading-empty-line.hsdeleted−11
@@ -1,11 +0,0 @@
1−-- |
2−-- Module : Text.Megaparsec
3−-- Copyright : © 2015–2019 Megaparsec contributors
4−-- © 2007 Paolo Martini
5−-- © 1999–2001 Daan Leijen
6−-- License : FreeBSD
7−--
8−-- Maintainer : Mark Karpov <markkarpov92@gmail.com>
9−-- Stability : experimental
10−-- Portability : portable
11−module Main where
data/examples/module-header/multiline-out.hs+2−2
@@ -1,6 +1,6 @@
1module Foo
1module Foo
2 ( foo,
2 ( foo,
3 bar,
3 bar,
4− baz,
4+ baz
5− )
5+ )
6where
6where
data/examples/module-header/multiline-with-comments-out.hs+2−3
@@ -6,7 +6,6 @@ module My.Module
6 ( -- * Something
6 ( -- * Something
7 foo,
7 foo,
8 bar,
8 bar,
9−
10 -- * Another thing
9 -- * Another thing
11 (<?>),
10 (<?>),
12 {- some other thing -} foo2, -- yet another
11 {- some other thing -} foo2, -- yet another
@@ -15,8 +14,8 @@ module My.Module
15 bar2, -- a multiline comment
14 bar2, -- a multiline comment
16 -- the second line
15 -- the second line
17 bar3,
16 bar3,
18− module Foo.Bar.Baz,
17+ module Foo.Bar.Baz
19− )
18+ )
20where
19where
21
20
22-- Wow
21-- Wow
data/examples/module-header/multiline2-out.hs+2−2
@@ -1,6 +1,6 @@
1module Foo
1module Foo
2 ( foo,
2 ( foo,
3 bar,
3 bar,
4− baz,
4+ baz
5− )
5+ )
6where
6where
data/examples/module-header/multiline2.hs+2−2
@@ -1,2 +1,2 @@
1−module Foo (
1+module Foo
2− foo, bar, baz) where
2+ (foo, bar, baz) where
data/examples/module-header/named-section-out.hsdeleted−13
@@ -1,13 +0,0 @@
1−module Magic
2− ( -- * Something
3− -- $explanation
4−
5− -- ** Another level
6− foo,
7− bar,
8− )
9−where
10−
11−-- $explanation
12−--
13−-- Here it goes.
data/examples/module-header/named-section.hsdeleted−13
@@ -1,13 +0,0 @@
1−module Magic
2− ( -- * Something
3− -- $explanation
4−
5− -- ** Another level
6− foo
7− , bar
8− )
9−where
10−
11−-- $explanation
12−--
13−-- Here it goes.
data/examples/module-header/preceding-comment-with-haddock-out.hsdeleted−8
@@ -1,8 +0,0 @@
1−{-
2− Here we go.
3−-}
4−
5−-- | This is the module's Haddock.
6−module Main (main) where
7−
8−main = return ()
data/examples/module-header/preceding-comment-with-haddock.hsdeleted−8
@@ -1,8 +0,0 @@
1−{-
2− Here we go.
3−-}
4−
5−-- | This is the module's Haddock.
6−module Main (main) where
7−
8−main = return ()
data/examples/module-header/shebang-out.hsdeleted−6
@@ -1,6 +0,0 @@
1−#! /usr/bin/env runhaskell
2−
3−import Prelude
4−
5−main :: IO ()
6−main = putStrLn "hello world"
data/examples/module-header/shebang-with-pragmas-out.hsdeleted−5
@@ -1,5 +0,0 @@
1−#!/usr/bin/env stack
2−
3−{-# LANGUAGE OverloadedStrings #-}
4−
5−main = pure ()
data/examples/module-header/shebang-with-pragmas.hsdeleted−5
@@ -1,5 +0,0 @@
1−#!/usr/bin/env stack
2−
3−{-# LANGUAGE OverloadedStrings #-}
4−
5−main = pure ()
data/examples/module-header/shebang.hsdeleted−6
@@ -1,6 +0,0 @@
1−#! /usr/bin/env runhaskell
2−
3−import Prelude
4−
5−main :: IO ()
6−main = putStrLn "hello world"
data/examples/module-header/singleline-empty-out.hs+4−1
@@ -1,2 +1,5 @@
1-- | This demonstrates a BUG.
1-- | This demonstrates a BUG.
2−module Foo () where
2+module Foo
3+ (
4+ )
5+where
data/examples/module-header/stack-header-0-out.hsdeleted−7
@@ -1,7 +0,0 @@
1−-- stack runhaskell
2−
3−{-# LANGUAGE OverloadedStrings #-}
4−
5−main = return ()
6−
7−-- stack runhaskell
data/examples/module-header/stack-header-0.hsdeleted−4
@@ -1,4 +0,0 @@
1−-- stack runhaskell
2−{-# LANGUAGE OverloadedStrings #-}
3−main = return ()
4−-- stack runhaskell
data/examples/module-header/stack-header-1-out.hsdeleted−8
@@ -1,8 +0,0 @@
1−#!/usr/bin/env stack
2−-- stack runhaskell
3−
4−{-# LANGUAGE OverloadedStrings #-}
5−
6−main = return ()
7−
8−-- stack runhaskell
data/examples/module-header/stack-header-1.hsdeleted−5
@@ -1,5 +0,0 @@
1−#!/usr/bin/env stack
2−-- stack runhaskell
3−{-# LANGUAGE OverloadedStrings #-}
4−main = return ()
5−-- stack runhaskell
data/examples/module-header/stack-header-2-out.hsdeleted−12
@@ -1,12 +0,0 @@
1−#!/usr/bin/env stack
2−{- stack
3− script
4− --resolver lts-6.25
5− --package turtle
6− --package "stm async"
7− --package http-client,http-conduit
8−-}
9−
10−{-# LANGUAGE OverloadedStrings #-}
11−
12−main = return ()
data/examples/module-header/stack-header-2.hsdeleted−12
@@ -1,12 +0,0 @@
1−#!/usr/bin/env stack
2−{- stack
3− script
4− --resolver lts-6.25
5− --package turtle
6− --package "stm async"
7− --package http-client,http-conduit
8−-}
9−
10−{-# LANGUAGE OverloadedStrings #-}
11−
12−main = return ()
data/examples/module-header/warning-pragma-list-multiline-out.hs+3−3
@@ -2,10 +2,10 @@ module Test
2 {-# DEPRECATED
2 {-# DEPRECATED
3 [ "This module is deprecated.",
3 [ "This module is deprecated.",
4 "Please use OtherModule instead."
4 "Please use OtherModule instead."
5− ]
5+ ]
6 #-}
6 #-}
7 ( foo,
7 ( foo,
8 bar,
8 bar,
9− baz,
9+ baz
10− )
10+ )
11where
11where
data/examples/module-header/warning-pragma-multiline-out.hs+4−1
@@ -1,6 +1,9 @@
1module Test
1module Test
2 {-# DEPRECATED "This module is unstable" #-}
2 {-# DEPRECATED "This module is unstable" #-}
3− (foo, bar, baz)
3+ ( foo,
4+ bar,
5+ baz
6+ )
4where
7where
5
8
6import Blah
9import Blah
data/examples/module-header/warning-pragma-out.hs+1−3
@@ -1,5 +1,3 @@
1module Test
1module Test
2− {-# WARNING
3− "This module is very internal"
2+ {-# WARNING "This module is very internal" #-}
4− #-}
5where
3where
data/examples/other/argument-comment-out.hs+12−14
@@ -1,16 +1,14 @@
1−foo ::
1+foo
2− -- | Documentation
2+ :: Int -- ^ Documentation
3− Int ->
4− Bool
3+ -> Bool
5foo _ = True
4foo _ = True
6
5
7−foo ::
6+foo
8− Foo a =>
7+ :: Foo a
9− -- | Foo
8+ => Int -- ^ Foo
10− Int ->
9+ -> Int
11− Int
10+
12−foo ::
11+foo
13− Foo a =>
12+ :: Foo a
14− -- | Foo
13+ => Int -- ^ Foo
15− Int ->
16− Int
14+ -> Int
data/examples/other/comment-after-preceding-haddock-out.hsdeleted−12
@@ -1,12 +0,0 @@
1−module Main where
2−
3−-- | A
4−
5−-- B
6−
7−type D = E
8−
9−-- | This is 'f'
10−
11−-- * Comment
12−f :: a -> b
data/examples/other/comment-after-preceding-haddock.hsdeleted−12
@@ -1,12 +0,0 @@
1−module Main where
2−
3−-- | A
4−
5−-- B
6−
7−type D = E
8−
9−-- | This is 'f'
10−
11−-- * Comment
12−f :: a -> b
data/examples/other/comment-alignment-out.hs+4−4
@@ -1,9 +1,9 @@
1class Foo a where
1class Foo a where
2+
2 -- | Foo.
3 -- | Foo.
3− foo ::
4+ foo
4− Int ->
5+ :: Int
5− -- | Something
6+ -> a -- ^ Something
6− a
7
7
8 -- | Bar.
8 -- | Bar.
9 bar :: a
9 bar :: a
data/examples/other/comment-before-hanging-out.hsdeleted−5
@@ -1,5 +0,0 @@
1−x = Just
2− -- comment
3− do
4− foo
5− bar
data/examples/other/comment-before-hanging.hsdeleted−5
@@ -1,5 +0,0 @@
1−x = Just
2− -- comment
3− do
4− foo
5− bar
data/examples/other/comment-following-preceding-gap-out.hsdeleted−6
@@ -1,6 +0,0 @@
1−foo = bar
2− where
3− baz = return (quux) -- Foo
4−
5− -- Bar
6− meme = gege
data/examples/other/comment-following-preceding-gap.hsdeleted−6
@@ -1,6 +0,0 @@
1−foo = bar
2− where
3− baz = return (quux) -- Foo
4−
5− -- Bar
6− meme = gege
data/examples/other/comment-glued-together-out.hsdeleted−7
@@ -1,7 +0,0 @@
1−module Main (main) where
2−
3−-- | Foo.
4−
5−-- Bar
6−main :: IO ()
7−main = return ()
data/examples/other/comment-glued-together.hsdeleted−6
@@ -1,6 +0,0 @@
1−module Main (main) where
2−
3−{- | Foo. -}
4−-- Bar
5−main :: IO ()
6−main = return ()
data/examples/other/comment-inside-construct-out.hs+2−2
@@ -3,6 +3,6 @@ xs =
3 [ inner list first item,
3 [ inner list first item,
4 inner list second item
4 inner list second item
5 -- inner list last item commented
5 -- inner list last item commented
6− ],
6+ ],
7 outer list item
7 outer list item
8− ]
8+ ]
data/examples/other/comment-multiline-after-out.hsdeleted−7
@@ -1,7 +0,0 @@
1−foo ::
2− -- | start index
3− Int ->
4− -- | length
5− Int ->
6− t a ->
7− t a
data/examples/other/comment-multiline-after.hsdeleted−1
@@ -1 +0,0 @@
1−foo :: Int {- ^ start index -} -> Int {- ^ length -} -> t a -> t a
data/examples/other/comment-style-transform-out.hsdeleted−17
@@ -1,17 +0,0 @@
1−-- |
2−-- Module: Data.Aeson.TH
3−-- Copyright: (c) 2011-2016 Bryan O'Sullivan
4−-- (c) 2011 MailRank, Inc.
5−-- License: BSD3
6−-- Stability: experimental
7−-- Portability: portable
8−module Main where
9−
10−-- |
11−--
12−-- Here is a snippet:
13−--
14−-- @
15−-- x = y + 2
16−-- @
17−x = y + 2
data/examples/other/comment-style-transform.hsdeleted−22
@@ -1,22 +0,0 @@
1−{-|
2−Module: Data.Aeson.TH
3−Copyright: (c) 2011-2016 Bryan O'Sullivan
4− (c) 2011 MailRank, Inc.
5−License: BSD3
6−Stability: experimental
7−Portability: portable
8−-}
9−
10−module Main where
11−
12−{- |
13−
14−Here is a snippet:
15−
16−@
17−x = y + 2
18−@
19−
20−-}
21−
22−x = y + 2
data/examples/other/comment-trailing-space-out.hsdeleted−9
@@ -1,9 +0,0 @@
1−data T
2− = {-
3−
4− some multi-line comment
5−
6− with empty lines
7−
8− -}
9− A
data/examples/other/comment-trailing-space.hsdeleted−9
@@ -1,9 +0,0 @@
1−data T
2− = {-
3−
4− some multi-line comment
5−
6− with empty lines
7−
8− -}
9− A
data/examples/other/comment-two-blocks-out.hsdeleted−8
@@ -1,8 +0,0 @@
1−newNames :: [(String, String)]
2−newNames =
3− let (*) = flip (,)
4− in [ "Control" * "Monad"
5− -- Foo
6−
7− -- Bar
8− ]
data/examples/other/comment-two-blocks.hsdeleted−9
@@ -1,9 +0,0 @@
1−newNames :: [(String, String)]
2−newNames = let (*) = flip (,) in
3− ["Control" * "Monad"
4−
5− -- Foo
6−
7− -- Bar
8−
9− ]
data/examples/other/consequetive-pipe-comments-out.hsdeleted−7
@@ -1,7 +0,0 @@
1−module Main where
2−
3−-- | Foo.
4−
5−-- | Bar.
6−bar :: Int
7−bar = 5
data/examples/other/consequetive-pipe-comments.hsdeleted−8
@@ -1,8 +0,0 @@
1−module Main where
2−
3−-- | Foo.
4−
5−-- | Bar.
6−
7−bar :: Int
8−bar = 5
data/examples/other/cpp/continuation-out.hsdeleted−8
@@ -1,8 +0,0 @@
1−foo :: Int
2−foo = 5
3−
4−#define message_for(a, b) \
5− printf(#a " and " #b ": We love you!\n")
6−
7−bar :: Int
8−bar = 6
data/examples/other/cpp/continuation.hsdeleted−8
@@ -1,8 +0,0 @@
1−foo :: Int
2−foo = 5
3−
4−#define message_for(a, b) \
5− printf(#a " and " #b ": We love you!\n")
6−
7−bar :: Int
8−bar = 6
data/examples/other/cpp/lonely-hash-out.hsdeleted−14
@@ -1,14 +0,0 @@
1−module Main (main) where
2−
3−import Data.Void
4−import Test.Hspec
5−import Test.Hspec.Megaparsec
6−import Text.Megaparsec
7−import Text.Megaparsec.Char
8−
9−# if !MIN_VERSION_base(4,13,0)
10−import Data.Semigroup ((<>))
11−# endif
12−
13−main :: IO ()
14−main = return ()
data/examples/other/cpp/lonely-hash.hsdeleted−14
@@ -1,14 +0,0 @@
1−module Main (main) where
2−
3−import Data.Void
4−import Test.Hspec
5−import Test.Hspec.Megaparsec
6−import Text.Megaparsec
7−import Text.Megaparsec.Char
8−
9−# if !MIN_VERSION_base(4,13,0)
10−import Data.Semigroup ((<>))
11−# endif
12−
13−main :: IO ()
14−main = return ()
data/examples/other/cpp/separation-0a-out.hsdeleted−7
@@ -1,7 +0,0 @@
1−instance Stream s => Monad (ParsecT e s m) where
2− return = pure
3− (>>=) = pBind
4−
5−#if !(MIN_VERSION_base(4,13,0))
6− fail = Fail.fail
7−#endif
data/examples/other/cpp/separation-0a.hsdeleted−6
@@ -1,6 +0,0 @@
1−instance Stream s => Monad (ParsecT e s m) where
2− return = pure
3− (>>=) = pBind
4−#if !(MIN_VERSION_base(4,13,0))
5− fail = Fail.fail
6−#endif
data/examples/other/cpp/separation-0b-out.hsdeleted−10
@@ -1,10 +0,0 @@
1−instance Stream s => Monad (ParsecT e s m) where
2− return = pure
3− (>>=) = pBind
4−
5−#if !(MIN_VERSION_base(4,13,0))
6− fail = Fail.fail
7−#endif
8−
9−foo :: Int
10−foo = undefined
data/examples/other/cpp/separation-0b.hsdeleted−9
@@ -1,9 +0,0 @@
1−instance Stream s => Monad (ParsecT e s m) where
2− return = pure
3− (>>=) = pBind
4−#if !(MIN_VERSION_base(4,13,0))
5− fail = Fail.fail
6−#endif
7−
8−foo :: Int
9−foo = undefined
data/examples/other/cpp/separation-1a-out.hsdeleted−12
@@ -1,12 +0,0 @@
1−decompressingPipe ::
2− (PrimMonad m, MonadThrow m, MonadResource m) =>
3− CompressionMethod ->
4− ConduitT ByteString ByteString m ()
5−decompressingPipe Store = C.awaitForever C.yield
6−decompressingPipe Deflate = Z.decompress $ Z.WindowBits (-15)
7−
8−#ifdef ENABLE_BZIP2
9−decompressingPipe BZip2 = BZ.bunzip2
10−#else
11−decompressingPipe BZip2 = throwM BZip2Unsupported
12−#endif
data/examples/other/cpp/separation-1a.hsdeleted−11
@@ -1,11 +0,0 @@
1−decompressingPipe
2− :: (PrimMonad m, MonadThrow m, MonadResource m)
3− => CompressionMethod
4− -> ConduitT ByteString ByteString m ()
5−decompressingPipe Store = C.awaitForever C.yield
6−decompressingPipe Deflate = Z.decompress $ Z.WindowBits (-15)
7−#ifdef ENABLE_BZIP2
8−decompressingPipe BZip2 = BZ.bunzip2
9−#else
10−decompressingPipe BZip2 = throwM BZip2Unsupported
11−#endif
data/examples/other/cpp/separation-1b-out.hsdeleted−15
@@ -1,15 +0,0 @@
1−decompressingPipe ::
2− (PrimMonad m, MonadThrow m, MonadResource m) =>
3− CompressionMethod ->
4− ConduitT ByteString ByteString m ()
5−decompressingPipe Store = C.awaitForever C.yield
6−decompressingPipe Deflate = Z.decompress $ Z.WindowBits (-15)
7−
8−#ifdef ENABLE_BZIP2
9−decompressingPipe BZip2 = BZ.bunzip2
10−#else
11−decompressingPipe BZip2 = throwM BZip2Unsupported
12−#endif
13−
14−foo :: Int
15−foo = undefined
data/examples/other/cpp/separation-1b.hsdeleted−14
@@ -1,14 +0,0 @@
1−decompressingPipe
2− :: (PrimMonad m, MonadThrow m, MonadResource m)
3− => CompressionMethod
4− -> ConduitT ByteString ByteString m ()
5−decompressingPipe Store = C.awaitForever C.yield
6−decompressingPipe Deflate = Z.decompress $ Z.WindowBits (-15)
7−#ifdef ENABLE_BZIP2
8−decompressingPipe BZip2 = BZ.bunzip2
9−#else
10−decompressingPipe BZip2 = throwM BZip2Unsupported
11−#endif
12−
13−foo :: Int
14−foo = undefined
data/examples/other/cpp/separation-2a-out.hsdeleted−9
@@ -1,9 +0,0 @@
1−ffff, ffffffff :: Natural
2−
3−#ifdef HASKELL_ZIP_DEV_MODE
4−ffff = 200
5−ffffffff = 5000
6−#else
7−ffff = 0xffff
8−ffffffff = 0xffffffff
9−#endif
data/examples/other/cpp/separation-2a.hsdeleted−8
@@ -1,8 +0,0 @@
1−ffff, ffffffff :: Natural
2−#ifdef HASKELL_ZIP_DEV_MODE
3−ffff = 200
4−ffffffff = 5000
5−#else
6−ffff = 0xffff
7−ffffffff = 0xffffffff
8−#endif
data/examples/other/cpp/separation-2b-out.hsdeleted−11
@@ -1,11 +0,0 @@
1−ffff, ffffffff :: Natural
2−#ifdef HASKELL_ZIP_DEV_MODE
3−ffff = 200
4−ffffffff = 5000
5−#else
6−ffff = 0xffff
7−ffffffff = 0xffffffff
8−#endif
9−
10−foo :: Int
11−foo = undefined
data/examples/other/cpp/separation-2b.hsdeleted−11
@@ -1,11 +0,0 @@
1−ffff, ffffffff :: Natural
2−#ifdef HASKELL_ZIP_DEV_MODE
3−ffff = 200
4−ffffffff = 5000
5−#else
6−ffff = 0xffff
7−ffffffff = 0xffffffff
8−#endif
9−
10−foo :: Int
11−foo = undefined
data/examples/other/cpp/shifted-out.hsdeleted−21
@@ -1,21 +0,0 @@
1−sinkData h compression = do
2− (uncompressedSize, crc32, compressedSize) <-
3− case compression of
4− Store ->
5− withCompression
6− dataSink
7− Deflate ->
8− withCompression $
9− Z.compress 9 (Z.WindowBits (-15)) .| dataSink
10−#ifdef ENABLE_BZIP2
11− BZip2 -> withCompression $
12− BZ.bzip2 .| dataSink
13−#else
14− BZip2 -> throwM BZip2Unsupported
15−#endif
16− return
17− DataDescriptor
18− { ddCRC32 = fromIntegral crc32,
19− ddCompressedSize = compressedSize,
20− ddUncompressedSize = uncompressedSize
21− }
data/examples/other/cpp/shifted.hsdeleted−17
@@ -1,17 +0,0 @@
1−sinkData h compression = do
2− (uncompressedSize, crc32, compressedSize) <-
3− case compression of
4− Store -> withCompression
5− dataSink
6− Deflate -> withCompression $
7− Z.compress 9 (Z.WindowBits (-15)) .| dataSink
8−#ifdef ENABLE_BZIP2
9− BZip2 -> withCompression $
10− BZ.bzip2 .| dataSink
11−#else
12− BZip2 -> throwM BZip2Unsupported
13−#endif
14− return DataDescriptor
15− { ddCRC32 = fromIntegral crc32
16− , ddCompressedSize = compressedSize
17− , ddUncompressedSize = uncompressedSize }
data/examples/other/cpp/simple-import-out.hsdeleted−14
@@ -1,14 +0,0 @@
1−module Main (main) where
2−
3−import Data.Void
4−import Test.Hspec
5−import Test.Hspec.Megaparsec
6−import Text.Megaparsec
7−import Text.Megaparsec.Char
8−
9−#if !MIN_VERSION_base(4,13,0)
10−import Data.Semigroup ((<>))
11−#endif
12−
13−main :: IO ()
14−main = return ()
data/examples/other/cpp/simple-import.hsdeleted−14
@@ -1,14 +0,0 @@
1−module Main (main) where
2−
3−import Data.Void
4−import Test.Hspec
5−import Test.Hspec.Megaparsec
6−import Text.Megaparsec
7−import Text.Megaparsec.Char
8−
9−#if !MIN_VERSION_base(4,13,0)
10−import Data.Semigroup ((<>))
11−#endif
12−
13−main :: IO ()
14−main = return ()
data/examples/other/disabling/indented-fragment-out.hsdeleted−7
@@ -1,7 +0,0 @@
1−foo =
2− {- ORMOLU_DISABLE -}
3− testCase "Foo" testFoo :
4− testCase "Bar" testBar :
5− testCase "Baz" testBaz :
6− {- ORMOLU_ENABLE -}
7− []
data/examples/other/disabling/indented-fragment.hsdeleted−7
@@ -1,7 +0,0 @@
1−foo =
2− {- ORMOLU_DISABLE -}
3− testCase "Foo" testFoo :
4− testCase "Bar" testBar :
5− testCase "Baz" testBaz :
6− {- ORMOLU_ENABLE -}
7− []
data/examples/other/disabling/single-definition-out.hsdeleted−10
@@ -1,10 +0,0 @@
1−module Foo (foo, bar) where
2−
3−{- ORMOLU_DISABLE -}
4−foo :: Int -> Int
5−foo = (+5)
6−{- ORMOLU_ENABLE -}
7−
8−bar :: Bool -> Bool
9−bar True = True
10−bar False = True
data/examples/other/disabling/single-definition.hsdeleted−10
@@ -1,10 +0,0 @@
1−module Foo (foo,bar) where
2−
3−{- ORMOLU_DISABLE -}
4−foo :: Int -> Int
5−foo = (+5)
6−{- ORMOLU_ENABLE -}
7−
8−bar :: Bool -> Bool
9−bar True = True
10−bar False = True
data/examples/other/disabling/whole-file-out.hsdeleted−10
@@ -1,10 +0,0 @@
1−{- ORMOLU_DISABLE -}
2−
3−module Foo (foo,bar) where
4−
5−foo :: Int -> Int
6−foo = (+5)
7−
8−bar :: Bool -> Bool
9−bar True = True
10−bar False = True
data/examples/other/disabling/whole-file.hsdeleted−10
@@ -1,10 +0,0 @@
1−{- ORMOLU_DISABLE -}
2−
3−module Foo (foo,bar) where
4−
5−foo :: Int -> Int
6−foo = (+5)
7−
8−bar :: Bool -> Bool
9−bar True = True
10−bar False = True
data/examples/other/empty-forall-out.hsdeleted−18
@@ -1,18 +0,0 @@
1−-- Empty foralls are handled correctly in different situations.
2−
3−data D = forall. D Int
4−
5−data G where
6− G :: forall. Int -> G
7−
8−f :: forall. a -> a
9−f x = x
10−
11−type family T x where
12− forall. T x = x
13−
14−{-# RULES
15−"r"
16− r a =
17− ()
18− #-}
data/examples/other/empty-forall.hsdeleted−17
@@ -1,17 +0,0 @@
1−-- Empty foralls are handled correctly in different situations.
2−
3−data D = forall. D Int
4−
5−data G where
6− G :: forall. Int -> G
7−
8−f :: forall. a -> a
9−f x = x
10−
11−type family T x where
12− forall. T x = x
13−
14−{-# RULES
15− "r"
16− forall. r a = ()
17−#-}
data/examples/other/empty-haddock-out.hsdeleted−5
@@ -1,5 +0,0 @@
1−module Main where
2−
3−-- |
4−foo :: Int
5−foo = 5
data/examples/other/empty-haddock.hsdeleted−6
@@ -1,6 +0,0 @@
1−module Main where
2−
3−-- |
4−
5−foo :: Int
6−foo = 5
data/examples/other/following-comment-last-0-out.hs−2
@@ -1,5 +1,3 @@
1−module Main where
2−
3-- | Another datatype...
1-- | Another datatype...
4data D'
2data D'
5-- ^ ...with two docstrings.
3-- ^ ...with two docstrings.
data/examples/other/following-comment-last-0.hs−2
@@ -1,5 +1,3 @@
1−module Main where
2−
3-- | Another datatype...
1-- | Another datatype...
4data D'
2data D'
5-- ^ ...with two docstrings.
3-- ^ ...with two docstrings.
data/examples/other/following-comment-last-1-out.hs−2
@@ -1,5 +1,3 @@
1−module Main where
2−
3-- | Another datatype...
1-- | Another datatype...
4data D'
2data D'
5 deriving (Show)
3 deriving (Show)
data/examples/other/following-comment-last-1.hs−2
@@ -1,5 +1,3 @@
1−module Main where
2−
3-- | Another datatype...
1-- | Another datatype...
4data D'
2data D'
5 deriving (Show)
3 deriving (Show)
data/examples/other/following-comment-last-2-out.hs−3
@@ -1,10 +1,7 @@
1−module Main where
2−
3-- | Another datatype...
1-- | Another datatype...
4data D'
2data D'
5 deriving (Show)
3 deriving (Show)
6-- ^ ...with two docstrings.
4-- ^ ...with two docstrings.
7
5
8-- more
6-- more
9−
10data B
7data B
data/examples/other/following-comment-last-2.hs−2
@@ -1,5 +1,3 @@
1−module Main where
2−
3-- | Another datatype...
1-- | Another datatype...
4data D'
2data D'
5 deriving (Show)
3 deriving (Show)
data/examples/other/following-comment-last-3-out.hs−2
@@ -1,5 +1,3 @@
1−module Main where
2−
3-- | Another datatype...
1-- | Another datatype...
4data D'
2data D'
5-- ^ ...with two docstrings.
3-- ^ ...with two docstrings.
data/examples/other/following-comment-last-3.hs−2
@@ -1,5 +1,3 @@
1−module Main where
2−
3-- | Another datatype...
1-- | Another datatype...
4data D'
2data D'
5-- ^ ...with two docstrings.
3-- ^ ...with two docstrings.
data/examples/other/haddock-sections-out.hsdeleted−7
@@ -1,7 +0,0 @@
1−-- $weird #anchor#
2−--
3−-- Section 1
4−
5−-- $normal
6−--
7−-- Section 2
data/examples/other/haddock-sections.hsdeleted−7
@@ -1,7 +0,0 @@
1−-- $weird #anchor#
2−--
3−-- Section 1
4−
5−-- $normal
6−--
7−-- Section 2
data/examples/other/inline-comment-0-out.hsdeleted−3
@@ -1,3 +0,0 @@
1−x = ({-a-} b, c)
2−
3−y = ({-a-} b)
data/examples/other/inline-comment-0.hsdeleted−3
@@ -1,3 +0,0 @@
1−x = ({-a-}b, c)
2−
3−y = ({-a-}b)
data/examples/other/inline-comment-1-out.hsdeleted−12
@@ -1,12 +0,0 @@
1−showPs env ((n, _, Let _ t v) : bs) =
2− " " ++ show n ++ " : "
3− ++ showEnv env ({- normalise ctxt env -} t)
4− ++ " = "
5− ++ showEnv env ({- normalise ctxt env -} v)
6− ++ "\n"
7− ++ showPs env bs
8−showPs env ((n, _, b) : bs) =
9− " " ++ show n ++ " : "
10− ++ showEnv env ({- normalise ctxt env -} (binderTy b))
11− ++ "\n"
12− ++ showPs env bs
data/examples/other/inline-comment-1.hsdeleted−9
@@ -1,9 +0,0 @@
1−showPs env ((n, _, Let _ t v):bs)
2− = " " ++ show n ++ " : " ++
3− showEnv env ({- normalise ctxt env -} t) ++ " = " ++
4− showEnv env ({- normalise ctxt env -} v) ++
5− "\n" ++ showPs env bs
6−showPs env ((n, _, b):bs)
7− = " " ++ show n ++ " : " ++
8− showEnv env ({- normalise ctxt env -} (binderTy b)) ++
9− "\n" ++ showPs env bs
data/examples/other/merging-comments-out.hsdeleted−12
@@ -1,12 +0,0 @@
1−foo xs = baz
2− where
3− bar =
4− catMaybes
5− [ lookup langKey gets, -- 1
6− lookup langKey cookies, -- 2
7− lookupText langKey session -- 3
8− ]
9− ++ xs -- 4
10−
11− -- Blah
12− baz = addTwoLetters (id, Set.empty) bar
data/examples/other/merging-comments.hsdeleted−9
@@ -1,9 +0,0 @@
1−foo xs = baz
2− where
3− bar = catMaybes [ lookup langKey gets -- 1
4− , lookup langKey cookies -- 2
5− , lookupText langKey session -- 3
6− ] ++ xs -- 4
7−
8− -- Blah
9− baz = addTwoLetters (id, Set.empty) bar
data/examples/other/multiline-forall-out.hsdeleted−58
@@ -1,58 +0,0 @@
1−{-# LANGUAGE GADTs #-}
2−{-# LANGUAGE PolyKinds #-}
3−{-# LANGUAGE RankNTypes #-}
4−{-# LANGUAGE TypeFamilies #-}
5−
6−-- Multiline foralls are consistent across all declarations
7−
8−data D
9− = forall
10− ( f ::
11− * -> * -> *
12− )
13− (x :: *)
14− (y :: *).
15− D (f x y)
16−
17−data G where
18− G ::
19− forall
20− ( f ::
21− * -> * -> *
22− )
23− (x :: *)
24− (y :: *).
25− f x y ->
26− G
27−
28−f ::
29− forall
30− ( f ::
31− * -> * -> *
32− )
33− (x :: *)
34− (y :: *).
35− f x y ->
36− ()
37−f = const ()
38−
39−type family T f x y where
40− forall
41− ( f ::
42− * -> * -> *
43− )
44− (x :: *)
45− (y :: *).
46− T f x y =
47− f x y
48−
49−{-# RULES
50−"r" forall
51− ( f ::
52− * -> * -> *
53− )
54− (x :: *)
55− (y :: *).
56− r (a :: f x y) =
57− ()
58− #-}
data/examples/other/multiline-forall.hsdeleted−46
@@ -1,46 +0,0 @@
1−{-# LANGUAGE RankNTypes, PolyKinds, GADTs, TypeFamilies #-}
2−
3−-- Multiline foralls are consistent across all declarations
4−
5−data D =
6− forall
7− (f ::
8− * -> * -> *)
9− (x :: *)
10− (y :: *)
11− . D (f x y)
12−
13−data G where
14− G :: forall
15− (f ::
16− * -> * -> *)
17− (x :: *)
18− (y :: *)
19− . f x y -> G
20−
21−f :: forall
22− (f ::
23− * -> * -> *)
24− (x :: *)
25− (y :: *)
26− . f x y -> ()
27−f = const ()
28−
29−type family T f x y where
30− forall
31− (f ::
32− * -> * -> *)
33− (x :: *)
34− (y :: *)
35− . T f x y = f x y
36−
37−{-# RULES
38− "r"
39− forall
40− (f ::
41− * -> * -> *)
42− (x :: *)
43− (y :: *)
44− . r (a :: f x y) =
45− ()
46− #-}
data/examples/other/multiple-blank-line-comment-out.hsdeleted−9
@@ -1,9 +0,0 @@
1−module A where
2−
3−a =
4− b
5− [ f
6− {-,
7−
8− -}
9− ]
data/examples/other/multiple-blank-line-comment.hsdeleted−10
@@ -1,10 +0,0 @@
1−module A where
2−
3−a =
4− b
5− [ f
6− {-,
7−
8−
9− -}
10− ]
data/examples/other/overly-indented-out.hsdeleted−11
@@ -1,11 +0,0 @@
1−tagCloudField ::
2− -- | Destination key
3− String ->
4− -- | Smallest font size, in percent
5− Double ->
6− -- | Biggest font size, in percent
7− Double ->
8− -- | Input tags
9− Tags ->
10− -- | Context
11− Context a
data/examples/other/overly-indented.hsdeleted−10
@@ -1,10 +0,0 @@
1−tagCloudField :: String
2− -- ^ Destination key
3− -> Double
4− -- ^ Smallest font size, in percent
5− -> Double
6− -- ^ Biggest font size, in percent
7− -> Tags
8− -- ^ Input tags
9− -> Context a
10− -- ^ Context
data/examples/other/pragma-comments-after-out.hsdeleted−4
@@ -1,4 +0,0 @@
1−{-# LANGUAGE AllowAmbiguousTypes #-}
2−{-# LANGUAGE ConstraintKinds #-}
3−-- TODO: Fix and delete this pragma
4−{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}
data/examples/other/pragma-comments-after.hsdeleted−3
@@ -1,3 +0,0 @@
1−{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-} -- TODO: Fix and delete this pragma
2−{-# LANGUAGE AllowAmbiguousTypes #-}
3−{-# LANGUAGE ConstraintKinds #-}
data/examples/other/pragma-comments-out.hsdeleted−8
@@ -1,8 +0,0 @@
1−{-# LANGUAGE OverloadedStrings #-}
2−-- TODO This extension is probably too dangerous, remove it.
3−{-# LANGUAGE RecordWildCards #-}
4−-- Avoid warning produced by TH.
5−{-# OPTIONS_GHC -fno-warn-overlapping-patterns #-}
6−
7−-- | Header comment.
8−module Foo () where
data/examples/other/pragma-comments.hsdeleted−11
@@ -1,11 +0,0 @@
1−-- | Header comment.
2−
3−{-# LANGUAGE OverloadedStrings #-}
4−
5−-- Avoid warning produced by TH.
6−{-# OPTIONS_GHC -fno-warn-overlapping-patterns #-}
7−
8−-- TODO This extension is probably too dangerous, remove it.
9−{-# LANGUAGE RecordWildCards #-}
10−
11−module Foo () where
data/examples/other/pragma-out.hs+4−1
@@ -9,4 +9,7 @@
9{-# OPTIONS_HADDOCK prune, show-extensions #-}
9{-# OPTIONS_HADDOCK prune, show-extensions #-}
10
10
11-- | Header comment.
11-- | Header comment.
12−module Foo () where
12+module Foo
13+ (
14+ )
15+where
data/examples/other/pragma-sorting-out.hsdeleted−11
@@ -1,11 +0,0 @@
1−{-# LANGUAGE NondecreasingIndentation #-}
2−{-# LANGUAGE ScopedTypeVariables #-}
3−{-# LANGUAGE TypeFamilies #-}
4−-- This gap is necessary for stylish Haskell not to re-arrange
5−-- NoMonoLocalBinds before TypeFamilies
6−{-# LANGUAGE NoMonoLocalBinds #-}
7−
8−module Foo
9− ( bar,
10− )
11−where
data/examples/other/pragma-sorting.hsdeleted−10
@@ -1,10 +0,0 @@
1−{-# LANGUAGE ScopedTypeVariables #-}
2−{-# LANGUAGE TypeFamilies #-}
3−{-# LANGUAGE NondecreasingIndentation #-}
4−-- This gap is necessary for stylish Haskell not to re-arrange
5−-- NoMonoLocalBinds before TypeFamilies
6−{-# LANGUAGE NoMonoLocalBinds #-}
7−
8−module Foo (
9− bar
10− ) where
data/printer/list0-multi.hsnew file+4
@@ -0,0 +1,4 @@
1+[ foo,
2+ bar,
3+ baz
4+ ]
data/printer/list0-single.hsnew file+1
@@ -0,0 +1 @@
1+[foo, bar, baz]
data/printer/list1-multi.hsnew file+8
@@ -0,0 +1,8 @@
1+[ foo,
2+ bar,
3+ foo
4+ :: ( Int
5+ -> Int
6+ )
7+ -> Bool
8+ ]
data/printer/list1-single.hsnew file+1
@@ -0,0 +1 @@
1+[foo, bar, foo :: (Int -> Int) -> Bool]
data/printer/mhdr-multi.hsnew file+7
@@ -0,0 +1,7 @@
1+module MyModule
2+ ( R,
3+ runR,
4+ txt,
5+ blah
6+ )
7+where
data/printer/mhdr-single.hsnew file+3
@@ -0,0 +1,3 @@
1+module MyModule
2+ (R, runR, txt, blah)
3+where
data/printer/ssig-multi.hsnew file+5
@@ -0,0 +1,5 @@
1+foo
2+ :: ( Int
3+ -> Int
4+ )
5+ -> Bool
data/printer/ssig-single.hsnew file+1
@@ -0,0 +1 @@
1+foo :: (Int -> Int) -> Bool
default.nix+10−148
@@ -1,14 +1,12 @@
1−{ pkgs ? (import ./nix/nixpkgs { inherit system; })
1+{ pkgs ? (import ./nix/nixpkgs) }:
2−, system ? builtins.currentSystem
3−, ormoluCompiler ? "ghc884" # the shell doesn't work with ghc8101 yet
4−}:
5
2
6let
3let
4+ ormoluCompiler = "ghc864";
7− source = pkgs.lib.sourceByRegex ./. [
5+ source = pkgs.lib.sourceByRegex ./.[
8 "^.*\.md$"
6 "^.*\.md$"
9 "^app.*$"
7 "^app.*$"
10 "^data.*$"
8 "^data.*$"
11− "^ormolu\.cabal$"
9+ "^ormolu.cabal$"
12 "^src.*$"
10 "^src.*$"
13 "^tests.*$"
11 "^tests.*$"
14 ];
12 ];
@@ -16,154 +14,18 @@ let
16 overrides = ormoluOverlay;
14 overrides = ormoluOverlay;
17 };
15 };
18 ormoluOverlay = self: super: {
16 ormoluOverlay = self: super: {
19− "ormolu" = super.callCabal2nixWithOptions "ormolu" source "-fdev" { };
17+ "ormolu" = super.callCabal2nix "ormolu" source { };
20− };
18+ };
21 ormolize = import ./nix/ormolize {
19 ormolize = import ./nix/ormolize {
22 inherit pkgs;
20 inherit pkgs;
23 inherit haskellPackages;
21 inherit haskellPackages;
24 };
22 };
25− expectedFailures = [
26− "Agda"
27− "aws"
28− "distributed-process"
29− "esqueleto"
30− "fay"
31− "hlint"
32− "idris"
33− "intero"
34− "leksah"
35− "pandoc"
36− "pipes"
37− "postgrest"
38− "purescript"
39− "tensorflow"
40− ] ++ (if ormoluCompiler == "ghc8101" then [] else ["lens"]);
41− ormolizedPackages = doCheck:
42− pkgs.lib.mapAttrs (name: p: ormolize {
43− package = p;
44− inherit doCheck;
45− expectedFailures =
46− if pkgs.lib.lists.any (x: x == name) expectedFailures
47− then ./expected-failures + "/${name}.txt"
48− else null;
49− }) haskellPackages;
50in {
23in {
51 ormolu = haskellPackages.ormolu;
24 ormolu = haskellPackages.ormolu;
52− # We put the derivations in another attribute set to avoid building them
53− # when nix-build is run.
54− dev = {
55− ormoluShell =
56− haskellPackages.shellFor {
25+ ormoluShell = haskellPackages.shellFor {
57− packages = ps: [
26+ packages = ps: [ ps.ormolu ];
58− ps.ormolu
59− ];
60− buildInputs = [
61− haskellPackages.cabal-install
27+ buildInputs = [ haskellPackages.cabal-install haskellPackages.ghcid ];
62− haskellPackages.ghcid
63− ];
64− };
65− withOrmolu = haskellPackages.shellFor {
66− packages = ps: [];
67− buildInputs = [
68− haskellPackages.cabal-install
69− haskellPackages.ormolu
70− ];
71− };
72 };
28 };
73 inherit ormoluOverlay ormoluCompiler;
29 inherit ormoluOverlay ormoluCompiler;
74− hackage = ormolizedPackages false;
75− hackageTests = with pkgs.lib; pkgs.recurseIntoAttrs (
76− let ps = [
77− "Agda"
78− "QuickCheck"
79− "ShellCheck"
80− "aeson"
81− "attoparsec"
82− "aws"
83− "brick"
84− "capability"
85− "cassava"
86− "conduit"
87− "cryptonite"
88− "diagrams-core"
89− "distributed-process"
90− "esqueleto"
91− "fay"
92− "hakyll"
93− "haxl"
94− "hedgehog"
95− "hledger"
96− "hlint"
97− "http-client"
98− "idris"
99− "intero"
100− "leksah"
101− "lens"
102− "megaparsec"
103− "optics"
104− "ormolu"
105− "pandoc"
106− "parsec3"
107− "pipes"
108− "postgrest"
109− "purescript"
110− "servant"
111− "servant-server"
112− "stack"
113− "tensorflow"
114− "text_1_2_4_0"
115− "tls"
116− "yesod-core"
117− ];
118− in listToAttrs (map (p: nameValuePair p (ormolizedPackages true).${p}) ps)
119− );
120− regionTests = pkgs.stdenv.mkDerivation {
121− name = "ormolu-region-tests";
122− src = ./region-tests;
123− buildInputs = [
124− haskellPackages.ormolu
30+ hackage = pkgs.lib.mapAttrs ormolize haskellPackages;
125− pkgs.diffutils
126− ];
127− doCheck = true;
128− buildPhase = ''
129− cp src.hs result-all-implicit.hs
130− ormolu --check-idempotence --mode inplace result-all-implicit.hs
131− cp src.hs result-all-explicit.hs
132− ormolu --check-idempotence --mode inplace --start-line 1 --end-line 18 result-all-explicit.hs
133− cp src.hs result-only-start.hs
134− ormolu --check-idempotence --mode inplace --start-line 1 result-only-start.hs
135− cp src.hs result-only-end.hs
136− ormolu --check-idempotence --mode inplace --end-line 18 result-only-end.hs
137− cp src.hs result-6-7.hs
138− ormolu --check-idempotence --mode inplace --start-line 6 --end-line 7 result-6-7.hs
139− cp src.hs result-6-8.hs
140− ormolu --check-idempotence --mode inplace --start-line 6 --end-line 8 result-6-8.hs
141− cp src.hs result-9-12.hs
142− ormolu --check-idempotence --mode inplace --start-line 9 --end-line 12 result-9-12.hs
143− cp src.hs result-17-18.hs
144− ormolu --check-idempotence --mode inplace --start-line 17 --end-line 18 result-17-18.hs
145− '';
146− checkPhase = ''
147− echo result-all-implicit.hs
148− diff --color=always expected-result-all.hs result-all-implicit.hs
149− echo result-all-explicit.hs
150− diff --color=always expected-result-all.hs result-all-explicit.hs
151− echo result-only-start.hs
152− diff --color=always expected-result-all.hs result-only-start.hs
153− echo result-only-end.hs
154− diff --color=always expected-result-all.hs result-only-end.hs
155− echo result-6-7.hs
156− diff --color=always expected-result-6-7.hs result-6-7.hs
157− echo result-6-8.hs
158− diff --color=always expected-result-6-8.hs result-6-8.hs
159− echo result-9-12.hs
160− diff --color=always expected-result-9-12.hs result-9-12.hs
161− echo result-17-18.hs
162− diff --color=always expected-result-17-18.hs result-17-18.hs
163− '';
164− installPhase = ''
165− mkdir "$out"
166− find . -name '*.hs' -exec cp --parents {} $out \;
167− '';
168− };
169}
31}
expected-failures/Agda.txtdeleted−11
@@ -1,11 +0,0 @@
1−Formatting is not idempotent:
2− dist/build/Agda/Syntax/Parser/Lexer.hs<rendered>:1602:17
3− before: " = (check_ac"
4− after: " =\n "
5−Please, consider reporting the bug.
6−
7−Formatting is not idempotent:
8− src/full/Agda/Syntax/Translation/InternalToAbstract.hs<rendered>:769:4
9− before: " nes\n\n "
10− after: " nes\n\n -- Andreas"
11−Please, consider reporting the bug.
expected-failures/aws.txtdeleted−9
@@ -1,9 +0,0 @@
1−The GHC parser (in Haddock mode) failed:
2− Examples/PutBucketNearLine.hs:5:1-6
3− parse error on input `import'
4−
5−The GHC parser (in Haddock mode) failed:
6− Examples/Sqs.hs:(88,3)-(90,4)
7− parse error on input `{- | Let's make sure the queue was actually deleted and that the same number of queues exist at when
8− | the program ends as when it started.
9− -}'
expected-failures/distributed-process.txtdeleted−7
@@ -1,7 +0,0 @@
1−The GHC parser (in Haddock mode) failed:
2− benchmarks/Channels.hs:2:1-6
3− parse error on input `import'
4−
5−The GHC parser (in Haddock mode) failed:
6− benchmarks/Spawns.hs:5:1-6
7− parse error on input `import'
expected-failures/esqueleto.txtdeleted−7
@@ -1,7 +0,0 @@
1−The GHC parser (in Haddock mode) failed:
2− src/Database/Esqueleto/Internal/Internal.hs:379:1
3− lexical error in string/character literal at character 's'
4−
5−The GHC parser (in Haddock mode) failed:
6− test/PostgreSQL/Test.hs:562:9-41
7− parse error on input `-- | Check the result is not null'
expected-failures/fay.txtdeleted−18
@@ -1,18 +0,0 @@
1−The GHC parser (in Haddock mode) failed:
2− examples/Separated.hs:12:1-6
3− parse error on input `module'
4−
5−The GHC parser (in Haddock mode) failed:
6− examples/calc.hs:(4,1)-(6,2)
7− parse error on input `-- $ fay -p --html-wrapper --html-js-lib jquery.min.js examples/calc.hs
8−-- You also need to download jquery.min.js.
9−--'
10−
11−The GHC parser (in Haddock mode) failed:
12− examples/canvaswater.hs:(6,1)-(7,17)
13− parse error on input `-- | A demonstration of Fay using the canvas element to display a
14−-- simple effect.'
15−
16−The GHC parser (in Haddock mode) failed:
17− examples/data.hs:9:1-6
18− parse error on input `module'
expected-failures/hlint.txtdeleted−11
@@ -1,11 +0,0 @@
1−Formatting is not idempotent:
2− src/Extension.hs<rendered>:19:22
3− before: "DoRec , -} Recursive"
4− after: "DoRec , -}\n "
5−Please, consider reporting the bug.
6−
7−Formatting is not idempotent:
8− src/Hint/Bracket.hs<rendered>:249:50
9− before: "\" x y [r]) {ideaSpan"
10− after: "\" x y [r])\n "
11−Please, consider reporting the bug.
expected-failures/idris.txtdeleted−7
@@ -1,7 +0,0 @@
1−The GHC parser (in Haddock mode) failed:
2− src/Idris/Parser.hs:1052:1
3− parse error on input `@'
4−
5−The GHC parser (in Haddock mode) failed:
6− src/Idris/Parser/Expr.hs:75:1
7− parse error on input `@'
expected-failures/intero.txtdeleted−5
@@ -1,5 +0,0 @@
1−Formatting is not idempotent:
2− src/InteractiveUI.hs<rendered>:3748:33
3− before: "text \"Try\" <+> doWha"
4− after: "text \"Try\"\n "
5−Please, consider reporting the bug.
expected-failures/leksah.txtdeleted−5
@@ -1,5 +0,0 @@
1−Formatting is not idempotent:
2− src/IDE/Pane/Modules.hs<rendered>:1184:7
3− before: "cr\n -- show"
4− after: "cr\n in -- show"
5−Please, consider reporting the bug.
expected-failures/lens.txtdeleted−3
@@ -1,3 +0,0 @@
1−The GHC parser (in Haddock mode) failed:
2− src/Control/Exception/Lens.hs:180:13-37
3− parse error on input `AllocationLimitExceeded__'
expected-failures/pandoc.txtdeleted−9
@@ -1,9 +0,0 @@
1−The GHC parser (in Haddock mode) failed:
2− benchmark/weigh-pandoc.hs:14:1-6
3− parse error on input `import'
4−
5−Formatting is not idempotent:
6− src/Text/Pandoc/Readers/Vimwiki.hs<rendered>:613:19
7− before: ".softbreak <$ endlin"
8− after: ".softbreak\n <$ en"
9−Please, consider reporting the bug.
expected-failures/pipes.txtdeleted−3
@@ -1,3 +0,0 @@
1−AST of input and AST of formatted code differ.
2− at src/Pipes/Core.hs:(128,1)-(151,2)
3−Please, consider reporting the bug.
expected-failures/postgrest.txtdeleted−5
@@ -1,5 +0,0 @@
1−Formatting is not idempotent:
2− src/PostgREST/DbRequestBuilder.hs<rendered>:149:24
3− before: " || -- clients"
4− after: " || ( origin ="
5−Please, consider reporting the bug.
expected-failures/purescript.txtdeleted−18
@@ -1,18 +0,0 @@
1−The GHC parser (in Haddock mode) failed:
2− src/Language/PureScript/AST/Declarations.hs:479:1-17
3− Invalid type signature: pattern ValueDecl :: ...
4−Perhaps you meant to use PatternSynonyms?
5−
6−The GHC parser (in Haddock mode) failed:
7− src/Language/PureScript/AST/SourcePos.hs:99:1-22
8− Invalid type signature: pattern NullSourceSpan :: ...
9−Perhaps you meant to use PatternSynonyms?
10−
11−The GHC parser (in Haddock mode) failed:
12− src/Language/PureScript/Constants.hs:42:1-15
13− Invalid type signature: pattern Discard :: ...
14−Perhaps you meant to use PatternSynonyms?
15−
16−The GHC parser (in Haddock mode) failed:
17− src/Language/PureScript/Crash.hs:16:1-6
18− parse error on input `import'
expected-failures/tensorflow.txtdeleted−7
@@ -1,7 +0,0 @@
1−The GHC parser (in Haddock mode) failed:
2− tensorflow-mnist/app/Main.hs:50:13-14
3− parse error on input `->'
4−
5−The GHC parser (in Haddock mode) failed:
6− tensorflow-ops/tests/RegressionTest.hs:3:1-6
7− parse error on input `import'
format.shdeleted−14
@@ -1,14 +0,0 @@
1−#!/usr/bin/env nix-shell
2−#!nix-shell default.nix -A dev.withOrmolu -i bash --pure
3−#
4−# Format Ormolu using current version of Ormolu.
5−
6−set -e
7−
8−export LANG="C.UTF-8"
9−
10−cabal format
11−
12−ormolu -m inplace $(find app -type f -name "*.hs")
13−ormolu -m inplace $(find src -type f \( -name "*.hs" -o -name "*.hs-boot" \))
14−ormolu -m inplace $(find tests -type f -name "*.hs")
nix/nixpkgs/default.nix+3−7
@@ -1,13 +1,9 @@
1−{ system ? builtins.currentSystem }:
2let
1let
3− rev = "32b46dd897ab2143a609988a04d87452f0bbef59";
2+ rev = "454eea84a757ca5f733c4ec0f234eba2281c74eb";
4− sha256 = "1gzfrpjnr1bz9zljsyg3a4zrhk8r927sz761mrgcg56dwinkhpjk";
3+ sha256 = "1k9jbix4w43brqlfmvwy218pf5fbmzsnc08shaww9qfdl1rdlaxy";
5 nixpkgs = builtins.fetchTarball {
4 nixpkgs = builtins.fetchTarball {
6 url = "https://github.com/NixOS/nixpkgs/archive/${rev}.tar.gz";
5 url = "https://github.com/NixOS/nixpkgs/archive/${rev}.tar.gz";
7 inherit sha256;
6 inherit sha256;
8 };
7 };
9− pkgs = import nixpkgs {
10− inherit system;
11− config.allowUnfree = true;
8+ pkgs = import nixpkgs { config.allowUnfree = true; };
12− };
13in pkgs
9in pkgs
nix/ormolize/default.nix+6−39
@@ -1,49 +1,16 @@
1−{ pkgs
2−, haskellPackages
1+{ pkgs, haskellPackages }: _: p:
3−}:
4−{ package
5−, expectedFailures ? null
6−, doCheck ? false
7−}:
8− pkgs.stdenv.mkDerivation rec {
2+ pkgs.stdenv.mkDerivation {
9− name = package.name + "-ormolized";
3+ name = p.name + "-ormolized";
10− src = package.src;
4+ src = p.src;
11 buildInputs = [
5 buildInputs = [
12 haskellPackages.cpphs
6 haskellPackages.cpphs
13− haskellPackages.ormolu
7+ (pkgs.haskell.lib.dontCheck haskellPackages.ormolu)
14− pkgs.diffutils
15 pkgs.glibcLocales
8 pkgs.glibcLocales
16 ];
9 ];
17 LANG = "en_US.UTF-8";
10 LANG = "en_US.UTF-8";
18 buildPhase = ''
11 buildPhase = ''
19− hs_files=$(find . -name '*.hs')
12+ find . -name '*.hs' -exec bash ${./ormolize.sh} {} \; 2> log.txt
20− for hs_file in $hs_files; do
21−
22− # drop includes
23− sed -i '/^#include/d' "$hs_file"
24−
25− # deal with CPP
26− cpphs "$hs_file" --noline -DARCH_X86 > "''${hs_file}-nocpp" 2> /dev/null
27−
28− # annoyingly, cpphs cannot modify files in place
29− mv "''${hs_file}-nocpp" "$hs_file"
30−
31− # preserve the original
32− cp "$hs_file" "''${hs_file}-original"
33− done
34−
35− (ormolu --check-idempotence --mode inplace $hs_files || true) 2> log.txt
36 '';
13 '';
37− inherit doCheck;
38− checkPhase =
39− if expectedFailures == null
40− then ''
41− echo "No failures expected"
42− if [[ -s log.txt ]]; then exit 1; fi
43− ''
44− else ''
45− diff --ignore-blank-lines --color=always ${expectedFailures} log.txt
46− '';
47 installPhase = ''
14 installPhase = ''
48 mkdir "$out"
15 mkdir "$out"
49 find . -name '*.hs-original' -exec cp --parents {} $out \;
16 find . -name '*.hs-original' -exec cp --parents {} $out \;
nix/ormolize/ormolize.shnew file+17
@@ -0,0 +1,17 @@
1+set -euo pipefail
2+
3+# drop includes
4+sed -i '/^#include/d' "$1"
5+
6+# deal with CPP in a fairly straightforward way
7+cpphs "$1" --noline > "$1-nocpp" 2> /dev/null
8+
9+# annoyingly, cpphs cannot modify files in place
10+mv "$1-nocpp" "$1"
11+
12+# preserve the original
13+cp "$1" "$1-original"
14+
15+# run ormolu
16+ormolu --tolerate-cpp --check-idempotency --mode inplace "$1" ||
17+ ormolu --tolerate-cpp --unsafe --mode inplace "$1"
ormolu.cabal+153−174
@@ -1,184 +1,163 @@
1+name: ormolu
2+version: 0.0.1.0
1−cabal-version: 1.18
3+cabal-version: 1.18
2−name: ormolu
4+tested-with: GHC==8.6.4
3−version: 0.1.2.0
4−license: BSD3
5+license: BSD3
5−license-file: LICENSE.md
6+license-file: LICENSE.md
6−maintainer: Mark Karpov <mark.karpov@tweag.io>
7+maintainer: Mark Karpov <mark.karpov@tweag.io>
7−tested-with: ghc ==8.6.5 ghc ==8.8.4 ghc ==8.10.1
8−homepage: https://github.com/tweag/ormolu
8+homepage: https://github.com/tweag/ormolu
9−bug-reports: https://github.com/tweag/ormolu/issues
9+bug-reports: https://github.com/tweag/ormolu/issues
10−synopsis: A formatter for Haskell source code
11−description: A formatter for Haskell source code.
12−category: Development, Formatting
10+category: Development, Formatting
11+synopsis: A formatter for Haskell source code
13−build-type: Simple
12+build-type: Simple
14−data-files:
13+description: A formatter for Haskell source code.
14+extra-doc-files: CONTRIBUTING.md
15+ , CHANGELOG.md
16+ , DESIGN.md
17+ , README.md
15− data/examples/declaration/annotation/*.hs
18+data-files: data/examples/declaration/annotation/*.hs
16− data/examples/declaration/class/*.hs
19+ , data/examples/declaration/class/*.hs
17− data/examples/declaration/data/*.hs
20+ , data/examples/declaration/data/*.hs
18− data/examples/declaration/data/gadt/*.hs
21+ , data/examples/declaration/data/gadt/*.hs
19− data/examples/declaration/default/*.hs
22+ , data/examples/declaration/default/*.hs
20− data/examples/declaration/deriving/*.hs
23+ , data/examples/declaration/deriving/*.hs
21− data/examples/declaration/foreign/*.hs
24+ , data/examples/declaration/foreign/*.hs
22− data/examples/declaration/instance/*.hs
25+ , data/examples/declaration/instance/*.hs
23− data/examples/declaration/rewrite-rule/*.hs
26+ , data/examples/declaration/rewrite-rule/*.hs
24− data/examples/declaration/role-annotation/*.hs
27+ , data/examples/declaration/role-annotation/*.hs
25− data/examples/declaration/signature/complete/*.hs
28+ , data/examples/declaration/signature/complete/*.hs
26− data/examples/declaration/signature/fixity/*.hs
29+ , data/examples/declaration/signature/fixity/*.hs
27− data/examples/declaration/signature/inline/*.hs
30+ , data/examples/declaration/signature/inline/*.hs
28− data/examples/declaration/signature/minimal/*.hs
31+ , data/examples/declaration/signature/minimal/*.hs
29− data/examples/declaration/signature/pattern/*.hs
32+ , data/examples/declaration/signature/pattern/*.hs
30− data/examples/declaration/signature/set-cost-centre/*.hs
33+ , data/examples/declaration/signature/set-cost-centre/*.hs
31− data/examples/declaration/signature/specialize/*.hs
34+ , data/examples/declaration/signature/specialize/*.hs
32− data/examples/declaration/signature/type/*.hs
35+ , data/examples/declaration/signature/type/*.hs
33− data/examples/declaration/splice/*.hs
36+ , data/examples/declaration/splice/*.hs
37+ , data/examples/declaration/type/*.hs
34− data/examples/declaration/type-families/closed-type-family/*.hs
38+ , data/examples/declaration/type-families/closed-type-family/*.hs
35− data/examples/declaration/type-families/data-family/*.hs
39+ , data/examples/declaration/type-families/data-family/*.hs
36− data/examples/declaration/type-families/type-family/*.hs
40+ , data/examples/declaration/type-families/type-family/*.hs
37− data/examples/declaration/type-synonyms/*.hs
41+ , data/examples/declaration/type-synonyms/*.hs
38− data/examples/declaration/type/*.hs
42+ , data/examples/declaration/value/function/*.hs
39− data/examples/declaration/value/function/*.hs
40− data/examples/declaration/value/function/arrow/*.hs
43+ , data/examples/declaration/value/function/arrow/*.hs
41− data/examples/declaration/value/function/comprehension/*.hs
42− data/examples/declaration/value/function/do/*.hs
43− data/examples/declaration/value/function/infix/*.hs
44− data/examples/declaration/value/function/pattern/*.hs
44+ , data/examples/declaration/value/function/pattern/*.hs
45− data/examples/declaration/value/other/*.hs
45+ , data/examples/declaration/value/other/*.hs
46− data/examples/declaration/value/pattern-synonyms/*.hs
46+ , data/examples/declaration/value/pattern-synonyms/*.hs
47− data/examples/declaration/warning/*.hs
47+ , data/examples/declaration/warning/*.hs
48− data/examples/import/*.hs
48+ , data/examples/import/*.hs
49− data/examples/module-header/*.hs
49+ , data/examples/module-header/*.hs
50− data/examples/other/*.hs
50+ , data/examples/other/*.hs
51−
51+ , data/printer/*.hs
52−extra-doc-files:
53− CONTRIBUTING.md
54− CHANGELOG.md
55− DESIGN.md
56− README.md
57
52
58source-repository head
53source-repository head
59− type: git
54+ type: git
60− location: https://github.com/tweag/ormolu.git
55+ location: https://github.com/tweag/ormolu.git
61
56
62flag dev
57flag dev
63− description: Turn on development settings.
58+ description: Turn on development settings.
64− default: False
65− manual: True
59+ manual: True
60+ default: False
66
61
67library
62library
63+ hs-source-dirs: src
64+ build-depends: base >= 4.12 && < 5.0
65+ , bytestring >= 0.2 && < 0.11
66+ , containers >= 0.5 && < 0.7
67+ , dlist >= 0.8 && < 0.9
68+ , exceptions >= 0.6 && < 0.11
69+ , ghc >= 8.4.3
70+ , ghc-boot-th >= 8.4.3
71+ , ghc-paths >= 0.1 && < 0.2
72+ , mtl >= 2.0 && < 3.0
73+ , syb >= 0.7 && < 0.8
74+ , text >= 0.2 && < 1.3
68− exposed-modules:
75+ exposed-modules: Ormolu
69− Ormolu
70− Ormolu.Config
76+ , Ormolu.Config
71− Ormolu.Diff
77+ , Ormolu.Diff
72− Ormolu.Exception
78+ , Ormolu.Exception
73− Ormolu.Imports
79+ , Ormolu.Imports
74− Ormolu.Parser
80+ , Ormolu.Parser
75− Ormolu.Parser.Anns
81+ , Ormolu.Parser.Anns
76− Ormolu.Parser.CommentStream
82+ , Ormolu.Parser.CommentStream
77− Ormolu.Parser.Pragma
83+ , Ormolu.Parser.Pragma
78− Ormolu.Parser.Result
84+ , Ormolu.Parser.Result
79− Ormolu.Parser.Shebang
80− Ormolu.Printer
85+ , Ormolu.Printer
81− Ormolu.Printer.Combinators
86+ , Ormolu.Printer.Combinators
82− Ormolu.Printer.Comments
87+ , Ormolu.Printer.Comments
83− Ormolu.Printer.Internal
88+ , Ormolu.Printer.Internal
84− Ormolu.Printer.Meat.Common
89+ , Ormolu.Printer.Meat.Common
85− Ormolu.Printer.Meat.Declaration
90+ , Ormolu.Printer.Meat.Declaration
86− Ormolu.Printer.Meat.Declaration.Annotation
91+ , Ormolu.Printer.Meat.Declaration.Annotation
87− Ormolu.Printer.Meat.Declaration.Class
92+ , Ormolu.Printer.Meat.Declaration.Class
88− Ormolu.Printer.Meat.Declaration.Data
93+ , Ormolu.Printer.Meat.Declaration.Data
89− Ormolu.Printer.Meat.Declaration.Default
94+ , Ormolu.Printer.Meat.Declaration.Default
90− Ormolu.Printer.Meat.Declaration.Foreign
95+ , Ormolu.Printer.Meat.Declaration.Foreign
91− Ormolu.Printer.Meat.Declaration.Instance
96+ , Ormolu.Printer.Meat.Declaration.Instance
92− Ormolu.Printer.Meat.Declaration.RoleAnnotation
97+ , Ormolu.Printer.Meat.Declaration.RoleAnnotation
93− Ormolu.Printer.Meat.Declaration.Rule
98+ , Ormolu.Printer.Meat.Declaration.Rule
94− Ormolu.Printer.Meat.Declaration.Signature
99+ , Ormolu.Printer.Meat.Declaration.Signature
95− Ormolu.Printer.Meat.Declaration.Splice
100+ , Ormolu.Printer.Meat.Declaration.Splice
96− Ormolu.Printer.Meat.Declaration.Type
101+ , Ormolu.Printer.Meat.Declaration.Type
97− Ormolu.Printer.Meat.Declaration.TypeFamily
102+ , Ormolu.Printer.Meat.Declaration.TypeFamily
98− Ormolu.Printer.Meat.Declaration.Value
103+ , Ormolu.Printer.Meat.Declaration.Value
99− Ormolu.Printer.Meat.Declaration.Warning
104+ , Ormolu.Printer.Meat.Declaration.Warning
100− Ormolu.Printer.Meat.ImportExport
105+ , Ormolu.Printer.Meat.ImportExport
106+ , Ormolu.Printer.Meat.Pragma
101− Ormolu.Printer.Meat.Module
107+ , Ormolu.Printer.Meat.Module
102− Ormolu.Printer.Meat.Pragma
103− Ormolu.Printer.Meat.Type
108+ , Ormolu.Printer.Meat.Type
104− Ormolu.Printer.Operators
105− Ormolu.Printer.SpanStream
109+ , Ormolu.Printer.SpanStream
106− Ormolu.Processing.Common
107− Ormolu.Processing.Cpp
108− Ormolu.Processing.Postprocess
109− Ormolu.Processing.Preprocess
110− Ormolu.Utils
110+ , Ormolu.Utils
111−
112− hs-source-dirs: src
113− other-modules:
114− GHC
115− GHC.DynFlags
116−
117− default-language: Haskell2010
118− build-depends:
119− base >=4.12 && <5.0,
120− bytestring >=0.2 && <0.11,
121− containers >=0.5 && <0.7,
122− dlist >=0.8 && <2.0,
123− exceptions >=0.6 && <0.11,
124− ghc-lib-parser >=8.10 && <8.11,
125− mtl >=2.0 && <3.0,
126− syb >=0.7 && <0.8,
127− text >=0.2 && <1.3
128−
129− if flag(dev)
111+ if flag(dev)
130− ghc-options:
112+ ghc-options: -Wall -Werror -Wcompat
131− -Wall -Werror -Wcompat -Wincomplete-record-updates
113+ -Wincomplete-record-updates
114+ -Wincomplete-uni-patterns
132− -Wincomplete-uni-patterns -Wnoncanonical-monad-instances
115+ -Wnoncanonical-monad-instances
133− -Wno-missing-home-modules
116+ -Wnoncanonical-monadfail-instances
134−
135− else
117+ else
136− ghc-options: -O2 -Wall
118+ ghc-options: -O2 -Wall
137−
138−executable ormolu
139− main-is: Main.hs
140− hs-source-dirs: app
141− other-modules: Paths_ormolu
142− default-language: Haskell2010
119+ default-language: Haskell2010
143− build-depends:
144− base >=4.12 && <5.0,
145− ghc-lib-parser >=8.10 && <8.11,
146− gitrev >=1.3 && <1.4,
147− optparse-applicative >=0.14 && <0.17,
148− ormolu -any,
149− text >=0.2 && <1.3
150−
151− if flag(dev)
152− ghc-options:
153− -Wall -Werror -Wcompat -Wincomplete-record-updates
154− -Wincomplete-uni-patterns -Wnoncanonical-monad-instances
155− -optP-Wno-nonportable-include-path
156−
157− else
158− ghc-options: -O2 -Wall -rtsopts
159
120
160test-suite tests
121test-suite tests
161− type: exitcode-stdio-1.0
162− main-is: Spec.hs
122+ main-is: Spec.hs
163− build-tools: hspec-discover >=2.0 && <3.0
164− hs-source-dirs: tests
123+ hs-source-dirs: tests
124+ type: exitcode-stdio-1.0
125+ build-depends: base >= 4.12 && < 5.0
126+ , containers >= 0.5 && < 0.7
127+ , filepath >= 1.2 && < 1.5
128+ , hspec >= 2.0 && < 3.0
129+ , ormolu
130+ , path >= 0.6 && < 0.7
131+ , path-io >= 1.4.2 && < 2.0
132+ , text >= 0.2 && < 1.3
133+ build-tools: hspec-discover >= 2.0 && < 3.0
165− other-modules:
134+ other-modules:
135+ Ormolu.Printer.CombinatorsSpec
166− Ormolu.Parser.PragmaSpec
136+ , Ormolu.Parser.PragmaSpec
167− Ormolu.PrinterSpec
137+ , Ormolu.PrinterSpec
168
138
139+ if flag(dev)
140+ ghc-options: -Wall -Werror
141+ else
142+ ghc-options: -O2 -Wall
169− default-language: Haskell2010
143+ default-language: Haskell2010
170− build-depends:
171− base >=4.12 && <5.0,
172− containers >=0.5 && <0.7,
173− filepath >=1.2 && <1.5,
174− hspec >=2.0 && <3.0,
175− ormolu -any,
176− path >=0.6 && <0.8,
177− path-io >=1.4.2 && <2.0,
178− text >=0.2 && <1.3
179
144
145+executable ormolu
146+ main-is: Main.hs
147+ hs-source-dirs: app
148+ build-depends: base >= 4.12 && < 5.0
149+ , ghc >= 8.4.3
150+ , gitrev >= 1.3 && < 1.4
151+ , optparse-applicative >= 0.14 && < 0.15
152+ , ormolu
153+ , text >= 0.2 && < 1.3
154+ other-modules: Paths_ormolu
180− if flag(dev)
155+ if flag(dev)
181− ghc-options: -Wall -Werror
156+ ghc-options: -Wall -Werror -Wcompat
182−
157+ -Wincomplete-record-updates
158+ -Wincomplete-uni-patterns
159+ -Wnoncanonical-monad-instances
160+ -Wnoncanonical-monadfail-instances
183− else
161+ else
184− ghc-options: -O2 -Wall
162+ ghc-options: -O2 -Wall
163+ default-language: Haskell2010
region-tests/expected-result-17-18.hsdeleted−17
@@ -1,17 +0,0 @@
1−{-# LANGUAGE LambdaCase #-}
2−
3−module Foo (
4− foo, bar, baz) where
5−
6−foo :: Int
7−foo = 5
8−
9−bar :: Int -> Int
10−bar = \case
11− 0 -> foo
12− x -> x - foo
13−
14−baz :: Int -> Int
15−baz = gege
16− where
17− gege = 1 + 2
region-tests/expected-result-6-7.hsdeleted−17
@@ -1,17 +0,0 @@
1−{-# LANGUAGE LambdaCase #-}
2−
3−module Foo (
4− foo, bar, baz) where
5−
6−foo :: Int
7−foo = 5
8−
9−bar :: Int -> Int
10−bar = \case
11− 0 -> foo
12− x -> x - foo
13−
14−baz :: Int -> Int
15−baz = gege
16− where
17− gege = 1 + 2
region-tests/expected-result-6-8.hsdeleted−16
@@ -1,16 +0,0 @@
1−{-# LANGUAGE LambdaCase #-}
2−
3−module Foo (
4− foo, bar, baz) where
5−
6−foo :: Int
7−foo = 5
8−bar :: Int -> Int
9−bar = \case
10− 0 -> foo
11− x -> x - foo
12−
13−baz :: Int -> Int
14−baz = gege
15− where
16− gege = 1 + 2
region-tests/expected-result-9-12.hsdeleted−17
@@ -1,17 +0,0 @@
1−{-# LANGUAGE LambdaCase #-}
2−
3−module Foo (
4− foo, bar, baz) where
5−
6−foo :: Int
7−foo = 5
8−
9−bar :: Int -> Int
10−bar = \case
11− 0 -> foo
12− x -> x - foo
13−
14−baz :: Int -> Int
15−baz = gege
16− where
17− gege = 1 + 2
region-tests/expected-result-all.hsdeleted−21
@@ -1,21 +0,0 @@
1−{-# LANGUAGE LambdaCase #-}
2−
3−module Foo
4− ( foo,
5− bar,
6− baz,
7− )
8−where
9−
10−foo :: Int
11−foo = 5
12−
13−bar :: Int -> Int
14−bar = \case
15− 0 -> foo
16− x -> x - foo
17−
18−baz :: Int -> Int
19−baz = gege
20− where
21− gege = 1 + 2
region-tests/src.hsdeleted−17
@@ -1,17 +0,0 @@
1−{-# LANGUAGE LambdaCase #-}
2−
3−module Foo (
4− foo, bar, baz) where
5−
6−foo :: Int
7−foo = 5
8−
9−bar :: Int -> Int
10−bar = \case
11− 0 -> foo
12− x -> x - foo
13−
14−baz :: Int -> Int
15−baz = gege
16− where
17− gege = 1 + 2
shell.nix+2−4
@@ -1,5 +1,3 @@
1−{ pkgs ? (import ./nix/nixpkgs { inherit system; })
1+{ pkgs ? (import ./nix/nixpkgs) }:
2−, system ? builtins.currentSystem
3−}:
4
2
5−(import ./default.nix { inherit pkgs; }).dev.ormoluShell
3+(import ./default.nix { inherit pkgs; }).ormoluShell
src/GHC.hsdeleted−12
@@ -1,12 +0,0 @@
1−module GHC
2− ( module X,
3− )
4−where
5−
6−import ApiAnnotation as X
7−import BasicTypes as X
8−import GHC.Hs as X
9−import GHC.Hs.Instances as X ()
10−import Module as X
11−import RdrName as X
12−import SrcLoc as X
src/GHC/DynFlags.hsdeleted−49
@@ -1,49 +0,0 @@
1−{-# OPTIONS_GHC -Wno-missing-fields #-}
2−
3−-- Modified from ghc-lib-api-ext.
4−
5−module GHC.DynFlags
6− ( baseDynFlags,
7− )
8−where
9−
10−import Config
11−import DynFlags
12−import Fingerprint
13−import GHC.Platform
14−import ToolSettings
15−
16−fakeSettings :: Settings
17−fakeSettings =
18− Settings
19− { sGhcNameVersion =
20− GhcNameVersion
21− { ghcNameVersion_programName = "ghc",
22− ghcNameVersion_projectVersion = cProjectVersion
23− },
24− sFileSettings = FileSettings {},
25− sTargetPlatform =
26− Platform
27− { platformWordSize = PW8,
28− platformMini =
29− PlatformMini
30− { platformMini_arch = ArchUnknown,
31− platformMini_os = OSUnknown
32− },
33− platformUnregisterised = True
34− },
35− sPlatformMisc = PlatformMisc {},
36− sPlatformConstants =
37− PlatformConstants {pc_DYNAMIC_BY_DEFAULT = False, pc_WORD_SIZE = 8},
38− sToolSettings =
39− ToolSettings
40− { toolSettings_opt_P_fingerprint = fingerprint0,
41− toolSettings_pgm_F = ""
42− }
43− }
44−
45−fakeLlvmConfig :: LlvmConfig
46−fakeLlvmConfig = LlvmConfig [] []
47−
48−baseDynFlags :: DynFlags
49−baseDynFlags = defaultDynFlags fakeSettings fakeLlvmConfig
src/Ormolu.hs+58−71
@@ -1,25 +1,23 @@
1−{-# LANGUAGE BangPatterns #-}
2−
3-- | A formatter for Haskell source code.
1-- | A formatter for Haskell source code.
2+
3+{-# LANGUAGE RecordWildCards #-}
4+
4module Ormolu
5module Ormolu
5− ( ormolu,
6+ ( ormolu
6− ormoluFile,
7+ , ormoluFile
7− ormoluStdin,
8+ , ormoluStdin
8− Config (..),
9+ , Config (..)
9− RegionIndices (..),
10− defaultConfig,
10+ , defaultConfig
11− DynOption (..),
11+ , DynOption (..)
12− OrmoluException (..),
12+ , OrmoluException (..)
13− withPrettyOrmoluExceptions,
13+ , withPrettyOrmoluExceptions
14 )
14 )
15where
15where
16
16
17−import qualified CmdLineParser as GHC
18import Control.Exception
17import Control.Exception
19import Control.Monad
18import Control.Monad
20import Control.Monad.IO.Class (MonadIO (..))
19import Control.Monad.IO.Class (MonadIO (..))
21import Data.Text (Text)
20import Data.Text (Text)
22−import qualified Data.Text as T
23import Debug.Trace
21import Debug.Trace
24import Ormolu.Config
22import Ormolu.Config
25import Ormolu.Diff
23import Ormolu.Diff
@@ -28,6 +26,9 @@ import Ormolu.Parser
28import Ormolu.Parser.Result
26import Ormolu.Parser.Result
29import Ormolu.Printer
27import Ormolu.Printer
30import Ormolu.Utils (showOutputable)
28import Ormolu.Utils (showOutputable)
29+import System.IO (hGetContents, stdin)
30+import qualified CmdLineParser as GHC
31+import qualified Data.Text as T
31import qualified SrcLoc as GHC
32import qualified SrcLoc as GHC
32
33
33-- | Format a 'String', return formatted version as 'Text'.
34-- | Format a 'String', return formatted version as 'Text'.
@@ -40,30 +41,22 @@ import qualified SrcLoc as GHC
40-- side-effects though.
41-- side-effects though.
41-- * Takes file name just to use it in parse error messages.
42-- * Takes file name just to use it in parse error messages.
42-- * Throws 'OrmoluException'.
43-- * Throws 'OrmoluException'.
44+
43−ormolu ::
45+ormolu
44− MonadIO m =>
46+ :: MonadIO m
45− -- | Ormolu configuration
47+ => Config -- ^ Ormolu configuration
46− Config RegionIndices ->
47− -- | Location of source file
48+ -> FilePath -- ^ Location of source file
48− FilePath ->
49− -- | Input to format
49+ -> String -- ^ Input to format
50− String ->
51− m Text
50+ -> m Text
52−ormolu cfgWithIndices path str = do
51+ormolu cfg path str = do
53− let totalLines = length (lines str)
54− cfg = regionIndicesToDeltas totalLines <$> cfgWithIndices
55− (warnings, result0) <-
52+ (ws, result0) <-
56 parseModule' cfg OrmoluParsingFailed path str
53 parseModule' cfg OrmoluParsingFailed path str
57 when (cfgDebug cfg) $ do
54 when (cfgDebug cfg) $ do
58 traceM "warnings:\n"
55 traceM "warnings:\n"
59− traceM (concatMap showWarn warnings)
56+ traceM (concatMap showWarn ws)
60 traceM (prettyPrintParseResult result0)
57 traceM (prettyPrintParseResult result0)
61− -- We're forcing 'txt' here because otherwise errors (such as messages
62− -- about not-yet-supported functionality) will be thrown later when we try
63− -- to parse the rendered code back, inside of GHC monad wrapper which will
64− -- lead to error messages presenting the exceptions as GHC bugs.
65− let !txt = printModule result0
58+ let txt = printModule (cfgDebug cfg) result0
66− when (not (cfgUnsafe cfg) || cfgCheckIdempotence cfg) $ do
59+ when (not (cfgUnsafe cfg) || cfgCheckIdempotency cfg) $ do
67 let pathRendered = path ++ "<rendered>"
60 let pathRendered = path ++ "<rendered>"
68 -- Parse the result of pretty-printing again and make sure that AST
61 -- Parse the result of pretty-printing again and make sure that AST
69 -- is the same as AST of original snippet module span positions.
62 -- is the same as AST of original snippet module span positions.
@@ -79,13 +72,12 @@ ormolu cfgWithIndices path str = do
79 Different ss -> liftIO $ throwIO (OrmoluASTDiffers path ss)
72 Different ss -> liftIO $ throwIO (OrmoluASTDiffers path ss)
80 -- Try re-formatting the formatted result to check if we get exactly
73 -- Try re-formatting the formatted result to check if we get exactly
81 -- the same output.
74 -- the same output.
82− when (cfgCheckIdempotence cfg) $
75+ when (cfgCheckIdempotency cfg) $
83− let txt2 = printModule result1
76+ let txt2 = printModule False result1
84 in case diffText txt txt2 pathRendered of
77 in case diffText txt txt2 pathRendered of
85 Nothing -> return ()
78 Nothing -> return ()
86− Just (loc, l, r) ->
79+ Just (loc, l, r) -> liftIO $
87− liftIO $
88− throwIO (OrmoluNonIdempotentOutput loc l r)
80+ throwIO (OrmoluNonIdempotentOutput loc l r)
89 return txt
81 return txt
90
82
91-- | Load a file and format it. The file stays intact and the rendered
83-- | Load a file and format it. The file stays intact and the rendered
@@ -93,14 +85,12 @@ ormolu cfgWithIndices path str = do
93--
85--
94-- > ormoluFile cfg path =
86-- > ormoluFile cfg path =
95-- > liftIO (readFile path) >>= ormolu cfg path
87-- > liftIO (readFile path) >>= ormolu cfg path
88+
96−ormoluFile ::
89+ormoluFile
97− MonadIO m =>
90+ :: MonadIO m
98− -- | Ormolu configuration
91+ => Config -- ^ Ormolu configuration
99− Config RegionIndices ->
100− -- | Location of source file
92+ -> FilePath -- ^ Location of source file
101− FilePath ->
102− -- | Resulting rendition
93+ -> m Text -- ^ Resulting rendition
103− m Text
104ormoluFile cfg path =
94ormoluFile cfg path =
105 liftIO (readFile path) >>= ormolu cfg path
95 liftIO (readFile path) >>= ormolu cfg path
106
96
@@ -108,40 +98,37 @@ ormoluFile cfg path =
108--
98--
109-- > ormoluStdin cfg =
99-- > ormoluStdin cfg =
110-- > liftIO (hGetContents stdin) >>= ormolu cfg "<stdin>"
100-- > liftIO (hGetContents stdin) >>= ormolu cfg "<stdin>"
101+
111−ormoluStdin ::
102+ormoluStdin
112− MonadIO m =>
103+ :: MonadIO m
113− -- | Ormolu configuration
104+ => Config -- ^ Ormolu configuration
114− Config RegionIndices ->
115− -- | Resulting rendition
105+ -> m Text -- ^ Resulting rendition
116− m Text
117ormoluStdin cfg =
106ormoluStdin cfg =
118− liftIO getContents >>= ormolu cfg "<stdin>"
107+ liftIO (hGetContents stdin) >>= ormolu cfg "<stdin>"
119
108
120----------------------------------------------------------------------------
109----------------------------------------------------------------------------
121-- Helpers
110-- Helpers
122
111
123-- | A wrapper around 'parseModule'.
112-- | A wrapper around 'parseModule'.
113+
124−parseModule' ::
114+parseModule'
125− MonadIO m =>
115+ :: MonadIO m
126− -- | Ormolu configuration
116+ => Config -- ^ Ormolu configuration
127− Config RegionDeltas ->
117+ -> (GHC.SrcSpan -> String -> OrmoluException)
128− -- | How to obtain 'OrmoluException' to throw when parsing fails
118+ -- ^ How to obtain 'OrmoluException' to throw when parsing fails
129− (GHC.SrcSpan -> String -> OrmoluException) ->
130− -- | File name to use in errors
119+ -> FilePath -- ^ File name to use in errors
131− FilePath ->
132− -- | Actual input for the parser
120+ -> String -- ^ Actual input for the parser
133− String ->
134− m ([GHC.Warn], ParseResult)
121+ -> m ([GHC.Warn], ParseResult)
135parseModule' cfg mkException path str = do
122parseModule' cfg mkException path str = do
136− (warnings, r) <- parseModule cfg path str
123+ (ws, r) <- parseModule cfg path str
137 case r of
124 case r of
138 Left (spn, err) -> liftIO $ throwIO (mkException spn err)
125 Left (spn, err) -> liftIO $ throwIO (mkException spn err)
139− Right x -> return (warnings, x)
126+ Right x -> return (ws, x)
140
127
141-- | Pretty-print a 'GHC.Warn'.
128-- | Pretty-print a 'GHC.Warn'.
129+
142showWarn :: GHC.Warn -> String
130showWarn :: GHC.Warn -> String
143−showWarn (GHC.Warn reason l) =
131+showWarn (GHC.Warn reason l) = unlines
144− unlines
145− [ showOutputable reason,
132+ [ showOutputable reason
146− showOutputable l
133+ , showOutputable l
147− ]
134+ ]
src/Ormolu/Config.hs+35−70
@@ -1,89 +1,54 @@
1−{-# LANGUAGE DeriveFunctor #-}
1+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
2+{-# LANGUAGE OverloadedStrings #-}
2−{-# LANGUAGE RecordWildCards #-}
3+{-# LANGUAGE RecordWildCards #-}
3
4
4-- | Configuration options used by the tool.
5-- | Configuration options used by the tool.
6+
5module Ormolu.Config
7module Ormolu.Config
6− ( Config (..),
8+ ( Config (..)
7− RegionIndices (..),
8− RegionDeltas (..),
9− defaultConfig,
9+ , defaultConfig
10− regionIndicesToDeltas,
11− DynOption (..),
10+ , DynOption (..)
12− dynOptionToLocatedStr,
11+ , dynOptionToLocatedStr
13 )
12 )
14where
13where
15
14
16import qualified SrcLoc as GHC
15import qualified SrcLoc as GHC
17
16
18-- | Ormolu configuration.
17-- | Ormolu configuration.
19−data Config region = Config
20− { -- | Dynamic options to pass to GHC parser
21− cfgDynOptions :: ![DynOption],
22− -- | Do formatting faster but without automatic detection of defects
23− cfgUnsafe :: !Bool,
24− -- | Output information useful for debugging
25− cfgDebug :: !Bool,
26− -- | Checks if re-formatting the result is idempotent
27− cfgCheckIdempotence :: !Bool,
28− -- | Region selection
29− cfgRegion :: !region
30− }
31− deriving (Eq, Show, Functor)
32
18
33−-- | Region selection as the combination of start and end line numbers.
19+data Config = Config
34−data RegionIndices = RegionIndices
20+ { cfgDynOptions :: ![DynOption]
35− { -- | Start line of the region to format
21+ -- ^ Dynamic options to pass to GHC parser
36− regionStartLine :: !(Maybe Int),
22+ , cfgUnsafe :: !Bool
37− -- | End line of the region to format
23+ -- ^ Do formatting faster but without automatic detection of defects
38− regionEndLine :: !(Maybe Int)
24+ , cfgDebug :: !Bool
25+ -- ^ Output information useful for debugging
26+ , cfgTolerateCpp :: !Bool
27+ -- ^ Do not fail if CPP pragma is present (still doesn't handle CPP but
28+ -- useful for formatting of files that enable the extension without
29+ -- actually containing CPP macros)
30+ , cfgCheckIdempotency :: !Bool
31+ -- ^ Checks if re-formatting the result is idempotent.
32+ } deriving (Eq, Show)
33+
34+-- | Default 'Config'.
35+
36+defaultConfig :: Config
37+defaultConfig = Config
38+ { cfgDynOptions = []
39+ , cfgUnsafe = False
40+ , cfgDebug = False
41+ , cfgTolerateCpp = False
42+ , cfgCheckIdempotency = False
39 }
43 }
40− deriving (Eq, Show)
41−
42−-- | Region selection as the length of the literal prefix and the literal
43−-- suffix.
44−data RegionDeltas = RegionDeltas
45− { -- | Prefix length in number of lines
46− regionPrefixLength :: !Int,
47− -- | Suffix length in number of lines
48− regionSuffixLength :: !Int
49− }
50− deriving (Eq, Show)
51−
52−-- | Default @'Config' 'RegionIndices'@.
53−defaultConfig :: Config RegionIndices
54−defaultConfig =
55− Config
56− { cfgDynOptions = [],
57− cfgUnsafe = False,
58− cfgDebug = False,
59− cfgCheckIdempotence = False,
60− cfgRegion =
61− RegionIndices
62− { regionStartLine = Nothing,
63− regionEndLine = Nothing
64− }
65− }
66−
67−-- | Convert 'RegionIndices' into 'RegionDeltas'.
68−regionIndicesToDeltas ::
69− -- | Total number of lines in the input
70− Int ->
71− -- | Region indices
72− RegionIndices ->
73− -- | Region deltas
74− RegionDeltas
75−regionIndicesToDeltas total RegionIndices {..} =
76− RegionDeltas
77− { regionPrefixLength = maybe 0 (subtract 1) regionStartLine,
78− regionSuffixLength = maybe 0 (total -) regionEndLine
79− }
80
44
81-- | A wrapper for dynamic options.
45-- | A wrapper for dynamic options.
46+
82newtype DynOption = DynOption
47newtype DynOption = DynOption
83 { unDynOption :: String
48 { unDynOption :: String
84− }
85− deriving (Eq, Ord, Show)
49+ } deriving (Eq, Ord, Show)
86
50
87-- | Convert 'DynOption' to @'GHC.Located' 'String'@.
51-- | Convert 'DynOption' to @'GHC.Located' 'String'@.
52+
88dynOptionToLocatedStr :: DynOption -> GHC.Located String
53dynOptionToLocatedStr :: DynOption -> GHC.Located String
89dynOptionToLocatedStr (DynOption o) = GHC.L GHC.noSrcSpan o
54dynOptionToLocatedStr (DynOption o) = GHC.L GHC.noSrcSpan o
src/Ormolu/Diff.hs+70−92
@@ -1,30 +1,32 @@
1+{-# LANGUAGE DeriveDataTypeable #-}
1−{-# LANGUAGE RankNTypes #-}
2+{-# LANGUAGE RankNTypes #-}
3+{-# LANGUAGE RecordWildCards #-}
2
4
3-- | Diffing GHC ASTs modulo span positions.
5-- | Diffing GHC ASTs modulo span positions.
6+
4module Ormolu.Diff
7module Ormolu.Diff
5− ( Diff (..),
8+ ( Diff(..)
6− diffParseResult,
9+ , diffParseResult
7− diffText,
10+ , diffText
8 )
11 )
9where
12where
10
13
14+import BasicTypes (SourceText)
11import Data.ByteString (ByteString)
15import Data.ByteString (ByteString)
12import Data.Generics
16import Data.Generics
13import Data.Text (Text)
17import Data.Text (Text)
14−import qualified Data.Text as T
15−import qualified FastString as GHC
16import GHC
18import GHC
17−import Ormolu.Imports (normalizeImports)
19+import Ormolu.Imports (sortImports)
18−import Ormolu.Parser.CommentStream
19import Ormolu.Parser.Result
20import Ormolu.Parser.Result
20−import Ormolu.Utils
21+import qualified Data.Text as T
22+import qualified FastString as GHC
23+import qualified SrcLoc as GHC
21
24
22-- | Result of comparing two 'ParseResult's.
25-- | Result of comparing two 'ParseResult's.
26+
23data Diff
27data Diff
24− = -- | Two parse results are the same
28+ = Same -- ^ Two parse results are the same
25− Same
26− | -- | Two parse results differ
27− Different [SrcSpan]
29+ | Different [SrcSpan] -- ^ Two parse results differ
28
30
29instance Semigroup Diff where
31instance Semigroup Diff where
30 Same <> a = a
32 Same <> a = a
@@ -35,123 +37,99 @@ instance Monoid Diff where
35 mempty = Same
37 mempty = Same
36
38
37-- | Return 'Diff' of two 'ParseResult's.
39-- | Return 'Diff' of two 'ParseResult's.
40+
38diffParseResult :: ParseResult -> ParseResult -> Diff
41diffParseResult :: ParseResult -> ParseResult -> Diff
39diffParseResult
42diffParseResult
40− ParseResult
41− { prCommentStream = cstream0,
43+ ParseResult { prCommentStream = cstream0
42− prParsedSource = hs0
44+ , prParsedSource = ps0
43− }
45+ }
44− ParseResult
45− { prCommentStream = cstream1,
46+ ParseResult { prCommentStream = cstream1
46− prParsedSource = hs1
47+ , prParsedSource = ps1
47− } =
48+ } =
48− matchIgnoringSrcSpans cstream0 cstream1
49+ matchIgnoringSrcSpans cstream0 cstream1 <>
49− <> matchIgnoringSrcSpans
50+ matchIgnoringSrcSpans ps0 ps1
50− hs0 {hsmodImports = normalizeImports (hsmodImports hs0)}
51− hs1 {hsmodImports = normalizeImports (hsmodImports hs1)}
52
51
53-- | Compare two values for equality disregarding differences in 'SrcSpan's
52-- | Compare two values for equality disregarding differences in 'SrcSpan's
54-- and the ordering of import lists.
53-- and the ordering of import lists.
54+
55matchIgnoringSrcSpans :: Data a => a -> a -> Diff
55matchIgnoringSrcSpans :: Data a => a -> a -> Diff
56matchIgnoringSrcSpans = genericQuery
56matchIgnoringSrcSpans = genericQuery
57 where
57 where
58 genericQuery :: GenericQ (GenericQ Diff)
58 genericQuery :: GenericQ (GenericQ Diff)
59 genericQuery x y
59 genericQuery x y
60− -- 'ByteString' implements 'Data' instance manually and does not
60+ -- NOTE 'ByteString' implement 'Data' instance manually and does not
61 -- implement 'toConstr', so we have to deal with it in a special way.
61 -- implement 'toConstr', so we have to deal with it in a special way.
62− | Just x' <- cast x,
62+ | Just x' <- cast x, Just y' <- cast y =
63− Just y' <- cast y =
64 if x' == (y' :: ByteString)
63 if x' == (y' :: ByteString)
65 then Same
64 then Same
66 else Different []
65 else Different []
67− | typeOf x == typeOf y,
68− toConstr x == toConstr y =
66+ | typeOf x == typeOf y, toConstr x == toConstr y =
69− mconcat $
70− gzipWithQ
67+ mconcat $ gzipWithQ
71− ( genericQuery
68+ (genericQuery
72− `extQ` srcSpanEq
69+ `extQ` srcSpanEq
73− `extQ` commentEq
70+ `extQ` hsModuleEq
74− `extQ` sourceTextEq
71+ `extQ` sourceTextEq
75− `extQ` hsDocStringEq
76− `extQ` importDeclQualifiedStyleEq
77− `ext2Q` forLocated
72+ `ext2Q` forLocated)
78− )
79− x
73+ x y
80− y
81 | otherwise = Different []
74 | otherwise = Different []
75+
82 srcSpanEq :: SrcSpan -> GenericQ Diff
76 srcSpanEq :: SrcSpan -> GenericQ Diff
83 srcSpanEq _ _ = Same
77 srcSpanEq _ _ = Same
84− commentEq :: Comment -> GenericQ Diff
78+
85− commentEq (Comment _ x) d =
79+ hsModuleEq :: HsModule GhcPs -> GenericQ Diff
80+ hsModuleEq hs0 hs1' =
86− case cast d :: Maybe Comment of
81+ case cast hs1' :: Maybe (HsModule GhcPs) of
87 Nothing -> Different []
82 Nothing -> Different []
88− Just (Comment _ y) ->
83+ Just hs1 ->
89− if x == y
84+ matchIgnoringSrcSpans
90− then Same
85+ hs0 { hsmodImports = sortImports (hsmodImports hs0) }
91− else Different []
86+ hs1 { hsmodImports = sortImports (hsmodImports hs1) }
87+
92 sourceTextEq :: SourceText -> GenericQ Diff
88 sourceTextEq :: SourceText -> GenericQ Diff
93 sourceTextEq _ _ = Same
89 sourceTextEq _ _ = Same
94− importDeclQualifiedStyleEq :: ImportDeclQualifiedStyle -> GenericQ Diff
90+
95− importDeclQualifiedStyleEq d0 d1' =
96− case (d0, cast d1' :: Maybe ImportDeclQualifiedStyle) of
97− (x, Just x') | x == x' -> Same
98− (QualifiedPre, Just QualifiedPost) -> Same
99− (QualifiedPost, Just QualifiedPre) -> Same
100− _ -> Different []
101− hsDocStringEq :: HsDocString -> GenericQ Diff
102− hsDocStringEq str0 str1' =
103− case cast str1' :: Maybe HsDocString of
104− Nothing -> Different []
105− Just str1 ->
106− if splitDocString str0 == splitDocString str1
107− then Same
108− else Different []
109− forLocated ::
91+ forLocated
110− (Data e0, Data e1) =>
92+ :: (Data e0, Data e1)
111− GenLocated e0 e1 ->
93+ => GenLocated e0 e1
112− GenericQ Diff
94+ -> GenericQ Diff
113 forLocated x@(L mspn _) y =
95 forLocated x@(L mspn _) y =
114 maybe id appendSpan (cast mspn) (genericQuery x y)
96 maybe id appendSpan (cast mspn) (genericQuery x y)
97+
115 appendSpan :: SrcSpan -> Diff -> Diff
98 appendSpan :: SrcSpan -> Diff -> Diff
116− appendSpan s (Different ss) | fresh && helpful = Different (s : ss)
99+ appendSpan s (Different ss) | fresh && helpful = Different (s:ss)
117 where
100 where
118− fresh = not $ any (`isSubspanOf` s) ss
101+ fresh = not $ any (flip isSubspanOf s) ss
119 helpful = isGoodSrcSpan s
102 helpful = isGoodSrcSpan s
120 appendSpan _ d = d
103 appendSpan _ d = d
121
104
122-- | Diff two texts and return the location they start to differ, alongside
105-- | Diff two texts and return the location they start to differ, alongside
123-- with excerpts around that location.
106-- with excerpts around that location.
107+
124−diffText ::
108+diffText
125− -- | Text before
109+ :: Text -- ^ Text before
126− Text ->
127− -- | Text after
110+ -> Text -- ^ Text after
128− Text ->
129− -- | Path to use to construct 'GHC.RealSrcLoc'
111+ -> FilePath -- ^ Path to use to construct 'GHC.RealSrcLoc'
130− FilePath ->
131− Maybe (GHC.RealSrcLoc, Text, Text)
112+ -> Maybe (GHC.RealSrcLoc, Text, Text)
132diffText left right fp =
113diffText left right fp =
133 case go (0, 0, 0) left right of
114 case go (0, 0, 0) left right of
134 Nothing -> Nothing
115 Nothing -> Nothing
135− Just (row, col, loc) ->
116+ Just (row, col, loc) -> Just (
136− Just
137− ( GHC.mkRealSrcLoc (GHC.mkFastString fp) row col,
117+ GHC.mkRealSrcLoc (GHC.mkFastString fp) row col,
138− getSpan loc left,
118+ getSpan loc left,
139− getSpan loc right
119+ getSpan loc right
140− )
120+ )
141 where
121 where
142− go (row, col, loc) t1 t2 =
122+ go (row, col, loc) t1 t2 =
143 case (T.uncons t1, T.uncons t2) of
123 case (T.uncons t1, T.uncons t2) of
144 -- both text empty, all good
124 -- both text empty, all good
145 (Nothing, Nothing) ->
125 (Nothing, Nothing) ->
146 Nothing
126 Nothing
147 -- first chars are the same, adjust position and recurse
127 -- first chars are the same, adjust position and recurse
148− (Just (c1, r1), Just (c2, r2))
128+ (Just (c1, r1), Just (c2, r2)) | c1 == c2 ->
149− | c1 == c2 ->
150− let (row', col', loc') =
129+ let (row', col', loc') = if c1 == '\n'
151− if c1 == '\n'
152− then (row + 1, 0, loc + 1)
130+ then (row + 1, 0, loc + 1)
153− else (row, col + 1, loc + 1)
131+ else (row, col + 1, loc + 1)
154− in go (row', col', loc') r1 r2
132+ in go (row', col', loc') r1 r2
155 -- something is different, return the position
133 -- something is different, return the position
156 _ ->
134 _ ->
157 Just (row, col, loc)
135 Just (row, col, loc)
src/Ormolu/Exception.hs+50−57
@@ -1,72 +1,66 @@
1{-# LANGUAGE LambdaCase #-}
1{-# LANGUAGE LambdaCase #-}
2
2
3-- | 'OrmoluException' type and surrounding definitions.
3-- | 'OrmoluException' type and surrounding definitions.
4+
4module Ormolu.Exception
5module Ormolu.Exception
5− ( OrmoluException (..),
6+ ( OrmoluException (..)
6− withPrettyOrmoluExceptions,
7+ , withPrettyOrmoluExceptions
7 )
8 )
8where
9where
9
10
10import Control.Exception
11import Control.Exception
11−import Data.List.NonEmpty (NonEmpty (..))
12−import qualified Data.List.NonEmpty as NE
13−import Data.Text (Text)
14−import qualified GHC
15import Ormolu.Utils (showOutputable)
12import Ormolu.Utils (showOutputable)
16−import qualified Outputable as GHC
17import System.Exit (ExitCode (..), exitWith)
13import System.Exit (ExitCode (..), exitWith)
18import System.IO
14import System.IO
15+import Data.Text (Text)
16+import qualified GHC
17+import qualified Outputable as GHC
19
18
20-- | Ormolu exception representing all cases when Ormolu can fail.
19-- | Ormolu exception representing all cases when Ormolu can fail.
20+
21data OrmoluException
21data OrmoluException
22+ = OrmoluCppEnabled FilePath
23+ -- ^ Ormolu does not work with source files that use CPP
24+ | OrmoluParsingFailed GHC.SrcSpan String
22− = -- | Parsing of original source code failed
25+ -- ^ Parsing of original source code failed
23− OrmoluParsingFailed GHC.SrcSpan String
26+ | OrmoluOutputParsingFailed GHC.SrcSpan String
24− | -- | Parsing of formatted source code failed
27+ -- ^ Parsing of formatted source code failed
25− OrmoluOutputParsingFailed GHC.SrcSpan String
28+ | OrmoluASTDiffers FilePath [GHC.SrcSpan]
26− | -- | Original and resulting ASTs differ
29+ -- ^ Original and resulting ASTs differ
27− OrmoluASTDiffers FilePath [GHC.SrcSpan]
30+ | OrmoluNonIdempotentOutput GHC.RealSrcLoc Text Text
28− | -- | Formatted source code is not idempotent
31+ -- ^ Formatted source code is not idempotent
29− OrmoluNonIdempotentOutput GHC.RealSrcLoc Text Text
30− | -- | Some GHC options were not recognized
31− OrmoluUnrecognizedOpts (NonEmpty String)
32 deriving (Eq, Show)
32 deriving (Eq, Show)
33
33
34instance Exception OrmoluException where
34instance Exception OrmoluException where
35 displayException = \case
35 displayException = \case
36+ OrmoluCppEnabled path -> unlines
37+ [ "CPP is not supported:"
38+ , withIndent path
39+ ]
36 OrmoluParsingFailed s e ->
40 OrmoluParsingFailed s e ->
37− showParsingErr "The GHC parser (in Haddock mode) failed:" s [e]
41+ showParsingErr "Parsing of source code failed:" s [e]
38 OrmoluOutputParsingFailed s e ->
42 OrmoluOutputParsingFailed s e ->
39− showParsingErr "Parsing of formatted code failed:" s [e]
43+ showParsingErr "Parsing of formatted code failed:" s [e] ++
40− ++ "Please, consider reporting the bug.\n"
44+ "Please, consider reporting the bug.\n"
41− OrmoluASTDiffers path ss ->
45+ OrmoluASTDiffers path ss -> unlines $
42− unlines $
43− [ "AST of input and AST of formatted code differ."
46+ [ "AST of input and AST of formatted code differ."
44− ]
47+ ]
45− ++ fmap
46− withIndent
47− ( case fmap (\s -> "at " ++ showOutputable s) ss of
48+ ++ (fmap withIndent $ case fmap (\s -> "at " ++ showOutputable s) ss of
48− [] -> ["in " ++ path]
49+ [] -> ["in " ++ path]
49− xs -> xs
50+ xs -> xs) ++
50− )
51− ++ ["Please, consider reporting the bug."]
51+ [ "Please, consider reporting the bug." ]
52 OrmoluNonIdempotentOutput loc left right ->
52 OrmoluNonIdempotentOutput loc left right ->
53− showParsingErr
54− "Formatting is not idempotent:"
53+ showParsingErr "Formatting is not idempotent:" loc
55− loc
56− ["before: " ++ show left, "after: " ++ show right]
54+ [ "before: " ++ show left , "after: " ++ show right ]
57 ++ "Please, consider reporting the bug.\n"
55 ++ "Please, consider reporting the bug.\n"
58− OrmoluUnrecognizedOpts opts ->
56+
59− unlines
60− [ "The following GHC options were not recognized:",
61− (withIndent . unwords . NE.toList) opts
62− ]
63
57
64-- | Inside this wrapper 'OrmoluException' will be caught and displayed
58-- | Inside this wrapper 'OrmoluException' will be caught and displayed
65-- nicely using 'displayException'.
59-- nicely using 'displayException'.
60+
66−withPrettyOrmoluExceptions ::
61+withPrettyOrmoluExceptions
67− -- | Action that may throw the exception
62+ :: IO a -- ^ Action that may throw the exception
68− IO a ->
69− IO a
63+ -> IO a
70withPrettyOrmoluExceptions m = m `catch` h
64withPrettyOrmoluExceptions m = m `catch` h
71 where
65 where
72 h :: OrmoluException -> IO a
66 h :: OrmoluException -> IO a
@@ -74,26 +68,25 @@ withPrettyOrmoluExceptions m = m `catch` h
74 hPutStrLn stderr (displayException e)
68 hPutStrLn stderr (displayException e)
75 exitWith . ExitFailure $
69 exitWith . ExitFailure $
76 case e of
70 case e of
77− -- Error code 1 is for 'error' or 'notImplemented'
71+ -- Error code 1 is for `error` or `notImplemented`
78− -- 2 used to be for erroring out on CPP
72+ OrmoluCppEnabled _ -> 2
79− OrmoluParsingFailed {} -> 3
73+ OrmoluParsingFailed _ _ -> 3
80− OrmoluOutputParsingFailed {} -> 4
74+ OrmoluOutputParsingFailed _ _ -> 4
81− OrmoluASTDiffers {} -> 5
75+ OrmoluASTDiffers _ _ -> 5
82− OrmoluNonIdempotentOutput {} -> 6
76+ OrmoluNonIdempotentOutput _ _ _ -> 6
83− OrmoluUnrecognizedOpts {} -> 7
84
77
85----------------------------------------------------------------------------
78----------------------------------------------------------------------------
86-- Helpers
79-- Helpers
87
80
88-- | Show a parse error.
81-- | Show a parse error.
82+
89showParsingErr :: GHC.Outputable a => String -> a -> [String] -> String
83showParsingErr :: GHC.Outputable a => String -> a -> [String] -> String
90−showParsingErr msg spn err =
84+showParsingErr msg spn err = unlines $
91− unlines $
92− [ msg,
85+ [ msg
93− withIndent (showOutputable spn)
86+ , withIndent (showOutputable spn)
94− ]
95− ++ map withIndent err
87+ ] ++ map withIndent err
96
88
97-- | Indent with 2 spaces for readability.
89-- | Indent with 2 spaces for readability.
90+
98withIndent :: String -> String
91withIndent :: String -> String
99withIndent txt = " " ++ txt
92withIndent txt = " " ++ txt
src/Ormolu/Imports.hs+62−176
@@ -1,202 +1,88 @@
1{-# LANGUAGE LambdaCase #-}
1{-# LANGUAGE LambdaCase #-}
2{-# LANGUAGE RankNTypes #-}
2{-# LANGUAGE RankNTypes #-}
3−{-# LANGUAGE RecordWildCards #-}
4
3
5-- | Manipulations on import lists.
4-- | Manipulations on import lists.
5+
6module Ormolu.Imports
6module Ormolu.Imports
7− ( normalizeImports,
7+ ( sortImports
8 )
8 )
9where
9where
10
10
11import Data.Bifunctor
11import Data.Bifunctor
12−import Data.Char (isAlphaNum)
13import Data.Function (on)
12import Data.Function (on)
14−import Data.List (foldl', nubBy, sortBy, sortOn)
13+import Data.Generics (gcompare)
15−import Data.Map.Strict (Map)
14+import Data.List (sortBy)
16−import qualified Data.Map.Strict as M
17−import FastString (FastString)
18import GHC hiding (GhcPs, IE)
15import GHC hiding (GhcPs, IE)
19−import GHC.Hs.Extension
16+import HsExtension
20−import GHC.Hs.ImpExp (IE (..))
17+import HsImpExp (IE (..))
21−import Ormolu.Utils (notImplemented, showOutputable)
18+import Ormolu.Utils (notImplemented)
22−
19+
23−-- | Sort and normalize imports.
20+-- | Sort imports by module name. This also sorts explicit import lists for
24−normalizeImports :: [LImportDecl GhcPs] -> [LImportDecl GhcPs]
21+-- each declaration.
25−normalizeImports =
22+
26− fmap snd
27− . M.toAscList
28− . M.fromListWith combineImports
29− . fmap (\x -> (importId x, g x))
30− where
31− g (L l ImportDecl {..}) =
32− L
33− l
34− ImportDecl
35− { ideclHiding = second (fmap normalizeLies) <$> ideclHiding,
36− ..
37− }
38− g _ = notImplemented "XImportDecl"
39−
40−-- | Combine two import declarations. It should be assumed that 'ImportId's
41−-- are equal.
42−combineImports ::
43− LImportDecl GhcPs ->
44− LImportDecl GhcPs ->
45− LImportDecl GhcPs
46−combineImports (L lx ImportDecl {..}) (L _ y) =
47− L
48− lx
49− ImportDecl
50− { ideclHiding = case (ideclHiding, GHC.ideclHiding y) of
51− (Just (hiding, L l' xs), Just (_, L _ ys)) ->
52− Just (hiding, (L l' (normalizeLies (xs ++ ys))))
53− _ -> Nothing,
54− ..
55− }
56−combineImports _ _ = notImplemented "XImportDecl"
57−
58−-- | Import id, a collection of all things that justify having a separate
59−-- import entry. This is used for merging of imports. If two imports have
60−-- the same 'ImportId' they can be merged.
61−data ImportId = ImportId
62− { importIsPrelude :: Bool,
63− importIdName :: ModuleName,
64− importPkgQual :: Maybe FastString,
65− importSource :: Bool,
66− importSafe :: Bool,
67− importQualified :: Bool,
68− importImplicit :: Bool,
69− importAs :: Maybe ModuleName,
70− importHiding :: Maybe Bool
71− }
72− deriving (Eq, Ord)
73−
74−-- | Obtain an 'ImportId' for a given import.
75−importId :: LImportDecl GhcPs -> ImportId
23+sortImports :: [LImportDecl GhcPs] -> [LImportDecl GhcPs]
76−importId (L _ ImportDecl {..}) =
24+sortImports = sortBy compareIdecl . fmap (fmap sortImportLists)
77− ImportId
78− { importIsPrelude = isPrelude,
79− importIdName = moduleName,
80− importPkgQual = sl_fs <$> ideclPkgQual,
81− importSource = ideclSource,
82− importSafe = ideclSafe,
83− importQualified = case ideclQualified of
84− QualifiedPre -> True
85− QualifiedPost -> True
86− NotQualified -> False,
87− importImplicit = ideclImplicit,
88− importAs = unLoc <$> ideclAs,
89− importHiding = fst <$> ideclHiding
90− }
91 where
25 where
92− isPrelude = moduleNameString moduleName == "Prelude"
26+ sortImportLists :: ImportDecl GhcPs -> ImportDecl GhcPs
93− moduleName = unLoc ideclName
27+ sortImportLists decl =
94−importId _ = notImplemented "XImportDecl"
28+ decl { ideclHiding = second (fmap sortLies) <$> ideclHiding decl
29+ }
95
30
96−-- | Normalize a collection of import\/export items.
31+-- | Compare two @'LImportDecl' 'GhcPs'@ things.
97−normalizeLies :: [LIE GhcPs] -> [LIE GhcPs]
32+
98−normalizeLies = sortOn (getIewn . unLoc) . M.elems . foldl' combine M.empty
33+compareIdecl :: LImportDecl GhcPs -> LImportDecl GhcPs -> Ordering
34+compareIdecl (L _ m0) (L _ m1) =
35+ case (isPrelude n0, isPrelude n1) of
36+ (False, False) -> n0 `compare` n1
37+ (True, False) -> GT
38+ (False, True) -> LT
39+ (True, True) -> m0 `gcompare` m1
99 where
40 where
100− combine ::
41+ n0 = unLoc (ideclName m0)
101− Map IEWrappedNameOrd (LIE GhcPs) ->
42+ n1 = unLoc (ideclName m1)
102− LIE GhcPs ->
43+ isPrelude = (== "Prelude") . moduleNameString
103− Map IEWrappedNameOrd (LIE GhcPs)
44+
104− combine m (L new_l new) =
45+-- | Sort located import or export.
105− let wname = getIewn new
46+
106− normalizeWNames =
47+sortLies :: [LIE GhcPs] -> [LIE GhcPs]
107− nubBy (\x y -> compareLIewn x y == EQ) . sortBy compareLIewn
48+sortLies = sortBy (compareIE `on` unLoc) . fmap (fmap sortThings)
108− alter = \case
49+
109− Nothing -> Just . L new_l $
50+-- | Sort imports\/exports inside of 'IEThingWith'.
110− case new of
51+
111− IEThingWith NoExtField n wildcard g flbl ->
52+sortThings :: IE GhcPs -> IE GhcPs
112− IEThingWith NoExtField n wildcard (normalizeWNames g) flbl
53+sortThings = \case
113− other -> other
54+ IEThingWith NoExt x w xs fl ->
114− Just old ->
55+ IEThingWith NoExt x w (sortBy (compareIewn `on` unLoc) xs) fl
115− let f = \case
56+ other -> other
116− IEVar NoExtField n -> IEVar NoExtField n
57+
117− IEThingAbs NoExtField _ -> new
58+-- | Compare two located imports or exports.
118− IEThingAll NoExtField n -> IEThingAll NoExtField n
59+
119− IEThingWith NoExtField n wildcard g flbl ->
60+compareIE :: IE GhcPs -> IE GhcPs -> Ordering
120− case new of
61+compareIE = compareIewn `on` getIewn
121− IEVar NoExtField _ ->
122− error "Ormolu.Imports broken presupposition"
123− IEThingAbs NoExtField _ ->
124− IEThingWith NoExtField n wildcard g flbl
125− IEThingAll NoExtField n' ->
126− IEThingAll NoExtField n'
127− IEThingWith NoExtField n' wildcard' g' flbl' ->
128− let combinedWildcard =
129− case (wildcard, wildcard') of
130− (IEWildcard _, _) -> IEWildcard 0
131− (_, IEWildcard _) -> IEWildcard 0
132− _ -> NoIEWildcard
133− in IEThingWith
134− NoExtField
135− n'
136− combinedWildcard
137− (normalizeWNames (g <> g'))
138− flbl'
139− IEModuleContents NoExtField _ -> notImplemented "IEModuleContents"
140− IEGroup NoExtField _ _ -> notImplemented "IEGroup"
141− IEDoc NoExtField _ -> notImplemented "IEDoc"
142− IEDocNamed NoExtField _ -> notImplemented "IEDocNamed"
143− XIE x -> noExtCon x
144− IEModuleContents NoExtField _ -> notImplemented "IEModuleContents"
145− IEGroup NoExtField _ _ -> notImplemented "IEGroup"
146− IEDoc NoExtField _ -> notImplemented "IEDoc"
147− IEDocNamed NoExtField _ -> notImplemented "IEDocNamed"
148− XIE x -> noExtCon x
149− in Just (f <$> old)
150− in M.alter alter wname m
151−
152−-- | A wrapper for @'IEWrappedName' 'RdrName'@ that allows us to define an
153−-- 'Ord' instance for it.
154−newtype IEWrappedNameOrd = IEWrappedNameOrd (IEWrappedName RdrName)
155− deriving (Eq)
156−
157−instance Ord IEWrappedNameOrd where
158− compare (IEWrappedNameOrd x) (IEWrappedNameOrd y) = compareIewn x y
159
62
160-- | Project @'IEWrappedName' 'RdrName'@ from @'IE' 'GhcPs'@.
63-- | Project @'IEWrappedName' 'RdrName'@ from @'IE' 'GhcPs'@.
64+
161−getIewn :: IE GhcPs -> IEWrappedNameOrd
65+getIewn :: IE GhcPs -> IEWrappedName RdrName
162getIewn = \case
66getIewn = \case
163− IEVar NoExtField x -> IEWrappedNameOrd (unLoc x)
67+ IEVar NoExt x -> unLoc x
164− IEThingAbs NoExtField x -> IEWrappedNameOrd (unLoc x)
68+ IEThingAbs NoExt x -> unLoc x
165− IEThingAll NoExtField x -> IEWrappedNameOrd (unLoc x)
69+ IEThingAll NoExt x -> unLoc x
166− IEThingWith NoExtField x _ _ _ -> IEWrappedNameOrd (unLoc x)
70+ IEThingWith NoExt x _ _ _ -> unLoc x
167− IEModuleContents NoExtField _ -> notImplemented "IEModuleContents"
71+ IEModuleContents NoExt _ -> notImplemented "IEModuleContents"
168− IEGroup NoExtField _ _ -> notImplemented "IEGroup"
72+ IEGroup NoExt _ _ -> notImplemented "IEGroup"
169− IEDoc NoExtField _ -> notImplemented "IEDoc"
73+ IEDoc NoExt _ -> notImplemented "IEDoc"
170− IEDocNamed NoExtField _ -> notImplemented "IEDocNamed"
74+ IEDocNamed NoExt _ -> notImplemented "IEDocNamed"
171− XIE x -> noExtCon x
75+ XIE NoExt -> notImplemented "XIE"
172−
173−-- | Like 'compareIewn' for located wrapped names.
174−compareLIewn :: LIEWrappedName RdrName -> LIEWrappedName RdrName -> Ordering
175−compareLIewn = compareIewn `on` unLoc
176
76
177-- | Compare two @'IEWrapppedName' 'RdrName'@ things.
77-- | Compare two @'IEWrapppedName' 'RdrName'@ things.
78+
178compareIewn :: IEWrappedName RdrName -> IEWrappedName RdrName -> Ordering
79compareIewn :: IEWrappedName RdrName -> IEWrappedName RdrName -> Ordering
179−compareIewn (IEName x) (IEName y) = unLoc x `compareRdrName` unLoc y
80+compareIewn (IEName x) (IEName y) = unLoc x `compare` unLoc y
180compareIewn (IEName _) (IEPattern _) = LT
81compareIewn (IEName _) (IEPattern _) = LT
181compareIewn (IEName _) (IEType _) = LT
82compareIewn (IEName _) (IEType _) = LT
182compareIewn (IEPattern _) (IEName _) = GT
83compareIewn (IEPattern _) (IEName _) = GT
183−compareIewn (IEPattern x) (IEPattern y) = unLoc x `compareRdrName` unLoc y
84+compareIewn (IEPattern x) (IEPattern y) = unLoc x `compare` unLoc y
184compareIewn (IEPattern _) (IEType _) = LT
85compareIewn (IEPattern _) (IEType _) = LT
185compareIewn (IEType _) (IEName _) = GT
86compareIewn (IEType _) (IEName _) = GT
186compareIewn (IEType _) (IEPattern _) = GT
87compareIewn (IEType _) (IEPattern _) = GT
187−compareIewn (IEType x) (IEType y) = unLoc x `compareRdrName` unLoc y
88+compareIewn (IEType x) (IEType y) = unLoc x `compare` unLoc y
188−
189−compareRdrName :: RdrName -> RdrName -> Ordering
190−compareRdrName x y =
191− case (getNameStr x, getNameStr y) of
192− ([], []) -> EQ
193− ((_ : _), []) -> GT
194− ([], (_ : _)) -> LT
195− ((x' : _), (y' : _)) ->
196− case (isAlphaNum x', isAlphaNum y') of
197− (False, False) -> x `compare` y
198− (True, False) -> LT
199− (False, True) -> GT
200− (True, True) -> x `compare` y
201− where
202− getNameStr = showOutputable . rdrNameOcc
src/Ormolu/Parser.hs+157−183
@@ -1,219 +1,193 @@
1−{-# LANGUAGE LambdaCase #-}
2−{-# LANGUAGE RecordWildCards #-}
1+{-# LANGUAGE RecordWildCards #-}
2+{-# LANGUAGE StandaloneDeriving #-}
3{-# OPTIONS_GHC -fno-warn-orphans #-}
3{-# OPTIONS_GHC -fno-warn-orphans #-}
4
4
5-- | Parser for Haskell source code.
5-- | Parser for Haskell source code.
6+
6module Ormolu.Parser
7module Ormolu.Parser
7− ( parseModule,
8+ ( parseModule
8− manualExts,
9+ , manualExts
9 )
10 )
10where
11where
11
12
12−import Bag (bagToList)
13−import qualified CmdLineParser as GHC
14import Control.Exception
13import Control.Exception
14+import Control.Monad
15import Control.Monad.IO.Class
15import Control.Monad.IO.Class
16−import qualified Data.List as L
16+import Data.List (isPrefixOf, foldl', (\\))
17−import qualified Data.List.NonEmpty as NE
18−import Data.Ord (Down (Down))
19−import qualified Data.Text as T
17+import Data.Maybe (catMaybes)
20−import DynFlags as GHC
21−import ErrUtils (Severity (..), errMsgSeverity, errMsgSpan)
22−import qualified FastString as GHC
23−import GHC hiding (IE, UnicodeSyntax)
18+import GHC hiding (IE, parseModule, parser)
24−import GHC.DynFlags (baseDynFlags)
25import GHC.LanguageExtensions.Type (Extension (..))
19import GHC.LanguageExtensions.Type (Extension (..))
26−import qualified HeaderInfo as GHC
20+import GHC.Paths (libdir)
27−import qualified HscTypes as GHC
28−import qualified Lexer as GHC
29import Ormolu.Config
21import Ormolu.Config
30import Ormolu.Exception
22import Ormolu.Exception
31import Ormolu.Parser.Anns
23import Ormolu.Parser.Anns
32import Ormolu.Parser.CommentStream
24import Ormolu.Parser.CommentStream
33import Ormolu.Parser.Result
25import Ormolu.Parser.Result
34−import Ormolu.Processing.Preprocess (preprocess)
26+import qualified CmdLineParser as GHC
35−import Ormolu.Utils (incSpanLine, removeIndentation)
27+import qualified DynFlags as GHC
36−import qualified Panic as GHC
28+import qualified FastString as GHC
29+import qualified HeaderInfo as GHC
30+import qualified Lexer as GHC
31+import qualified Outputable as GHC
37import qualified Parser as GHC
32import qualified Parser as GHC
33+import qualified SrcLoc as GHC
38import qualified StringBuffer as GHC
34import qualified StringBuffer as GHC
39
35
40-- | Parse a complete module from string.
36-- | Parse a complete module from string.
41−parseModule ::
42− MonadIO m =>
43− -- | Ormolu configuration
44− Config RegionDeltas ->
45− -- | File name (only for source location annotations)
46− FilePath ->
47− -- | Input for parser
48− String ->
49− m
50− ( [GHC.Warn],
51− Either (SrcSpan, String) ParseResult
52− )
53−parseModule Config {..} path rawInput = liftIO $ do
54− let (literalPrefix, indentedInput, literalSuffix, extraComments) =
55− preprocess path rawInput cfgRegion
56− (input, indent) = removeIndentation indentedInput
57− -- It's important that 'setDefaultExts' is done before
58− -- 'parsePragmasIntoDynFlags', because otherwise we might enable an
59− -- extension that was explicitly disabled in the file.
60− let baseFlags =
61− GHC.setGeneralFlag'
62− GHC.Opt_Haddock
63− (setDefaultExts baseDynFlags)
64− extraOpts = dynOptionToLocatedStr <$> cfgDynOptions
65− (warnings, dynFlags) <-
66− parsePragmasIntoDynFlags baseFlags extraOpts path rawInput >>= \case
67− Right res -> pure res
68− Left err ->
69− let loc =
70− mkSrcSpan
71− (mkSrcLoc (GHC.mkFastString path) 1 1)
72− (mkSrcLoc (GHC.mkFastString path) 1 1)
73− in throwIO (OrmoluParsingFailed loc err)
74− let useRecordDot =
75− "record-dot-preprocessor" == pgm_F dynFlags
76− || any
77− (("RecordDotPreprocessor" ==) . moduleNameString)
78− (pluginModNames dynFlags)
79− pStateErrors = \pstate ->
80− let errs = bagToList $ GHC.getErrorMessages pstate dynFlags
81− fixupErrSpan = incSpanLine (regionPrefixLength cfgRegion)
82− in case L.sortOn (Down . SeverityOrd . errMsgSeverity) errs of
83− [] -> Nothing
84− err : _ ->
85− -- Show instance returns a short error message
86− Just (fixupErrSpan (errMsgSpan err), show err)
87− r = case runParser GHC.parseModule dynFlags path input of
88− GHC.PFailed pstate ->
89− case pStateErrors pstate of
90− Just err -> Left err
91− Nothing -> error "PFailed does not have an error"
92− GHC.POk pstate (L _ hsModule) ->
93− case pStateErrors pstate of
94− -- Some parse errors (pattern/arrow syntax in expr context)
95− -- do not cause a parse error, but they are replaced with "_"
96− -- by the parser and the modified AST is propagated to the
97− -- later stages; but we fail in those cases.
98− Just err -> Left err
99− Nothing ->
100− let (stackHeader, shebangs, pragmas, comments) =
101− mkCommentStream input extraComments pstate
102− in Right
103− ParseResult
104− { prParsedSource = hsModule,
105− prAnns = mkAnns pstate,
106− prStackHeader = stackHeader,
107− prShebangs = shebangs,
108− prPragmas = pragmas,
109− prCommentStream = comments,
110− prUseRecordDot = useRecordDot,
111− prImportQualifiedPost =
112− GHC.xopt ImportQualifiedPost dynFlags,
113− prLiteralPrefix = T.pack literalPrefix,
114− prLiteralSuffix = T.pack literalSuffix,
115− prIndent = indent
116− }
117− return (warnings, r)
118
37
119−-- | Enable all language extensions that we think should be enabled by
38+parseModule
120−-- default for ease of use.
39+ :: MonadIO m
121−setDefaultExts :: DynFlags -> DynFlags
40+ => Config -- ^ Ormolu configuration
122−setDefaultExts flags = L.foldl' xopt_set flags autoExts
41+ -> FilePath -- ^ File name (only for source location annotations)
123− where
42+ -> String -- ^ Input for parser
124− autoExts = allExts L.\\ manualExts
43+ -> m ( [GHC.Warn]
125− allExts = [minBound .. maxBound]
44+ , Either (SrcSpan, String) ParseResult
45+ )
46+parseModule Config {..} path input' = liftIO $ do
47+ let (input, extraComments) = stripLinePragmas input'
48+ (ws, dynFlags) <- ghcWrapper $ do
49+ dynFlags0 <- initDynFlagsPure path input
50+ (dynFlags1, _, ws) <- GHC.parseDynamicFilePragma
51+ dynFlags0
52+ (dynOptionToLocatedStr <$> cfgDynOptions)
53+ return (ws, dynFlags1)
54+ -- NOTE It's better to throw this outside of 'ghcWrapper' because
55+ -- otherwise the exception will be wrapped as a GHC panic, which we don't
56+ -- want.
57+ when (GHC.xopt Cpp dynFlags && not cfgTolerateCpp) $
58+ throwIO (OrmoluCppEnabled path)
59+ let r = case runParser GHC.parseModule dynFlags path input of
60+ GHC.PFailed _ ss m ->
61+ Left (ss, GHC.showSDoc dynFlags m)
62+ GHC.POk pstate pmod ->
63+ let (comments, exts) = mkCommentStream extraComments pstate
64+ in Right ParseResult
65+ { prParsedSource = pmod
66+ , prAnns = mkAnns pstate
67+ , prCommentStream = comments
68+ , prExtensions = exts
69+ }
70+ return (ws, r)
126
71
127-- | Extensions that are not enabled automatically and should be activated
72-- | Extensions that are not enabled automatically and should be activated
128-- by user.
73-- by user.
74+
129manualExts :: [Extension]
75manualExts :: [Extension]
130manualExts =
76manualExts =
131− [ Arrows, -- steals proc
77+ [ Arrows -- steals proc
132− Cpp, -- forbidden
78+ , Cpp -- forbidden
133− BangPatterns, -- makes certain patterns with ! fail
134− PatternSynonyms, -- steals the pattern keyword
79+ , PatternSynonyms -- steals the pattern keyword
135− RecursiveDo, -- steals the rec keyword
80+ , RecursiveDo -- steals the rec keyword
136− StaticPointers, -- steals static keyword
81+ , StaticPointers -- steals static keyword
137− TransformListComp, -- steals the group keyword
82+ , TransformListComp -- steals the group keyword
138− UnboxedTuples, -- breaks (#) lens operator
83+ , UnboxedTuples -- breaks (#) lens operator
139− MagicHash, -- screws {-# these things #-}
84+ , MagicHash -- screws {-# these things #-}
140− TypeApplications, -- steals (@) operator on some cases
141− AlternativeLayoutRule,
85+ , AlternativeLayoutRule
142− AlternativeLayoutRuleTransitional,
86+ , AlternativeLayoutRuleTransitional
143− MonadComprehensions,
87+ , MonadComprehensions
144− UnboxedSums,
88+ , UnboxedSums
145− UnicodeSyntax, -- gives special meanings to operators like (→)
146− TemplateHaskellQuotes, -- enables TH subset of quasi-quotes, this
89+ , TemplateHaskellQuotes -- enables TH subset of quasi-quotes, this
147− -- apparently interferes with QuasiQuotes in
90+ -- apparently interferes with QuasiQuotes in
148− -- weird ways
91+ -- weird ways
149− ImportQualifiedPost -- affects how Ormolu renders imports, so the
150− -- decision of enabling this style is left to the user
151 ]
92 ]
152
93
94+----------------------------------------------------------------------------
95+-- Helpers (taken from ghc-exactprint)
96+
97+-- | Requires GhcMonad constraint because there is no pure variant of
98+-- 'parseDynamicFilePragma'. Yet, in constrast to 'initDynFlags', it does
99+-- not (try to) read the file at filepath, but solely depends on the module
100+-- source in the input string.
101+--
102+-- Passes "-hide-all-packages" to the GHC API to prevent parsing of package
103+-- environment files. However this only works if there is no invocation of
104+-- 'setSessionDynFlags' before calling 'initDynFlagsPure'. See GHC tickets
105+-- #15513, #15541.
106+
107+initDynFlagsPure
108+ :: GHC.GhcMonad m
109+ => FilePath -- ^ Module path
110+ -> String -- ^ Module contents
111+ -> m GHC.DynFlags -- ^ Dynamic flags for that module
112+initDynFlagsPure fp input = do
113+ -- I was told we could get away with using the 'unsafeGlobalDynFlags'. as
114+ -- long as 'parseDynamicFilePragma' is impure there seems to be no reason
115+ -- to use it.
116+ dflags0 <- setDefaultExts <$> GHC.getSessionDynFlags
117+ let tokens = GHC.getOptions dflags0 (GHC.stringToStringBuffer input) fp
118+ (dflags1, _, _) <- GHC.parseDynamicFilePragma dflags0 tokens
119+ -- Turn this on last to avoid T10942
120+ let dflags2 = dflags1 `GHC.gopt_set` GHC.Opt_KeepRawTokenStream
121+ -- Prevent parsing of .ghc.environment.* "package environment files"
122+ (dflags3, _, _) <- GHC.parseDynamicFlagsCmdLine
123+ dflags2
124+ [GHC.noLoc "-hide-all-packages"]
125+ _ <- GHC.setSessionDynFlags dflags3
126+ return dflags3
127+
128+-- | Default runner of 'GHC.Ghc' action in 'IO'.
129+
130+ghcWrapper :: GHC.Ghc a -> IO a
131+ghcWrapper
132+ = GHC.defaultErrorHandler GHC.defaultFatalMessager GHC.defaultFlushOut
133+ . GHC.runGhc (Just libdir)
134+
153-- | Run a 'GHC.P' computation.
135-- | Run a 'GHC.P' computation.
136+
154−runParser ::
137+runParser
155− -- | Computation to run
138+ :: GHC.P a -- ^ Computation to run
156− GHC.P a ->
157− -- | Dynamic flags
139+ -> GHC.DynFlags -- ^ Dynamic flags
158− GHC.DynFlags ->
159− -- | Module path
160− FilePath ->
140+ -> FilePath -- ^ Module path
161− -- | Module contents
162− String ->
141+ -> String -- ^ Module contents
163− -- | Parse result
142+ -> GHC.ParseResult a -- ^ Parse result
164− GHC.ParseResult a
165runParser parser flags filename input = GHC.unP parser parseState
143runParser parser flags filename input = GHC.unP parser parseState
166 where
144 where
167 location = GHC.mkRealSrcLoc (GHC.mkFastString filename) 1 1
145 location = GHC.mkRealSrcLoc (GHC.mkFastString filename) 1 1
168 buffer = GHC.stringToStringBuffer input
146 buffer = GHC.stringToStringBuffer input
169 parseState = GHC.mkPState flags buffer location
147 parseState = GHC.mkPState flags buffer location
170
148
171−-- | Wrap GHC's 'Severity' to add 'Ord' instance.
149+-- | Remove GHC style line pragams (@{-# LINE .. #-}@) and convert them into
172−newtype SeverityOrd = SeverityOrd Severity
150+-- comments.
173−
174−instance Eq SeverityOrd where
175− s1 == s2 = compare s1 s2 == EQ
176−
177−instance Ord SeverityOrd where
178− compare (SeverityOrd s1) (SeverityOrd s2) =
179− compare (f s1) (f s2)
180− where
181− f :: Severity -> Int
182− f SevOutput = 1
183− f SevFatal = 2
184− f SevInteractive = 3
185− f SevDump = 4
186− f SevInfo = 5
187− f SevWarning = 6
188− f SevError = 7
189
151
190−----------------------------------------------------------------------------
152+stripLinePragmas :: String -> (String, [Located String])
191−-- Helpers taken from HLint
153+stripLinePragmas = unlines' . unzip . findLines . lines
192−
154+ where
193−parsePragmasIntoDynFlags ::
155+ unlines' (a, b) = (unlines a, catMaybes b)
194− -- | Pre-set 'DynFlags'
156+
195− DynFlags ->
157+findLines :: [String] -> [(String, Maybe (Located String))]
196− -- | Extra options (provided by user)
158+findLines = zipWith checkLine [1..]
197− [Located String] ->
159+
198− -- | File name (only for source location annotations)
160+checkLine :: Int -> String -> (String, Maybe (Located String))
199− FilePath ->
161+checkLine line s
200− -- | Input for parser
162+ | "{-# LINE" `isPrefixOf` s =
201− String ->
163+ let (pragma, res) = getPragma s
202− IO (Either String ([GHC.Warn], DynFlags))
164+ size = length pragma
203−parsePragmasIntoDynFlags flags extraOpts filepath str =
165+ mSrcLoc = mkSrcLoc (GHC.mkFastString "LINE")
204− catchErrors $ do
166+ ss = mkSrcSpan (mSrcLoc line 1) (mSrcLoc line (size+1))
205− let opts = GHC.getOptions flags (GHC.stringToStringBuffer str) filepath
167+ in (res, Just $ L ss pragma)
206− (flags', leftovers, warnings) <-
168+ -- Deal with shebang/cpp directives too
207− parseDynamicFilePragma flags (opts <> extraOpts)
169+ -- x | "#" `isPrefixOf` s = ("",Just $ Comment ((line, 1), (line, length s)) s)
208− case NE.nonEmpty leftovers of
170+ | "#!" `isPrefixOf` s =
209− Nothing -> return ()
171+ let mSrcLoc = mkSrcLoc (GHC.mkFastString "SHEBANG")
210− Just unrecognizedOpts ->
172+ ss = mkSrcSpan (mSrcLoc line 1) (mSrcLoc line (length s))
211− throwIO (OrmoluUnrecognizedOpts (unLoc <$> unrecognizedOpts))
173+ in ("",Just $ L ss s)
212− let flags'' = flags' `gopt_set` Opt_KeepRawTokenStream
174+ | otherwise = (s, Nothing)
213− return $ Right (warnings, flags'')
175+
176+getPragma :: String -> (String, String)
177+getPragma [] = error "Ormolu.Parser.getPragma: input must not be empty"
178+getPragma s@(x:xs)
179+ | "#-}" `isPrefixOf` s = ("#-}", " " ++ drop 3 s)
180+ | otherwise =
181+ let (prag, remline) = getPragma xs
182+ in (x:prag, ' ':remline)
183+
184+-- | Enable all language extensions that we think should be enabled by
185+-- default for ease of use.
186+
187+setDefaultExts :: DynFlags -> DynFlags
188+setDefaultExts flags = foldl' GHC.xopt_set flags autoExts
214 where
189 where
215− catchErrors act =
190+ autoExts = allExts \\ manualExts
216− GHC.handleGhcException
191+ allExts = [minBound..maxBound]
217− reportErr
192+
218− (GHC.handleSourceError reportErr act)
193+deriving instance Bounded Extension
219− reportErr e = return $ Left (show e)
src/Ormolu/Parser/Anns.hs+20−18
@@ -1,34 +1,37 @@
1-- | Ormolu-specific representation of GHC annotations.
1-- | Ormolu-specific representation of GHC annotations.
2+
2module Ormolu.Parser.Anns
3module Ormolu.Parser.Anns
3− ( Anns (..),
4+ ( Anns (..)
4− emptyAnns,
5+ , emptyAnns
5− mkAnns,
6+ , mkAnns
6− lookupAnns,
7+ , lookupAnns
7 )
8 )
8where
9where
9
10
10import Data.Map.Strict (Map)
11import Data.Map.Strict (Map)
11−import qualified Data.Map.Strict as M
12import Data.Maybe (mapMaybe)
12import Data.Maybe (mapMaybe)
13+import SrcLoc
14+import qualified Data.Map.Strict as M
13import qualified GHC
15import qualified GHC
14import qualified Lexer as GHC
16import qualified Lexer as GHC
15−import SrcLoc
16
17
17-- | Ormolu-specific representation of GHC annotations.
18-- | Ormolu-specific representation of GHC annotations.
19+
18newtype Anns = Anns (Map RealSrcSpan [GHC.AnnKeywordId])
20newtype Anns = Anns (Map RealSrcSpan [GHC.AnnKeywordId])
19 deriving (Eq)
21 deriving (Eq)
20
22
21-- | Empty 'Anns'.
23-- | Empty 'Anns'.
24+
22emptyAnns :: Anns
25emptyAnns :: Anns
23emptyAnns = Anns M.empty
26emptyAnns = Anns M.empty
24
27
25-- | Create 'Anns' from 'GHC.PState'.
28-- | Create 'Anns' from 'GHC.PState'.
29+
26−mkAnns ::
30+mkAnns
27− GHC.PState ->
31+ :: GHC.PState
28− Anns
32+ -> Anns
29−mkAnns pstate =
33+mkAnns pstate = Anns $
30− Anns $
31− M.fromListWith (++) (mapMaybe f (GHC.annotations pstate))
34+ M.fromListWith (++) (mapMaybe f (GHC.annotations pstate))
32 where
35 where
33 f ((spn, kid), _) =
36 f ((spn, kid), _) =
34 case spn of
37 case spn of
@@ -36,11 +39,10 @@ mkAnns pstate =
36 UnhelpfulSpan _ -> Nothing
39 UnhelpfulSpan _ -> Nothing
37
40
38-- | Lookup 'GHC.AnnKeywordId's corresponding to a given 'SrcSpan'.
41-- | Lookup 'GHC.AnnKeywordId's corresponding to a given 'SrcSpan'.
42+
39−lookupAnns ::
43+lookupAnns
40− -- | Span to lookup with
44+ :: SrcSpan -- ^ Span to lookup with
41− SrcSpan ->
42− -- | Collection of annotations
45+ -> Anns -- ^ Collection of annotations
43− Anns ->
44− [GHC.AnnKeywordId]
46+ -> [GHC.AnnKeywordId]
45lookupAnns (RealSrcSpan rspn) (Anns m) = M.findWithDefault [] rspn m
47lookupAnns (RealSrcSpan rspn) (Anns m) = M.findWithDefault [] rspn m
46lookupAnns (UnhelpfulSpan _) _ = []
48lookupAnns (UnhelpfulSpan _) _ = []
src/Ormolu/Parser/CommentStream.hs+89−184
@@ -1,226 +1,131 @@
1+{-# LANGUAGE BangPatterns #-}
1−{-# LANGUAGE DeriveDataTypeable #-}
2+{-# LANGUAGE DeriveDataTypeable #-}
2{-# LANGUAGE GeneralizedNewtypeDeriving #-}
3{-# LANGUAGE GeneralizedNewtypeDeriving #-}
3−{-# LANGUAGE LambdaCase #-}
4+{-# LANGUAGE LambdaCase #-}
5+{-# LANGUAGE TupleSections #-}
4
6
5-- | Functions for working with comment stream.
7-- | Functions for working with comment stream.
8+
6module Ormolu.Parser.CommentStream
9module Ormolu.Parser.CommentStream
7− ( -- * Comment stream
8− CommentStream (..),
10+ ( CommentStream (..)
11+ , Comment (..)
9− mkCommentStream,
12+ , mkCommentStream
13+ , isPrevHaddock
10− showCommentStream,
14+ , showCommentStream
11−
12− -- * Comment
13− Comment (..),
14− unComment,
15− hasAtomsBefore,
16− isMultilineComment,
17 )
15 )
18where
16where
19
17
20import Data.Char (isSpace)
18import Data.Char (isSpace)
21import Data.Data (Data)
19import Data.Data (Data)
22−import qualified Data.List as L
20+import Data.Either (partitionEithers)
21+import Data.List (isPrefixOf, sortOn, dropWhileEnd)
23import Data.List.NonEmpty (NonEmpty (..))
22import Data.List.NonEmpty (NonEmpty (..))
24−import qualified Data.List.NonEmpty as NE
25import Data.Maybe (mapMaybe)
23import Data.Maybe (mapMaybe)
26−import qualified GHC
27−import qualified Lexer as GHC
28import Ormolu.Parser.Pragma
24import Ormolu.Parser.Pragma
29−import Ormolu.Parser.Shebang
30−import Ormolu.Processing.Common
31−import Ormolu.Utils (onTheSameLine, showOutputable)
25+import Ormolu.Utils (showOutputable)
32import SrcLoc
26import SrcLoc
33−
27+import qualified Data.List.NonEmpty as NE
34−----------------------------------------------------------------------------
28+import qualified GHC
35−-- Comment stream
29+import qualified Lexer as GHC
36
30
37-- | A stream of 'RealLocated' 'Comment's in ascending order with respect to
31-- | A stream of 'RealLocated' 'Comment's in ascending order with respect to
38-- beginning of corresponding spans.
32-- beginning of corresponding spans.
33+
39newtype CommentStream = CommentStream [RealLocated Comment]
34newtype CommentStream = CommentStream [RealLocated Comment]
40 deriving (Eq, Data, Semigroup, Monoid)
35 deriving (Eq, Data, Semigroup, Monoid)
41
36
37+-- | A wrapper for a single comment. The 'NonEmpty' list inside contains
38+-- lines of multiline comment @{- … -}@ or just single item\/line otherwise.
39+
40+newtype Comment = Comment (NonEmpty String)
41+ deriving (Eq, Show, Data)
42+
42−-- | Create 'CommentStream' from 'GHC.PState'. The pragmas and shebangs are
43+-- | Create 'CommentStream' from 'GHC.PState'. We also create a 'Set' of
44+-- extensions here, which is not sorted in any way. The pragma comment are
43−-- removed from the 'CommentStream'. Shebangs are only extracted from the
45+-- removed from the 'CommentStream'.
44−-- comments that come from the first argument.
46+
45−mkCommentStream ::
47+mkCommentStream
46− -- | Original input
47− String ->
48− -- | Extra comments to include
48+ :: [Located String] -- ^ Extra comments to include
49− [Located String] ->
50− -- | Parser state to use for comment extraction
49+ -> GHC.PState -- ^ Parser state to use for comment extraction
51− GHC.PState ->
50+ -> (CommentStream, [Pragma])
52− -- | Stack header, shebangs, pragmas, and comment stream
51+ -- ^ Comment stream and a set of extracted pragmas
53− ( Maybe (RealLocated Comment),
54− [Shebang],
55− [([RealLocated Comment], Pragma)],
56− CommentStream
57− )
58−mkCommentStream input extraComments pstate =
52+mkCommentStream extraComments pstate =
59− ( mstackHeader,
53+ ( CommentStream $
60− shebangs,
54+ -- NOTE It's easier to normalize pragmas right when we construct comment
61− pragmas,
55+ -- streams. Because this way we need to do it only once and when we
62− CommentStream comments
56+ -- perform checking later they'll automatically match.
57+ mkComment <$> sortOn (realSrcSpanStart . getLoc) comments
58+ , pragmas
63 )
59 )
64 where
60 where
65− (comments, pragmas) = extractPragmas input rawComments1
61+ (comments, pragmas) = partitionEithers (partitionComments <$> rawComments)
66− (rawComments1, mstackHeader) = extractStackHeader rawComments0
67− rawComments0 =
68− L.sortOn (realSrcSpanStart . getRealSrcSpan) . mapMaybe toRealSpan $
62+ rawComments = mapMaybe toRealSpan $
69− otherExtraComments
63+ extraComments ++
70− ++ mapMaybe (liftMaybe . fmap unAnnotationComment) (GHC.comment_q pstate)
64+ (fmap unAnnotationComment <$> GHC.comment_q pstate) ++
71− ++ concatMap
72− (mapMaybe (liftMaybe . fmap unAnnotationComment) . snd)
65+ concatMap (fmap (fmap unAnnotationComment) . snd)
73− (GHC.annotations_comments pstate)
66+ (GHC.annotations_comments pstate)
74− (shebangs, otherExtraComments) = extractShebangs extraComments
67+
68+-- | Test whether a 'Comment' looks like a Haddock following a definition,
69+-- i.e. something starting with @-- ^@.
70+
71+isPrevHaddock :: Comment -> Bool
72+isPrevHaddock (Comment (x :| _)) = "-- ^" `isPrefixOf` x
75
73
76-- | Pretty-print a 'CommentStream'.
74-- | Pretty-print a 'CommentStream'.
75+
77showCommentStream :: CommentStream -> String
76showCommentStream :: CommentStream -> String
78−showCommentStream (CommentStream xs) =
77+showCommentStream (CommentStream xs) = unlines $
79− unlines $
80− showComment <$> xs
78+ showComment <$> xs
81 where
79 where
82 showComment (GHC.L l str) = showOutputable l ++ " " ++ show str
80 showComment (GHC.L l str) = showOutputable l ++ " " ++ show str
83
81
84----------------------------------------------------------------------------
82----------------------------------------------------------------------------
85−-- Comment
83+-- Helpers
86−
87−-- | A wrapper for a single comment. The 'Bool' indicates whether there were
88−-- atoms before beginning of the comment in the original input. The
89−-- 'NonEmpty' list inside contains lines of multiline comment @{- … -}@ or
90−-- just single item\/line otherwise.
91−data Comment = Comment Bool (NonEmpty String)
92− deriving (Eq, Show, Data)
93
84
94-- | Normalize comment string. Sometimes one multi-line comment is turned
85-- | Normalize comment string. Sometimes one multi-line comment is turned
95-- into several lines for subsequent outputting with correct indentation for
86-- into several lines for subsequent outputting with correct indentation for
96-- each line.
87-- each line.
97−mkComment ::
98− -- | Lines of original input with their indices
99− [(Int, String)] ->
100− -- | Raw comment string
101− RealLocated String ->
102− -- | Remaining lines of original input and the constructed 'Comment'
103− ([(Int, String)], RealLocated Comment)
104−mkComment ls (L l s) = (ls', comment)
105− where
106− comment =
107− L l . Comment atomsBefore . removeConseqBlanks . fmap dropTrailing $
108− if "{-" `L.isPrefixOf` s
109− then case NE.nonEmpty (lines s) of
110− Nothing -> s :| []
111− Just (x :| xs) ->
112− let getIndent y =
113− if all isSpace y || y == endDisabling
114− then startIndent
115− else length (takeWhile isSpace y)
116− n = minimum (startIndent : fmap getIndent xs)
117− removeIndent y =
118− if y == endDisabling
119− then y
120− else drop n y
121− in x :| (removeIndent <$> xs)
122− else s :| []
123− (atomsBefore, ls') =
124− case dropWhile ((< commentLine) . fst) ls of
125− [] -> (False, [])
126− ((_, i) : ls'') ->
127− case take 2 (dropWhile isSpace i) of
128− "--" -> (False, ls'')
129− "{-" -> (False, ls'')
130− _ -> (True, ls'')
131− dropTrailing = L.dropWhileEnd isSpace
132− startIndent = srcSpanStartCol l - 1
133− commentLine = srcSpanStartLine l
134−
135−-- | Get a collection of lines from a 'Comment'.
136−unComment :: Comment -> NonEmpty String
137−unComment (Comment _ xs) = xs
138−
139−-- | Check whether the 'Comment' had some non-whitespace atoms in front of
140−-- it in the original input.
141−hasAtomsBefore :: Comment -> Bool
142−hasAtomsBefore (Comment atomsBefore _) = atomsBefore
143−
144−-- | Is this comment multiline-style?
145−isMultilineComment :: Comment -> Bool
146−isMultilineComment (Comment _ (x :| _)) = "{-" `L.isPrefixOf` x
147
88
148−----------------------------------------------------------------------------
89+mkComment :: RealLocated String -> RealLocated Comment
149−-- Helpers
90+mkComment (L l s) = L l . Comment . fmap dropTrailing $
150−
91+ if "{-" `isPrefixOf` s
151−-- | Detect and extract stack header if it is present.
92+ then case NE.nonEmpty (lines s) of
152−extractStackHeader ::
93+ Nothing -> s :| []
153− -- | Comment stream to analyze
154− [RealLocated String] ->
155− ([RealLocated String], Maybe (RealLocated Comment))
156−extractStackHeader = \case
157− [] -> ([], Nothing)
158− (x : xs) ->
94+ Just (x:|xs) ->
159− let comment = snd (mkComment [] x)
95+ let getIndent y =
160− in if isStackHeader (unRealSrcSpan comment)
96+ if all isSpace y
161− then (xs, Just comment)
97+ then startIndent
162− else (x : xs, Nothing)
98+ else length (takeWhile isSpace y)
163− where
99+ n = minimum (startIndent : fmap getIndent xs)
164− isStackHeader (Comment _ (x :| _)) =
100+ in x :| (drop n <$> xs)
165− "stack" `L.isPrefixOf` dropWhile isSpace (drop 2 x)
101+ else s :| []
166−
167−-- | Extract pragmas and their associated comments.
168−extractPragmas ::
169− -- | Input
170− String ->
171− -- | Comment stream to analyze
172− [RealLocated String] ->
173− ([RealLocated Comment], [([RealLocated Comment], Pragma)])
174−extractPragmas input = go initialLs id id
175 where
102 where
176− initialLs = zip [1 ..] (lines input)
103+ dropTrailing = dropWhileEnd isSpace
177− go ls csSoFar pragmasSoFar = \case
104+ startIndent = srcSpanStartCol l - 1
178− [] -> (csSoFar [], pragmasSoFar [])
179− (x : xs) ->
180− case parsePragma (unRealSrcSpan x) of
181− Nothing ->
182− let (ls', x') = mkComment ls x
183− in go ls' (csSoFar . (x' :)) pragmasSoFar xs
184− Just pragma ->
185− let combined ys = (csSoFar ys, pragma)
186− go' ls' ys rest = go ls' id (pragmasSoFar . (combined ys :)) rest
187− in case xs of
188− [] -> go' ls [] xs
189− (y : ys) ->
190− let (ls', y') = mkComment ls y
191− in if onTheSameLine
192− (RealSrcSpan (getRealSrcSpan x))
193− (RealSrcSpan (getRealSrcSpan y))
194− then go' ls' [y'] ys
195− else go' ls [] xs
196
105
197-- | Get a 'String' from 'GHC.AnnotationComment'.
106-- | Get a 'String' from 'GHC.AnnotationComment'.
107+
198−unAnnotationComment :: GHC.AnnotationComment -> Maybe String
108+unAnnotationComment :: GHC.AnnotationComment -> String
199unAnnotationComment = \case
109unAnnotationComment = \case
200− GHC.AnnDocCommentNext _ -> Nothing -- @-- |@
110+ GHC.AnnDocCommentNext s -> s
201− GHC.AnnDocCommentPrev _ -> Nothing -- @-- ^@
111+ GHC.AnnDocCommentPrev s -> s
202− GHC.AnnDocCommentNamed _ -> Nothing -- @-- $@
112+ GHC.AnnDocCommentNamed s -> s
203− GHC.AnnDocSection _ _ -> Nothing -- @-- *@
113+ GHC.AnnDocSection _ s -> s
204− GHC.AnnDocOptions s -> Just s
114+ GHC.AnnDocOptions s -> s
205− GHC.AnnLineComment s -> Just s
115+ GHC.AnnLineComment s -> s
206− GHC.AnnBlockComment s -> Just s
116+ GHC.AnnBlockComment s -> s
207−
208−liftMaybe :: Located (Maybe a) -> Maybe (Located a)
209−liftMaybe = \case
210− L _ Nothing -> Nothing
211− L l (Just a) -> Just (L l a)
212
117
213toRealSpan :: Located a -> Maybe (RealLocated a)
118toRealSpan :: Located a -> Maybe (RealLocated a)
214toRealSpan (L (RealSrcSpan l) a) = Just (L l a)
119toRealSpan (L (RealSrcSpan l) a) = Just (L l a)
215toRealSpan _ = Nothing
120toRealSpan _ = Nothing
216
121
217−-- | Remove consecutive blank lines.
122+-- | If a given comment is a pragma, return it in parsed form in 'Right'.
218−removeConseqBlanks :: NonEmpty String -> NonEmpty String
123+-- Otherwise return the original comment unchanged.
219−removeConseqBlanks (x :| xs) = x :| go (null x) id xs
124+
220− where
125+partitionComments
221− go seenBlank acc = \case
126+ :: RealLocated String
222− [] -> acc []
127+ -> Either (RealLocated String) Pragma
223− (y : ys) ->
128+partitionComments input =
224− if seenBlank && null y
129+ case parsePragma (unLoc input) of
225− then go True acc ys
130+ Nothing -> Left input
226− else go (null y) (acc . (y :)) ys
131+ Just pragma -> Right pragma
src/Ormolu/Parser/Pragma.hs+33−34
@@ -1,42 +1,41 @@
1+-- | A module for parsing of pragmas from comments.
2+
1−{-# LANGUAGE LambdaCase #-}
3+{-# LANGUAGE LambdaCase #-}
2{-# LANGUAGE OverloadedStrings #-}
4{-# LANGUAGE OverloadedStrings #-}
3
5
4−-- | A module for parsing of pragmas from comments.
5module Ormolu.Parser.Pragma
6module Ormolu.Parser.Pragma
6− ( Pragma (..),
7+ ( Pragma (..)
7− parsePragma,
8+ , parsePragma
8 )
9 )
9where
10where
10
11
11import Control.Monad
12import Control.Monad
12−import Data.Char (isSpace, toLower)
13+import Data.Char (toLower, isSpace)
13−import qualified Data.List as L
14+import Data.List
14−import qualified EnumSet as ES
15import FastString (mkFastString, unpackFS)
15import FastString (mkFastString, unpackFS)
16−import qualified Lexer as L
17−import Module (ComponentId (..), newSimpleUnitId)
16+import Module (newSimpleUnitId, ComponentId (..))
18import SrcLoc
17import SrcLoc
19import StringBuffer
18import StringBuffer
19+import qualified EnumSet as ES
20+import qualified Lexer as L
20
21
21-- | Ormolu's representation of pragmas.
22-- | Ormolu's representation of pragmas.
23+
22data Pragma
24data Pragma
23− = -- | Language pragma
24− PragmaLanguage [String]
25+ = PragmaLanguage [String] -- ^ Language pragma
25− | -- | GHC options pragma
26+ | PragmaOptionsGHC String -- ^ GHC options pragma
26− PragmaOptionsGHC String
27− | -- | Haddock options pragma
28− PragmaOptionsHaddock String
27+ | PragmaOptionsHaddock String -- ^ Haddock options pragma
29 deriving (Show, Eq)
28 deriving (Show, Eq)
30
29
31-- | Extract a pragma from a comment if possible, or return 'Nothing'
30-- | Extract a pragma from a comment if possible, or return 'Nothing'
32-- otherwise.
31-- otherwise.
32+
33−parsePragma ::
33+parsePragma
34− -- | Comment to try to parse
34+ :: String -- ^ Comment to try to parse
35− String ->
36− Maybe Pragma
35+ -> Maybe Pragma
37parsePragma input = do
36parsePragma input = do
38− inputNoPrefix <- L.stripPrefix "{-#" input
37+ inputNoPrefix <- stripPrefix "{-#" input
39− guard ("#-}" `L.isSuffixOf` input)
38+ guard ("#-}" `isSuffixOf` input)
40 let contents = take (length inputNoPrefix - 3) inputNoPrefix
39 let contents = take (length inputNoPrefix - 3) inputNoPrefix
41 (pragmaName, cs) = (break isSpace . dropWhile isSpace) contents
40 (pragmaName, cs) = (break isSpace . dropWhile isSpace) contents
42 case toLower <$> pragmaName of
41 case toLower <$> pragmaName of
@@ -46,19 +45,21 @@ parsePragma input = do
46 _ -> Nothing
45 _ -> Nothing
47 where
46 where
48 trimSpaces :: String -> String
47 trimSpaces :: String -> String
49− trimSpaces = L.dropWhileEnd isSpace . dropWhile isSpace
48+ trimSpaces = dropWhileEnd isSpace . dropWhile isSpace
50
49
51-- | Assuming the input consists of a series of tokens from a language
50-- | Assuming the input consists of a series of tokens from a language
52-- pragma, return the set of enabled extensions.
51-- pragma, return the set of enabled extensions.
52+
53−parseExtensions :: String -> Maybe [String]
53+parseExtensions :: String -> Maybe [String]
54parseExtensions str = tokenize str >>= go
54parseExtensions str = tokenize str >>= go
55 where
55 where
56 go = \case
56 go = \case
57− [L.ITconid ext] -> return [unpackFS ext]
57+ (L.ITconid ext : []) -> return [unpackFS ext]
58 (L.ITconid ext : L.ITcomma : xs) -> (unpackFS ext :) <$> go xs
58 (L.ITconid ext : L.ITcomma : xs) -> (unpackFS ext :) <$> go xs
59 _ -> Nothing
59 _ -> Nothing
60
60
61-- | Tokenize a given input using GHC's lexer.
61-- | Tokenize a given input using GHC's lexer.
62+
62tokenize :: String -> Maybe [L.Token]
63tokenize :: String -> Maybe [L.Token]
63tokenize input =
64tokenize input =
64 case L.unP pLexer parseState of
65 case L.unP pLexer parseState of
@@ -68,17 +69,15 @@ tokenize input =
68 location = mkRealSrcLoc (mkFastString "") 1 1
69 location = mkRealSrcLoc (mkFastString "") 1 1
69 buffer = stringToStringBuffer input
70 buffer = stringToStringBuffer input
70 parseState = L.mkPStatePure parserFlags buffer location
71 parseState = L.mkPStatePure parserFlags buffer location
71− parserFlags =
72+ parserFlags = L.ParserFlags
72− L.mkParserFlags'
73− ES.empty
73+ { L.pWarningFlags = ES.empty
74− ES.empty
74+ , L.pExtensionFlags = ES.empty
75− (newSimpleUnitId (ComponentId (mkFastString "")))
75+ , L.pThisPackage = newSimpleUnitId (ComponentId (mkFastString ""))
76− True
76+ , L.pExtsBitmap = 0xffffffffffffffff
77− True
77+ }
78− True
79− True
80
78
81-- | Haskell lexer.
79-- | Haskell lexer.
80+
82pLexer :: L.P [L.Token]
81pLexer :: L.P [L.Token]
83pLexer = go
82pLexer = go
84 where
83 where
@@ -86,4 +85,4 @@ pLexer = go
86 r <- L.lexer False return
85 r <- L.lexer False return
87 case unLoc r of
86 case unLoc r of
88 L.ITeof -> return []
87 L.ITeof -> return []
89− x -> (x :) <$> go
88+ x -> (x:) <$> go
src/Ormolu/Parser/Result.hs+20−34
@@ -1,51 +1,37 @@
1+-- | A type for result of parsing.
2+
1{-# LANGUAGE RecordWildCards #-}
3{-# LANGUAGE RecordWildCards #-}
2
4
3−-- | A type for result of parsing.
4module Ormolu.Parser.Result
5module Ormolu.Parser.Result
5− ( ParseResult (..),
6+ ( ParseResult (..)
6− prettyPrintParseResult,
7+ , prettyPrintParseResult
7 )
8 )
8where
9where
9
10
10−import Data.Text (Text)
11import GHC
11import GHC
12import Ormolu.Parser.Anns
12import Ormolu.Parser.Anns
13import Ormolu.Parser.CommentStream
13import Ormolu.Parser.CommentStream
14import Ormolu.Parser.Pragma (Pragma)
14import Ormolu.Parser.Pragma (Pragma)
15−import Ormolu.Parser.Shebang (Shebang)
16
15
17-- | A collection of data that represents a parsed module in Ormolu.
16-- | A collection of data that represents a parsed module in Ormolu.
17+
18data ParseResult = ParseResult
18data ParseResult = ParseResult
19+ { prParsedSource :: ParsedSource
19− { -- | 'ParsedSource' from GHC
20+ -- ^ 'ParsedSource' from GHC
20− prParsedSource :: HsModule GhcPs,
21+ , prAnns :: Anns
21− -- | Ormolu-specfic representation of annotations
22+ -- ^ Ormolu-specfic representation of annotations
22− prAnns :: Anns,
23− -- | Stack header
24− prStackHeader :: Maybe (RealLocated Comment),
25− -- | Shebangs found in the input
26− prShebangs :: [Shebang],
27− -- | Pragmas and the associated comments
28− prPragmas :: [([RealLocated Comment], Pragma)],
29− -- | Comment stream
30− prCommentStream :: CommentStream,
23+ , prCommentStream :: CommentStream
31− -- | Whether or not record dot syntax is enabled
24+ -- ^ Comment stream
32− prUseRecordDot :: Bool,
25+ , prExtensions :: [Pragma]
33− -- | Whether or not ImportQualifiedPost is enabled
26+ -- ^ Extensions enabled in that module
34− prImportQualifiedPost :: Bool,
35− -- | Literal prefix
36− prLiteralPrefix :: Text,
37− -- | Literal suffix
38− prLiteralSuffix :: Text,
39− -- | Indentation level, can be non-zero in case of region formatting
40− prIndent :: Int
41 }
27 }
42
28
43-- | Pretty-print a 'ParseResult'.
29-- | Pretty-print a 'ParseResult'.
30+
44prettyPrintParseResult :: ParseResult -> String
31prettyPrintParseResult :: ParseResult -> String
45−prettyPrintParseResult ParseResult {..} =
32+prettyPrintParseResult ParseResult {..} = unlines
46− unlines
47− [ "parse result:",
33+ [ "parse result:"
48− " comment stream:",
34+ , " comment stream:"
49− showCommentStream prCommentStream
35+ , showCommentStream prCommentStream
50− -- XXX extend as needed
36+ -- XXX extend as needed
51− ]
37+ ]
src/Ormolu/Parser/Shebang.hsdeleted−27
@@ -1,27 +0,0 @@
1−{-# LANGUAGE DeriveDataTypeable #-}
2−
3−-- | A module for dealing with shebangs.
4−module Ormolu.Parser.Shebang
5− ( Shebang (..),
6− extractShebangs,
7− isShebang,
8− )
9−where
10−
11−import Data.Data (Data)
12−import qualified Data.List as L
13−import SrcLoc
14−
15−-- | A wrapper for a shebang.
16−newtype Shebang = Shebang (Located String)
17− deriving (Eq, Data)
18−
19−-- | Extract shebangs from the beginning of a comment stream.
20−extractShebangs :: [Located String] -> ([Shebang], [Located String])
21−extractShebangs comments = (Shebang <$> shebangs, rest)
22− where
23− (shebangs, rest) = span (isShebang . unLoc) comments
24−
25−-- | Return 'True' if given 'String' is a shebang.
26−isShebang :: String -> Bool
27−isShebang str = "#!" `L.isPrefixOf` str
src/Ormolu/Printer.hs+16−25
@@ -1,8 +1,11 @@
1+{-# LANGUAGE LambdaCase #-}
2+{-# LANGUAGE OverloadedStrings #-}
1−{-# LANGUAGE RecordWildCards #-}
3+{-# LANGUAGE RecordWildCards #-}
2
4
3-- | Pretty-printer for Haskell AST.
5-- | Pretty-printer for Haskell AST.
6+
4module Ormolu.Printer
7module Ormolu.Printer
5− ( printModule,
8+ ( printModule
6 )
9 )
7where
10where
8
11
@@ -11,28 +14,16 @@ import Ormolu.Parser.Result
11import Ormolu.Printer.Combinators
14import Ormolu.Printer.Combinators
12import Ormolu.Printer.Meat.Module
15import Ormolu.Printer.Meat.Module
13import Ormolu.Printer.SpanStream
16import Ormolu.Printer.SpanStream
14−import Ormolu.Processing.Postprocess (postprocess)
15
17
16-- | Render a module.
18-- | Render a module.
19+
17−printModule ::
20+printModule
21+ :: Bool -- ^ Whether to trace debugging information
18− -- | Result of parsing
22+ -> ParseResult -- ^ Result of parsing
19− ParseResult ->
20− -- | Resulting rendition
23+ -> Text -- ^ Resulting rendition
21− Text
22−printModule ParseResult {..} =
24+printModule debugOn ParseResult {..} =
23− prLiteralPrefix <> region <> prLiteralSuffix
24− where
25− region =
26− postprocess prIndent $
27− runR
25+ runR debugOn
28− ( p_hsModule
29− prStackHeader
30− prShebangs
31− prPragmas
32− prImportQualifiedPost
33− prParsedSource
26+ (p_hsModule prExtensions prParsedSource)
34− )
35− (mkSpanStream prParsedSource)
27+ (mkSpanStream prParsedSource)
36− prCommentStream
28+ prCommentStream
37− prAnns
29+ prAnns
38− prUseRecordDot
src/Ormolu/Printer/Combinators.hs+177−165
@@ -1,113 +1,115 @@
1−{-# LANGUAGE FlexibleContexts #-}
2−{-# LANGUAGE GADTs #-}
3−{-# LANGUAGE LambdaCase #-}
1+{-# LANGUAGE LambdaCase #-}
4{-# LANGUAGE OverloadedStrings #-}
2{-# LANGUAGE OverloadedStrings #-}
3+{-# LANGUAGE RecordWildCards #-}
5
4
6-- | Printing combinators. The definitions here are presented in such an
5-- | Printing combinators. The definitions here are presented in such an
7-- order so you can just go through the Haddocks and by the end of the file
6-- order so you can just go through the Haddocks and by the end of the file
8-- you should have a pretty good idea how to program rendering logic.
7-- you should have a pretty good idea how to program rendering logic.
8+
9module Ormolu.Printer.Combinators
9module Ormolu.Printer.Combinators
10 ( -- * The 'R' monad
10 ( -- * The 'R' monad
11− R,
11+ R
12− runR,
12+ , runR
13− getAnns,
13+ , getAnns
14− getEnclosingSpan,
14+ , getEnclosingSpan
15−
16 -- * Combinators
15 -- * Combinators
17−
18 -- ** Basic
16 -- ** Basic
19− txt,
17+ , txt
20− atom,
18+ , atom
21− space,
22− newline,
19+ , newline
23− inci,
20+ , inci
24− inciIf,
25− located,
21+ , located
26− located',
22+ , located'
27− switchLayout,
23+ , switchLayout
28− Layout (..),
29− vlayout,
24+ , vlayout
30− getLayout,
25+ , breakpoint
31− breakpoint,
32− breakpoint',
26+ , breakpoint'
33−
34 -- ** Formatting lists
27 -- ** Formatting lists
35− sep,
28+ , sep
36− sepSemi,
29+ , sepSemi
37− canUseBraces,
30+ , canUseBraces
38− useBraces,
31+ , useBraces
39− dontUseBraces,
32+ , dontUseBraces
40−
41 -- ** Wrapping
33 -- ** Wrapping
42− BracketStyle (..),
43− sitcc,
34+ , sitcc
35+ , line
44− backticks,
36+ , backticks
45− banana,
37+ , banana
46− braces,
38+ , braces
47− brackets,
39+ , brackets
40+ , bracketsPar
48− parens,
41+ , parens
49− parensHash,
42+ , parensHash
50− pragmaBraces,
43+ , pragmaBraces
51− pragma,
44+ , pragma
52−
53 -- ** Literals
45 -- ** Literals
54− comma,
46+ , comma
55− commaDel,
47+ , space
56− equals,
57−
58− -- ** Stateful markers
59− SpanMark (..),
60− spanMarkSpan,
61− HaddockStyle (..),
62− setSpanMark,
63− getSpanMark,
64 )
48 )
65where
49where
66
50
67import Control.Monad
51import Control.Monad
52+import Data.Data (Data)
68import Data.List (intersperse)
53import Data.List (intersperse)
69import Data.Text (Text)
54import Data.Text (Text)
70import Ormolu.Printer.Comments
55import Ormolu.Printer.Comments
71import Ormolu.Printer.Internal
56import Ormolu.Printer.Internal
57+import Ormolu.Utils (isModule, showOutputable)
58+import Outputable (Outputable)
72import SrcLoc
59import SrcLoc
60+import qualified Data.Text as T
73
61
74----------------------------------------------------------------------------
62----------------------------------------------------------------------------
75-- Basic
63-- Basic
76
64
77−-- | Indent the inner expression if the first argument is 'True'.
65+-- | Output a fixed 'Text' fragment. The argument may not contain any line
78−inciIf ::
66+-- breaks or tab characters. 'txt' is used to output all sorts of “fixed”
79− -- | Whether to indent
67+-- bits of syntax like keywords and pipes @|@ in functional dependencies.
80− Bool ->
68+
81− -- | The expression to indent
69+txt :: Text -> R ()
82− R () ->
70+txt t = ensureIndent >> spit t
83− R ()
71+
84−inciIf b m = if b then inci m else m
72+-- | Output 'Outputable' fragment of AST. This can be used to output numeric
73+-- literals and similar. Everything that doesn't have inner structure but
74+-- does have an 'Outputable' instance.
75+
76+atom :: Outputable a => a -> R ()
77+atom = txt . T.pack . showOutputable
85
78
86-- | Enter a 'Located' entity. This combinator handles outputting comments
79-- | Enter a 'Located' entity. This combinator handles outputting comments
87-- and sets layout (single-line vs multi-line) for the inner computation.
80-- and sets layout (single-line vs multi-line) for the inner computation.
88-- Roughly, the rule for using 'located' is that every time there is a
81-- Roughly, the rule for using 'located' is that every time there is a
89-- 'Located' wrapper, it should be “discharged” with a corresponding
82-- 'Located' wrapper, it should be “discharged” with a corresponding
90-- 'located' invocation.
83-- 'located' invocation.
84+
91−located ::
85+located
86+ :: Data a
92− -- | Thing to enter
87+ => Located a -- ^ Thing to enter
93− Located a ->
94− -- | How to render inner value
88+ -> (a -> R ()) -- ^ How to render inner value
95− (a -> R ()) ->
96− R ()
89+ -> R ()
97−located (L (UnhelpfulSpan _) a) f = f a
90+located loc f = do
98−located (L (RealSrcSpan l) a) f = do
91+ let withRealLocated (L l a) g =
92+ case l of
93+ UnhelpfulSpan _ -> return ()
94+ RealSrcSpan l' -> g (L l' a)
99− spitPrecedingComments l
95+ withRealLocated loc spitPrecedingComments
96+ let setEnclosingSpan =
97+ case getLoc loc of
98+ UnhelpfulSpan _ -> id
99+ RealSrcSpan orf ->
100+ if isModule (unLoc loc)
101+ then id
100− withEnclosingSpan l $
102+ else withEnclosingSpan orf
101− switchLayout [RealSrcSpan l] (f a)
103+ setEnclosingSpan $ switchLayout [getLoc loc] (f (unLoc loc))
102− spitFollowingComments l
104+ withRealLocated loc spitFollowingComments
103
105
104-- | A version of 'located' with arguments flipped.
106-- | A version of 'located' with arguments flipped.
107+
105−located' ::
108+located'
109+ :: Data a
106− -- | How to render inner value
110+ => (a -> R ()) -- ^ How to render inner value
107− (a -> R ()) ->
108− -- | Thing to enter
111+ -> Located a -- ^ Thing to enter
109− Located a ->
110− R ()
112+ -> R ()
111located' = flip located
113located' = flip located
112
114
113-- | Set layout according to combination of given 'SrcSpan's for a given.
115-- | Set layout according to combination of given 'SrcSpan's for a given.
@@ -116,19 +118,19 @@ located' = flip located
116-- provided by GHC AST. It is relatively rare that this one is needed.
118-- provided by GHC AST. It is relatively rare that this one is needed.
117--
119--
118-- Given empty list this function will set layout to single line.
120-- Given empty list this function will set layout to single line.
121+
119−switchLayout ::
122+switchLayout
120− -- | Span that controls layout
123+ :: [SrcSpan] -- ^ Span that controls layout
121− [SrcSpan] ->
122− -- | Computation to run with changed layout
124+ -> R () -- ^ Computation to run with changed layout
123− R () ->
124− R ()
125+ -> R ()
125switchLayout spans' = enterLayout (spansLayout spans')
126switchLayout spans' = enterLayout (spansLayout spans')
126
127
127-- | Which layout combined spans result in?
128-- | Which layout combined spans result in?
129+
128spansLayout :: [SrcSpan] -> Layout
130spansLayout :: [SrcSpan] -> Layout
129spansLayout = \case
131spansLayout = \case
130 [] -> SingleLine
132 [] -> SingleLine
131− (x : xs) ->
133+ (x:xs) ->
132 if isOneLineSpan (foldr combineSrcSpans x xs)
134 if isOneLineSpan (foldr combineSrcSpans x xs)
133 then SingleLine
135 then SingleLine
134 else MultiLine
136 else MultiLine
@@ -137,6 +139,7 @@ spansLayout = \case
137-- multiline.
139-- multiline.
138--
140--
139-- > breakpoint = vlayout space newline
141-- > breakpoint = vlayout space newline
142+
140breakpoint :: R ()
143breakpoint :: R ()
141breakpoint = vlayout space newline
144breakpoint = vlayout space newline
142
145
@@ -144,6 +147,7 @@ breakpoint = vlayout space newline
144-- layout.
147-- layout.
145--
148--
146-- > breakpoint' = vlayout (return ()) newline
149-- > breakpoint' = vlayout (return ()) newline
150+
147breakpoint' :: R ()
151breakpoint' :: R ()
148breakpoint' = vlayout (return ()) newline
152breakpoint' = vlayout (return ()) newline
149
153
@@ -151,14 +155,12 @@ breakpoint' = vlayout (return ()) newline
151-- Formatting lists
155-- Formatting lists
152
156
153-- | Render a collection of elements inserting a separator between them.
157-- | Render a collection of elements inserting a separator between them.
158+
154−sep ::
159+sep
155− -- | Separator
160+ :: R () -- ^ Separator
156− R () ->
157− -- | How to render an element
161+ -> (a -> R ()) -- ^ How to render an element
158− (a -> R ()) ->
162+ -> [a] -- ^ Elements to render
159− -- | Elements to render
160− [a] ->
161− R ()
163+ -> R ()
162sep s f xs = sequence_ (intersperse s (f <$> xs))
164sep s f xs = sequence_ (intersperse s (f <$> xs))
163
165
164-- | Render a collection of elements layout-sensitively using given printer,
166-- | Render a collection of elements layout-sensitively using given printer,
@@ -170,12 +172,11 @@ sep s f xs = sequence_ (intersperse s (f <$> xs))
170--
172--
171-- > dontUseBraces $ sepSemi txt ["foo", "bar"]
173-- > dontUseBraces $ sepSemi txt ["foo", "bar"]
172-- > == vlayout (txt "foo; bar") (txt "foo\nbar")
174-- > == vlayout (txt "foo; bar") (txt "foo\nbar")
175+
173−sepSemi ::
176+sepSemi
174− -- | How to render an element
177+ :: (a -> R ()) -- ^ How to render an element
175− (a -> R ()) ->
178+ -> [a] -- ^ Elements to render
176− -- | Elements to render
177− [a] ->
178− R ()
179+ -> R ()
179sepSemi f xs = vlayout singleLine multiLine
180sepSemi f xs = vlayout singleLine multiLine
180 where
181 where
181 singleLine = do
182 singleLine = do
@@ -184,28 +185,31 @@ sepSemi f xs = vlayout singleLine multiLine
184 [] -> when ub $ txt "{}"
185 [] -> when ub $ txt "{}"
185 xs' ->
186 xs' ->
186 if ub
187 if ub
187− then do
188+ then do
188− txt "{"
189+ txt "{ "
189− space
190− sep (txt ";" >> space) (dontUseBraces . f) xs'
190+ sep (txt "; ") (dontUseBraces . f) xs'
191− space
192− txt "}"
191+ txt " }"
192+ else
193− else sep (txt ";" >> space) f xs'
193+ sep (txt "; ") f xs'
194 multiLine =
194 multiLine =
195 sep newline (dontUseBraces . f) xs
195 sep newline (dontUseBraces . f) xs
196
196
197----------------------------------------------------------------------------
197----------------------------------------------------------------------------
198-- Wrapping
198-- Wrapping
199
199
200−-- | 'BracketStyle' controlling how closing bracket is rendered.
200+-- | Finish given entity by a 'newline'.
201−data BracketStyle
201+--
202− = -- | Normal
202+-- > line m = do
203− N
203+-- > m
204− | -- | Shifted one level
204+-- > newline
205− S
205+
206− deriving (Eq, Show)
206+line :: R () -> R ()
207+line m = do
208+ m
209+ newline
207
210
208-- | Surround given entity by backticks.
211-- | Surround given entity by backticks.
212+
209backticks :: R () -> R ()
213backticks :: R () -> R ()
210backticks m = do
214backticks m = do
211 txt "`"
215 txt "`"
@@ -213,86 +217,94 @@ backticks m = do
213 txt "`"
217 txt "`"
214
218
215-- | Surround given entity by banana brackets (i.e., from arrow notation.)
219-- | Surround given entity by banana brackets (i.e., from arrow notation.)
220+
216banana :: R () -> R ()
221banana :: R () -> R ()
217−banana = brackets_ True "(|" "|)" N
222+banana m = sitcc $ do
223+ txt "(|"
224+ ospaces m
225+ txt "|)"
218
226
219-- | Surround given entity by curly braces @{@ and @}@.
227-- | Surround given entity by curly braces @{@ and @}@.
228+
220−braces :: BracketStyle -> R () -> R ()
229+braces :: R () -> R ()
221−braces = brackets_ False "{" "}"
230+braces m = sitcc $ do
231+ txt "{"
232+ ospaces m
233+ txt "}"
222
234
223-- | Surround given entity by square brackets @[@ and @]@.
235-- | Surround given entity by square brackets @[@ and @]@.
236+
224−brackets :: BracketStyle -> R () -> R ()
237+brackets :: R () -> R ()
225−brackets = brackets_ False "[" "]"
238+brackets m = sitcc $ do
239+ txt "["
240+ ospaces m
241+ txt "]"
242+
243+-- | Surround given entity by parallel array brackets @[:@ and @:]@.
244+
245+bracketsPar :: R () -> R ()
246+bracketsPar m = sitcc $ do
247+ txt "[: "
248+ m
249+ vlayout (return ()) space
250+ txt " :]"
226
251
227-- | Surround given entity by parentheses @(@ and @)@.
252-- | Surround given entity by parentheses @(@ and @)@.
253+
228−parens :: BracketStyle -> R () -> R ()
254+parens :: R () -> R ()
229−parens = brackets_ False "(" ")"
255+parens m = sitcc $ do
256+ txt "("
257+ ospaces m
258+ txt ")"
230
259
231-- | Surround given entity by @(# @ and @ #)@.
260-- | Surround given entity by @(# @ and @ #)@.
261+
232−parensHash :: BracketStyle -> R () -> R ()
262+parensHash :: R () -> R ()
233−parensHash = brackets_ True "(#" "#)"
263+parensHash m = sitcc $ do
264+ txt "(# "
265+ m
266+ vlayout space (newline >> txt " ")
267+ txt "#)"
234
268
235-- | Braces as used for pragmas: @{-#@ and @#-}@.
269-- | Braces as used for pragmas: @{-#@ and @#-}@.
270+
236pragmaBraces :: R () -> R ()
271pragmaBraces :: R () -> R ()
237pragmaBraces m = sitcc $ do
272pragmaBraces m = sitcc $ do
238− txt "{-#"
273+ txt "{-# "
239− space
240 m
274 m
241− breakpoint
275+ vlayout space (newline >> txt " ")
242− inci (txt "#-}")
276+ txt "#-}"
243
277
244-- | Surround the body with a pragma name and 'pragmaBraces'.
278-- | Surround the body with a pragma name and 'pragmaBraces'.
279+
245−pragma ::
280+pragma
246− -- | Pragma text
281+ :: Text -- ^ Pragma text
247− Text ->
248− -- | Pragma body
282+ -> R () -- ^ Pragma body
249− R () ->
250− R ()
283+ -> R ()
251pragma pragmaText body = pragmaBraces $ do
284pragma pragmaText body = pragmaBraces $ do
252 txt pragmaText
285 txt pragmaText
253 breakpoint
286 breakpoint
254 body
287 body
255
288
256−-- | A helper for defining wrappers like 'parens' and 'braces'.
289+-- | Surround given entity by optional space before and a newline after, iff
257−brackets_ ::
290+-- current layout is multiline.
258− -- | Insert breakpoints around brackets
291+
259− Bool ->
292+ospaces :: R () -> R ()
260− -- | Opening bracket
293+ospaces m = vlayout m $ do
261− Text ->
294+ space
262− -- | Closing bracket
263− Text ->
264− -- | Bracket style
265− BracketStyle ->
266− -- | Inner expression
267− R () ->
268− R ()
269−brackets_ needBreaks open close style m = sitcc (vlayout singleLine multiLine)
270− where
271− singleLine = do
272− txt open
273− when needBreaks space
274− m
275− when needBreaks space
276− txt close
277− multiLine = do
278− txt open
279− if needBreaks
280− then newline >> inci m
281− else space >> sitcc m
295+ sitcc m
282− newline
296+ newline
283− inciIf (style == S) (txt close)
297+ txt " "
284
298
285----------------------------------------------------------------------------
299----------------------------------------------------------------------------
286-- Literals
300-- Literals
287
301
288-- | Print @,@.
302-- | Print @,@.
303+
289comma :: R ()
304comma :: R ()
290comma = txt ","
305comma = txt ","
291
306
292−-- | Delimiting combination with 'comma'. To be used with 'sep'.
307+-- | Print single space.
293−commaDel :: R ()
294−commaDel = comma >> breakpoint
295
308
296−-- | Print @=@. Do not use @'txt' "="@.
309+space :: R ()
297−equals :: R ()
310+space = txt " "
298−equals = interferingTxt "="
src/Ormolu/Printer/Comments.hs+145−191
@@ -1,200 +1,182 @@
1−{-# LANGUAGE LambdaCase #-}
1+{-# LANGUAGE LambdaCase #-}
2{-# LANGUAGE OverloadedStrings #-}
2{-# LANGUAGE OverloadedStrings #-}
3
3
4-- | Helpers for formatting of comments. This is low-level code, use
4-- | Helpers for formatting of comments. This is low-level code, use
5-- "Ormolu.Printer.Combinators" unless you know what you are doing.
5-- "Ormolu.Printer.Combinators" unless you know what you are doing.
6+
6module Ormolu.Printer.Comments
7module Ormolu.Printer.Comments
7− ( spitPrecedingComments,
8+ ( spitPrecedingComments
8− spitFollowingComments,
9+ , spitFollowingComments
9− spitRemainingComments,
10+ , spitRemainingComments
10− spitCommentNow,
11+ , isNewlineModified
11− spitCommentPending,
12+ , hasMoreComments
12 )
13 )
13where
14where
14
15
15import Control.Monad
16import Control.Monad
16−import qualified Data.List.NonEmpty as NE
17+import Data.Coerce (coerce)
17−import Data.Maybe (listToMaybe)
18+import Data.Data (Data)
18−import qualified Data.Text as T
19import Ormolu.Parser.CommentStream
19import Ormolu.Parser.CommentStream
20import Ormolu.Printer.Internal
20import Ormolu.Printer.Internal
21+import Ormolu.Utils (isModule)
21import SrcLoc
22import SrcLoc
23+import qualified Data.List.NonEmpty as NE
24+import qualified Data.Text as T
22
25
23----------------------------------------------------------------------------
26----------------------------------------------------------------------------
24-- Top-level
27-- Top-level
25
28
26-- | Output all preceding comments for an element at given location.
29-- | Output all preceding comments for an element at given location.
30+
27−spitPrecedingComments ::
31+spitPrecedingComments
32+ :: Data a
28− -- | Span of the element to attach comments to
33+ => RealLocated a -- ^ AST element to attach comments to
29− RealSrcSpan ->
30− R ()
34+ -> R ()
31−spitPrecedingComments ref = do
32− gotSome <- handleCommentSeries (spitPrecedingComment ref)
35+spitPrecedingComments = handleCommentSeries . spitPrecedingComment
33− when gotSome $ do
34− lastMark <- getSpanMark
35− -- Insert a blank line between the preceding comments and the thing
36− -- after them if there was a blank line in the input.
37− when (needsNewlineBefore ref lastMark) newline
38
36
39-- | Output all comments following an element at given location.
37-- | Output all comments following an element at given location.
38+
40−spitFollowingComments ::
39+spitFollowingComments
40+ :: Data a
41− -- | Span of the element to attach comments to
41+ => RealLocated a -- ^ AST element of attach comments to
42− RealSrcSpan ->
43− R ()
42+ -> R ()
44spitFollowingComments ref = do
43spitFollowingComments ref = do
45− trimSpanStream ref
44+ trimSpanStream (getLoc ref)
46− void $ handleCommentSeries (spitFollowingComment ref)
45+ handleCommentSeries (spitFollowingComment ref)
47
46
48-- | Output all remaining comments in the comment stream.
47-- | Output all remaining comments in the comment stream.
48+
49spitRemainingComments :: R ()
49spitRemainingComments :: R ()
50−spitRemainingComments = do
51− -- Make sure we have a blank a line between the last definition and the
52− -- trailing comments.
53− newline
54− void $ handleCommentSeries spitRemainingComment
50+spitRemainingComments = handleCommentSeries spitRemainingComment
55
51
56----------------------------------------------------------------------------
52----------------------------------------------------------------------------
57-- Single-comment functions
53-- Single-comment functions
58
54
59-- | Output a single preceding comment for an element at given location.
55-- | Output a single preceding comment for an element at given location.
56+
60−spitPrecedingComment ::
57+spitPrecedingComment
58+ :: Data a
61− -- | Span of the element to attach comments to
59+ => RealLocated a -- ^ AST element to attach comments to
62− RealSrcSpan ->
60+ -> Maybe RealSrcSpan -- ^ Location of last comment in the series
63− -- | Are we done?
61+ -> R (Maybe RealSrcSpan) -- ^ Location of this comment
64− R Bool
65−spitPrecedingComment ref = do
62+spitPrecedingComment (L ref a) mlastSpn = do
66− mlastMark <- getSpanMark
67 let p (L l _) = realSrcSpanEnd l <= realSrcSpanStart ref
63 let p (L l _) = realSrcSpanEnd l <= realSrcSpanStart ref
68 withPoppedComment p $ \l comment -> do
64 withPoppedComment p $ \l comment -> do
69− lineSpans <- thisLineSpans
70− let thisCommentLine = srcLocLine (realSrcSpanStart l)
71− needsNewline =
72− case listToMaybe lineSpans of
73− Nothing -> False
74− Just spn -> srcLocLine (realSrcSpanEnd spn) /= thisCommentLine
75− when (needsNewline || needsNewlineBefore l mlastMark) newline
65+ when (needsNewlineBefore l mlastSpn) newline
76− spitCommentNow l comment
66+ spitComment comment
77− if theSameLinePre l ref
67+ if theSameLine l ref && not (isModule a)
78− then space
68+ then spit " "
79 else newline
69 else newline
80
70
81-- | Output a comment that follows element at given location immediately on
71-- | Output a comment that follows element at given location immediately on
82-- the same line, if there is any.
72-- the same line, if there is any.
73+
83−spitFollowingComment ::
74+spitFollowingComment
75+ :: Data a
84− -- | AST element to attach comments to
76+ => RealLocated a -- ^ AST element to attach comments to
85− RealSrcSpan ->
77+ -> Maybe RealSrcSpan -- ^ Location of last comment in the series
86− -- | Are we done?
78+ -> R (Maybe RealSrcSpan) -- ^ Location of this comment
87− R Bool
88−spitFollowingComment ref = do
79+spitFollowingComment (L ref a) mlastSpn = do
89− mlastMark <- getSpanMark
90 mnSpn <- nextEltSpan
80 mnSpn <- nextEltSpan
91 -- Get first enclosing span that is not equal to reference span, i.e. it's
81 -- Get first enclosing span that is not equal to reference span, i.e. it's
92 -- truly something enclosing the AST element.
82 -- truly something enclosing the AST element.
93 meSpn <- getEnclosingSpan (/= ref)
83 meSpn <- getEnclosingSpan (/= ref)
84+ newlineModified <- isNewlineModified
85+ i <- getIndent
94− withPoppedComment (commentFollowsElt ref mnSpn meSpn mlastMark) $ \l comment ->
86+ withPoppedComment (commentFollowsElt ref mnSpn meSpn mlastSpn) $ \l comment ->
95− if theSameLinePost l ref
87+ if theSameLine l ref && not (isModule a)
96− then
88+ then modNewline $ \m -> setIndent i $ do
97− if isMultilineComment comment
89+ if newlineModified
98− then space >> spitCommentNow l comment
90+ then do
99− else spitCommentPending OnTheSameLine l comment
91+ -- This happens when we have several lines each with its own
100− else do
92+ -- comment and they get merged by the formatter.
93+ m
94+ spitComment comment
95+ newline
96+ else do
97+ spit " "
98+ spitComment comment
99+ m
100+ else modNewline $ \m -> setIndent i $ do
101+ m
101− when (needsNewlineBefore l mlastMark) $
102+ when (needsNewlineBefore l mlastSpn) newline
102− registerPendingCommentLine OnNextLine ""
103+ spitComment comment
103− spitCommentPending OnNextLine l comment
104+ newline
104
105
105-- | Output a single remaining comment from the comment stream.
106-- | Output a single remaining comment from the comment stream.
107+
106−spitRemainingComment ::
108+spitRemainingComment
107− -- | Are we done?
109+ :: Maybe RealSrcSpan -- ^ Location of last comment in the series
108− R Bool
110+ -> R (Maybe RealSrcSpan) -- ^ Location of this comment
109−spitRemainingComment = do
111+spitRemainingComment mlastSpn =
110− mlastMark <- getSpanMark
111 withPoppedComment (const True) $ \l comment -> do
112 withPoppedComment (const True) $ \l comment -> do
112− when (needsNewlineBefore l mlastMark) newline
113+ when (needsNewlineBefore l mlastSpn) newline
113− spitCommentNow l comment
114+ spitComment comment
114 newline
115 newline
115
116
116----------------------------------------------------------------------------
117----------------------------------------------------------------------------
117-- Helpers
118-- Helpers
118
119
119-- | Output series of comments.
120-- | Output series of comments.
121+
120−handleCommentSeries ::
122+handleCommentSeries
123+ :: (Maybe RealSrcSpan -> R (Maybe RealSrcSpan))
121− -- | Given location of previous comment, output the next comment
124+ -- ^ Given location of previous comment, output the next comment
122− -- returning 'True' if we're done
125+ -- returning its location, or 'Nothing' if we are done
123− R Bool ->
126+ -> R ()
124− -- | Whether we printed any comments
125− R Bool
126−handleCommentSeries f = go False
127+handleCommentSeries f = go Nothing
127 where
128 where
128− go gotSome = do
129+ go mlastSpn = do
129− done <- f
130+ r <- f mlastSpn
130− if done
131+ case r of
131− then return gotSome
132+ Nothing -> return ()
132− else go True
133+ Just spn -> go (Just spn)
133
134
134-- | Try to pop a comment using given predicate and if there is a comment
135-- | Try to pop a comment using given predicate and if there is a comment
135-- matching the predicate, print it out.
136-- matching the predicate, print it out.
137+
136−withPoppedComment ::
138+withPoppedComment
137− -- | Comment predicate
139+ :: (RealLocated Comment -> Bool) -- ^ Comment predicate
138− (RealLocated Comment -> Bool) ->
140+ -> (RealSrcSpan -> Comment -> R ()) -- ^ Priting function
139− -- | Printing function
141+ -> R (Maybe RealSrcSpan)
140− (RealSrcSpan -> Comment -> R ()) ->
141− -- | Are we done?
142− R Bool
143withPoppedComment p f = do
142withPoppedComment p f = do
144 r <- popComment p
143 r <- popComment p
145 case r of
144 case r of
146− Nothing -> return True
145+ Nothing -> return Nothing
147− Just (L l comment) -> False <$ f l comment
146+ Just (L l comment) -> Just l <$ f l comment
148
147
149-- | Determine if we need to insert a newline between current comment and
148-- | Determine if we need to insert a newline between current comment and
150-- last printed comment.
149-- last printed comment.
150+
151−needsNewlineBefore ::
151+needsNewlineBefore
152− -- | Current comment span
152+ :: RealSrcSpan -- ^ Current comment span
153− RealSrcSpan ->
154− -- | Last printed comment span
153+ -> Maybe RealSrcSpan -- ^ Last printed comment span
155− Maybe SpanMark ->
156− Bool
154+ -> Bool
157−needsNewlineBefore _ (Just (HaddockSpan _ _)) = True
158−needsNewlineBefore l mlastMark =
155+needsNewlineBefore l mlastSpn =
159− case spanMarkSpan <$> mlastMark of
156+ case mlastSpn of
160 Nothing -> False
157 Nothing -> False
161− Just lastMark ->
158+ Just lastSpn ->
162− srcSpanStartLine l > srcSpanEndLine lastMark + 1
159+ srcSpanStartLine l > srcSpanEndLine lastSpn + 1
163−
160+
164−-- | Is the preceding comment and AST element are on the same line?
161+-- | Is the comment and AST element are on the same line?
165−theSameLinePre ::
166− -- | Current comment span
167− RealSrcSpan ->
168− -- | AST element location
169− RealSrcSpan ->
170− Bool
171−theSameLinePre l ref =
172− srcSpanEndLine l == srcSpanStartLine ref
173
162
174−-- | Is the following comment and AST element are on the same line?
163+theSameLine
175−theSameLinePost ::
176− -- | Current comment span
164+ :: RealSrcSpan -- ^ Current comment span
177− RealSrcSpan ->
178− -- | AST element location
165+ -> RealSrcSpan -- ^ AST element location
179− RealSrcSpan ->
180− Bool
166+ -> Bool
181−theSameLinePost l ref =
167+theSameLine l ref =
182− srcSpanStartLine l == srcSpanEndLine ref
168+ srcSpanEndLine l == srcSpanStartLine ref
183
169
184-- | Determine if given comment follows AST element.
170-- | Determine if given comment follows AST element.
171+
185−commentFollowsElt ::
172+commentFollowsElt
186− -- | Location of AST element
173+ :: RealSrcSpan -- ^ Location of AST element
187− RealSrcSpan ->
188− -- | Location of next AST element
174+ -> Maybe RealSrcSpan -- ^ Location of next AST element
189− Maybe RealSrcSpan ->
190− -- | Location of enclosing AST element
175+ -> Maybe RealSrcSpan -- ^ Location of enclosing AST element
191− Maybe RealSrcSpan ->
192− -- | Location of last comment in the series
176+ -> Maybe RealSrcSpan -- ^ Location of last comment in the series
193− Maybe SpanMark ->
194− -- | Comment to test
177+ -> RealLocated Comment -- ^ Comment to test
195− RealLocated Comment ->
196− Bool
178+ -> Bool
197−commentFollowsElt ref mnSpn meSpn mlastMark (L l comment) =
179+commentFollowsElt ref mnSpn meSpn mlastSpn (L l comment) =
198 -- A comment follows a AST element if all 4 conditions are satisfied:
180 -- A comment follows a AST element if all 4 conditions are satisfied:
199 goesAfter
181 goesAfter
200 && logicallyFollows
182 && logicallyFollows
@@ -205,10 +187,11 @@ commentFollowsElt ref mnSpn meSpn mlastMark (L l comment) =
205 goesAfter =
187 goesAfter =
206 realSrcSpanStart l >= realSrcSpanEnd ref
188 realSrcSpanStart l >= realSrcSpanEnd ref
207 -- 2) The comment logically belongs to the element, four cases:
189 -- 2) The comment logically belongs to the element, four cases:
208− logicallyFollows =
190+ logicallyFollows
209− theSameLinePost l ref -- a) it's on the same line
191+ = theSameLine l ref -- a) it's on the same line
192+ || isPrevHaddock comment -- b) it's a Haddock string starting with -- ^
210− || continuation -- b) it's a continuation of a comment block
193+ || continuation -- c) it's a continuation of a comment block
211− || lastInEnclosing -- c) it's the last element in the enclosing construct
194+ || lastInEnclosing -- d) it's the last element in the enclosing construct
212
195
213 -- 3) There is no other AST element between this element and the comment:
196 -- 3) There is no other AST element between this element and the comment:
214 noEltBetween =
197 noEltBetween =
@@ -230,57 +213,28 @@ commentFollowsElt ref mnSpn meSpn mlastMark (L l comment) =
230 Nothing -> True
213 Nothing -> True
231 Just espn ->
214 Just espn ->
232 let startColumn = srcLocCol . realSrcSpanStart
215 let startColumn = srcLocCol . realSrcSpanStart
233− in startColumn espn > startColumn ref
216+ in if startColumn espn > startColumn ref
217+ then True
234− || ( abs (startColumn espn - startColumn l)
218+ else abs (startColumn espn - startColumn l)
235− >= abs (startColumn ref - startColumn l)
219+ >= abs (startColumn ref - startColumn l)
236− )
237 continuation =
220 continuation =
238− -- A comment is a continuation when it doesn't have non-whitespace
239− -- lexemes in front of it and goes right after the previous comment.
240− not (hasAtomsBefore comment)
241− && ( case mlastMark of
221+ case mlastSpn of
242− Just (HaddockSpan _ _) -> False
222+ Nothing -> False
243− Just (CommentSpan spn) ->
244− srcSpanEndLine spn + 1 == srcSpanStartLine l
223+ Just spn -> srcSpanEndLine spn + 1 == srcSpanStartLine l
245− _ -> False
224+
246− )
247 lastInEnclosing =
225 lastInEnclosing =
248− case meSpn of
226+ case (,) <$> meSpn <*> mnSpn of
249− -- When there is no enclosing element, return false
250 Nothing -> False
227 Nothing -> False
251− -- When there is an enclosing element,
252− Just espn ->
228+ Just (espn, nspn) ->
253− let -- Make sure that the comment is inside the enclosing element
229+ -- Make sure that the comment is inside the parent
254− insideParent = realSrcSpanEnd l <= realSrcSpanEnd espn
230+ realSrcSpanEnd l <= realSrcSpanEnd espn
255− -- And check if the next element is outside of the parent
231+ -- Check if the next element is outside of the parent
256− nextOutsideParent = case mnSpn of
257− Nothing -> True
258− Just nspn -> realSrcSpanEnd espn < realSrcSpanStart nspn
232+ && realSrcSpanEnd espn < realSrcSpanStart nspn
259− in insideParent && nextOutsideParent
233+
260−
261−-- | Output a 'Comment' immediately. This is a low-level printing function.
234+-- | Output a 'Comment'. This is a low-level printing function.
262−spitCommentNow :: RealSrcSpan -> Comment -> R ()
235+
263−spitCommentNow spn comment = do
236+spitComment :: Comment -> R ()
264− sitcc
237+spitComment =
265− . sequence_
266− . NE.intersperse newline
238+ sitcc . sequence_ . NE.intersperse newline . fmap f . coerce
267− . fmap (txt . T.pack)
239+ where
268− . unComment
240+ f x = ensureIndent >> spit (T.pack x)
269− $ comment
270− setSpanMark (CommentSpan spn)
271−
272−-- | Output a 'Comment' at the end of correct line or after it depending on
273−-- 'CommentPosition'. Used for comments that may potentially follow on the
274−-- same line as something we just rendered, but not immediately after it.
275−spitCommentPending :: CommentPosition -> RealSrcSpan -> Comment -> R ()
276−spitCommentPending position spn comment = do
277− let wrapper = case position of
278− OnTheSameLine -> sitcc
279− OnNextLine -> id
280− wrapper
281− . sequence_
282− . NE.toList
283− . fmap (registerPendingCommentLine position . T.pack)
284− . unComment
285− $ comment
286− setSpanMark (CommentSpan spn)
src/Ormolu/Printer/Internal.hs+260−434
@@ -1,577 +1,403 @@
1{-# LANGUAGE GeneralizedNewtypeDeriving #-}
1{-# LANGUAGE GeneralizedNewtypeDeriving #-}
2−{-# LANGUAGE LambdaCase #-}
2+{-# LANGUAGE LambdaCase #-}
3−{-# LANGUAGE OverloadedStrings #-}
3+{-# LANGUAGE OverloadedStrings #-}
4−{-# LANGUAGE RankNTypes #-}
4+{-# LANGUAGE RankNTypes #-}
5
5
6-- | In most cases import "Ormolu.Printer.Combinators" instead, these
6-- | In most cases import "Ormolu.Printer.Combinators" instead, these
7-- functions are the low-level building blocks and should not be used on
7-- functions are the low-level building blocks and should not be used on
8-- their own. The 'R' monad is re-exported from "Ormolu.Printer.Combinators"
8-- their own. The 'R' monad is re-exported from "Ormolu.Printer.Combinators"
9-- as well.
9-- as well.
10+
10module Ormolu.Printer.Internal
11module Ormolu.Printer.Internal
11 ( -- * The 'R' monad
12 ( -- * The 'R' monad
12− R,
13+ R
13− runR,
14+ , runR
14−
15 -- * Internal functions
15 -- * Internal functions
16− txt,
16+ , spit
17− interferingTxt,
18− atom,
19− space,
20− newline,
17+ , newline
21− useRecordDot,
18+ , modNewline
19+ , isNewlineModified
20+ , ensureIndent
22− inci,
21+ , inci
23− sitcc,
22+ , sitcc
24− Layout (..),
23+ , Layout (..)
25− enterLayout,
24+ , enterLayout
26− vlayout,
25+ , vlayout
27− getLayout,
28−
29 -- * Helpers for braces
26 -- * Helpers for braces
30− useBraces,
27+ , useBraces
31− dontUseBraces,
28+ , dontUseBraces
32− canUseBraces,
29+ , canUseBraces
33−
34 -- * Special helpers for comment placement
30 -- * Special helpers for comment placement
35− CommentPosition (..),
36− registerPendingCommentLine,
37− trimSpanStream,
31+ , trimSpanStream
38− nextEltSpan,
32+ , nextEltSpan
39− popComment,
33+ , popComment
34+ , hasMoreComments
35+ , getIndent
36+ , setIndent
40− getEnclosingSpan,
37+ , getEnclosingSpan
41− withEnclosingSpan,
38+ , withEnclosingSpan
42− thisLineSpans,
43−
44− -- * Stateful markers
45− SpanMark (..),
46− spanMarkSpan,
47− HaddockStyle (..),
48− setSpanMark,
49− getSpanMark,
50−
51 -- * Annotations
39 -- * Annotations
52− getAnns,
40+ , getAnns
53 )
41 )
54where
42where
55
43
56import Control.Monad.Reader
44import Control.Monad.Reader
57import Control.Monad.State.Strict
45import Control.Monad.State.Strict
58−import Data.Bool (bool)
59import Data.Coerce
46import Data.Coerce
60−import Data.Maybe (listToMaybe)
47+import Data.Maybe (fromMaybe, isJust, listToMaybe)
61import Data.Text (Text)
48import Data.Text (Text)
62−import qualified Data.Text as T
63−import qualified Data.Text.Lazy as TL
64import Data.Text.Lazy.Builder
49import Data.Text.Lazy.Builder
50+import Debug.Trace
65import GHC
51import GHC
66import Ormolu.Parser.Anns
52import Ormolu.Parser.Anns
67import Ormolu.Parser.CommentStream
53import Ormolu.Parser.CommentStream
68import Ormolu.Printer.SpanStream
54import Ormolu.Printer.SpanStream
69−import Ormolu.Utils (showOutputable)
55+import SrcLoc
70−import Outputable (Outputable)
56+import qualified Data.Text as T
57+import qualified Data.Text.Lazy as TL
71
58
72----------------------------------------------------------------------------
59----------------------------------------------------------------------------
73-- The 'R' monad
60-- The 'R' monad
74
61
75-- | The 'R' monad hosts combinators that allow us to describe how to render
62-- | The 'R' monad hosts combinators that allow us to describe how to render
76-- AST.
63-- AST.
64+
77newtype R a = R (ReaderT RC (State SC) a)
65newtype R a = R (ReaderT RC (State SC) a)
78 deriving (Functor, Applicative, Monad)
66 deriving (Functor, Applicative, Monad)
79
67
80−-- | Reader context of 'R'. This should be used when we control rendering by
68+-- | Reader context of 'R'.
81−-- enclosing certain expressions with wrappers.
69+
82data RC = RC
70data RC = RC
71+ { rcIndent :: !Int
83− { -- | Indentation level, as the column index we need to start from after
72+ -- ^ Indentation level, as the column index we need to start from after a
84− -- a newline if we break lines
73+ -- newline if we break lines
85− rcIndent :: !Int,
86− -- | Current layout
87− rcLayout :: Layout,
74+ , rcLayout :: Layout
75+ -- ^ Current layout
76+ , rcDebug :: Bool
77+ -- ^ Whether to print debugging info as we go
78+ , rcEnclosingSpans :: [RealSrcSpan]
88− -- | Spans of enclosing elements of AST
79+ -- ^ Spans of enclosing elements of AST
89− rcEnclosingSpans :: [RealSrcSpan],
80+ , rcAnns :: Anns
90− -- | Collection of annotations
81+ -- ^ Collection of annotations
91− rcAnns :: Anns,
82+ , rcCanUseBraces :: Bool
92− -- | Whether the last expression in the layout can use braces
83+ -- ^ If the last expression in the layout can use braces
93− rcCanUseBraces :: Bool,
94− -- | Whether the source could have used the record dot preprocessor
95− rcUseRecDot :: Bool
96 }
84 }
97
85
98-- | State context of 'R'.
86-- | State context of 'R'.
87+
99data SC = SC
88data SC = SC
89+ { scColumn :: !Int
100− { -- | Index of the next column to render
90+ -- ^ Index of the next column to render
101− scColumn :: !Int,
91+ , scBuilder :: Builder
102− -- | Indentation level that was used for the current line
103− scIndent :: !Int,
104− -- | Rendered source code so far
92+ -- ^ Rendered source code so far
105− scBuilder :: Builder,
106− -- | Span stream
107− scSpanStream :: SpanStream,
93+ , scSpanStream :: SpanStream
108− -- | Spans of atoms that have been printed on the current line so far
94+ -- ^ Span stream
109− scThisLineSpans :: [RealSrcSpan],
110− -- | Comment stream
111− scCommentStream :: CommentStream,
95+ , scCommentStream :: CommentStream
112− -- | Pending comment lines (in reverse order) to be inserted before next
96+ -- ^ Comment stream
113− -- newline, 'Int' is the indentation level
97+ , scNewline :: Maybe (R ())
114− scPendingComments :: ![(CommentPosition, Text)],
98+ -- ^ What to render as newline, or 'Nothing' ('newlineRaw' will be used)
115− -- | Whether to output a space before the next output
116− scRequestedDelimiter :: !RequestedDelimiter,
117− -- | An auxiliary marker for keeping track of last output element
118− scSpanMark :: !(Maybe SpanMark)
119 }
99 }
120
100
121−-- | Make sure next output is delimited by one of the following.
122−data RequestedDelimiter
123− = -- | A space
124− RequestedSpace
125− | -- | A newline
126− RequestedNewline
127− | -- | Nothing
128− RequestedNothing
129− | -- | We just output a newline
130− AfterNewline
131− | -- | We haven't printed anything yet
132− VeryBeginning
133− deriving (Eq, Show)
134−
135-- | 'Layout' options.
101-- | 'Layout' options.
136−data Layout
137− = -- | Put everything on single line
138− SingleLine
139− | -- | Use multiple lines
140− MultiLine
141− deriving (Eq, Show)
142
102
143−-- | Modes for rendering of pending comments.
103+data Layout
144−data CommentPosition
104+ = SingleLine -- ^ Put everything on single line
145− = -- | Put the comment on the same line
105+ | MultiLine -- ^ Use multiple lines
146− OnTheSameLine
147− | -- | Put the comment on next line
148− OnNextLine
149 deriving (Eq, Show)
106 deriving (Eq, Show)
150
107
151-- | Run an 'R' monad.
108-- | Run an 'R' monad.
109+
152−runR ::
110+runR
111+ :: Bool -- ^ Whether to print debugging info
153− -- | Monad to run
112+ -> R () -- ^ Monad to run
154− R () ->
155− -- | Span stream
156− SpanStream ->
113+ -> SpanStream -- ^ Span stream
157− -- | Comment stream
158− CommentStream ->
114+ -> CommentStream -- ^ Comment stream
159− -- | Annotations
160− Anns ->
115+ -> Anns -- ^ Annotations
161− -- | Use Record Dot Syntax
162− Bool ->
163− -- | Resulting rendition
116+ -> Text -- ^ Resulting rendition
164− Text
165−runR (R m) sstream cstream anns recDot =
117+runR debug (R m) sstream cstream anns =
166 TL.toStrict . toLazyText . scBuilder $ execState (runReaderT m rc) sc
118 TL.toStrict . toLazyText . scBuilder $ execState (runReaderT m rc) sc
167 where
119 where
168− rc =
120+ rc = RC
169− RC
170− { rcIndent = 0,
121+ { rcIndent = 0
171− rcLayout = MultiLine,
122+ , rcLayout = MultiLine
123+ , rcDebug = debug
172− rcEnclosingSpans = [],
124+ , rcEnclosingSpans = []
173− rcAnns = anns,
125+ , rcAnns = anns
174− rcCanUseBraces = False,
126+ , rcCanUseBraces = False
175− rcUseRecDot = recDot
176− }
127+ }
177− sc =
128+ sc = SC
178− SC
179− { scColumn = 0,
129+ { scColumn = 0
180− scIndent = 0,
181− scBuilder = mempty,
130+ , scBuilder = mempty
182− scSpanStream = sstream,
131+ , scSpanStream = sstream
183− scThisLineSpans = [],
184− scCommentStream = cstream,
132+ , scCommentStream = cstream
185− scPendingComments = [],
186− scRequestedDelimiter = VeryBeginning,
187− scSpanMark = Nothing
133+ , scNewline = Nothing
188− }
134+ }
189
135
190----------------------------------------------------------------------------
136----------------------------------------------------------------------------
191-- Internal functions
137-- Internal functions
192
138
193−-- | Type of the thing to output. Influences the primary low-level rendering
139+-- | Grow current output by appending given 'Text' to it, which may not
194−-- function 'spit'.
140+-- contain newlines.
195−data SpitType
196− = -- | Simple opaque text that breaks comment series.
197− SimpleText
198− | -- | Like 'SimpleText', but assume that when this text is inserted it
199− -- will separate an 'Atom' and its pending comments, so insert an extra
200− -- 'newline' in that case to force the pending comments and continue on
201− -- a fresh line.
202− InterferingText
203− | -- | An atom that typically have span information in the AST and can
204− -- have comments attached to it.
205− Atom
206− | -- | Used for rendering comment lines.
207− CommentPart
208− deriving (Show, Eq)
209−
210−-- | Output a fixed 'Text' fragment. The argument may not contain any line
211−-- breaks. 'txt' is used to output all sorts of “fixed” bits of syntax like
212−-- keywords and pipes @|@ in functional dependencies.
213−--
214−-- To separate various bits of syntax with white space use 'space' instead
215−-- of @'txt' " "@. To output 'Outputable' Haskell entities like numbers use
216−-- 'atom'.
217−txt ::
218− -- | 'Text' to output
219− Text ->
220− R ()
221−txt = spit SimpleText
222−
223−-- | Similar to 'txt' but the text inserted this way is assumed to break the
224−-- “link” between the preceding atom and its pending comments.
225−interferingTxt ::
226− -- | 'Text' to output
227− Text ->
228− R ()
229−interferingTxt = spit InterferingText
230−
231−-- | Output 'Outputable' fragment of AST. This can be used to output numeric
232−-- literals and similar. Everything that doesn't have inner structure but
233−-- does have an 'Outputable' instance.
234−atom ::
235− Outputable a =>
236− a ->
237− R ()
238−atom = spit Atom . T.pack . showOutputable
239−
240−-- | Low-level non-public helper to define 'txt' and 'atom'.
241−spit ::
242− -- | Type of the thing to spit
243− SpitType ->
244− -- | 'Text' to output
245− Text ->
246− R ()
247−spit _ "" = return ()
248−spit stype text = do
249− requestedDel <- R (gets scRequestedDelimiter)
250− pendingComments <- R (gets scPendingComments)
251− when (stype == InterferingText && not (null pendingComments)) newline
252− case requestedDel of
253− RequestedNewline -> do
254− R . modify $ \sc ->
255− sc
256− { scRequestedDelimiter = RequestedNothing
257− }
258− case stype of
259− CommentPart -> newlineRaw
260− _ -> newline
261− _ -> return ()
262− R $ do
263− i <- asks rcIndent
264− c <- gets scColumn
265− closestEnclosing <- listToMaybe <$> asks rcEnclosingSpans
266− let indentedTxt = spaces <> text
267− spaces = T.replicate spacesN " "
268− spacesN =
269− if c == 0
270− then i
271− else bool 0 1 (requestedDel == RequestedSpace)
272− modify $ \sc ->
273− sc
274− { scBuilder = scBuilder sc <> fromText indentedTxt,
275− scColumn = scColumn sc + T.length indentedTxt,
276− scIndent =
277− if c == 0
278− then i
279− else scIndent sc,
280− scThisLineSpans =
281− let xs = scThisLineSpans sc
282− in case stype of
283− Atom -> case closestEnclosing of
284− Nothing -> xs
285− Just x -> x : xs
286− _ -> xs,
287− scRequestedDelimiter = RequestedNothing,
288− scSpanMark =
289− -- If there are pending comments, do not reset last comment
290− -- location.
291− if (stype == CommentPart) || (not . null . scPendingComments) sc
292− then scSpanMark sc
293− else Nothing
294− }
295
141
296−-- | This primitive /does not/ necessarily output a space. It just ensures
142+spit :: Text -> R ()
297−-- that the next thing that will be printed on the same line will be
143+spit x = do
298−-- separated by a single space from the previous output. Using this
144+ traceR "spit_before" (Just x)
299−-- combinator twice results in at most one space.
300−--
301−-- In practice this design prevents trailing white space and makes it hard
302−-- to output more than one delimiting space in a row, which is what we
303−-- usually want.
304−space :: R ()
305−space = R . modify $ \sc ->
145+ R . modify $ \sc -> sc
306− sc
146+ { scBuilder = scBuilder sc <> fromText x
307− { scRequestedDelimiter = case scRequestedDelimiter sc of
147+ , scColumn = scColumn sc + T.length x
308− RequestedNothing -> RequestedSpace
309− other -> other
310 }
148 }
149+ traceR "spit_after" Nothing
150+
151+-- | Output a newline.
311
152
312−-- | Output a newline. First time 'newline' is used after some non-'newline'
313−-- output it gets inserted immediately. Second use of 'newline' does not
314−-- output anything but makes sure that the next non-white space output will
315−-- be prefixed by a newline. Using 'newline' more than twice in a row has no
316−-- effect. Also, using 'newline' at the very beginning has no effect, this
317−-- is to avoid leading whitespace.
318−--
319−-- Similarly to 'space', this design prevents trailing newlines and makes it
320−-- hard to output more than one blank newline in a row.
321newline :: R ()
153newline :: R ()
322newline = do
154newline = do
323− indent <- R (gets scIndent)
155+ n <- R (gets scNewline)
324− cs <- reverse <$> R (gets scPendingComments)
325− case cs of
326− [] -> newlineRaw
327− ((position, _) : _) -> do
328− case position of
329− OnTheSameLine -> space
330− OnNextLine -> newlineRaw
331− R . forM_ cs $ \(_, text) ->
332− let modRC rc =
333− rc
334− { rcIndent = indent
335− }
336− R m = do
337− unless (T.null text) $
338− spit CommentPart text
339− newlineRaw
340− in local modRC m
341− R . modify $ \sc ->
156+ R . modify $ \sc -> sc
342− sc
157+ { scNewline = Nothing
343− { scPendingComments = []
344− }
158+ }
159+ fromMaybe newlineRaw n
345
160
346-- | Low-level newline primitive. This one always just inserts a newline, no
161-- | Low-level newline primitive. This one always just inserts a newline, no
347-- hooks can be attached.
162-- hooks can be attached.
163+
348newlineRaw :: R ()
164newlineRaw :: R ()
349−newlineRaw = R . modify $ \sc ->
165+newlineRaw = do
350− let requestedDel = scRequestedDelimiter sc
166+ traceR "newline_before" (Just "\n")
351− builderSoFar = scBuilder sc
167+ R . modify $ \sc -> sc
352− in sc
168+ { scBuilder = scBuilder sc <> "\n"
353− { scBuilder = case requestedDel of
354− AfterNewline -> builderSoFar
355− RequestedNewline -> builderSoFar
356− VeryBeginning -> builderSoFar
357− _ -> builderSoFar <> "\n",
358− scColumn = 0,
169+ , scColumn = 0
359− scIndent = 0,
360− scThisLineSpans = [],
361− scRequestedDelimiter = case scRequestedDelimiter sc of
362− AfterNewline -> RequestedNewline
363− RequestedNewline -> RequestedNewline
364− VeryBeginning -> VeryBeginning
365− _ -> AfterNewline
366− }
170+ }
171+ traceR "newline_after" Nothing
367
172
368−-- | Return 'True' if we should print record dot syntax.
173+-- | The 'modNewline' function can be used to alter what will be inserted as
369−useRecordDot :: R Bool
174+-- a newline. This is used to output comments following an element of AST
370−useRecordDot = R (asks rcUseRecDot)
175+-- because we cannot output comments immediately, e.g. because we need to
176+-- close parentheses first, etc.
177+--
178+-- 'newline' auto-resets its modifications so the changes introduced with
179+-- 'modNewline' only have effect once.
180+--
181+-- The argument of the call-back is the version of 'newline' built so far.
182+
183+modNewline :: (R () -> R ()) -> R ()
184+modNewline f = R $ do
185+ old <- gets scNewline
186+ modify $ \sc -> sc
187+ { scNewline = Just $ f (fromMaybe newlineRaw old)
188+ }
189+
190+-- | Check if newline is in modified state.
191+
192+isNewlineModified :: R Bool
193+isNewlineModified = isJust <$> R (gets scNewline)
194+
195+-- | Ensure that indentation level is satisfied. Insert correct number of
196+-- spaces if it isn't.
197+
198+ensureIndent :: R ()
199+ensureIndent = do
200+ traceR "ensure_indent" Nothing
201+ i <- R (asks rcIndent)
202+ c <- R (gets scColumn)
203+ when (c < i) $
204+ spit (T.replicate (i - c) " ")
371
205
372-- | Increase indentation level by one indentation step for the inner
206-- | Increase indentation level by one indentation step for the inner
373-- computation. 'inci' should be used when a part of code must be more
207-- computation. 'inci' should be used when a part of code must be more
374-- indented relative to the parts outside of 'inci' in order for the output
208-- indented relative to the parts outside of 'inci' in order for the output
375-- to be valid Haskell. When layout is single-line there is no obvious
209-- to be valid Haskell. When layout is single-line there is no obvious
376-- effect, but with multi-line layout correct indentation levels matter.
210-- effect, but with multi-line layout correct indentation levels matter.
211+
377inci :: R () -> R ()
212inci :: R () -> R ()
378−inci (R m) = R (local modRC m)
213+inci m' = do
379− where
214+ traceR "inci_before" Nothing
380− modRC rc =
215+ let R m = traceR "inci_inside" Nothing >> m'
381− rc
216+ modRC rc = rc
382 { rcIndent = rcIndent rc + indentStep
217 { rcIndent = rcIndent rc + indentStep
383 }
218 }
219+ R (local modRC m)
220+ traceR "inci_ended" Nothing
384
221
385-- | Set indentation level for the inner computation equal to current
222-- | Set indentation level for the inner computation equal to current
386-- column. This makes sure that the entire inner block is uniformly
223-- column. This makes sure that the entire inner block is uniformly
387−-- \"shifted\" to the right.
224+-- \"shifted\" to the right. Only works (and makes sense) when enclosing
225+-- layout is multi-line.
226+
388sitcc :: R () -> R ()
227sitcc :: R () -> R ()
389−sitcc (R m) = do
228+sitcc m' = do
390− requestedDel <- R (gets scRequestedDelimiter)
229+ traceR "sitcc_before" Nothing
391 i <- R (asks rcIndent)
230 i <- R (asks rcIndent)
392 c <- R (gets scColumn)
231 c <- R (gets scColumn)
232+ let R m = traceR "sitcc_inside" Nothing >> m'
393− let modRC rc =
233+ modRC rc = rc
394− rc
395− { rcIndent = max i (c + bool 0 1 (requestedDel == RequestedSpace))
234+ { rcIndent = max i c
396− }
235+ }
397− R (local modRC m)
236+ vlayout m' (R (local modRC m))
237+ traceR "sitcc_ended" Nothing
398
238
399-- | Set 'Layout' for internal computation.
239-- | Set 'Layout' for internal computation.
240+
400enterLayout :: Layout -> R () -> R ()
241enterLayout :: Layout -> R () -> R ()
401−enterLayout l (R m) = R (local modRC m)
242+enterLayout l (R m) = do
402− where
243+ let label =
244+ case l of
245+ SingleLine -> "single_line"
246+ MultiLine -> "multi_line"
247+ traceR ("lstart_" ++ label) Nothing
403− modRC rc =
248+ let modRC rc = rc
404− rc
405 { rcLayout = l
249 { rcLayout = l
406 }
250 }
251+ x <- R (local modRC m)
252+ traceR ("lend_" ++ label) Nothing
253+ return x
407
254
408-- | Do one or another thing depending on current 'Layout'.
255-- | Do one or another thing depending on current 'Layout'.
256+
409−vlayout ::
257+vlayout
410− -- | Single line
258+ :: R a -- ^ Single line
411− R a ->
412− -- | Multi line
259+ -> R a -- ^ Multi line
413− R a ->
414− R a
260+ -> R a
415vlayout sline mline = do
261vlayout sline mline = do
416− l <- getLayout
262+ l <- R (asks rcLayout)
417 case l of
263 case l of
418 SingleLine -> sline
264 SingleLine -> sline
419 MultiLine -> mline
265 MultiLine -> mline
420
266
421−-- | Get current 'Layout'.
422−getLayout :: R Layout
423−getLayout = R (asks rcLayout)
424−
425----------------------------------------------------------------------------
267----------------------------------------------------------------------------
426-- Special helpers for comment placement
268-- Special helpers for comment placement
427
269
428−-- | Register a comment line for outputting. It will be inserted right
429−-- before next newline. When the comment goes after something else on the
430−-- same line, a space will be inserted between preceding text and the
431−-- comment when necessary.
432−registerPendingCommentLine ::
433− -- | Comment position
434− CommentPosition ->
435− -- | 'Text' to output
436− Text ->
437− R ()
438−registerPendingCommentLine position text = R $ do
439− modify $ \sc ->
440− sc
441− { scPendingComments = (position, text) : scPendingComments sc
442− }
443−
444-- | Drop elements that begin before or at the same place as given
270-- | Drop elements that begin before or at the same place as given
445-- 'SrcSpan'.
271-- 'SrcSpan'.
272+
446−trimSpanStream ::
273+trimSpanStream
447− -- | Reference span
274+ :: RealSrcSpan -- ^ Reference span
448− RealSrcSpan ->
449− R ()
275+ -> R ()
450trimSpanStream ref = do
276trimSpanStream ref = do
451 let leRef :: RealSrcSpan -> Bool
277 let leRef :: RealSrcSpan -> Bool
452 leRef x = realSrcSpanStart x <= realSrcSpanStart ref
278 leRef x = realSrcSpanStart x <= realSrcSpanStart ref
453− R . modify $ \sc ->
279+ R . modify $ \sc -> sc
454− sc
455− { scSpanStream = coerce (dropWhile leRef) (scSpanStream sc)
280+ { scSpanStream = coerce (dropWhile leRef) (scSpanStream sc)
456− }
281+ }
457
282
458-- | Get location of next element in AST.
283-- | Get location of next element in AST.
284+
459nextEltSpan :: R (Maybe RealSrcSpan)
285nextEltSpan :: R (Maybe RealSrcSpan)
460nextEltSpan = listToMaybe . coerce <$> R (gets scSpanStream)
286nextEltSpan = listToMaybe . coerce <$> R (gets scSpanStream)
461
287
462-- | Pop a 'Comment' from the 'CommentStream' if given predicate is
288-- | Pop a 'Comment' from the 'CommentStream' if given predicate is
463-- satisfied and there are comments in the stream.
289-- satisfied and there are comments in the stream.
290+
464−popComment ::
291+popComment
465− (RealLocated Comment -> Bool) ->
292+ :: (RealLocated Comment -> Bool)
466− R (Maybe (RealLocated Comment))
293+ -> R (Maybe (RealLocated Comment))
467popComment f = R $ do
294popComment f = R $ do
468 CommentStream cstream <- gets scCommentStream
295 CommentStream cstream <- gets scCommentStream
469 case cstream of
296 case cstream of
470 [] -> return Nothing
297 [] -> return Nothing
471− (x : xs) ->
298+ (x:xs) ->
472 if f x
299 if f x
473− then
474− Just x
475− <$ modify
300+ then Just x <$ modify (\sc -> sc
476− ( \sc ->
477− sc
478− { scCommentStream = CommentStream xs
301+ { scCommentStream = CommentStream xs
479− }
302+ })
480− )
481 else return Nothing
303 else return Nothing
482
304
305+-- | Return 'True' if there are more comments in the 'CommentStream'.
306+
307+hasMoreComments :: R Bool
308+hasMoreComments = R $ do
309+ CommentStream cstream <- gets scCommentStream
310+ (return . not . null) cstream
311+
312+-- | Current indentation level.
313+
314+getIndent :: R Int
315+getIndent = R (asks rcIndent)
316+
317+-- | Set indentation level for the given computation.
318+
319+setIndent :: Int -> R () -> R ()
320+setIndent i m' = do
321+ traceR "set_indent_before" Nothing
322+ let R m = traceR "set_indent_inside" Nothing >> m'
323+ modRC rc = rc
324+ { rcIndent = i
325+ }
326+ R (local modRC m)
327+ traceR "set_indent_after" Nothing
328+
483-- | Get the first enclosing 'RealSrcSpan' that satisfies given predicate.
329-- | Get the first enclosing 'RealSrcSpan' that satisfies given predicate.
330+
484−getEnclosingSpan ::
331+getEnclosingSpan
485− -- | Predicate to use
332+ :: (RealSrcSpan -> Bool) -- ^ Predicate to use
486− (RealSrcSpan -> Bool) ->
487− R (Maybe RealSrcSpan)
333+ -> R (Maybe RealSrcSpan)
488getEnclosingSpan f =
334getEnclosingSpan f =
489 listToMaybe . filter f <$> R (asks rcEnclosingSpans)
335 listToMaybe . filter f <$> R (asks rcEnclosingSpans)
490
336
491-- | Set 'RealSrcSpan' of enclosing span for the given computation.
337-- | Set 'RealSrcSpan' of enclosing span for the given computation.
338+
492withEnclosingSpan :: RealSrcSpan -> R () -> R ()
339withEnclosingSpan :: RealSrcSpan -> R () -> R ()
493−withEnclosingSpan spn (R m) = R (local modRC m)
340+withEnclosingSpan spn (R m) = do
494− where
495− modRC rc =
341+ let modRC rc = rc
496− rc
497 { rcEnclosingSpans = spn : rcEnclosingSpans rc
342 { rcEnclosingSpans = spn : rcEnclosingSpans rc
498 }
343 }
499−
344+ R (local modRC m)
500−-- | Get spans on this line so far.
501−thisLineSpans :: R [RealSrcSpan]
502−thisLineSpans = R (gets scThisLineSpans)
503−
504−----------------------------------------------------------------------------
505−-- Stateful markers
506−
507−-- | An auxiliary marker for keeping track of last output element.
508−data SpanMark
509− = -- | Haddock comment
510− HaddockSpan HaddockStyle RealSrcSpan
511− | -- | Non-haddock comment
512− CommentSpan RealSrcSpan
513− | -- | A statement in a do-block and such span
514− StatementSpan RealSrcSpan
515−
516−-- | Project 'RealSrcSpan' from 'SpanMark'.
517−spanMarkSpan :: SpanMark -> RealSrcSpan
518−spanMarkSpan = \case
519− HaddockSpan _ s -> s
520− CommentSpan s -> s
521− StatementSpan s -> s
522−
523−-- | Haddock string style.
524−data HaddockStyle
525− = -- | @-- |@
526− Pipe
527− | -- | @-- ^@
528− Caret
529− | -- | @-- *@
530− Asterisk Int
531− | -- | @-- $@
532− Named String
533−
534−-- | Set span of last output comment.
535−setSpanMark ::
536− -- | Span mark to set
537− SpanMark ->
538− R ()
539−setSpanMark spnMark = R . modify $ \sc ->
540− sc
541− { scSpanMark = Just spnMark
542− }
543−
544−-- | Get span of last output comment.
545−getSpanMark :: R (Maybe SpanMark)
546−getSpanMark = R (gets scSpanMark)
547
345
548----------------------------------------------------------------------------
346----------------------------------------------------------------------------
549-- Annotations
347-- Annotations
550
348
551-- | For a given span return 'AnnKeywordId's associated with it.
349-- | For a given span return 'AnnKeywordId's associated with it.
350+
552−getAnns ::
351+getAnns
553− SrcSpan ->
352+ :: SrcSpan
554− R [AnnKeywordId]
353+ -> R [AnnKeywordId]
555getAnns spn = lookupAnns spn <$> R (asks rcAnns)
354getAnns spn = lookupAnns spn <$> R (asks rcAnns)
556
355
557----------------------------------------------------------------------------
356----------------------------------------------------------------------------
558-- Helpers for braces
357-- Helpers for braces
559
358
560-- | Make the inner computation use braces around single-line layouts.
359-- | Make the inner computation use braces around single-line layouts.
360+
561useBraces :: R () -> R ()
361useBraces :: R () -> R ()
562−useBraces (R r) = R (local (\i -> i {rcCanUseBraces = True}) r)
362+useBraces (R r) = R (local (\i -> i {rcCanUseBraces = True}) r)
563
363
564-- | Make the inner computation omit braces around single-line layouts.
364-- | Make the inner computation omit braces around single-line layouts.
365+
565dontUseBraces :: R () -> R ()
366dontUseBraces :: R () -> R ()
566−dontUseBraces (R r) = R (local (\i -> i {rcCanUseBraces = False}) r)
367+dontUseBraces (R r) = R (local (\i -> i {rcCanUseBraces = False}) r)
567
368
568-- | Return 'True' if we can use braces in this context.
369-- | Return 'True' if we can use braces in this context.
370+
569canUseBraces :: R Bool
371canUseBraces :: R Bool
570−canUseBraces = R (asks rcCanUseBraces)
372+canUseBraces = R $ asks rcCanUseBraces
373+
374+----------------------------------------------------------------------------
375+-- Debug helpers
376+
377+-- | Tracing helper.
378+
379+traceR
380+ :: String -- ^ Label
381+ -> Maybe Text -- ^ Output, if any
382+ -> R ()
383+traceR label moutput = R $ do
384+ debug <- asks rcDebug
385+ i <- asks rcIndent
386+ c <- gets scColumn
387+ when debug . traceM . concat $
388+ [ replicate i ' '
389+ , unwords [ label ++ ":"
390+ , "i=" ++ show i
391+ , "c=" ++ show c
392+ ]
393+ ] ++ case moutput of
394+ Nothing -> []
395+ Just output -> [" out=" ++ show output]
571
396
572----------------------------------------------------------------------------
397----------------------------------------------------------------------------
573-- Constants
398-- Constants
574
399
575-- | Indentation step.
400-- | Indentation step.
401+
576indentStep :: Int
402indentStep :: Int
577indentStep = 2
403indentStep = 2
src/Ormolu/Printer/Meat/Common.hs+44−91
@@ -1,55 +1,50 @@
1−{-# LANGUAGE LambdaCase #-}
1+{-# LANGUAGE LambdaCase #-}
2{-# LANGUAGE OverloadedStrings #-}
2{-# LANGUAGE OverloadedStrings #-}
3
3
4-- | Rendering of commonly useful bits.
4-- | Rendering of commonly useful bits.
5+
5module Ormolu.Printer.Meat.Common
6module Ormolu.Printer.Meat.Common
6− ( FamilyStyle (..),
7+ ( FamilyStyle (..)
7− p_hsmodName,
8+ , p_hsmodName
8− p_ieWrappedName,
9+ , p_ieWrappedName
9− p_rdrName,
10+ , p_rdrName
10− doesNotNeedExtraParens,
11+ , doesNotNeedExtraParens
11− p_qualName,
12+ , p_qualName
12− p_infixDefHelper,
13+ , p_infixDefHelper
13− p_hsDocString,
14− p_hsDocName,
15 )
14 )
16where
15where
17
16
18import Control.Monad
17import Control.Monad
19import Data.List (isPrefixOf)
18import Data.List (isPrefixOf)
20−import qualified Data.Text as T
21import GHC hiding (GhcPs, IE)
19import GHC hiding (GhcPs, IE)
22import Name (nameStableString)
20import Name (nameStableString)
23import OccName (OccName (..))
21import OccName (OccName (..))
24import Ormolu.Printer.Combinators
22import Ormolu.Printer.Combinators
25−import Ormolu.Utils
23+import RdrName (RdrName (..))
26
24
27-- | Data and type family style.
25-- | Data and type family style.
26+
28data FamilyStyle
27data FamilyStyle
29− = -- | Declarations in type classes
28+ = Associated -- ^ Declarations in type classes
30− Associated
31− | -- | Top-level declarations
29+ | Free -- ^ Top-level declarations
32− Free
33
30
34p_hsmodName :: ModuleName -> R ()
31p_hsmodName :: ModuleName -> R ()
35p_hsmodName mname = do
32p_hsmodName mname = do
36− txt "module"
33+ txt "module "
37− space
38 atom mname
34 atom mname
39
35
40p_ieWrappedName :: IEWrappedName RdrName -> R ()
36p_ieWrappedName :: IEWrappedName RdrName -> R ()
41p_ieWrappedName = \case
37p_ieWrappedName = \case
42 IEName x -> p_rdrName x
38 IEName x -> p_rdrName x
43 IEPattern x -> do
39 IEPattern x -> do
44− txt "pattern"
40+ txt "pattern "
45− space
46 p_rdrName x
41 p_rdrName x
47 IEType x -> do
42 IEType x -> do
48− txt "type"
43+ txt "type "
49− space
50 p_rdrName x
44 p_rdrName x
51
45
52-- | Render a @'Located' 'RdrName'@.
46-- | Render a @'Located' 'RdrName'@.
47+
53p_rdrName :: Located RdrName -> R ()
48p_rdrName :: Located RdrName -> R ()
54p_rdrName l@(L spn _) = located l $ \x -> do
49p_rdrName l@(L spn _) = located l $ \x -> do
55 ids <- getAnns spn
50 ids <- getAnns spn
@@ -59,14 +54,14 @@ p_rdrName l@(L spn _) = located l $ \x -> do
59 else id
54 else id
60 parensWrapper =
55 parensWrapper =
61 if AnnOpenP `elem` ids
56 if AnnOpenP `elem` ids
62− then parens N
57+ then parens
63 else id
58 else id
64 singleQuoteWrapper =
59 singleQuoteWrapper =
65 if AnnSimpleQuote `elem` ids
60 if AnnSimpleQuote `elem` ids
66 then \y -> do
61 then \y -> do
67− txt "'"
62+ txt "'"
68− y
63+ y
69− else id
64+ else id
70 m =
65 m =
71 case x of
66 case x of
72 Unqual occName ->
67 Unqual occName ->
@@ -74,10 +69,10 @@ p_rdrName l@(L spn _) = located l $ \x -> do
74 Qual mname occName ->
69 Qual mname occName ->
75 p_qualName mname occName
70 p_qualName mname occName
76 Orig _ occName ->
71 Orig _ occName ->
77− -- This is used when GHC generates code that will be fed into
72+ -- NOTE This is used when GHC generates code that will be fed
78− -- the renamer (e.g. from deriving clauses), but where we want
73+ -- into the renamer (e.g. from deriving clauses), but where we
79− -- to say that something comes from given module which is not
74+ -- want to say that something comes from given module which is
80− -- specified in the source code, e.g. @Prelude.map@.
75+ -- not specified in the source code, e.g. @Prelude.map@.
81 --
76 --
82 -- My current understanding is that the provided module name
77 -- My current understanding is that the provided module name
83 -- serves no purpose for us and can be safely ignored.
78 -- serves no purpose for us and can be safely ignored.
@@ -93,15 +88,16 @@ p_rdrName l@(L spn _) = located l $ \x -> do
93-- to detect e.g. tuples for which annotations will indicate parentheses,
88-- to detect e.g. tuples for which annotations will indicate parentheses,
94-- but the parentheses are already part of the symbol, so no extra layer of
89-- but the parentheses are already part of the symbol, so no extra layer of
95-- parentheses should be added. It also detects the [] literal.
90-- parentheses should be added. It also detects the [] literal.
91+
96doesNotNeedExtraParens :: RdrName -> Bool
92doesNotNeedExtraParens :: RdrName -> Bool
97doesNotNeedExtraParens = \case
93doesNotNeedExtraParens = \case
98 Exact name ->
94 Exact name ->
99 let s = nameStableString name
95 let s = nameStableString name
100− in -- I'm not sure this "stable string" is stable enough, but it looks
96+ -- NOTE I'm not sure this "stable string" is stable enough, but it looks
101− -- like this is the most robust way to tell if we're looking at
97+ -- like this is the most robust way to tell if we're looking at exactly
102− -- exactly this piece of built-in syntax.
98+ -- this piece of built-in syntax.
103− ("$ghc-prim$GHC.Tuple$" `isPrefixOf` s)
99+ in ("$ghc-prim$GHC.Tuple$" `isPrefixOf` s) ||
104− || ("$ghc-prim$GHC.Types$[]" `isPrefixOf` s)
100+ ("$ghc-prim$GHC.Types$[]" `isPrefixOf` s)
105 _ -> False
101 _ -> False
106
102
107p_qualName :: ModuleName -> OccName -> R ()
103p_qualName :: ModuleName -> OccName -> R ()
@@ -111,75 +107,32 @@ p_qualName mname occName = do
111 atom occName
107 atom occName
112
108
113-- | A helper for formatting infix constructions in lhs of definitions.
109-- | A helper for formatting infix constructions in lhs of definitions.
110+
114−p_infixDefHelper ::
111+p_infixDefHelper
115− -- | Whether to format in infix style
112+ :: Bool -- ^ Whether to format in infix style
116− Bool ->
113+ -> (R () -> R ()) -- ^ Indentation-bumping wrapper
117− -- | Whether to bump indentation for arguments
118− Bool ->
119− -- | How to print the operator\/name
114+ -> R () -- ^ How to print the operator\/name
120− R () ->
115+ -> [R ()] -- ^ How to print the arguments
121− -- | How to print the arguments
122− [R ()] ->
123− R ()
116+ -> R ()
124−p_infixDefHelper isInfix indentArgs name args =
117+p_infixDefHelper isInfix inci' name args =
125 case (isInfix, args) of
118 case (isInfix, args) of
126− (True, p0 : p1 : ps) -> do
119+ (True, p0:p1:ps) -> do
127 let parens' =
120 let parens' =
128 if null ps
121 if null ps
129 then id
122 then id
130− else parens N
123+ else parens
131 parens' $ do
124 parens' $ do
132 p0
125 p0
133 breakpoint
126 breakpoint
134− inci . sitcc $ do
127+ inci $ sitcc $ do
135 name
128 name
136 space
129 space
137 p1
130 p1
138− unless (null ps) . inciIf indentArgs $ do
131+ unless (null ps) . inci' $ do
139 breakpoint
132 breakpoint
140 sitcc (sep breakpoint sitcc ps)
133 sitcc (sep breakpoint sitcc ps)
141 (_, ps) -> do
134 (_, ps) -> do
142 name
135 name
143 unless (null ps) $ do
136 unless (null ps) $ do
144 breakpoint
137 breakpoint
145− inciIf indentArgs $ sitcc (sep breakpoint sitcc args)
138+ inci' $ sitcc (sep breakpoint sitcc args)
146−
147−-- | Print a Haddock.
148−p_hsDocString ::
149− -- | Haddock style
150− HaddockStyle ->
151− -- | Finish the doc string with a newline
152− Bool ->
153− -- | The doc string to render
154− LHsDocString ->
155− R ()
156−p_hsDocString hstyle needsNewline (L l str) = do
157− let isCommentSpan = \case
158− HaddockSpan _ _ -> True
159− CommentSpan _ -> True
160− _ -> False
161− goesAfterComment <- maybe False isCommentSpan <$> getSpanMark
162− -- Make sure the Haddock is separated by a newline from other comments.
163− when goesAfterComment newline
164− forM_ (zip (splitDocString str) (True : repeat False)) $ \(x, isFirst) -> do
165− if isFirst
166− then case hstyle of
167− Pipe -> txt "-- |"
168− Caret -> txt "-- ^"
169− Asterisk n -> txt ("-- " <> T.replicate n "*")
170− Named name -> p_hsDocName name
171− else newline >> txt "--"
172− space
173− unless (T.null x) (txt x)
174− when needsNewline newline
175− case l of
176− UnhelpfulSpan _ ->
177− -- It's often the case that the comment itself doesn't have a span
178− -- attached to it and instead its location can be obtained from
179− -- nearest enclosing span.
180− getEnclosingSpan (const True) >>= mapM_ (setSpanMark . HaddockSpan hstyle)
181− RealSrcSpan spn -> setSpanMark (HaddockSpan hstyle spn)
182−
183−-- | Print anchor of named doc section.
184−p_hsDocName :: String -> R ()
185−p_hsDocName name = txt ("-- $" <> T.pack name)
src/Ormolu/Printer/Meat/Declaration.hs+131−216
@@ -1,20 +1,18 @@
1−{-# LANGUAGE LambdaCase #-}
1+{-# LANGUAGE LambdaCase #-}
2{-# LANGUAGE OverloadedStrings #-}
2{-# LANGUAGE OverloadedStrings #-}
3{-# LANGUAGE PatternSynonyms #-}
3{-# LANGUAGE PatternSynonyms #-}
4{-# LANGUAGE RecordWildCards #-}
4{-# LANGUAGE RecordWildCards #-}
5−{-# LANGUAGE ViewPatterns #-}
5+{-# LANGUAGE ViewPatterns #-}
6
6
7-- | Rendering of declarations.
7-- | Rendering of declarations.
8+
8module Ormolu.Printer.Meat.Declaration
9module Ormolu.Printer.Meat.Declaration
9− ( p_hsDecls,
10+ ( p_hsDecls
10− p_hsDeclsRespectGrouping,
11+ , hasSeparatedDecls
11 )
12 )
12where
13where
13
14
14−import Data.List (sort)
15+import GHC
15−import Data.List.NonEmpty (NonEmpty (..), (<|))
16−import qualified Data.List.NonEmpty as NE
17−import GHC hiding (InlinePragma)
18import OccName (occNameFS)
16import OccName (occNameFS)
19import Ormolu.Printer.Combinators
17import Ormolu.Printer.Combinators
20import Ormolu.Printer.Meat.Common
18import Ormolu.Printer.Meat.Common
@@ -30,103 +28,68 @@ import Ormolu.Printer.Meat.Declaration.Signature
30import Ormolu.Printer.Meat.Declaration.Splice
28import Ormolu.Printer.Meat.Declaration.Splice
31import Ormolu.Printer.Meat.Declaration.Type
29import Ormolu.Printer.Meat.Declaration.Type
32import Ormolu.Printer.Meat.Declaration.TypeFamily
30import Ormolu.Printer.Meat.Declaration.TypeFamily
31+import Data.List
33import Ormolu.Printer.Meat.Declaration.Value
32import Ormolu.Printer.Meat.Declaration.Value
34import Ormolu.Printer.Meat.Declaration.Warning
33import Ormolu.Printer.Meat.Declaration.Warning
35import Ormolu.Printer.Meat.Type
34import Ormolu.Printer.Meat.Type
36import Ormolu.Utils
35import Ormolu.Utils
37−
36+import RdrName (rdrNameOcc)
38−data UserGrouping
37+import Data.List.NonEmpty (NonEmpty((:|)))
39− = -- | Always put newlines where we think they should be
38+import qualified Data.List.NonEmpty as NE
40− Disregard
41− | -- | Respect user preferences regarding grouping
42− Respect
43− deriving (Eq, Show)
44
39
45p_hsDecls :: FamilyStyle -> [LHsDecl GhcPs] -> R ()
40p_hsDecls :: FamilyStyle -> [LHsDecl GhcPs] -> R ()
46−p_hsDecls = p_hsDecls' Disregard
47−
48−-- | Like 'p_hsDecls' but respects user choices regarding grouping. If the
49−-- user omits newlines between declarations, we also omit them in most
50−-- cases, except when said declarations have associated Haddocks.
51−--
52−-- Does some normalization (compress subsequent newlines into a single one)
53−p_hsDeclsRespectGrouping :: FamilyStyle -> [LHsDecl GhcPs] -> R ()
54−p_hsDeclsRespectGrouping = p_hsDecls' Respect
55−
56−p_hsDecls' :: UserGrouping -> FamilyStyle -> [LHsDecl GhcPs] -> R ()
57−p_hsDecls' grouping style decls =
58− sepSemi id $
41+p_hsDecls style decls = sepSemi id $
59− -- Return a list of rendered declarations, adding a newline to separate
42+ -- Return a list of rendered declarations, adding a newline to separate
60− -- groups.
43+ -- groups.
61− case groupDecls decls of
44+ case groupDecls decls of
62− [] -> []
45+ [] -> []
63− (x : xs) -> renderGroup x ++ concat (zipWith renderGroupWithPrev (x : xs) xs)
46+ (x:xs) ->
64− where
47+ NE.toList (renderGroup x)
65− renderGroup = NE.toList . fmap (located' $ dontUseBraces . p_hsDecl style)
48+ ++ concatMap (NE.toList . separateGroup . renderGroup) xs
66− renderGroupWithPrev prev curr =
67− -- We can omit a blank line when the user didn't add one, but we must
68− -- ensure we always add blank lines around documented declarations
69− case grouping of
70− Disregard ->
71− breakpoint : renderGroup curr
72− Respect ->
73− if separatedByBlankNE getLoc prev curr
74− || isDocumented prev
75− || isDocumented curr
76− then breakpoint : renderGroup curr
77− else renderGroup curr
78−
79−-- | Is a declaration group documented?
80−isDocumented :: NonEmpty (LHsDecl GhcPs) -> Bool
81−isDocumented = any (isHaddock . unLoc)
82 where
49 where
83− isHaddock DocNext = True
50+ renderGroup = fmap (located' $ dontUseBraces . p_hsDecl style)
84− isHaddock DocPrev = True
51+ separateGroup (x :| xs) = (breakpoint' >> x) :| xs
85− isHaddock _ = False
86
52
87-- | Group relevant declarations together.
53-- | Group relevant declarations together.
54+--
55+-- Add a declaration to a group iff it is relevant to either the first or
56+-- the last declaration of the group.
57+
88groupDecls :: [LHsDecl GhcPs] -> [NonEmpty (LHsDecl GhcPs)]
58groupDecls :: [LHsDecl GhcPs] -> [NonEmpty (LHsDecl GhcPs)]
89groupDecls [] = []
59groupDecls [] = []
90−groupDecls (l@(L _ DocNext) : xs) =
60+groupDecls (lhdr:xs) =
91− -- If the first element is a doc string for next element, just include it
61+ let -- Pick the first decl as the group header
92− -- in the next block:
62+ hdr = unLoc lhdr
93− case groupDecls xs of
63+ -- Zip rest of the decls with their previous decl
94− [] -> [l :| []]
64+ zipped = zip (lhdr:xs) xs
95− (x : xs') -> (l <| x) : xs'
65+ -- Pick decls from the tail if they are relevant to the group header
96−groupDecls (header : xs) =
66+ -- or the previous decl.
97− let (grp, rest) = flip span (zip (header : xs) xs) $ \(previous, current) ->
67+ (grp, rest) = flip span zipped $ \(L _ prev, L _ cur) ->
98− let relevantToHdr = groupedDecls header current
68+ let relevantToHdr = groupedDecls hdr cur
99− relevantToPrev = groupedDecls previous current
69+ relevantToPrev = groupedDecls prev cur
100− isDeclSeries = declSeries previous current
101− in isDeclSeries || relevantToHdr || relevantToPrev
70+ in relevantToHdr || relevantToPrev
102− in (header :| map snd grp) : groupDecls (map snd rest)
71+ in (lhdr :| map snd grp) : groupDecls (map snd rest)
103
72
104p_hsDecl :: FamilyStyle -> HsDecl GhcPs -> R ()
73p_hsDecl :: FamilyStyle -> HsDecl GhcPs -> R ()
105p_hsDecl style = \case
74p_hsDecl style = \case
106− TyClD NoExtField x -> p_tyClDecl style x
75+ TyClD NoExt x -> p_tyClDecl style x
107− ValD NoExtField x -> p_valDecl x
76+ ValD NoExt x -> p_valDecl x
108− SigD NoExtField x -> p_sigDecl x
77+ SigD NoExt x -> p_sigDecl x
109− InstD NoExtField x -> p_instDecl style x
78+ InstD NoExt x -> p_instDecl style x
110− DerivD NoExtField x -> p_derivDecl x
79+ DerivD NoExt x -> p_derivDecl x
111− DefD NoExtField x -> p_defaultDecl x
80+ DefD NoExt x -> p_defaultDecl x
112− ForD NoExtField x -> p_foreignDecl x
81+ ForD NoExt x -> p_foreignDecl x
113− WarningD NoExtField x -> p_warnDecls x
82+ WarningD NoExt x -> p_warnDecls x
114− AnnD NoExtField x -> p_annDecl x
83+ AnnD NoExt x -> p_annDecl x
115− RuleD NoExtField x -> p_ruleDecls x
84+ RuleD NoExt x -> p_ruleDecls x
116− SpliceD NoExtField x -> p_spliceDecl x
85+ SpliceD NoExt x -> p_spliceDecl x
117− DocD NoExtField docDecl ->
86+ DocD _ _ -> notImplemented "DocD"
118− case docDecl of
119− DocCommentNext str -> p_hsDocString Pipe False (noLoc str)
120− DocCommentPrev str -> p_hsDocString Caret False (noLoc str)
121− DocCommentNamed name str -> p_hsDocString (Named name) False (noLoc str)
122− DocGroup n str -> p_hsDocString (Asterisk n) False (noLoc str)
123− RoleAnnotD NoExtField x -> p_roleAnnot x
87+ RoleAnnotD NoExt x -> p_roleAnnot x
124− KindSigD NoExtField s -> p_standaloneKindSig s
88+ XHsDecl _ -> notImplemented "XHsDecl"
125− XHsDecl x -> noExtCon x
126
89
127p_tyClDecl :: FamilyStyle -> TyClDecl GhcPs -> R ()
90p_tyClDecl :: FamilyStyle -> TyClDecl GhcPs -> R ()
128p_tyClDecl style = \case
91p_tyClDecl style = \case
129− FamDecl NoExtField x -> p_famDecl style x
92+ FamDecl NoExt x -> p_famDecl style x
130 SynDecl {..} -> p_synDecl tcdLName tcdFixity tcdTyVars tcdRhs
93 SynDecl {..} -> p_synDecl tcdLName tcdFixity tcdTyVars tcdRhs
131 DataDecl {..} ->
94 DataDecl {..} ->
132 p_dataDecl
95 p_dataDecl
@@ -146,66 +109,36 @@ p_tyClDecl style = \case
146 tcdMeths
109 tcdMeths
147 tcdATs
110 tcdATs
148 tcdATDefs
111 tcdATDefs
149− tcdDocs
112+ XTyClDecl {} -> notImplemented "XTyClDecl"
150− XTyClDecl x -> noExtCon x
151
113
152p_instDecl :: FamilyStyle -> InstDecl GhcPs -> R ()
114p_instDecl :: FamilyStyle -> InstDecl GhcPs -> R ()
153p_instDecl style = \case
115p_instDecl style = \case
154− ClsInstD NoExtField x -> p_clsInstDecl x
116+ ClsInstD NoExt x -> p_clsInstDecl x
155− TyFamInstD NoExtField x -> p_tyFamInstDecl style x
117+ TyFamInstD NoExt x -> p_tyFamInstDecl style x
156− DataFamInstD NoExtField x -> p_dataFamInstDecl style x
118+ DataFamInstD NoExt x -> p_dataFamInstDecl style x
157− XInstDecl x -> noExtCon x
119+ XInstDecl _ -> notImplemented "XInstDecl"
158
120
159p_derivDecl :: DerivDecl GhcPs -> R ()
121p_derivDecl :: DerivDecl GhcPs -> R ()
160p_derivDecl = \case
122p_derivDecl = \case
161− d@DerivDecl {} -> p_standaloneDerivDecl d
123+ d@DerivDecl {..} -> p_standaloneDerivDecl d
162− XDerivDecl x -> noExtCon x
124+ XDerivDecl _ -> notImplemented "XDerivDecl standalone deriving"
163
125
164-- | Determine if these declarations should be grouped together.
126-- | Determine if these declarations should be grouped together.
165−groupedDecls ::
166− LHsDecl GhcPs ->
167− LHsDecl GhcPs ->
168− Bool
169−groupedDecls (L l_x x') (L l_y y') =
170− case (x', y') of
171− (TypeSignature ns, FunctionBody ns') -> ns `intersects` ns'
172− (TypeSignature ns, DefaultSignature ns') -> ns `intersects` ns'
173− (DefaultSignature ns, TypeSignature ns') -> ns `intersects` ns'
174− (DefaultSignature ns, FunctionBody ns') -> ns `intersects` ns'
175− (x, FunctionBody ns) | Just ns' <- isPragma x -> ns `intersects` ns'
176− (FunctionBody ns, x) | Just ns' <- isPragma x -> ns `intersects` ns'
177− (x, DataDeclaration n) | Just ns <- isPragma x -> n `elem` ns
178− (DataDeclaration n, x)
179− | Just ns <- isPragma x ->
180− let f = occNameFS . rdrNameOcc in f n `elem` map f ns
181− (x, y)
182− | Just ns <- isPragma x,
183− Just ns' <- isPragma y ->
184− ns `intersects` ns'
185− (x, TypeSignature ns) | Just ns' <- isPragma x -> ns `intersects` ns'
186− (TypeSignature ns, x) | Just ns' <- isPragma x -> ns `intersects` ns'
187− (PatternSignature ns, Pattern n) -> n `elem` ns
188− (KindSignature n, DataDeclaration n') -> n == n'
189− (KindSignature n, ClassDeclaration n') -> n == n'
190− (KindSignature n, FamilyDeclaration n') -> n == n'
191− -- Special case for TH splices, we look at locations
192− (Splice, Splice) -> not (separatedByBlank id l_x l_y)
193− -- This looks only at Haddocks, normal comments are handled elsewhere
194− (DocNext, _) -> True
195− (_, DocPrev) -> True
196− _ -> False
197
127
198−-- | Detect declaration series that should not have blanks between them.
128+groupedDecls
199−declSeries ::
200− LHsDecl GhcPs ->
129+ :: HsDecl GhcPs
201− LHsDecl GhcPs ->
130+ -> HsDecl GhcPs
202− Bool
131+ -> Bool
203−declSeries (L _ x) (L _ y) =
132+groupedDecls (TypeSignature ns) (FunctionBody ns') = ns `intersects` ns'
204− case (x, y) of
133+groupedDecls x (FunctionBody ns) | Just ns' <- isPragma x = ns `intersects` ns'
205− ( SigD NoExtField (TypeSig NoExtField _ _),
134+groupedDecls (FunctionBody ns) x | Just ns' <- isPragma x = ns `intersects` ns'
206− SigD NoExtField (TypeSig NoExtField _ _)
135+groupedDecls x (DataDeclaration n) | Just ns <- isPragma x = n `elem` ns
207− ) -> True
136+groupedDecls (DataDeclaration n) x | Just ns <- isPragma x =
137+ let f = occNameFS . rdrNameOcc in f n `elem` map f ns
138+groupedDecls x y | Just ns <- isPragma x, Just ns' <- isPragma y = ns `intersects` ns'
139+groupedDecls x (TypeSignature ns) | Just ns' <- isPragma x = ns `intersects` ns'
140+groupedDecls (PatternSignature ns) (Pattern n) = n `elem` ns
208− _ -> False
141+groupedDecls _ _ = False
209
142
210intersects :: Ord a => [a] -> [a] -> Bool
143intersects :: Ord a => [a] -> [a] -> Bool
211intersects a b = go (sort a) (sort b)
144intersects a b = go (sort a) (sort b)
@@ -213,14 +146,22 @@ intersects a b = go (sort a) (sort b)
213 go :: Ord a => [a] -> [a] -> Bool
146 go :: Ord a => [a] -> [a] -> Bool
214 go _ [] = False
147 go _ [] = False
215 go [] _ = False
148 go [] _ = False
216− go (x : xs) (y : ys)
149+ go (x:xs) (y:ys)
217− | x < y = go xs (y : ys)
150+ | x < y = go xs (y:ys)
218− | x > y = go (x : xs) ys
151+ | x > y = go (x:xs) ys
219 | otherwise = True
152 | otherwise = True
220
153
154+-- | Checks if given list of declarations contain a pair which should
155+-- be separated by a blank line.
156+
157+hasSeparatedDecls :: [LHsDecl GhcPs] -> Bool
158+hasSeparatedDecls xs = case groupDecls xs of
159+ _:_:_ -> True
160+ _ -> False
161+
221−isPragma ::
162+isPragma
222− HsDecl GhcPs ->
163+ :: HsDecl GhcPs
223− Maybe [RdrName]
164+ -> Maybe [RdrName]
224isPragma = \case
165isPragma = \case
225 InlinePragma n -> Just [n]
166 InlinePragma n -> Just [n]
226 SpecializePragma n -> Just [n]
167 SpecializePragma n -> Just [n]
@@ -230,98 +171,72 @@ isPragma = \case
230 WarningPragma n -> Just n
171 WarningPragma n -> Just n
231 _ -> Nothing
172 _ -> Nothing
232
173
233−-- Declarations that do not refer to names
234−
235−pattern Splice :: HsDecl GhcPs
236−pattern Splice <- SpliceD NoExtField (SpliceDecl NoExtField _ _)
237−
238-- Declarations referring to a single name
174-- Declarations referring to a single name
239
175
240−pattern
241− InlinePragma,
176+pattern InlinePragma
242− SpecializePragma,
177+ , SpecializePragma
243− SCCPragma,
178+ , SCCPragma
244− AnnTypePragma,
179+ , AnnTypePragma
245− AnnValuePragma,
180+ , AnnValuePragma
246− Pattern,
181+ , Pattern
247− DataDeclaration,
248− ClassDeclaration,
249− KindSignature,
250− FamilyDeclaration ::
251− RdrName -> HsDecl GhcPs
182+ , DataDeclaration :: RdrName -> HsDecl GhcPs
252−pattern InlinePragma n <- SigD NoExtField (InlineSig NoExtField (L _ n) _)
183+pattern InlinePragma n <- SigD NoExt (InlineSig NoExt (L _ n) _)
253−pattern SpecializePragma n <- SigD NoExtField (SpecSig NoExtField (L _ n) _ _)
184+pattern SpecializePragma n <- SigD NoExt (SpecSig NoExt (L _ n) _ _)
254−pattern SCCPragma n <- SigD NoExtField (SCCFunSig NoExtField _ (L _ n) _)
185+pattern SCCPragma n <- SigD NoExt (SCCFunSig NoExt _ (L _ n) _)
255−pattern AnnTypePragma n <- AnnD NoExtField (HsAnnotation NoExtField _ (TypeAnnProvenance (L _ n)) _)
186+pattern AnnTypePragma n <- AnnD NoExt (HsAnnotation NoExt _ (TypeAnnProvenance (L _ n)) _)
256−pattern AnnValuePragma n <- AnnD NoExtField (HsAnnotation NoExtField _ (ValueAnnProvenance (L _ n)) _)
187+pattern AnnValuePragma n <- AnnD NoExt (HsAnnotation NoExt _ (ValueAnnProvenance (L _ n)) _)
257−pattern Pattern n <- ValD NoExtField (PatSynBind NoExtField (PSB _ (L _ n) _ _ _))
188+pattern Pattern n <- ValD NoExt (PatSynBind NoExt (PSB _ (L _ n) _ _ _))
258−pattern DataDeclaration n <- TyClD NoExtField (DataDecl NoExtField (L _ n) _ _ _)
189+pattern DataDeclaration n <- TyClD NoExt (DataDecl NoExt (L _ n) _ _ _)
259−pattern ClassDeclaration n <- TyClD NoExtField (ClassDecl NoExtField _ (L _ n) _ _ _ _ _ _ _ _)
260−pattern KindSignature n <- KindSigD NoExtField (StandaloneKindSig NoExtField (L _ n) _)
261−pattern FamilyDeclaration n <- TyClD NoExtField (FamDecl NoExtField (FamilyDecl NoExtField _ (L _ n) _ _ _ _))
262
190
263-- Declarations which can refer to multiple names
191-- Declarations which can refer to multiple names
264
192
265−pattern
266− TypeSignature,
193+pattern TypeSignature
267− DefaultSignature,
268− FunctionBody,
194+ , FunctionBody
269− PatternSignature,
195+ , PatternSignature
270− WarningPragma ::
271− [RdrName] -> HsDecl GhcPs
196+ , WarningPragma :: [RdrName] -> HsDecl GhcPs
272pattern TypeSignature n <- (sigRdrNames -> Just n)
197pattern TypeSignature n <- (sigRdrNames -> Just n)
273−pattern DefaultSignature n <- (defSigRdrNames -> Just n)
274pattern FunctionBody n <- (funRdrNames -> Just n)
198pattern FunctionBody n <- (funRdrNames -> Just n)
275pattern PatternSignature n <- (patSigRdrNames -> Just n)
199pattern PatternSignature n <- (patSigRdrNames -> Just n)
276pattern WarningPragma n <- (warnSigRdrNames -> Just n)
200pattern WarningPragma n <- (warnSigRdrNames -> Just n)
277
201
278−pattern DocNext, DocPrev :: HsDecl GhcPs
279−pattern DocNext <- (DocD NoExtField (DocCommentNext _))
280−pattern DocPrev <- (DocD NoExtField (DocCommentPrev _))
281−
282sigRdrNames :: HsDecl GhcPs -> Maybe [RdrName]
202sigRdrNames :: HsDecl GhcPs -> Maybe [RdrName]
283−sigRdrNames (SigD NoExtField (TypeSig NoExtField ns _)) = Just $ map unLoc ns
203+sigRdrNames (SigD NoExt (TypeSig NoExt ns _)) = Just $ map unLoc ns
284−sigRdrNames (SigD NoExtField (ClassOpSig NoExtField _ ns _)) = Just $ map unLoc ns
204+sigRdrNames (SigD NoExt (ClassOpSig NoExt _ ns _)) = Just $ map unLoc ns
285−sigRdrNames (SigD NoExtField (PatSynSig NoExtField ns _)) = Just $ map unLoc ns
205+sigRdrNames (SigD NoExt (PatSynSig NoExt ns _)) = Just $ map unLoc ns
286sigRdrNames _ = Nothing
206sigRdrNames _ = Nothing
287
207
288−defSigRdrNames :: HsDecl GhcPs -> Maybe [RdrName]
289−defSigRdrNames (SigD NoExtField (ClassOpSig NoExtField True ns _)) = Just $ map unLoc ns
290−defSigRdrNames _ = Nothing
291−
292funRdrNames :: HsDecl GhcPs -> Maybe [RdrName]
208funRdrNames :: HsDecl GhcPs -> Maybe [RdrName]
293−funRdrNames (ValD NoExtField (FunBind NoExtField (L _ n) _ _ _)) = Just [n]
209+funRdrNames (ValD NoExt (FunBind NoExt (L _ n) _ _ _)) = Just [n]
294−funRdrNames (ValD NoExtField (PatBind NoExtField (L _ n) _ _)) = Just $ patBindNames n
210+funRdrNames (ValD NoExt (PatBind NoExt (L _ n) _ _)) = Just $ patBindNames n
295funRdrNames _ = Nothing
211funRdrNames _ = Nothing
296
212
297patSigRdrNames :: HsDecl GhcPs -> Maybe [RdrName]
213patSigRdrNames :: HsDecl GhcPs -> Maybe [RdrName]
298−patSigRdrNames (SigD NoExtField (PatSynSig NoExtField ns _)) = Just $ map unLoc ns
214+patSigRdrNames (SigD NoExt (PatSynSig NoExt ns _)) = Just $ map unLoc ns
299patSigRdrNames _ = Nothing
215patSigRdrNames _ = Nothing
300
216
301warnSigRdrNames :: HsDecl GhcPs -> Maybe [RdrName]
217warnSigRdrNames :: HsDecl GhcPs -> Maybe [RdrName]
302−warnSigRdrNames (WarningD NoExtField (Warnings NoExtField _ ws)) = Just $
218+warnSigRdrNames (WarningD NoExt (Warnings NoExt _ ws)) = Just $ flip concatMap ws $ \case
303− flip concatMap ws $ \case
304− L _ (Warning NoExtField ns _) -> map unLoc ns
219+ L _ (Warning NoExt ns _) -> map unLoc ns
305− L _ (XWarnDecl x) -> noExtCon x
220+ L _ (XWarnDecl NoExt) -> []
306warnSigRdrNames _ = Nothing
221warnSigRdrNames _ = Nothing
307
222
308patBindNames :: Pat GhcPs -> [RdrName]
223patBindNames :: Pat GhcPs -> [RdrName]
309−patBindNames (TuplePat NoExtField ps _) = concatMap (patBindNames . unLoc) ps
224+patBindNames (TuplePat NoExt ps _) = concatMap (patBindNames . unLoc) ps
310−patBindNames (VarPat NoExtField (L _ n)) = [n]
225+patBindNames (VarPat NoExt (L _ n)) = [n]
311−patBindNames (WildPat NoExtField) = []
226+patBindNames (WildPat NoExt) = []
312−patBindNames (LazyPat NoExtField (L _ p)) = patBindNames p
227+patBindNames (LazyPat NoExt (L _ p)) = patBindNames p
313−patBindNames (BangPat NoExtField (L _ p)) = patBindNames p
228+patBindNames (BangPat NoExt (L _ p)) = patBindNames p
314−patBindNames (ParPat NoExtField (L _ p)) = patBindNames p
229+patBindNames (ParPat NoExt (L _ p)) = patBindNames p
315−patBindNames (ListPat NoExtField ps) = concatMap (patBindNames . unLoc) ps
230+patBindNames (ListPat NoExt ps) = concatMap (patBindNames . unLoc) ps
316−patBindNames (AsPat NoExtField (L _ n) (L _ p)) = n : patBindNames p
231+patBindNames (AsPat NoExt (L _ n) (L _ p)) = n : patBindNames p
317−patBindNames (SumPat NoExtField (L _ p) _ _) = patBindNames p
232+patBindNames (SumPat NoExt (L _ p) _ _) = patBindNames p
318−patBindNames (ViewPat NoExtField _ (L _ p)) = patBindNames p
233+patBindNames (ViewPat NoExt _ (L _ p)) = patBindNames p
319−patBindNames (SplicePat NoExtField _) = []
234+patBindNames (SplicePat NoExt _) = []
320−patBindNames (LitPat NoExtField _) = []
235+patBindNames (LitPat NoExt _) = []
321−patBindNames (SigPat _ (L _ p) _) = patBindNames p
236+patBindNames (SigPat _ (L _ p)) = patBindNames p
322−patBindNames (NPat NoExtField _ _ _) = []
237+patBindNames (NPat NoExt _ _ _) = []
323−patBindNames (NPlusKPat NoExtField (L _ n) _ _ _ _) = [n]
238+patBindNames (NPlusKPat NoExt (L _ n) _ _ _ _) = [n]
324patBindNames (ConPatIn _ d) = concatMap (patBindNames . unLoc) (hsConPatArgs d)
239patBindNames (ConPatIn _ d) = concatMap (patBindNames . unLoc) (hsConPatArgs d)
325−patBindNames ConPatOut {} = notImplemented "ConPatOut" -- created by renamer
240+patBindNames (ConPatOut _ _ _ _ _ _ _) = notImplemented "ConPatOut" -- created by renamer
326−patBindNames (CoPat NoExtField _ p _) = patBindNames p
241+patBindNames (CoPat NoExt _ p _) = patBindNames p
327−patBindNames (XPat x) = noExtCon x
242+patBindNames (XPat NoExt) = notImplemented "XPat"
src/Ormolu/Printer/Meat/Declaration.hs-boot+3−3
@@ -1,6 +1,6 @@
1module Ormolu.Printer.Meat.Declaration
1module Ormolu.Printer.Meat.Declaration
2− ( p_hsDecls,
2+ ( p_hsDecls
3− p_hsDeclsRespectGrouping,
3+ , hasSeparatedDecls
4 )
4 )
5where
5where
6
6
@@ -9,4 +9,4 @@ import Ormolu.Printer.Combinators
9import Ormolu.Printer.Meat.Common
9import Ormolu.Printer.Meat.Common
10
10
11p_hsDecls :: FamilyStyle -> [LHsDecl GhcPs] -> R ()
11p_hsDecls :: FamilyStyle -> [LHsDecl GhcPs] -> R ()
12−p_hsDeclsRespectGrouping :: FamilyStyle -> [LHsDecl GhcPs] -> R ()
12+hasSeparatedDecls :: [LHsDecl GhcPs] -> Bool
src/Ormolu/Printer/Meat/Declaration/Annotation.hs+6−5
@@ -1,8 +1,8 @@
1−{-# LANGUAGE LambdaCase #-}
1+{-# LANGUAGE LambdaCase #-}
2{-# LANGUAGE OverloadedStrings #-}
2{-# LANGUAGE OverloadedStrings #-}
3
3
4module Ormolu.Printer.Meat.Declaration.Annotation
4module Ormolu.Printer.Meat.Declaration.Annotation
5− ( p_annDecl,
5+ ( p_annDecl
6 )
6 )
7where
7where
8
8
@@ -10,17 +10,18 @@ import GHC
10import Ormolu.Printer.Combinators
10import Ormolu.Printer.Combinators
11import Ormolu.Printer.Meat.Common
11import Ormolu.Printer.Meat.Common
12import Ormolu.Printer.Meat.Declaration.Value
12import Ormolu.Printer.Meat.Declaration.Value
13+import Ormolu.Utils
13
14
14p_annDecl :: AnnDecl GhcPs -> R ()
15p_annDecl :: AnnDecl GhcPs -> R ()
15p_annDecl = \case
16p_annDecl = \case
16− HsAnnotation NoExtField _ annProv expr -> pragma "ANN" . inci $ do
17+ HsAnnotation NoExt _ annProv expr -> pragma "ANN" . inci $ do
17 p_annProv annProv
18 p_annProv annProv
18 breakpoint
19 breakpoint
19 located expr p_hsExpr
20 located expr p_hsExpr
20− XAnnDecl x -> noExtCon x
21+ XAnnDecl {} -> notImplemented "XAnnDecl"
21
22
22p_annProv :: AnnProvenance (IdP GhcPs) -> R ()
23p_annProv :: AnnProvenance (IdP GhcPs) -> R ()
23p_annProv = \case
24p_annProv = \case
24 ValueAnnProvenance name -> p_rdrName name
25 ValueAnnProvenance name -> p_rdrName name
25− TypeAnnProvenance name -> txt "type" >> space >> p_rdrName name
26+ TypeAnnProvenance name -> txt "type " >> p_rdrName name
26 ModuleAnnProvenance -> txt "module"
27 ModuleAnnProvenance -> txt "module"
src/Ormolu/Printer/Meat/Declaration/Class.hs+53−48
@@ -1,10 +1,11 @@
1−{-# LANGUAGE LambdaCase #-}
1+{-# LANGUAGE LambdaCase #-}
2{-# LANGUAGE OverloadedStrings #-}
2{-# LANGUAGE OverloadedStrings #-}
3−{-# LANGUAGE RecordWildCards #-}
3+{-# LANGUAGE RecordWildCards #-}
4
4
5-- | Rendering of type class declarations.
5-- | Rendering of type class declarations.
6+
6module Ormolu.Printer.Meat.Declaration.Class
7module Ormolu.Printer.Meat.Declaration.Class
7− ( p_classDecl,
8+ ( p_classDecl
8 )
9 )
9where
10where
10
11
@@ -12,89 +13,93 @@ import Class
12import Control.Arrow
13import Control.Arrow
13import Control.Monad
14import Control.Monad
14import Data.Foldable
15import Data.Foldable
15−import Data.List (sortOn)
16+import Data.List (sortBy)
17+import Data.Ord (comparing)
16import GHC
18import GHC
17import Ormolu.Printer.Combinators
19import Ormolu.Printer.Combinators
18import Ormolu.Printer.Meat.Common
20import Ormolu.Printer.Meat.Common
19−import {-# SOURCE #-} Ormolu.Printer.Meat.Declaration
20import Ormolu.Printer.Meat.Type
21import Ormolu.Printer.Meat.Type
22+import Ormolu.Utils
23+import RdrName (RdrName (..))
24+import {-# SOURCE #-} Ormolu.Printer.Meat.Declaration
21
25
22−p_classDecl ::
26+p_classDecl
23− LHsContext GhcPs ->
27+ :: LHsContext GhcPs
24− Located RdrName ->
28+ -> Located RdrName
25− LHsQTyVars GhcPs ->
29+ -> LHsQTyVars GhcPs
26− LexicalFixity ->
30+ -> LexicalFixity
27− [Located (FunDep (Located RdrName))] ->
31+ -> [Located (FunDep (Located RdrName))]
28− [LSig GhcPs] ->
32+ -> [LSig GhcPs]
29− LHsBinds GhcPs ->
33+ -> LHsBinds GhcPs
30− [LFamilyDecl GhcPs] ->
34+ -> [LFamilyDecl GhcPs]
31− [LTyFamDefltDecl GhcPs] ->
35+ -> [LTyFamDefltEqn GhcPs]
32− [LDocDecl] ->
33− R ()
36+ -> R ()
34−p_classDecl ctx name HsQTvs {..} fixity fdeps csigs cdefs cats catdefs cdocs = do
37+p_classDecl ctx name tvars fixity fdeps csigs cdefs cats catdefs = do
38+ let HsQTvs {..} = tvars
35− let variableSpans = getLoc <$> hsq_explicit
39+ variableSpans = getLoc <$> hsq_explicit
36 signatureSpans = getLoc name : variableSpans
40 signatureSpans = getLoc name : variableSpans
37 dependencySpans = getLoc <$> fdeps
41 dependencySpans = getLoc <$> fdeps
38 combinedSpans = getLoc ctx : (signatureSpans ++ dependencySpans)
42 combinedSpans = getLoc ctx : (signatureSpans ++ dependencySpans)
39− -- GHC's AST does not necessarily store each kind of element in source
40− -- location order. This happens because different declarations are stored
41− -- in different lists. Consequently, to get all the declarations in proper
42− -- order, they need to be manually sorted.
43− sigs = (getLoc &&& fmap (SigD NoExtField)) <$> csigs
44− vals = (getLoc &&& fmap (ValD NoExtField)) <$> toList cdefs
45− tyFams = (getLoc &&& fmap (TyClD NoExtField . FamDecl NoExtField)) <$> cats
46− docs = (getLoc &&& fmap (DocD NoExtField)) <$> cdocs
47− tyFamDefs =
48− ( getLoc &&& fmap (InstD NoExtField . TyFamInstD NoExtField)
49− )
50− <$> catdefs
51− allDecls =
52− snd <$> sortOn fst (sigs <> vals <> tyFams <> tyFamDefs <> docs)
53 txt "class"
43 txt "class"
54 switchLayout combinedSpans $ do
44 switchLayout combinedSpans $ do
55 breakpoint
45 breakpoint
56 inci $ do
46 inci $ do
57 p_classContext ctx
47 p_classContext ctx
58− switchLayout signatureSpans $
48+ switchLayout signatureSpans $ do
59 p_infixDefHelper
49 p_infixDefHelper
60 (isInfix fixity)
50 (isInfix fixity)
61− True
51+ inci
62 (p_rdrName name)
52 (p_rdrName name)
63 (located' p_hsTyVarBndr <$> hsq_explicit)
53 (located' p_hsTyVarBndr <$> hsq_explicit)
64 inci (p_classFundeps fdeps)
54 inci (p_classFundeps fdeps)
55+ -- GHC's AST does not necessarily store each kind of element in source
56+ -- location order. This happens because different declarations are stored in
57+ -- different lists. Consequently, to get all the declarations in proper order,
58+ -- they need to be manually sorted.
59+ let sigs = (getLoc &&& fmap (SigD NoExt)) <$> csigs
60+ vals = (getLoc &&& fmap (ValD NoExt)) <$> toList cdefs
61+ tyFams = (getLoc &&& fmap (TyClD NoExt . FamDecl NoExt)) <$> cats
62+ tyFamDefs =
63+ ( getLoc &&& fmap (InstD NoExt . TyFamInstD NoExt . defltEqnToInstDecl)
64+ ) <$> catdefs
65− unless (null allDecls) $ do
65+ allDecls =
66− breakpoint
66+ snd <$> sortBy (comparing fst) (sigs <> vals <> tyFams <> tyFamDefs)
67− txt "where"
68 unless (null allDecls) $ do
67 unless (null allDecls) $ do
68+ txt " where"
69 breakpoint -- Ensure whitespace is added after where clause.
69 breakpoint -- Ensure whitespace is added after where clause.
70+ -- Add newline before first declaration if the body contains separate
71+ -- declarations
72+ when (hasSeparatedDecls allDecls) breakpoint'
70− inci (p_hsDeclsRespectGrouping Associated allDecls)
73+ inci (p_hsDecls Associated allDecls)
71−p_classDecl _ _ (XLHsQTyVars c) _ _ _ _ _ _ _ = noExtCon c
72
74
73p_classContext :: LHsContext GhcPs -> R ()
75p_classContext :: LHsContext GhcPs -> R ()
74p_classContext ctx = unless (null (unLoc ctx)) $ do
76p_classContext ctx = unless (null (unLoc ctx)) $ do
75 located ctx p_hsContext
77 located ctx p_hsContext
76− space
77− txt "=>"
78 breakpoint
78 breakpoint
79+ txt "=> "
79
80
80p_classFundeps :: [Located (FunDep (Located RdrName))] -> R ()
81p_classFundeps :: [Located (FunDep (Located RdrName))] -> R ()
81p_classFundeps fdeps = unless (null fdeps) $ do
82p_classFundeps fdeps = unless (null fdeps) $ do
82 breakpoint
83 breakpoint
83− txt "|"
84+ txt "| "
84− space
85− inci $ sep commaDel (sitcc . located' p_funDep) fdeps
85+ sitcc $ sep (comma >> breakpoint) (sitcc . located' p_funDep) fdeps
86
86
87p_funDep :: FunDep (Located RdrName) -> R ()
87p_funDep :: FunDep (Located RdrName) -> R ()
88p_funDep (before, after) = do
88p_funDep (before, after) = do
89 sep space p_rdrName before
89 sep space p_rdrName before
90− space
91− txt "->"
90+ txt " -> "
92− space
93 sep space p_rdrName after
91 sep space p_rdrName after
94
92
95----------------------------------------------------------------------------
93----------------------------------------------------------------------------
96-- Helpers
94-- Helpers
97
95
96+defltEqnToInstDecl :: TyFamDefltEqn GhcPs -> TyFamInstDecl GhcPs
97+defltEqnToInstDecl FamEqn {..} = TyFamInstDecl {..}
98+ where
99+ eqn = FamEqn {feqn_pats = tyVarsToTypes feqn_pats, ..}
100+ tfid_eqn = HsIB {hsib_ext = NoExt, hsib_body = eqn}
101+defltEqnToInstDecl XFamEqn {} = notImplemented "XFamEqn"
102+
98isInfix :: LexicalFixity -> Bool
103isInfix :: LexicalFixity -> Bool
99isInfix = \case
104isInfix = \case
100 Infix -> True
105 Infix -> True
src/Ormolu/Printer/Meat/Declaration/Data.hs+104−176
@@ -1,33 +1,31 @@
1−{-# LANGUAGE LambdaCase #-}
1+{-# LANGUAGE LambdaCase #-}
2{-# LANGUAGE OverloadedStrings #-}
2{-# LANGUAGE OverloadedStrings #-}
3−{-# LANGUAGE RecordWildCards #-}
3+{-# LANGUAGE RecordWildCards #-}
4
4
5-- | Renedring of data type declarations.
5-- | Renedring of data type declarations.
6+
6module Ormolu.Printer.Meat.Declaration.Data
7module Ormolu.Printer.Meat.Declaration.Data
7− ( p_dataDecl,
8+ ( p_dataDecl
8 )
9 )
9where
10where
10
11
11import Control.Monad
12import Control.Monad
12−import Data.Maybe (isJust, maybeToList)
13+import Data.Maybe (isJust)
13import GHC
14import GHC
14import Ormolu.Printer.Combinators
15import Ormolu.Printer.Combinators
15import Ormolu.Printer.Meat.Common
16import Ormolu.Printer.Meat.Common
16import Ormolu.Printer.Meat.Type
17import Ormolu.Printer.Meat.Type
17import Ormolu.Utils
18import Ormolu.Utils
19+import RdrName (RdrName (..))
20+import SrcLoc (Located)
18
21
19−p_dataDecl ::
22+p_dataDecl
20− -- | Whether to format as data family
23+ :: FamilyStyle -- ^ Whether to format as data family
21− FamilyStyle ->
22− -- | Type constructor
23− Located RdrName ->
24+ -> Located RdrName -- ^ Type constructor
24− -- | Type patterns
25− [LHsType GhcPs] ->
25+ -> [LHsType GhcPs] -- ^ Type patterns
26− -- | Lexical fixity
26+ -> LexicalFixity -- ^ Lexical fixity
27− LexicalFixity ->
28− -- | Data definition
27+ -> HsDataDefn GhcPs -- ^ Data definition
29− HsDataDefn GhcPs ->
30− R ()
28+ -> R ()
31p_dataDecl style name tpats fixity HsDataDefn {..} = do
29p_dataDecl style name tpats fixity HsDataDefn {..} = do
32 txt $ case dd_ND of
30 txt $ case dd_ND of
33 NewType -> "newtype"
31 NewType -> "newtype"
@@ -35,160 +33,107 @@ p_dataDecl style name tpats fixity HsDataDefn {..} = do
35 txt $ case style of
33 txt $ case style of
36 Associated -> mempty
34 Associated -> mempty
37 Free -> " instance"
35 Free -> " instance"
38− let constructorSpans = getLoc name : fmap getLoc tpats
36+ switchLayout (getLoc name : fmap getLoc tpats) $ do
39− switchLayout constructorSpans $ do
40 breakpoint
37 breakpoint
41− inci $
42− p_infixDefHelper
38+ inci $ p_infixDefHelper
43− (isInfix fixity)
39+ (isInfix fixity)
44− True
40+ inci
45− (p_rdrName name)
41+ (p_rdrName name)
46− (located' p_hsType <$> tpats)
42+ (located' p_hsType <$> tpats)
47 case dd_kindSig of
43 case dd_kindSig of
48 Nothing -> return ()
44 Nothing -> return ()
49 Just k -> do
45 Just k -> do
50 space
46 space
51− txt "::"
47+ txt ":: "
52− space
53 located k p_hsType
48 located k p_hsType
54 let gadt = isJust dd_kindSig || any (isGadt . unLoc) dd_cons
49 let gadt = isJust dd_kindSig || any (isGadt . unLoc) dd_cons
55 unless (null dd_cons) $
50 unless (null dd_cons) $
56 if gadt
51 if gadt
57− then inci $ do
52+ then do
58− switchLayout constructorSpans $ do
59− breakpoint
60− txt "where"
53+ txt " where"
61 breakpoint
54 breakpoint
62− sepSemi (located' (p_conDecl False)) dd_cons
55+ inci $ sepSemi (located' p_conDecl) dd_cons
63− else switchLayout (getLoc name : (getLoc <$> dd_cons)) . inci $ do
56+ else switchLayout (getLoc name : (getLoc <$> dd_cons)) $
64− let singleConstRec = isSingleConstRec dd_cons
57+ inci $ do
65− if singleConstRec
66− then space
67− else
68− if hasHaddocks dd_cons
69− then newline
70− else breakpoint
58+ breakpoint
71− equals
59+ txt "= "
72− space
73− layout <- getLayout
74− let s =
75− if layout == MultiLine || hasHaddocks dd_cons
76− then newline >> txt "|" >> space
60+ let s = vlayout (txt " | ") (newline >> txt "| ")
77− else space >> txt "|" >> space
78− sitcc' =
79− if singleConstRec
80− then id
81− else sitcc
82− sep s (sitcc' . located' (p_conDecl singleConstRec)) dd_cons
61+ sep s (sitcc . located' p_conDecl) dd_cons
62+
83 unless (null $ unLoc dd_derivs) breakpoint
63 unless (null $ unLoc dd_derivs) breakpoint
84− inci . located dd_derivs $ \xs ->
64+ inci . located dd_derivs $ \xs -> do
85 sep newline (located' p_hsDerivingClause) xs
65 sep newline (located' p_hsDerivingClause) xs
86−p_dataDecl _ _ _ _ (XHsDataDefn x) = noExtCon x
66+p_dataDecl _ _ _ _ (XHsDataDefn NoExt) = notImplemented "XHsDataDefn"
87
67
88−p_conDecl ::
89− Bool ->
90− ConDecl GhcPs ->
68+p_conDecl :: ConDecl GhcPs -> R ()
91− R ()
92−p_conDecl singleConstRec = \case
69+p_conDecl = \case
93 ConDeclGADT {..} -> do
70 ConDeclGADT {..} -> do
94− mapM_ (p_hsDocString Pipe True) con_doc
95− let conDeclSpn =
96− fmap getLoc con_names
97− <> [getLoc con_forall]
98− <> conTyVarsSpans con_qvars
99− <> maybeToList (fmap getLoc con_mb_cxt)
100− <> conArgsSpans con_args
101− switchLayout conDeclSpn $ do
102− case con_names of
71+ case con_names of
103− [] -> return ()
72+ [] -> return ()
104− (c : cs) -> do
73+ (c:cs) -> do
105− p_rdrName c
74+ p_rdrName c
106− unless (null cs) . inci $ do
75+ unless (null cs) . inci $ do
107− commaDel
76+ comma
77+ breakpoint
108− sep commaDel p_rdrName cs
78+ sitcc $ sep (comma >> breakpoint) p_rdrName cs
79+ breakpoint
109− inci $ do
80+ inci $ do
110− space
111− txt "::"
81+ txt ":: "
112− let interArgBreak =
113− if hasDocStrings (unLoc con_res_ty)
114− then newline
115− else breakpoint
116− interArgBreak
117− when (unLoc con_forall) $ do
118− p_forallBndrs ForallInvis p_hsTyVarBndr (hsq_explicit con_qvars)
82+ p_forallBndrs (hsq_explicit con_qvars)
119− interArgBreak
120− forM_ con_mb_cxt p_lhsContext
121− case con_args of
122− PrefixCon xs -> do
123− sep breakpoint (located' p_hsType) xs
124− unless (null xs) $ do
125− space
126− txt "->"
127− breakpoint
128− RecCon l -> do
129− located l p_conDeclFields
130− unless (null $ unLoc l) $ do
131− space
132− txt "->"
133− breakpoint
134− InfixCon _ _ -> notImplemented "InfixCon"
135− p_hsType (unLoc con_res_ty)
136− ConDeclH98 {..} -> do
137− mapM_ (p_hsDocString Pipe True) con_doc
138− let conDeclWithContextSpn =
139− [getLoc con_forall]
140− <> fmap getLoc con_ex_tvs
141− <> maybeToList (fmap getLoc con_mb_cxt)
142− <> conDeclSpn
143− conDeclSpn =
144− getLoc con_name : conArgsSpans con_args
145− switchLayout conDeclWithContextSpn $ do
146− when (unLoc con_forall) $ do
147− p_forallBndrs ForallInvis p_hsTyVarBndr con_ex_tvs
148− breakpoint
149 forM_ con_mb_cxt p_lhsContext
83 forM_ con_mb_cxt p_lhsContext
150− switchLayout conDeclSpn $ case con_args of
84+ case con_args of
151 PrefixCon xs -> do
85 PrefixCon xs -> do
152− p_rdrName con_name
86+ sep breakpoint (located' p_hsType) xs
153− unless (null xs) breakpoint
87+ unless (null xs) $ do
154− inci . sitcc $ sep breakpoint (sitcc . located' p_hsTypePostDoc) xs
88+ breakpoint
89+ txt "-> "
155 RecCon l -> do
90 RecCon l -> do
91+ located l p_conDeclFields
92+ unless (null $ unLoc l) $ do
93+ breakpoint
94+ txt "-> "
95+ InfixCon _ _ -> notImplemented "InfixCon"
96+ p_hsType (unLoc con_res_ty)
97+ ConDeclH98 {..} -> do
98+ p_forallBndrs con_ex_tvs
99+ forM_ con_mb_cxt p_lhsContext
100+ case con_args of
101+ PrefixCon xs -> do
102+ p_rdrName con_name
103+ unless (null xs) breakpoint
104+ inci . sitcc $ sep breakpoint (sitcc . located' p_hsType) xs
105+ RecCon l -> do
106+ p_rdrName con_name
107+ breakpoint
108+ inci $ located l p_conDeclFields
109+ InfixCon x y -> do
110+ located x p_hsType
111+ breakpoint
112+ inci $ do
156 p_rdrName con_name
113 p_rdrName con_name
157− breakpoint
158− inciIf (not singleConstRec) (located l p_conDeclFields)
159− InfixCon x y -> do
160− located x p_hsType
161− breakpoint
162− inci $ do
163− p_rdrName con_name
164− space
114+ space
165− located y p_hsType
115+ located y p_hsType
166− XConDecl x -> noExtCon x
116+ XConDecl NoExt -> notImplemented "XConDecl"
167−
168−conArgsSpans :: HsConDeclDetails GhcPs -> [SrcSpan]
169−conArgsSpans = \case
170− PrefixCon xs ->
171− getLoc <$> xs
172− RecCon l ->
173− [getLoc l]
174− InfixCon x y ->
175− [getLoc x, getLoc y]
176
117
177−conTyVarsSpans :: LHsQTyVars GhcPs -> [SrcSpan]
118+p_forallBndrs
178−conTyVarsSpans = \case
119+ :: [LHsTyVarBndr GhcPs]
179− HsQTvs {..} -> getLoc <$> hsq_explicit
120+ -> R ()
180− XLHsQTyVars x -> noExtCon x
121+p_forallBndrs = \case
122+ [] -> return ()
123+ bndrs -> do
124+ txt "forall "
125+ sep space (located' p_hsTyVarBndr) bndrs
126+ txt ". "
181
127
182−p_lhsContext ::
128+p_lhsContext
183− LHsContext GhcPs ->
129+ :: LHsContext GhcPs
184− R ()
130+ -> R ()
185p_lhsContext = \case
131p_lhsContext = \case
186 L _ [] -> pure ()
132 L _ [] -> pure ()
187 ctx -> do
133 ctx -> do
188 located ctx p_hsContext
134 located ctx p_hsContext
189− space
190− txt "=>"
191 breakpoint
135 breakpoint
136+ txt "=> "
192
137
193isGadt :: ConDecl GhcPs -> Bool
138isGadt :: ConDecl GhcPs -> Bool
194isGadt = \case
139isGadt = \case
@@ -196,35 +141,32 @@ isGadt = \case
196 ConDeclH98 {} -> False
141 ConDeclH98 {} -> False
197 XConDecl {} -> False
142 XConDecl {} -> False
198
143
199−p_hsDerivingClause ::
144+p_hsDerivingClause
200− HsDerivingClause GhcPs ->
145+ :: HsDerivingClause GhcPs
201− R ()
146+ -> R ()
202p_hsDerivingClause HsDerivingClause {..} = do
147p_hsDerivingClause HsDerivingClause {..} = do
203 txt "deriving"
148 txt "deriving"
204 let derivingWhat = located deriv_clause_tys $ \case
149 let derivingWhat = located deriv_clause_tys $ \case
205 [] -> txt "()"
150 [] -> txt "()"
206− xs ->
207− parens N $
151+ xs -> parens . sitcc $ sep
208− sep
152+ (comma >> breakpoint)
209− commaDel
210− (sitcc . located' p_hsType . hsib_body)
153+ (sitcc . located' p_hsType . hsib_body)
211− xs
154+ xs
212− space
213 case deriv_clause_strategy of
155 case deriv_clause_strategy of
214 Nothing -> do
156 Nothing -> do
215 breakpoint
157 breakpoint
216 inci derivingWhat
158 inci derivingWhat
217 Just (L _ a) -> case a of
159 Just (L _ a) -> case a of
218 StockStrategy -> do
160 StockStrategy -> do
219− txt "stock"
161+ txt " stock"
220 breakpoint
162 breakpoint
221 inci derivingWhat
163 inci derivingWhat
222 AnyclassStrategy -> do
164 AnyclassStrategy -> do
223− txt "anyclass"
165+ txt " anyclass"
224 breakpoint
166 breakpoint
225 inci derivingWhat
167 inci derivingWhat
226 NewtypeStrategy -> do
168 NewtypeStrategy -> do
227− txt "newtype"
169+ txt " newtype"
228 breakpoint
170 breakpoint
229 inci derivingWhat
171 inci derivingWhat
230 ViaStrategy HsIB {..} -> do
172 ViaStrategy HsIB {..} -> do
@@ -232,12 +174,11 @@ p_hsDerivingClause HsDerivingClause {..} = do
232 inci $ do
174 inci $ do
233 derivingWhat
175 derivingWhat
234 breakpoint
176 breakpoint
235− txt "via"
177+ txt "via "
236− space
237 located hsib_body p_hsType
178 located hsib_body p_hsType
238− ViaStrategy (XHsImplicitBndrs x) ->
179+ ViaStrategy (XHsImplicitBndrs NoExt) ->
239− noExtCon x
180+ notImplemented "XHsImplicitBndrs"
240−p_hsDerivingClause (XHsDerivingClause x) = noExtCon x
181+p_hsDerivingClause (XHsDerivingClause NoExt) = notImplemented "XHsDerivingClause"
241
182
242----------------------------------------------------------------------------
183----------------------------------------------------------------------------
243-- Helpers
184-- Helpers
@@ -246,16 +187,3 @@ isInfix :: LexicalFixity -> Bool
246isInfix = \case
187isInfix = \case
247 Infix -> True
188 Infix -> True
248 Prefix -> False
189 Prefix -> False
249−
250−isSingleConstRec :: [LConDecl GhcPs] -> Bool
251−isSingleConstRec [(L _ ConDeclH98 {..})] =
252− case con_args of
253− RecCon _ -> True
254− _ -> False
255−isSingleConstRec _ = False
256−
257−hasHaddocks :: [LConDecl GhcPs] -> Bool
258−hasHaddocks = any (f . unLoc)
259− where
260− f ConDeclH98 {..} = isJust con_doc
261− f _ = False
src/Ormolu/Printer/Meat/Declaration/Default.hs+7−6
@@ -1,20 +1,21 @@
1−{-# LANGUAGE LambdaCase #-}
1+{-# LANGUAGE LambdaCase #-}
2{-# LANGUAGE OverloadedStrings #-}
2{-# LANGUAGE OverloadedStrings #-}
3
3
4module Ormolu.Printer.Meat.Declaration.Default
4module Ormolu.Printer.Meat.Declaration.Default
5− ( p_defaultDecl,
5+ ( p_defaultDecl
6 )
6 )
7where
7where
8
8
9import GHC
9import GHC
10import Ormolu.Printer.Combinators
10import Ormolu.Printer.Combinators
11import Ormolu.Printer.Meat.Type
11import Ormolu.Printer.Meat.Type
12+import Ormolu.Utils
12
13
13p_defaultDecl :: DefaultDecl GhcPs -> R ()
14p_defaultDecl :: DefaultDecl GhcPs -> R ()
14p_defaultDecl = \case
15p_defaultDecl = \case
15− DefaultDecl NoExtField ts -> do
16+ DefaultDecl NoExt ts -> do
16 txt "default"
17 txt "default"
17 breakpoint
18 breakpoint
18− inci . parens N $
19+ inci . parens . sitcc $
19− sep commaDel (sitcc . located' p_hsType) ts
20+ sep (comma >> breakpoint) (sitcc . located' p_hsType) ts
20− XDefaultDecl x -> noExtCon x
21+ XDefaultDecl {} -> notImplemented "XDefaultDecl"
src/Ormolu/Printer/Meat/Declaration/Foreign.hs+14−16
@@ -1,9 +1,9 @@
1−{-# LANGUAGE LambdaCase #-}
1+{-# LANGUAGE LambdaCase #-}
2−{-# LANGUAGE NamedFieldPuns #-}
2+{-# LANGUAGE NamedFieldPuns #-}
3{-# LANGUAGE OverloadedStrings #-}
3{-# LANGUAGE OverloadedStrings #-}
4
4
5module Ormolu.Printer.Meat.Declaration.Foreign
5module Ormolu.Printer.Meat.Declaration.Foreign
6− ( p_foreignDecl,
6+ ( p_foreignDecl
7 )
7 )
8where
8where
9
9
@@ -15,6 +15,7 @@ import GHC
15import Ormolu.Printer.Combinators
15import Ormolu.Printer.Combinators
16import Ormolu.Printer.Meat.Common
16import Ormolu.Printer.Meat.Common
17import Ormolu.Printer.Meat.Declaration.Signature
17import Ormolu.Printer.Meat.Declaration.Signature
18+import Ormolu.Utils
18
19
19p_foreignDecl :: ForeignDecl GhcPs -> R ()
20p_foreignDecl :: ForeignDecl GhcPs -> R ()
20p_foreignDecl = \case
21p_foreignDecl = \case
@@ -24,21 +25,19 @@ p_foreignDecl = \case
24 fd@ForeignExport {fd_fe} -> do
25 fd@ForeignExport {fd_fe} -> do
25 p_foreignExport fd_fe
26 p_foreignExport fd_fe
26 p_foreignTypeSig fd
27 p_foreignTypeSig fd
27− XForeignDecl x -> noExtCon x
28+ XForeignDecl {} -> notImplemented "XForeignDecl"
28
29
29-- | Printer for the last part of an import\/export, which is function name
30-- | Printer for the last part of an import\/export, which is function name
30-- and type signature.
31-- and type signature.
32+
31p_foreignTypeSig :: ForeignDecl GhcPs -> R ()
33p_foreignTypeSig :: ForeignDecl GhcPs -> R ()
32p_foreignTypeSig fd = do
34p_foreignTypeSig fd = do
33 breakpoint
35 breakpoint
34− inci
36+ -- Switch into the layout of the signature, to allow us to pull name and
35− . switchLayout
37+ -- signature onto a single line.
36− [ getLoc (fd_name fd),
37− (getLoc . hsib_body . fd_sig_ty) fd
38+ inci . switchLayout [getLoc . hsib_body $ fd_sig_ty fd] $ do
38− ]
39− $ do
40− p_rdrName (fd_name fd)
39+ p_rdrName (fd_name fd)
41− p_typeAscription (HsWC NoExtField (fd_sig_ty fd))
40+ p_typeAscription (HsWC NoExt (fd_sig_ty fd))
42
41
43-- | Printer for 'ForeignImport'.
42-- | Printer for 'ForeignImport'.
44--
43--
@@ -52,10 +51,10 @@ p_foreignTypeSig fd = do
52-- We also layout the identifier using the 'SourceText', because printing
51-- We also layout the identifier using the 'SourceText', because printing
53-- with the other two fields of 'CImport' is very complicated. See the
52-- with the other two fields of 'CImport' is very complicated. See the
54-- 'Outputable' instance of 'ForeignImport' for details.
53-- 'Outputable' instance of 'ForeignImport' for details.
54+
55p_foreignImport :: ForeignImport -> R ()
55p_foreignImport :: ForeignImport -> R ()
56p_foreignImport (CImport cCallConv safety _ _ sourceText) = do
56p_foreignImport (CImport cCallConv safety _ _ sourceText) = do
57− txt "foreign import"
57+ txt "foreign import "
58− space
59 located cCallConv atom
58 located cCallConv atom
60 -- Need to check for 'noLoc' for the 'safe' annotation
59 -- Need to check for 'noLoc' for the 'safe' annotation
61 when (isGoodSrcSpan $ getLoc safety) (space >> atom safety)
60 when (isGoodSrcSpan $ getLoc safety) (space >> atom safety)
@@ -63,8 +62,7 @@ p_foreignImport (CImport cCallConv safety _ _ sourceText) = do
63
62
64p_foreignExport :: ForeignExport -> R ()
63p_foreignExport :: ForeignExport -> R ()
65p_foreignExport (CExport (L loc (CExportStatic _ _ cCallConv)) sourceText) = do
64p_foreignExport (CExport (L loc (CExportStatic _ _ cCallConv)) sourceText) = do
66− txt "foreign export"
65+ txt "foreign export "
67− space
68 located (L loc cCallConv) atom
66 located (L loc cCallConv) atom
69 located sourceText p_sourceText
67 located sourceText p_sourceText
70
68
src/Ormolu/Printer/Meat/Declaration/Instance.hs+43−38
@@ -1,13 +1,14 @@
1−{-# LANGUAGE LambdaCase #-}
1+{-# LANGUAGE LambdaCase #-}
2{-# LANGUAGE OverloadedStrings #-}
2{-# LANGUAGE OverloadedStrings #-}
3−{-# LANGUAGE RecordWildCards #-}
3+{-# LANGUAGE RecordWildCards #-}
4
4
5-- | Type class, type family, and data family instance declarations.
5-- | Type class, type family, and data family instance declarations.
6+
6module Ormolu.Printer.Meat.Declaration.Instance
7module Ormolu.Printer.Meat.Declaration.Instance
7− ( p_clsInstDecl,
8+ ( p_clsInstDecl
8− p_tyFamInstDecl,
9+ , p_tyFamInstDecl
9− p_dataFamInstDecl,
10+ , p_dataFamInstDecl
10− p_standaloneDerivDecl,
11+ , p_standaloneDerivDecl
11 )
12 )
12where
13where
13
14
@@ -15,15 +16,16 @@ import BasicTypes
15import Control.Arrow
16import Control.Arrow
16import Control.Monad
17import Control.Monad
17import Data.Foldable
18import Data.Foldable
18−import Data.List (sortOn)
19+import Data.List (sortBy)
20+import Data.Ord (comparing)
19import GHC
21import GHC
20import Ormolu.Printer.Combinators
22import Ormolu.Printer.Combinators
21import Ormolu.Printer.Meat.Common
23import Ormolu.Printer.Meat.Common
22−import {-# SOURCE #-} Ormolu.Printer.Meat.Declaration
23import Ormolu.Printer.Meat.Declaration.Data
24import Ormolu.Printer.Meat.Declaration.Data
24import Ormolu.Printer.Meat.Declaration.TypeFamily
25import Ormolu.Printer.Meat.Declaration.TypeFamily
25import Ormolu.Printer.Meat.Type
26import Ormolu.Printer.Meat.Type
26import Ormolu.Utils
27import Ormolu.Utils
28+import {-# SOURCE #-} Ormolu.Printer.Meat.Declaration
27
29
28p_standaloneDerivDecl :: DerivDecl GhcPs -> R ()
30p_standaloneDerivDecl :: DerivDecl GhcPs -> R ()
29p_standaloneDerivDecl DerivDecl {..} = do
31p_standaloneDerivDecl DerivDecl {..} = do
@@ -32,30 +34,32 @@ p_standaloneDerivDecl DerivDecl {..} = do
32 txt "instance"
34 txt "instance"
33 breakpoint
35 breakpoint
34 match_overlap_mode deriv_overlap_mode breakpoint
36 match_overlap_mode deriv_overlap_mode breakpoint
37+ if toIndent
38+ then inci typesAfterInstance
35− inciIf toIndent typesAfterInstance
39+ else typesAfterInstance
36 txt "deriving"
40 txt "deriving"
37− space
38 case deriv_strategy of
41 case deriv_strategy of
39− Nothing ->
42+ Nothing -> do
43+ space
40 instTypes False
44 instTypes False
41 Just (L _ a) -> case a of
45 Just (L _ a) -> case a of
42 StockStrategy -> do
46 StockStrategy -> do
43− txt "stock "
47+ txt " stock "
44 instTypes False
48 instTypes False
45 AnyclassStrategy -> do
49 AnyclassStrategy -> do
46− txt "anyclass "
50+ txt " anyclass "
47 instTypes False
51 instTypes False
48 NewtypeStrategy -> do
52 NewtypeStrategy -> do
49− txt "newtype "
53+ txt " newtype "
50 instTypes False
54 instTypes False
51 ViaStrategy HsIB {..} -> do
55 ViaStrategy HsIB {..} -> do
52− txt "via"
56+ txt " via"
53 breakpoint
57 breakpoint
54 inci (located hsib_body p_hsType)
58 inci (located hsib_body p_hsType)
55 breakpoint
59 breakpoint
56 instTypes True
60 instTypes True
57− ViaStrategy (XHsImplicitBndrs x) ->
61+ ViaStrategy (XHsImplicitBndrs NoExt) ->
58− noExtCon x
62+ notImplemented "XHsImplicitBndrs"
59p_standaloneDerivDecl (XDerivDecl _) = notImplemented "XDerivDecl"
63p_standaloneDerivDecl (XDerivDecl _) = notImplemented "XDerivDecl"
60
64
61p_clsInstDecl :: ClsInstDecl GhcPs -> R ()
65p_clsInstDecl :: ClsInstDecl GhcPs -> R ()
@@ -68,18 +72,17 @@ p_clsInstDecl = \case
68 -- location order. This happens because different declarations are stored in
72 -- location order. This happens because different declarations are stored in
69 -- different lists. Consequently, to get all the declarations in proper
73 -- different lists. Consequently, to get all the declarations in proper
70 -- order, they need to be manually sorted.
74 -- order, they need to be manually sorted.
71− let sigs = (getLoc &&& fmap (SigD NoExtField)) <$> cid_sigs
75+ let sigs = (getLoc &&& fmap (SigD NoExt)) <$> cid_sigs
72− vals = (getLoc &&& fmap (ValD NoExtField)) <$> toList cid_binds
76+ vals = (getLoc &&& fmap (ValD NoExt)) <$> toList cid_binds
73 tyFamInsts =
77 tyFamInsts =
74− ( getLoc &&& fmap (InstD NoExtField . TyFamInstD NoExtField)
78+ ( getLoc &&& fmap (InstD NoExt . TyFamInstD NoExt)
75− )
76− <$> cid_tyfam_insts
79+ ) <$> cid_tyfam_insts
77 dataFamInsts =
80 dataFamInsts =
78− ( getLoc &&& fmap (InstD NoExtField . DataFamInstD NoExtField)
81+ ( getLoc &&& fmap (InstD NoExt . DataFamInstD NoExt)
79− )
80− <$> cid_datafam_insts
82+ ) <$> cid_datafam_insts
81 allDecls =
83 allDecls =
84+ snd <$>
82− snd <$> sortOn fst (sigs <> vals <> tyFamInsts <> dataFamInsts)
85+ sortBy (comparing fst) (sigs <> vals <> tyFamInsts <> dataFamInsts)
83 located hsib_body $ \x -> do
86 located hsib_body $ \x -> do
84 breakpoint
87 breakpoint
85 inci $ do
88 inci $ do
@@ -88,12 +91,16 @@ p_clsInstDecl = \case
88 unless (null allDecls) $ do
91 unless (null allDecls) $ do
89 breakpoint
92 breakpoint
90 txt "where"
93 txt "where"
91− unless (null allDecls) . inci $ do
94+ unless (null allDecls) $ do
95+ inci $ do
92− -- Ensure whitespace is added after where clause.
96+ -- Ensure whitespace is added after where clause.
97+ breakpoint
98+ -- Add newline before first declaration if the body contains separate
99+ -- declarations
93− breakpoint
100+ when (hasSeparatedDecls allDecls) breakpoint'
94− dontUseBraces $ p_hsDeclsRespectGrouping Associated allDecls
101+ dontUseBraces $ p_hsDecls Associated allDecls
95− XHsImplicitBndrs x -> noExtCon x
102+ XHsImplicitBndrs NoExt -> notImplemented "XHsImplicitBndrs"
96− XClsInstDecl x -> noExtCon x
103+ XClsInstDecl NoExt -> notImplemented "XClsInstDecl"
97
104
98p_tyFamInstDecl :: FamilyStyle -> TyFamInstDecl GhcPs -> R ()
105p_tyFamInstDecl :: FamilyStyle -> TyFamInstDecl GhcPs -> R ()
99p_tyFamInstDecl style = \case
106p_tyFamInstDecl style = \case
@@ -106,12 +113,10 @@ p_tyFamInstDecl style = \case
106
113
107p_dataFamInstDecl :: FamilyStyle -> DataFamInstDecl GhcPs -> R ()
114p_dataFamInstDecl :: FamilyStyle -> DataFamInstDecl GhcPs -> R ()
108p_dataFamInstDecl style = \case
115p_dataFamInstDecl style = \case
109− DataFamInstDecl {dfid_eqn = HsIB {hsib_body = FamEqn {..}}} ->
116+ DataFamInstDecl {..} -> do
117+ let HsIB {..} = dfid_eqn
118+ FamEqn {..} = hsib_body
110− p_dataDecl style feqn_tycon (map typeArgToType feqn_pats) feqn_fixity feqn_rhs
119+ p_dataDecl style feqn_tycon feqn_pats feqn_fixity feqn_rhs
111− DataFamInstDecl {dfid_eqn = HsIB {hsib_body = XFamEqn {}}} ->
112− notImplemented "XFamEqn"
113− DataFamInstDecl {dfid_eqn = XHsImplicitBndrs {}} ->
114− notImplemented "XHsImplicitBndrs"
115
120
116match_overlap_mode :: Maybe (Located OverlapMode) -> R () -> R ()
121match_overlap_mode :: Maybe (Located OverlapMode) -> R () -> R ()
117match_overlap_mode overlap_mode layoutStrategy =
122match_overlap_mode overlap_mode layoutStrategy =
src/Ormolu/Printer/Meat/Declaration/RoleAnnotation.hs+11−5
@@ -1,10 +1,12 @@
1−{-# LANGUAGE LambdaCase #-}
1+{-# LANGUAGE LambdaCase #-}
2{-# LANGUAGE OverloadedStrings #-}
2{-# LANGUAGE OverloadedStrings #-}
3+{-# LANGUAGE RecordWildCards #-}
3{-# LANGUAGE TypeFamilies #-}
4{-# LANGUAGE TypeFamilies #-}
4
5
5-- | Rendering of Role annotation declarations.
6-- | Rendering of Role annotation declarations.
7+
6module Ormolu.Printer.Meat.Declaration.RoleAnnotation
8module Ormolu.Printer.Meat.Declaration.RoleAnnotation
7− ( p_roleAnnot,
9+ ( p_roleAnnot
8 )
10 )
9where
11where
10
12
@@ -12,11 +14,14 @@ import CoAxiom
12import GHC
14import GHC
13import Ormolu.Printer.Combinators
15import Ormolu.Printer.Combinators
14import Ormolu.Printer.Meat.Common
16import Ormolu.Printer.Meat.Common
17+import Ormolu.Utils
18+import RdrName (RdrName (..))
19+import SrcLoc (Located)
15
20
16p_roleAnnot :: RoleAnnotDecl GhcPs -> R ()
21p_roleAnnot :: RoleAnnotDecl GhcPs -> R ()
17p_roleAnnot = \case
22p_roleAnnot = \case
18− RoleAnnotDecl NoExtField l_name anns -> p_roleAnnot' l_name anns
23+ RoleAnnotDecl NoExt l_name anns -> p_roleAnnot' l_name anns
19− XRoleAnnotDecl x -> noExtCon x
24+ XRoleAnnotDecl _ -> notImplemented "XRoleAnnotDecl"
20
25
21p_roleAnnot' :: Located RdrName -> [Located (Maybe Role)] -> R ()
26p_roleAnnot' :: Located RdrName -> [Located (Maybe Role)] -> R ()
22p_roleAnnot' l_name anns = do
27p_roleAnnot' l_name anns = do
@@ -25,7 +30,8 @@ p_roleAnnot' l_name anns = do
25 inci $ do
30 inci $ do
26 p_rdrName l_name
31 p_rdrName l_name
27 breakpoint
32 breakpoint
33+ let
28− let p_role' = maybe (txt "_") p_role
34+ p_role' = maybe (txt "_") p_role
29 inci . sitcc $ sep breakpoint (sitcc . located' p_role') anns
35 inci . sitcc $ sep breakpoint (sitcc . located' p_role') anns
30
36
31p_role :: Role -> R ()
37p_role :: Role -> R ()
src/Ormolu/Printer/Meat/Declaration/Rule.hs+29−28
@@ -1,61 +1,62 @@
1−{-# LANGUAGE LambdaCase #-}
1+{-# LANGUAGE LambdaCase #-}
2{-# LANGUAGE OverloadedStrings #-}
2{-# LANGUAGE OverloadedStrings #-}
3+{-# LANGUAGE RecordWildCards #-}
3
4
4module Ormolu.Printer.Meat.Declaration.Rule
5module Ormolu.Printer.Meat.Declaration.Rule
5− ( p_ruleDecls,
6+ ( p_ruleDecls
6 )
7 )
7where
8where
8
9
9import BasicTypes
10import BasicTypes
10−import Control.Monad (unless)
11+import Control.Monad
11import GHC
12import GHC
12import Ormolu.Printer.Combinators
13import Ormolu.Printer.Combinators
13import Ormolu.Printer.Meat.Common
14import Ormolu.Printer.Meat.Common
14import Ormolu.Printer.Meat.Declaration.Signature
15import Ormolu.Printer.Meat.Declaration.Signature
15import Ormolu.Printer.Meat.Declaration.Value
16import Ormolu.Printer.Meat.Declaration.Value
16−import Ormolu.Printer.Meat.Type
17+import Ormolu.Utils
17
18
18p_ruleDecls :: RuleDecls GhcPs -> R ()
19p_ruleDecls :: RuleDecls GhcPs -> R ()
19p_ruleDecls = \case
20p_ruleDecls = \case
20− HsRules NoExtField _ xs ->
21− pragma "RULES" $
21+ HsRules NoExt _ xs -> pragma "RULES" . sitcc $
22− sep breakpoint (sitcc . located' p_ruleDecl) xs
22+ sep breakpoint (sitcc . located' p_ruleDecl) xs
23− XRuleDecls x -> noExtCon x
23+ XRuleDecls NoExt -> notImplemented "XRuleDecls"
24
24
25p_ruleDecl :: RuleDecl GhcPs -> R ()
25p_ruleDecl :: RuleDecl GhcPs -> R ()
26p_ruleDecl = \case
26p_ruleDecl = \case
27− HsRule NoExtField ruleName activation tyvars ruleBndrs lhs rhs -> do
27+ HsRule NoExt ruleName activation ruleBndrs lhs rhs -> do
28 located ruleName p_ruleName
28 located ruleName p_ruleName
29− space
29+ let gotBinders = not (null ruleBndrs)
30+ when (visibleActivation activation || gotBinders) space
30 p_activation activation
31 p_activation activation
31− space
32+ when (visibleActivation activation && gotBinders) space
32− case tyvars of
33+ p_ruleBndrs ruleBndrs
33− Nothing -> return ()
34− Just xs -> do
35− p_forallBndrs ForallInvis p_hsTyVarBndr xs
36− space
37− -- It appears that there is no way to tell if there was an empty forall
38− -- in the input or no forall at all. We do not want to add redundant
39− -- foralls, so let's just skip the empty ones.
40− unless (null ruleBndrs) $
41− p_forallBndrs ForallInvis p_ruleBndr ruleBndrs
42 breakpoint
34 breakpoint
43 inci $ do
35 inci $ do
44 located lhs p_hsExpr
36 located lhs p_hsExpr
45− space
37+ txt " ="
46− equals
47 inci $ do
38 inci $ do
48 breakpoint
39 breakpoint
49 located rhs p_hsExpr
40 located rhs p_hsExpr
50− XRuleDecl x -> noExtCon x
41+ XRuleDecl NoExt -> notImplemented "XRuleDecl"
51
42
52p_ruleName :: (SourceText, RuleName) -> R ()
43p_ruleName :: (SourceText, RuleName) -> R ()
53−p_ruleName (_, name) = atom $ (HsString NoSourceText name :: HsLit GhcPs)
44+p_ruleName (_, name) = atom $ HsString NoSourceText name
45+
46+p_ruleBndrs :: [LRuleBndr GhcPs] -> R ()
47+p_ruleBndrs [] = return ()
48+p_ruleBndrs bndrs =
49+ switchLayout (getLoc <$> bndrs) $ do
50+ txt "forall"
51+ breakpoint
52+ inci $ do
53+ sitcc $ sep breakpoint (sitcc . located' p_ruleBndr) bndrs
54+ txt "."
54
55
55p_ruleBndr :: RuleBndr GhcPs -> R ()
56p_ruleBndr :: RuleBndr GhcPs -> R ()
56p_ruleBndr = \case
57p_ruleBndr = \case
57− RuleBndr NoExtField x -> p_rdrName x
58+ RuleBndr NoExt x -> p_rdrName x
58− RuleBndrSig NoExtField x hswc -> parens N $ do
59+ RuleBndrSig NoExt x hswc -> parens $ do
59 p_rdrName x
60 p_rdrName x
60 p_typeAscription hswc
61 p_typeAscription hswc
61− XRuleBndr x -> noExtCon x
62+ XRuleBndr NoExt -> notImplemented "XRuleBndr"
src/Ormolu/Printer/Meat/Declaration/Signature.hs+113−153
@@ -1,13 +1,14 @@
1−{-# LANGUAGE LambdaCase #-}
1+{-# LANGUAGE LambdaCase #-}
2{-# LANGUAGE OverloadedStrings #-}
2{-# LANGUAGE OverloadedStrings #-}
3−{-# LANGUAGE RecordWildCards #-}
3+{-# LANGUAGE RecordWildCards #-}
4
4
5-- | Type signature declarations.
5-- | Type signature declarations.
6+
6module Ormolu.Printer.Meat.Declaration.Signature
7module Ormolu.Printer.Meat.Declaration.Signature
7− ( p_sigDecl,
8+ ( p_sigDecl
8− p_typeAscription,
9+ , p_typeAscription
9− p_activation,
10+ , p_activation
10− p_standaloneKindSig,
11+ , visibleActivation
11 )
12 )
12where
13where
13
14
@@ -22,81 +23,65 @@ import Ormolu.Utils
22
23
23p_sigDecl :: Sig GhcPs -> R ()
24p_sigDecl :: Sig GhcPs -> R ()
24p_sigDecl = \case
25p_sigDecl = \case
25− TypeSig NoExtField names hswc -> p_typeSig True names hswc
26+ TypeSig NoExt names hswc -> p_typeSig names hswc
26− PatSynSig NoExtField names hsib -> p_patSynSig names hsib
27+ PatSynSig NoExt names hsib -> p_patSynSig names hsib
27− ClassOpSig NoExtField def names hsib -> p_classOpSig def names hsib
28+ ClassOpSig NoExt def names hsib -> p_classOpSig def names hsib
28− FixSig NoExtField sig -> p_fixSig sig
29+ FixSig NoExt sig -> p_fixSig sig
29− InlineSig NoExtField name inlinePragma -> p_inlineSig name inlinePragma
30+ InlineSig NoExt name inlinePragma -> p_inlineSig name inlinePragma
30− SpecSig NoExtField name ts inlinePragma -> p_specSig name ts inlinePragma
31+ SpecSig NoExt name ts inlinePragma -> p_specSig name ts inlinePragma
31− SpecInstSig NoExtField _ hsib -> p_specInstSig hsib
32+ SpecInstSig NoExt _ hsib -> p_specInstSig hsib
32− MinimalSig NoExtField _ booleanFormula -> p_minimalSig booleanFormula
33+ MinimalSig NoExt _ booleanFormula -> p_minimalSig booleanFormula
33− CompleteMatchSig NoExtField _sourceText cs ty -> p_completeSig cs ty
34+ CompleteMatchSig NoExt _sourceText cs ty -> p_completeSig cs ty
34− SCCFunSig NoExtField _ name literal -> p_sccSig name literal
35+ SCCFunSig NoExt _ name literal -> p_sccSig name literal
35 _ -> notImplemented "certain types of signature declarations"
36 _ -> notImplemented "certain types of signature declarations"
36
37
37−p_typeSig ::
38+p_typeSig
38− -- | Should the tail of the names be indented
39− Bool ->
40− -- | Names (before @::@)
41− [Located RdrName] ->
39+ :: [Located RdrName] -- ^ Names (before @::@)
42− -- | Type
43− LHsSigWcType GhcPs ->
40+ -> LHsSigWcType GhcPs -- ^ Type
44− R ()
41+ -> R ()
45−p_typeSig _ [] _ = return () -- should not happen though
42+p_typeSig [] _ = return () -- should not happen though
46−p_typeSig indentTail (n : ns) hswc = do
43+p_typeSig (n:ns) hswc = do
47 p_rdrName n
44 p_rdrName n
48 if null ns
45 if null ns
49 then p_typeAscription hswc
46 then p_typeAscription hswc
50− else inciIf indentTail $ do
47+ else inci $ do
51− commaDel
48+ comma
49+ breakpoint
52− sep commaDel p_rdrName ns
50+ sep (comma >> breakpoint) p_rdrName ns
53 p_typeAscription hswc
51 p_typeAscription hswc
54
52
55−p_typeAscription ::
53+p_typeAscription
56− LHsSigWcType GhcPs ->
54+ :: LHsSigWcType GhcPs
57− R ()
55+ -> R ()
58−p_typeAscription HsWC {..} = inci $ do
56+p_typeAscription HsWC {..} = do
59− space
57+ breakpoint
58+ inci $ do
60− txt "::"
59+ txt ":: "
61− let t = hsib_body hswc_body
60+ located (hsib_body hswc_body) p_hsType
62− if hasDocStrings (unLoc t)
63− then newline
64− else breakpoint
65− located t p_hsType
66−p_typeAscription (XHsWildCardBndrs x) = noExtCon x
61+p_typeAscription (XHsWildCardBndrs NoExt) = notImplemented "XHsWildCardBndrs"
67−
62+
68−p_patSynSig ::
63+p_patSynSig
69− [Located RdrName] ->
64+ :: [Located RdrName]
70− HsImplicitBndrs GhcPs (LHsType GhcPs) ->
65+ -> HsImplicitBndrs GhcPs (LHsType GhcPs)
71− R ()
66+ -> R ()
72p_patSynSig names hsib = do
67p_patSynSig names hsib = do
73− txt "pattern"
68+ txt "pattern "
74− let body =
75− p_typeSig
76− False
77− names
78− HsWC {hswc_ext = NoExtField, hswc_body = hsib}
69+ p_typeSig names HsWC {hswc_ext = NoExt, hswc_body = hsib}
79− if length names > 1
70+
80− then breakpoint >> inci body
81− else space >> body
82−
83−p_classOpSig ::
71+p_classOpSig
84− -- | Whether this is a \"default\" signature
72+ :: Bool -- ^ Whether this is a \"default\" signature
85− Bool ->
86− -- | Names (before @::@)
87− [Located RdrName] ->
73+ -> [Located RdrName] -- ^ Names (before @::@)
88− -- | Type
89− HsImplicitBndrs GhcPs (LHsType GhcPs) ->
74+ -> HsImplicitBndrs GhcPs (LHsType GhcPs) -- ^ Type
90− R ()
75+ -> R ()
91−p_classOpSig def names hsib = do
76+p_classOpSig def names hsib = do
92− when def (txt "default" >> space)
77+ when def (txt "default ")
93− p_typeSig True names HsWC {hswc_ext = NoExtField, hswc_body = hsib}
78+ p_typeSig names HsWC {hswc_ext = NoExt, hswc_body = hsib}
94−
79+
95−p_fixSig ::
80+p_fixSig
96− FixitySig GhcPs ->
81+ :: FixitySig GhcPs
97− R ()
82+ -> R ()
98p_fixSig = \case
83p_fixSig = \case
99− FixitySig NoExtField names (Fixity _ n dir) -> do
84+ FixitySig NoExt names (Fixity _ n dir) -> do
100 txt $ case dir of
85 txt $ case dir of
101 InfixL -> "infixl"
86 InfixL -> "infixl"
102 InfixR -> "infixr"
87 InfixR -> "infixr"
@@ -104,53 +89,45 @@ p_fixSig = \case
104 space
89 space
105 atom n
90 atom n
106 space
91 space
107− sitcc $ sep commaDel p_rdrName names
92+ sitcc $ sep (comma >> breakpoint) p_rdrName names
108− XFixitySig x -> noExtCon x
93+ XFixitySig NoExt -> notImplemented "XFixitySig"
109−
94+
110−p_inlineSig ::
95+p_inlineSig
111− -- | Name
112− Located RdrName ->
96+ :: Located RdrName -- ^ Name
113− -- | Inline pragma specification
97+ -> InlinePragma -- ^ Inline pragma specification
114− InlinePragma ->
115− R ()
98+ -> R ()
116p_inlineSig name InlinePragma {..} = pragmaBraces $ do
99p_inlineSig name InlinePragma {..} = pragmaBraces $ do
117 p_inlineSpec inl_inline
100 p_inlineSpec inl_inline
118− space
119 case inl_rule of
101 case inl_rule of
120− ConLike -> txt "CONLIKE"
102+ ConLike -> txt "CONLIKE "
121 FunLike -> return ()
103 FunLike -> return ()
122− space
123 p_activation inl_act
104 p_activation inl_act
124− space
105+ when (visibleActivation inl_act) space
125 p_rdrName name
106 p_rdrName name
126
107
127−p_specSig ::
108+p_specSig
128− -- | Name
129− Located RdrName ->
109+ :: Located RdrName -- ^ Name
130− -- | The types to specialize to
131− [LHsSigType GhcPs] ->
110+ -> [LHsSigType GhcPs] -- ^ The types to specialize to
132− -- | For specialize inline
111+ -> InlinePragma -- ^ For specialize inline
133− InlinePragma ->
134− R ()
112+ -> R ()
135p_specSig name ts InlinePragma {..} = pragmaBraces $ do
113p_specSig name ts InlinePragma {..} = pragmaBraces $ do
136 txt "SPECIALIZE"
114 txt "SPECIALIZE"
137 space
115 space
138 p_inlineSpec inl_inline
116 p_inlineSpec inl_inline
139− space
140 p_activation inl_act
117 p_activation inl_act
141− space
118+ when (visibleActivation inl_act) space
142 p_rdrName name
119 p_rdrName name
143− space
144− txt "::"
145 breakpoint
120 breakpoint
121+ inci $ do
122+ txt ":: "
146− inci $ sep commaDel (located' p_hsType . hsib_body) ts
123+ sep (comma >> breakpoint) (located' p_hsType . hsib_body) ts
147
124
148p_inlineSpec :: InlineSpec -> R ()
125p_inlineSpec :: InlineSpec -> R ()
149−p_inlineSpec = \case
126+p_inlineSpec = txt . \case
150− Inline -> txt "INLINE"
127+ Inline -> "INLINE "
151− Inlinable -> txt "INLINEABLE"
128+ Inlinable -> "INLINEABLE "
152− NoInline -> txt "NOINLINE"
129+ NoInline -> "NOINLINE "
153− NoUserInline -> return ()
130+ NoUserInline -> ""
154
131
155p_activation :: Activation -> R ()
132p_activation :: Activation -> R ()
156p_activation = \case
133p_activation = \case
@@ -165,54 +142,51 @@ p_activation = \case
165 atom n
142 atom n
166 txt "]"
143 txt "]"
167
144
145+visibleActivation :: Activation -> Bool
146+visibleActivation = \case
147+ NeverActive -> False
148+ AlwaysActive -> False
149+ _ -> True
150+
168p_specInstSig :: LHsSigType GhcPs -> R ()
151p_specInstSig :: LHsSigType GhcPs -> R ()
169−p_specInstSig hsib =
170− pragma "SPECIALIZE instance" . inci $
152+p_specInstSig hsib = pragma "SPECIALIZE instance" . inci $
171− located (hsib_body hsib) p_hsType
153+ located (hsib_body hsib) p_hsType
172−
154+
173−p_minimalSig ::
155+p_minimalSig
174− -- | Boolean formula
175− LBooleanFormula (Located RdrName) ->
156+ :: LBooleanFormula (Located RdrName) -- ^ Boolean formula
176− R ()
157+ -> R ()
177p_minimalSig =
158p_minimalSig =
178 located' $ \booleanFormula ->
159 located' $ \booleanFormula ->
179 pragma "MINIMAL" (inci $ p_booleanFormula booleanFormula)
160 pragma "MINIMAL" (inci $ p_booleanFormula booleanFormula)
180
161
181−p_booleanFormula ::
162+p_booleanFormula
182− -- | Boolean formula
163+ :: BooleanFormula (Located RdrName) -- ^ Boolean formula
183− BooleanFormula (Located RdrName) ->
184− R ()
164+ -> R ()
185p_booleanFormula = \case
165p_booleanFormula = \case
186 Var name -> p_rdrName name
166 Var name -> p_rdrName name
187− And xs ->
167+ And xs -> sitcc $ sep
188− sitcc $
168+ (comma >> breakpoint)
189− sep
190− commaDel
191− (located' p_booleanFormula)
169+ (located' p_booleanFormula)
192− xs
170+ xs
193− Or xs ->
194− sitcc $
171+ Or xs -> sitcc $ sep
195− sep
196− (breakpoint >> txt "|" >> space)
172+ (breakpoint >> txt "| ")
197− (located' p_booleanFormula)
173+ (located' p_booleanFormula)
198− xs
174+ xs
199− Parens l -> located l (parens N . p_booleanFormula)
175+ Parens l -> located l (parens . p_booleanFormula)
200−
176+
201−p_completeSig ::
177+p_completeSig
202− -- | Constructors\/patterns
178+ :: Located [Located RdrName] -- ^ Constructors\/patterns
203− Located [Located RdrName] ->
179+ -> Maybe (Located RdrName) -- ^ Type
204− -- | Type
205− Maybe (Located RdrName) ->
206− R ()
180+ -> R ()
207p_completeSig cs' mty =
181p_completeSig cs' mty =
208 located cs' $ \cs ->
182 located cs' $ \cs ->
209 pragma "COMPLETE" . inci $ do
183 pragma "COMPLETE" . inci $ do
210− sep commaDel p_rdrName cs
184+ sitcc $ sep (comma >> breakpoint) p_rdrName cs
211 forM_ mty $ \ty -> do
185 forM_ mty $ \ty -> do
212− space
213− txt "::"
214 breakpoint
186 breakpoint
187+ inci $ do
188+ txt ":: "
215− inci (p_rdrName ty)
189+ p_rdrName ty
216
190
217p_sccSig :: Located (IdP GhcPs) -> Maybe (Located StringLiteral) -> R ()
191p_sccSig :: Located (IdP GhcPs) -> Maybe (Located StringLiteral) -> R ()
218p_sccSig loc literal = pragma "SCC" . inci $ do
192p_sccSig loc literal = pragma "SCC" . inci $ do
@@ -220,17 +194,3 @@ p_sccSig loc literal = pragma "SCC" . inci $ do
220 forM_ literal $ \x -> do
194 forM_ literal $ \x -> do
221 breakpoint
195 breakpoint
222 atom x
196 atom x
223−
224−p_standaloneKindSig :: StandaloneKindSig GhcPs -> R ()
225−p_standaloneKindSig (StandaloneKindSig NoExtField name bndrs) = do
226− txt "type"
227− inci $ do
228− space
229− p_rdrName name
230− space
231− txt "::"
232− breakpoint
233− case bndrs of
234− HsIB NoExtField sig -> located sig p_hsType
235− XHsImplicitBndrs x -> noExtCon x
236−p_standaloneKindSig (XStandaloneKindSig c) = noExtCon c
src/Ormolu/Printer/Meat/Declaration/Splice.hs+4−3
@@ -1,15 +1,16 @@
1{-# LANGUAGE LambdaCase #-}
1{-# LANGUAGE LambdaCase #-}
2
2
3module Ormolu.Printer.Meat.Declaration.Splice
3module Ormolu.Printer.Meat.Declaration.Splice
4− ( p_spliceDecl,
4+ ( p_spliceDecl
5 )
5 )
6where
6where
7
7
8import GHC
8import GHC
9import Ormolu.Printer.Combinators
9import Ormolu.Printer.Combinators
10import Ormolu.Printer.Meat.Declaration.Value (p_hsSplice)
10import Ormolu.Printer.Meat.Declaration.Value (p_hsSplice)
11+import Ormolu.Utils
11
12
12p_spliceDecl :: SpliceDecl GhcPs -> R ()
13p_spliceDecl :: SpliceDecl GhcPs -> R ()
13p_spliceDecl = \case
14p_spliceDecl = \case
14− SpliceDecl NoExtField splice _explicit -> located splice p_hsSplice
15+ SpliceDecl NoExt splice _explicit -> located splice p_hsSplice
15− XSpliceDecl x -> noExtCon x
16+ XSpliceDecl {} -> notImplemented "XSpliceDecl"
src/Ormolu/Printer/Meat/Declaration/Type.hs+18−24
@@ -1,9 +1,10 @@
1{-# LANGUAGE OverloadedStrings #-}
1{-# LANGUAGE OverloadedStrings #-}
2−{-# LANGUAGE RecordWildCards #-}
2+{-# LANGUAGE RecordWildCards #-}
3
3
4-- | Rendering of type synonym declarations.
4-- | Rendering of type synonym declarations.
5+
5module Ormolu.Printer.Meat.Declaration.Type
6module Ormolu.Printer.Meat.Declaration.Type
6− ( p_synDecl,
7+ ( p_synDecl
7 )
8 )
8where
9where
9
10
@@ -11,30 +12,23 @@ import GHC
11import Ormolu.Printer.Combinators
12import Ormolu.Printer.Combinators
12import Ormolu.Printer.Meat.Common
13import Ormolu.Printer.Meat.Common
13import Ormolu.Printer.Meat.Type
14import Ormolu.Printer.Meat.Type
15+import RdrName (RdrName (..))
16+import SrcLoc (Located)
14
17
15−p_synDecl ::
18+p_synDecl
16− -- | Type constructor
17− Located RdrName ->
19+ :: Located RdrName -- ^ Type constructor
18− -- | Fixity
19− LexicalFixity ->
20+ -> LexicalFixity -- ^ Fixity
20− -- | Type variables
21− LHsQTyVars GhcPs ->
21+ -> LHsQTyVars GhcPs -- ^ Type variables
22− -- | RHS of type declaration
22+ -> LHsType GhcPs -- ^ RHS of type declaration
23− LHsType GhcPs ->
24− R ()
23+ -> R ()
25−p_synDecl name fixity HsQTvs {..} t = do
24+p_synDecl name fixity tvars t = do
26− txt "type"
25+ txt "type "
27− space
26+ let HsQTvs {..} = tvars
28− switchLayout (getLoc name : map getLoc hsq_explicit) $
27+ switchLayout (getLoc name : map getLoc hsq_explicit) $ do
29 p_infixDefHelper
28 p_infixDefHelper
30 (case fixity of Infix -> True; _ -> False)
29 (case fixity of Infix -> True; _ -> False)
31− True
30+ inci
32 (p_rdrName name)
31 (p_rdrName name)
33 (map (located' p_hsTyVarBndr) hsq_explicit)
32 (map (located' p_hsTyVarBndr) hsq_explicit)
34− space
35− equals
36− if hasDocStrings (unLoc t)
37− then newline
38− else breakpoint
33+ breakpoint
39− inci (located t p_hsType)
34+ inci (txt "= " >> located t p_hsType)
40−p_synDecl _ _ (XLHsQTyVars x) _ = noExtCon x
src/Ormolu/Printer/Meat/Declaration/TypeFamily.hs+45−58
@@ -1,24 +1,27 @@
1−{-# LANGUAGE LambdaCase #-}
1+{-# LANGUAGE LambdaCase #-}
2{-# LANGUAGE OverloadedStrings #-}
2{-# LANGUAGE OverloadedStrings #-}
3−{-# LANGUAGE RecordWildCards #-}
3+{-# LANGUAGE RecordWildCards #-}
4
4
5-- | Rendering of data\/type families.
5-- | Rendering of data\/type families.
6+
6module Ormolu.Printer.Meat.Declaration.TypeFamily
7module Ormolu.Printer.Meat.Declaration.TypeFamily
7− ( p_famDecl,
8+ ( p_famDecl
8− p_tyFamInstEqn,
9+ , p_tyFamInstEqn
9 )
10 )
10where
11where
11
12
13+import BasicTypes (LexicalFixity (..))
12import Control.Monad
14import Control.Monad
13−import Data.Maybe (isNothing)
15+import Data.Maybe (isNothing, isJust)
14import GHC
16import GHC
15import Ormolu.Printer.Combinators
17import Ormolu.Printer.Combinators
16import Ormolu.Printer.Meat.Common
18import Ormolu.Printer.Meat.Common
17import Ormolu.Printer.Meat.Type
19import Ormolu.Printer.Meat.Type
18import Ormolu.Utils
20import Ormolu.Utils
21+import SrcLoc (Located, GenLocated (..))
19
22
20p_famDecl :: FamilyStyle -> FamilyDecl GhcPs -> R ()
23p_famDecl :: FamilyStyle -> FamilyDecl GhcPs -> R ()
21−p_famDecl style FamilyDecl {fdTyVars = HsQTvs {..}, ..} = do
24+p_famDecl style FamilyDecl {..} = do
22 mmeqs <- case fdInfo of
25 mmeqs <- case fdInfo of
23 DataFamily -> Nothing <$ txt "data"
26 DataFamily -> Nothing <$ txt "data"
24 OpenTypeFamily -> Nothing <$ txt "type"
27 OpenTypeFamily -> Nothing <$ txt "type"
@@ -26,86 +29,70 @@ p_famDecl style FamilyDecl {fdTyVars = HsQTvs {..}, ..} = do
26 txt $ case style of
29 txt $ case style of
27 Associated -> mempty
30 Associated -> mempty
28 Free -> " family"
31 Free -> " family"
32+ let HsQTvs {..} = fdTyVars
29 breakpoint
33 breakpoint
30 inci $ do
34 inci $ do
31− switchLayout (getLoc fdLName : (getLoc <$> hsq_explicit)) $
35+ switchLayout (getLoc fdLName : (getLoc <$> hsq_explicit)) $ do
32 p_infixDefHelper
36 p_infixDefHelper
33 (isInfix fdFixity)
37 (isInfix fdFixity)
34− True
38+ inci
35 (p_rdrName fdLName)
39 (p_rdrName fdLName)
36 (located' p_hsTyVarBndr <$> hsq_explicit)
40 (located' p_hsTyVarBndr <$> hsq_explicit)
37− let resultSig = p_familyResultSigL fdResultSig
41+ let rsig = p_familyResultSigL (isJust fdInjectivityAnn) fdResultSig
38− unless (isNothing resultSig && isNothing fdInjectivityAnn) space
42+ unless (isNothing rsig && isNothing fdInjectivityAnn) $
43+ breakpoint
39 inci $ do
44 inci $ do
40− sequence_ resultSig
45+ sequence_ rsig
41− space
46+ when (isJust rsig && isJust fdInjectivityAnn) breakpoint
42 forM_ fdInjectivityAnn (located' p_injectivityAnn)
47 forM_ fdInjectivityAnn (located' p_injectivityAnn)
43 case mmeqs of
48 case mmeqs of
44 Nothing -> return ()
49 Nothing -> return ()
45 Just meqs -> do
50 Just meqs -> do
46− inci $ do
47− breakpoint
48− txt "where"
51+ txt " where"
49 case meqs of
52 case meqs of
50− Nothing -> do
53+ Nothing -> txt " .."
51− space
52− txt ".."
53 Just eqs -> do
54 Just eqs -> do
54 newline
55 newline
55 sep newline (located' (inci . p_tyFamInstEqn)) eqs
56 sep newline (located' (inci . p_tyFamInstEqn)) eqs
56−p_famDecl _ FamilyDecl {fdTyVars = XLHsQTyVars {}} =
57+p_famDecl _ (XFamilyDecl NoExt) = notImplemented "XFamilyDecl"
57− notImplemented "XLHsQTyVars"
58−p_famDecl _ (XFamilyDecl x) = noExtCon x
59
58
60−p_familyResultSigL ::
59+p_familyResultSigL
60+ :: Bool
61− Located (FamilyResultSig GhcPs) ->
61+ -> Located (FamilyResultSig GhcPs)
62− Maybe (R ())
62+ -> Maybe (R ())
63−p_familyResultSigL l =
63+p_familyResultSigL injAnn l =
64 case l of
64 case l of
65 L _ a -> case a of
65 L _ a -> case a of
66− NoSig NoExtField -> Nothing
66+ NoSig NoExt -> Nothing
67− KindSig NoExtField k -> Just $ do
67+ KindSig NoExt k -> Just $ do
68− txt "::"
68+ if injAnn then txt "= " else txt ":: "
69− breakpoint
70 located k p_hsType
69 located k p_hsType
71− TyVarSig NoExtField bndr -> Just $ do
70+ TyVarSig NoExt bndr -> Just $ do
72− equals
71+ if injAnn then txt "= " else txt ":: "
73− breakpoint
74 located bndr p_hsTyVarBndr
72 located bndr p_hsTyVarBndr
75− XFamilyResultSig x ->
73+ XFamilyResultSig NoExt ->
76− noExtCon x
74+ notImplemented "XFamilyResultSig"
77
75
78p_injectivityAnn :: InjectivityAnn GhcPs -> R ()
76p_injectivityAnn :: InjectivityAnn GhcPs -> R ()
79p_injectivityAnn (InjectivityAnn a bs) = do
77p_injectivityAnn (InjectivityAnn a bs) = do
80− txt "|"
78+ txt "| "
81− space
82 p_rdrName a
79 p_rdrName a
83 space
80 space
84− txt "->"
81+ txt "-> "
85− space
86 sep space p_rdrName bs
82 sep space p_rdrName bs
87
83
88p_tyFamInstEqn :: TyFamInstEqn GhcPs -> R ()
84p_tyFamInstEqn :: TyFamInstEqn GhcPs -> R ()
89−p_tyFamInstEqn HsIB {hsib_body = FamEqn {..}} = do
85+p_tyFamInstEqn HsIB {..} = do
90− case feqn_bndrs of
86+ let FamEqn {..} = hsib_body
91− Nothing -> return ()
92− Just bndrs -> do
93− p_forallBndrs ForallInvis p_hsTyVarBndr bndrs
94− breakpoint
95− inciIf (not $ null feqn_bndrs) $ do
96− let famLhsSpn = getLoc feqn_tycon : fmap (getLoc . typeArgToType) feqn_pats
97− switchLayout famLhsSpn $
98− p_infixDefHelper
87+ switchLayout (getLoc feqn_tycon : (getLoc <$> feqn_pats)) $ p_infixDefHelper
99− (isInfix feqn_fixity)
88+ (isInfix feqn_fixity)
100− True
89+ inci
101− (p_rdrName feqn_tycon)
90+ (p_rdrName feqn_tycon)
102− (located' p_hsType . typeArgToType <$> feqn_pats)
91+ (located' p_hsType <$> feqn_pats)
103− space
92+ txt " ="
104− equals
105− breakpoint
93+ breakpoint
106− inci (located feqn_rhs p_hsType)
94+ inci (located feqn_rhs p_hsType)
107−p_tyFamInstEqn HsIB {hsib_body = XFamEqn x} = noExtCon x
95+p_tyFamInstEqn (XHsImplicitBndrs NoExt) = notImplemented "XHsImplicitBndrs"
108−p_tyFamInstEqn (XHsImplicitBndrs x) = noExtCon x
109
96
110----------------------------------------------------------------------------
97----------------------------------------------------------------------------
111-- Helpers
98-- Helpers
src/Ormolu/Printer/Meat/Declaration/Value.hs+536−899
@@ -1,43 +1,36 @@
1−{-# LANGUAGE LambdaCase #-}
1+{-# LANGUAGE LambdaCase #-}
2−{-# LANGUAGE MultiWayIf #-}
3{-# LANGUAGE OverloadedStrings #-}
2{-# LANGUAGE OverloadedStrings #-}
4−{-# LANGUAGE RecordWildCards #-}
3+{-# LANGUAGE RecordWildCards #-}
5−{-# LANGUAGE TypeApplications #-}
6
4
7module Ormolu.Printer.Meat.Declaration.Value
5module Ormolu.Printer.Meat.Declaration.Value
8− ( p_valDecl,
6+ ( p_valDecl
9− p_pat,
7+ , p_pat
10− p_hsExpr,
8+ , p_hsExpr
11− p_hsSplice,
9+ , p_hsSplice
12− p_stringLit,
13 )
10 )
14where
11where
15
12
16import Bag (bagToList)
13import Bag (bagToList)
17import BasicTypes
14import BasicTypes
18import Control.Monad
15import Control.Monad
19−import Ctype (is_space)
20import Data.Bool (bool)
16import Data.Bool (bool)
21import Data.Char (isPunctuation, isSymbol)
17import Data.Char (isPunctuation, isSymbol)
22import Data.Data hiding (Infix, Prefix)
18import Data.Data hiding (Infix, Prefix)
23−import Data.Functor ((<&>))
24import Data.List (intersperse, sortOn)
19import Data.List (intersperse, sortOn)
25−import Data.List.NonEmpty (NonEmpty (..), (<|))
20+import Data.List.NonEmpty (NonEmpty ((:|)))
26−import qualified Data.List.NonEmpty as NE
27import Data.Text (Text)
21import Data.Text (Text)
28−import qualified Data.Text as Text
29import GHC
22import GHC
30−import OccName (occNameString)
31import Ormolu.Printer.Combinators
23import Ormolu.Printer.Combinators
32−import Ormolu.Printer.Internal
33import Ormolu.Printer.Meat.Common
24import Ormolu.Printer.Meat.Common
34−import {-# SOURCE #-} Ormolu.Printer.Meat.Declaration
35import Ormolu.Printer.Meat.Declaration.Signature
25import Ormolu.Printer.Meat.Declaration.Signature
36import Ormolu.Printer.Meat.Type
26import Ormolu.Printer.Meat.Type
37−import Ormolu.Printer.Operators
38import Ormolu.Utils
27import Ormolu.Utils
28+import Outputable (Outputable (..))
29+import RdrName (rdrNameOcc)
30+import SrcLoc (combineSrcSpans, isOneLineSpan)
31+import qualified Data.List.NonEmpty as NE
32+import {-# SOURCE #-} Ormolu.Printer.Meat.Declaration
39
33
40−-- | Style of a group of equations.
41data MatchGroupStyle
34data MatchGroupStyle
42 = Function (Located RdrName)
35 = Function (Located RdrName)
43 | PatternBind
36 | PatternBind
@@ -45,62 +38,55 @@ data MatchGroupStyle
45 | Lambda
38 | Lambda
46 | LambdaCase
39 | LambdaCase
47
40
48−-- | Style of equations in a group.
49data GroupStyle
41data GroupStyle
50 = EqualSign
42 = EqualSign
51 | RightArrow
43 | RightArrow
52
44
53-- | Expression placement. This marks the places where expressions that
45-- | Expression placement. This marks the places where expressions that
54-- implement handing forms may use them.
46-- implement handing forms may use them.
47+
55data Placement
48data Placement
56− = -- | Multi-line layout should cause
49+ = Normal -- ^ Multi-line layout should cause
57− -- insertion of a newline and indentation
50+ -- insertion of a newline and indentation
58− -- bump
51+ -- bump
59− Normal
60− | -- | Expressions that have hanging form
52+ | Hanging -- ^ Expressions that have hanging form
61− -- should use it and avoid bumping one level
53+ -- should use it and avoid bumping one level
62− -- of indentation
54+ -- of indentation
63− Hanging
64− deriving (Eq, Show)
65
55
66p_valDecl :: HsBindLR GhcPs GhcPs -> R ()
56p_valDecl :: HsBindLR GhcPs GhcPs -> R ()
67p_valDecl = \case
57p_valDecl = \case
68− FunBind NoExtField funId funMatches _ _ -> p_funBind funId funMatches
58+ FunBind NoExt funId funMatches _ _ -> p_funBind funId funMatches
69− PatBind NoExtField pat grhss _ -> p_match PatternBind False NoSrcStrict [pat] grhss
59+ PatBind NoExt pat grhss _ -> p_match PatternBind False NoSrcStrict [pat] grhss
70 VarBind {} -> notImplemented "VarBinds" -- introduced by the type checker
60 VarBind {} -> notImplemented "VarBinds" -- introduced by the type checker
71 AbsBinds {} -> notImplemented "AbsBinds" -- introduced by the type checker
61 AbsBinds {} -> notImplemented "AbsBinds" -- introduced by the type checker
72− PatSynBind NoExtField psb -> p_patSynBind psb
62+ PatSynBind NoExt psb -> p_patSynBind psb
73− XHsBindsLR x -> noExtCon x
63+ XHsBindsLR NoExt -> notImplemented "XHsBindsLR"
74
64
75−p_funBind ::
65+p_funBind
76− Located RdrName ->
66+ :: Located RdrName
77− MatchGroup GhcPs (LHsExpr GhcPs) ->
67+ -> MatchGroup GhcPs (LHsExpr GhcPs)
78− R ()
68+ -> R ()
79p_funBind name = p_matchGroup (Function name)
69p_funBind name = p_matchGroup (Function name)
80
70
81−p_matchGroup ::
71+p_matchGroup
82− MatchGroupStyle ->
72+ :: MatchGroupStyle
83− MatchGroup GhcPs (LHsExpr GhcPs) ->
73+ -> MatchGroup GhcPs (LHsExpr GhcPs)
84− R ()
74+ -> R ()
85p_matchGroup = p_matchGroup' exprPlacement p_hsExpr
75p_matchGroup = p_matchGroup' exprPlacement p_hsExpr
86
76
87−p_matchGroup' ::
77+p_matchGroup'
88− Data body =>
78+ :: Data body
89− -- | How to get body placement
90− (body -> Placement) ->
79+ => (body -> Placement)
91− -- | How to print body
92− (body -> R ()) ->
80+ -> (body -> R ())
93− -- | Style of this group of equations
94− MatchGroupStyle ->
81+ -> MatchGroupStyle
95− -- | Match group
96− MatchGroup GhcPs (Located body) ->
82+ -> MatchGroup GhcPs (Located body)
97− R ()
83+ -> R ()
98−p_matchGroup' placer render style MG {..} = do
84+p_matchGroup' placer pretty style MG {..} = do
99 let ob = case style of
85 let ob = case style of
100 Case -> id
86 Case -> id
101 LambdaCase -> id
87 LambdaCase -> id
102 _ -> dontUseBraces
88 _ -> dontUseBraces
103− -- Since we are forcing braces on 'sepSemi' based on 'ob', we have to
89+ -- NOTE since we are forcing braces on 'sepSemi' based on 'ob', we have to
104 -- restore the brace state inside the sepsemi.
90 -- restore the brace state inside the sepsemi.
105 ub <- bool dontUseBraces useBraces <$> canUseBraces
91 ub <- bool dontUseBraces useBraces <$> canUseBraces
106 ob $ sepSemi (located' (ub . p_Match)) (unLoc mg_alts)
92 ob $ sepSemi (located' (ub . p_Match)) (unLoc mg_alts)
@@ -108,14 +94,14 @@ p_matchGroup' placer render style MG {..} = do
108 p_Match m@Match {..} =
94 p_Match m@Match {..} =
109 p_match'
95 p_match'
110 placer
96 placer
111− render
97+ pretty
112 (adjustMatchGroupStyle m style)
98 (adjustMatchGroupStyle m style)
113 (isInfixMatch m)
99 (isInfixMatch m)
114 (matchStrictness m)
100 (matchStrictness m)
115 m_pats
101 m_pats
116 m_grhss
102 m_grhss
117− p_Match (XMatch x) = noExtCon x
103+ p_Match _ = notImplemented "XMatch"
118−p_matchGroup' _ _ _ (XMatchGroup x) = noExtCon x
104+p_matchGroup' _ _ _ (XMatchGroup NoExt) = notImplemented "XMatchGroup"
119
105
120-- | Function id obtained through pattern matching on 'FunBind' should not
106-- | Function id obtained through pattern matching on 'FunBind' should not
121-- be used to print the actual equations because the different ‘RdrNames’
107-- be used to print the actual equations because the different ‘RdrNames’
@@ -123,10 +109,11 @@ p_matchGroup' _ _ _ (XMatchGroup x) = noExtCon x
123-- and paretheses) associated with them. It is necessary to use per-equation
109-- and paretheses) associated with them. It is necessary to use per-equation
124-- names obtained from 'm_ctxt' of 'Match'. This function replaces function
110-- names obtained from 'm_ctxt' of 'Match'. This function replaces function
125-- name inside of 'Function' accordingly.
111-- name inside of 'Function' accordingly.
112+
126−adjustMatchGroupStyle ::
113+adjustMatchGroupStyle
127− Match GhcPs body ->
114+ :: Match GhcPs body
128− MatchGroupStyle ->
115+ -> MatchGroupStyle
129− MatchGroupStyle
116+ -> MatchGroupStyle
130adjustMatchGroupStyle m = \case
117adjustMatchGroupStyle m = \case
131 Function _ -> (Function . mc_fun . m_ctxt) m
118 Function _ -> (Function . mc_fun . m_ctxt) m
132 style -> style
119 style -> style
@@ -134,43 +121,31 @@ adjustMatchGroupStyle m = \case
134matchStrictness :: Match id body -> SrcStrictness
121matchStrictness :: Match id body -> SrcStrictness
135matchStrictness match =
122matchStrictness match =
136 case m_ctxt match of
123 case m_ctxt match of
137− FunRhs {mc_strictness = s} -> s
124+ FunRhs{mc_strictness=s} -> s
138 _ -> NoSrcStrict
125 _ -> NoSrcStrict
139
126
140−p_match ::
127+p_match
141− -- | Style of the group
142− MatchGroupStyle ->
128+ :: MatchGroupStyle
143− -- | Is this an infix match?
129+ -> Bool -- ^ Is this an infix match?
144− Bool ->
145− -- | Strictness prefix (FunBind)
130+ -> SrcStrictness -- ^ Strictness prefix (FunBind)
146− SrcStrictness ->
147− -- | Argument patterns
148− [LPat GhcPs] ->
131+ -> [LPat GhcPs]
149− -- | Equations
150− GRHSs GhcPs (LHsExpr GhcPs) ->
132+ -> GRHSs GhcPs (LHsExpr GhcPs)
151− R ()
133+ -> R ()
152p_match = p_match' exprPlacement p_hsExpr
134p_match = p_match' exprPlacement p_hsExpr
153
135
154−p_match' ::
136+p_match'
155− Data body =>
137+ :: Data body
156− -- | How to get body placement
157− (body -> Placement) ->
138+ => (body -> Placement)
158− -- | How to print body
159− (body -> R ()) ->
139+ -> (body -> R ())
160− -- | Style of this group of equations
161− MatchGroupStyle ->
140+ -> MatchGroupStyle
162− -- | Is this an infix match?
141+ -> Bool -- ^ Is this an infix match?
163− Bool ->
164− -- | Strictness prefix (FunBind)
142+ -> SrcStrictness -- ^ Strictness prefix (FunBind)
165− SrcStrictness ->
166− -- | Argument patterns
167− [LPat GhcPs] ->
143+ -> [LPat GhcPs]
168− -- | Equations
169− GRHSs GhcPs (Located body) ->
144+ -> GRHSs GhcPs (Located body)
170− R ()
145+ -> R ()
171−p_match' placer render style isInfix strictness m_pats GRHSs {..} = do
146+p_match' placer pretty style isInfix strictness m_pats m_grhss = do
172− -- Normally, since patterns may be placed in a multi-line layout, it is
147+ -- NOTE Normally, since patterns may be placed in a multi-line layout, it
173− -- necessary to bump indentation for the pattern group so it's more
148+ -- is necessary to bump indentation for the pattern group so it's more
174 -- indented than function name. This in turn means that indentation for
149 -- indented than function name. This in turn means that indentation for
175 -- the body should also be bumped. Normally this would mean that bodies
150 -- the body should also be bumped. Normally this would mean that bodies
176 -- would start with two indentation steps applied, which is ugly, so we
151 -- would start with two indentation steps applied, which is ugly, so we
@@ -180,24 +155,23 @@ p_match' placer render style isInfix strictness m_pats GRHSs {..} = do
180 NoSrcStrict -> return ()
155 NoSrcStrict -> return ()
181 SrcStrict -> txt "!"
156 SrcStrict -> txt "!"
182 SrcLazy -> txt "~"
157 SrcLazy -> txt "~"
183− indentBody <- case NE.nonEmpty m_pats of
158+ inci' <- case NE.nonEmpty m_pats of
184− Nothing ->
185− False <$ case style of
159+ Nothing -> id <$ case style of
186− Function name -> p_rdrName name
160+ Function name -> p_rdrName name
187− _ -> return ()
161+ _ -> return ()
188 Just ne_pats -> do
162 Just ne_pats -> do
189− let combinedSpans = case style of
163+ let combinedSpans = combineSrcSpans' $
190− Function name -> combineSrcSpans (getLoc name) patSpans
191− _ -> patSpans
192− patSpans = combineSrcSpans' (getLoc <$> ne_pats)
164+ getLoc <$> ne_pats
193− indentBody = not (isOneLineSpan combinedSpans)
165+ inci' = if isOneLineSpan combinedSpans
166+ then id
167+ else inci
194 switchLayout [combinedSpans] $ do
168 switchLayout [combinedSpans] $ do
195 let stdCase = sep breakpoint (located' p_pat) m_pats
169 let stdCase = sep breakpoint (located' p_pat) m_pats
196 case style of
170 case style of
197 Function name ->
171 Function name ->
198 p_infixDefHelper
172 p_infixDefHelper
199 isInfix
173 isInfix
200− indentBody
174+ inci'
201 (p_rdrName name)
175 (p_rdrName name)
202 (located' p_pat <$> m_pats)
176 (located' p_pat <$> m_pats)
203 PatternBind -> stdCase
177 PatternBind -> stdCase
@@ -208,44 +182,49 @@ p_match' placer render style isInfix strictness m_pats GRHSs {..} = do
208 BangPat _ _ -> True
182 BangPat _ _ -> True
209 SplicePat _ _ -> True
183 SplicePat _ _ -> True
210 _ -> False
184 _ -> False
211− txt "\\"
212− when needsSpace space
185+ txt (if needsSpace then "\\ " else "\\")
213 sitcc stdCase
186 sitcc stdCase
214 LambdaCase -> stdCase
187 LambdaCase -> stdCase
215− return indentBody
188+ return inci'
189+ let
216− let -- Calculate position of end of patterns. This is useful when we decide
190+ -- Calculate position of end of patterns. This is useful when we decide
217− -- about putting certain constructions in hanging positions.
191+ -- about putting certain constructions in hanging positions.
218− endOfPats = case NE.nonEmpty m_pats of
192+ endOfPats = case NE.nonEmpty m_pats of
219− Nothing -> case style of
193+ Nothing -> case style of
220− Function name -> Just (getLoc name)
194+ Function name -> (Just . srcSpanEnd . getLoc) name
221− _ -> Nothing
195+ _ -> Nothing
222− Just pats -> (Just . getLoc . NE.last) pats
196+ Just pats -> (Just . srcSpanEnd . getLoc . NE.last) pats
223− isCase = \case
197+ isCase = \case
224− Case -> True
198+ Case -> True
225− LambdaCase -> True
199+ LambdaCase -> True
226− _ -> False
200+ _ -> False
201+ let GRHSs {..} = m_grhss
227 hasGuards = withGuards grhssGRHSs
202 hasGuards = withGuards grhssGRHSs
228− grhssSpan =
203+ unless (length grhssGRHSs > 1) $ do
204+ case style of
205+ Function _ | hasGuards -> return ()
206+ Function _ -> txt " ="
207+ PatternBind -> txt " ="
208+ s | isCase s && hasGuards -> return ()
209+ _ -> txt " ->"
229− combineSrcSpans' $
210+ let grhssSpan = combineSrcSpans' $
230− getGRHSSpan . unLoc <$> NE.fromList grhssGRHSs
211+ getGRHSSpan . unLoc <$> NE.fromList grhssGRHSs
231− patGrhssSpan =
212+ patGrhssSpan = maybe grhssSpan
232− maybe
233− grhssSpan
234− (combineSrcSpans grhssSpan . srcLocSpan . srcSpanEnd)
213+ (combineSrcSpans grhssSpan . srcLocSpan) endOfPats
235− endOfPats
236 placement =
214 placement =
237 case endOfPats of
215 case endOfPats of
238 Nothing -> blockPlacement placer grhssGRHSs
216 Nothing -> blockPlacement placer grhssGRHSs
239 Just spn ->
217 Just spn ->
218+ if isOneLineSpan
240− if onTheSameLine spn grhssSpan
219+ (mkSrcSpan spn (srcSpanStart grhssSpan))
241 then blockPlacement placer grhssGRHSs
220 then blockPlacement placer grhssGRHSs
242 else Normal
221 else Normal
243 p_body = do
222 p_body = do
244 let groupStyle =
223 let groupStyle =
245 if isCase style && hasGuards
224 if isCase style && hasGuards
246− then RightArrow
225+ then RightArrow
247− else EqualSign
226+ else EqualSign
248− sep newline (located' (p_grhs' placer render groupStyle)) grhssGRHSs
227+ sep newline (located' (p_grhs' pretty groupStyle)) grhssGRHSs
249 p_where = do
228 p_where = do
250 let whereIsEmpty = GHC.isEmptyLocalBindsPR (unLoc grhssLocalBinds)
229 let whereIsEmpty = GHC.isEmptyLocalBindsPR (unLoc grhssLocalBinds)
251 unless (GHC.eqEmptyLocalBinds (unLoc grhssLocalBinds)) $ do
230 unless (GHC.eqEmptyLocalBinds (unLoc grhssLocalBinds)) $ do
@@ -253,211 +232,166 @@ p_match' placer render style isInfix strictness m_pats GRHSs {..} = do
253 txt "where"
232 txt "where"
254 unless whereIsEmpty breakpoint
233 unless whereIsEmpty breakpoint
255 inci $ located grhssLocalBinds p_hsLocalBinds
234 inci $ located grhssLocalBinds p_hsLocalBinds
256− inciIf indentBody $ do
235+ inci' $ do
257− unless (length grhssGRHSs > 1) $
258− case style of
259− Function _ | hasGuards -> return ()
260− Function _ -> space >> inci equals
261− PatternBind -> space >> inci equals
262− s | isCase s && hasGuards -> return ()
263− _ -> space >> txt "->"
264 switchLayout [patGrhssSpan] $
236 switchLayout [patGrhssSpan] $
265 placeHanging placement p_body
237 placeHanging placement p_body
266 inci p_where
238 inci p_where
267−p_match' _ _ _ _ _ _ (XGRHSs x) = noExtCon x
268
239
269p_grhs :: GroupStyle -> GRHS GhcPs (LHsExpr GhcPs) -> R ()
240p_grhs :: GroupStyle -> GRHS GhcPs (LHsExpr GhcPs) -> R ()
270−p_grhs = p_grhs' exprPlacement p_hsExpr
241+p_grhs = p_grhs' p_hsExpr
271−
242+
272−p_grhs' ::
243+p_grhs'
273− Data body =>
244+ :: Data body
274− -- | How to get body placement
275− (body -> Placement) ->
276− -- | How to print body
277− (body -> R ()) ->
245+ => (body -> R ())
278− GroupStyle ->
246+ -> GroupStyle
279− GRHS GhcPs (Located body) ->
247+ -> GRHS GhcPs (Located body)
280− R ()
248+ -> R ()
281−p_grhs' placer render style (GRHS NoExtField guards body) =
249+p_grhs' pretty style (GRHS NoExt guards body) =
282 case guards of
250 case guards of
283 [] -> p_body
251 [] -> p_body
284 xs -> do
252 xs -> do
285− txt "|"
253+ txt "| "
286− space
287− sitcc (sep commaDel (sitcc . located' p_stmt) xs)
254+ sitcc (sep (comma >> breakpoint) (sitcc . located' p_stmt) xs)
288 space
255 space
289− inci $ case style of
256+ txt $ case style of
290− EqualSign -> equals
257+ EqualSign -> "="
291− RightArrow -> txt "->"
258+ RightArrow -> "->"
292− placeHanging placement p_body
259+ breakpoint
260+ inci p_body
293 where
261 where
294− placement =
295− case endOfGuards of
296− Nothing -> placer (unLoc body)
297− Just spn ->
298− if onTheSameLine spn (getLoc body)
299− then placer (unLoc body)
300− else Normal
301− endOfGuards =
302− case NE.nonEmpty guards of
303− Nothing -> Nothing
304− Just gs -> (Just . getLoc . NE.last) gs
305− p_body = located body render
262+ p_body = located body pretty
306−p_grhs' _ _ _ (XGRHS x) = noExtCon x
263+p_grhs' _ _ (XGRHS NoExt) = notImplemented "XGRHS"
307
264
308p_hsCmd :: HsCmd GhcPs -> R ()
265p_hsCmd :: HsCmd GhcPs -> R ()
309p_hsCmd = \case
266p_hsCmd = \case
310− HsCmdArrApp NoExtField body input arrType _ -> do
267+ HsCmdArrApp NoExt body input arrType _ -> do
311 located body p_hsExpr
268 located body p_hsExpr
312− breakpoint
313− inci $ do
314− case arrType of
269+ txt $ case arrType of
315− HsFirstOrderApp -> txt "-<"
270+ HsFirstOrderApp -> " -<"
316− HsHigherOrderApp -> txt "-<<"
271+ HsHigherOrderApp -> " -<<"
317− placeHanging (exprPlacement (unLoc input)) $
272+ placeHanging (exprPlacement (unLoc input)) $
318− located input p_hsExpr
273+ located input p_hsExpr
319− HsCmdArrForm NoExtField form Prefix _ cmds -> banana $ do
274+ HsCmdArrForm NoExt form Prefix _ cmds -> banana $ sitcc $ do
320 located form p_hsExpr
275 located form p_hsExpr
321 unless (null cmds) $ do
276 unless (null cmds) $ do
322 breakpoint
277 breakpoint
323 inci (sequence_ (intersperse breakpoint (located' p_hsCmdTop <$> cmds)))
278 inci (sequence_ (intersperse breakpoint (located' p_hsCmdTop <$> cmds)))
324− HsCmdArrForm NoExtField form Infix _ [left, right] -> do
279+ HsCmdArrForm NoExt form Infix _ [left, right] -> do
325 located left p_hsCmdTop
280 located left p_hsCmdTop
326 space
281 space
327 located form p_hsExpr
282 located form p_hsExpr
328 placeHanging (cmdTopPlacement (unLoc right)) $
283 placeHanging (cmdTopPlacement (unLoc right)) $
329 located right p_hsCmdTop
284 located right p_hsCmdTop
330− HsCmdArrForm NoExtField _ Infix _ _ -> notImplemented "HsCmdArrForm"
285+ HsCmdArrForm NoExt _ Infix _ _ -> notImplemented "HsCmdArrForm"
331 HsCmdApp {} ->
286 HsCmdApp {} ->
332 -- XXX Does this ever occur in the syntax tree? It does not seem like it
287 -- XXX Does this ever occur in the syntax tree? It does not seem like it
333 -- does. Open an issue and ping @yumiova if this ever occurs in output.
288 -- does. Open an issue and ping @yumiova if this ever occurs in output.
334 notImplemented "HsCmdApp"
289 notImplemented "HsCmdApp"
335− HsCmdLam NoExtField mgroup -> p_matchGroup' cmdPlacement p_hsCmd Lambda mgroup
290+ HsCmdLam NoExt mgroup -> p_matchGroup' cmdPlacement p_hsCmd Lambda mgroup
336− HsCmdPar NoExtField c -> parens N (located c p_hsCmd)
291+ HsCmdPar NoExt c -> parens (located c p_hsCmd)
337− HsCmdCase NoExtField e mgroup ->
292+ HsCmdCase NoExt e mgroup -> do
293+ txt "case "
294+ located e p_hsExpr
295+ txt " of"
296+ breakpoint
338− p_case cmdPlacement p_hsCmd e mgroup
297+ inci (p_matchGroup' cmdPlacement p_hsCmd Case mgroup)
339− HsCmdIf NoExtField _ if' then' else' ->
298+ HsCmdIf NoExt _ if' then' else' -> do
340− p_if cmdPlacement p_hsCmd if' then' else'
299+ txt "if "
300+ located if' p_hsExpr
301+ breakpoint
302+ txt "then"
303+ located then' $ \x -> do
304+ breakpoint
305+ inci (p_hsCmd x)
306+ breakpoint
307+ txt "else"
308+ located else' $ \x -> do
309+ breakpoint
310+ inci (p_hsCmd x)
341− HsCmdLet NoExtField localBinds c ->
311+ HsCmdLet NoExt localBinds c -> do
342− p_let p_hsCmd localBinds c
312+ txt "let "
313+ sitcc (located localBinds p_hsLocalBinds)
314+ breakpoint
315+ txt "in "
316+ sitcc (located c p_hsCmd)
343− HsCmdDo NoExtField es -> do
317+ HsCmdDo NoExt es -> do
344 txt "do"
318 txt "do"
345 newline
319 newline
346− inci . located es $
347− sitcc . sep newline (sitcc . withSpacing (p_stmt' cmdPlacement p_hsCmd))
320+ inci (located es (sitcc . sep newline (located' (sitcc . p_stmt' p_hsCmd))))
348 HsCmdWrap {} -> notImplemented "HsCmdWrap"
321 HsCmdWrap {} -> notImplemented "HsCmdWrap"
349− XCmd x -> noExtCon x
322+ XCmd {} -> notImplemented "XCmd"
350
323
351p_hsCmdTop :: HsCmdTop GhcPs -> R ()
324p_hsCmdTop :: HsCmdTop GhcPs -> R ()
352p_hsCmdTop = \case
325p_hsCmdTop = \case
353− HsCmdTop NoExtField cmd -> located cmd p_hsCmd
326+ HsCmdTop NoExt cmd -> located cmd p_hsCmd
354− XCmdTop x -> noExtCon x
327+ XCmdTop {} -> notImplemented "XHsCmdTop"
355−
356−-- | Render an expression preserving blank lines between such consecutive
357−-- expressions found in the original source code.
358−withSpacing ::
359− -- | Rendering function
360− (a -> R ()) ->
361− -- | Entity to render
362− Located a ->
363− R ()
364−withSpacing f l = located l $ \x -> do
365− case getLoc l of
366− UnhelpfulSpan _ -> f x
367− RealSrcSpan currentSpn -> do
368− getSpanMark >>= \case
369− -- Spacing before comments will be handled by the code
370− -- that prints comments, so we just have to deal with
371− -- blank lines between statements here.
372− Just (StatementSpan lastSpn) ->
373− if srcSpanStartLine currentSpn > srcSpanEndLine lastSpn + 1
374− then newline
375− else return ()
376− _ -> return ()
377− f x
378− -- In some cases the (f x) expression may insert a new mark. We want
379− -- to be careful not to override comment marks.
380− getSpanMark >>= \case
381− Just (HaddockSpan _ _) -> return ()
382− Just (CommentSpan _) -> return ()
383− _ -> setSpanMark (StatementSpan currentSpn)
384
328
385p_stmt :: Stmt GhcPs (LHsExpr GhcPs) -> R ()
329p_stmt :: Stmt GhcPs (LHsExpr GhcPs) -> R ()
386−p_stmt = p_stmt' exprPlacement p_hsExpr
330+p_stmt = p_stmt' p_hsExpr
387−
331+
388−p_stmt' ::
332+p_stmt'
389− Data body =>
333+ :: Data body
390− -- | Placer
391− (body -> Placement) ->
334+ => (body -> R ())
392− -- | Render
393− (body -> R ()) ->
394− -- | Statement to render
395− Stmt GhcPs (Located body) ->
335+ -> Stmt GhcPs (Located body)
396− R ()
336+ -> R ()
397−p_stmt' placer render = \case
337+p_stmt' pretty = \case
398− LastStmt NoExtField body _ _ -> located body render
338+ LastStmt NoExt body _ _ -> located body pretty
399− BindStmt NoExtField p f _ _ -> do
339+ BindStmt NoExt l f _ _ -> do
400− located p p_pat
340+ located l p_pat
401 space
341 space
402 txt "<-"
342 txt "<-"
403− let loc = getLoc p
343+ breakpoint
404− placement =
344+ inci (located f pretty)
405− case f of
406− L l' x ->
407− if isOneLineSpan
408− (mkSrcSpan (srcSpanEnd loc) (srcSpanStart l'))
409− then placer x
410− else Normal
411− switchLayout [loc, getLoc f] $
412− placeHanging placement (located f render)
413 ApplicativeStmt {} -> notImplemented "ApplicativeStmt" -- generated by renamer
345 ApplicativeStmt {} -> notImplemented "ApplicativeStmt" -- generated by renamer
414− BodyStmt NoExtField body _ _ -> located body render
346+ BodyStmt NoExt body _ _ -> located body pretty
415− LetStmt NoExtField binds -> do
347+ LetStmt NoExt binds -> do
416− txt "let"
348+ txt "let "
417− space
418 sitcc $ located binds p_hsLocalBinds
349 sitcc $ located binds p_hsLocalBinds
419 ParStmt {} ->
350 ParStmt {} ->
420− -- 'ParStmt' should always be eliminated in 'gatherStmt' already, such
351+ -- NOTE 'ParStmt' should always be eliminated in 'gatherStmt' already,
421− -- that it never occurs in 'p_stmt''. Consequently, handling it here
352+ -- such that it never occurs in 'p_stmt''. Consequently, handling it
422− -- would be redundant.
353+ -- here would be redundant.
423 notImplemented "ParStmt"
354 notImplemented "ParStmt"
424− TransStmt {..} ->
355+ TransStmt {..} -> do
425− -- 'TransStmt' only needs to account for render printing itself, since
356+ -- NOTE 'TransStmt' only needs to account for pretty printing itself,
426− -- pretty printing of relevant statements (e.g., in 'trS_stmts') is
357+ -- since pretty printing of relevant statements (e.g., in 'trS_stmts')
427− -- handled through 'gatherStmt'.
358+ -- is handled through 'gatherStmt'.
428 case (trS_form, trS_by) of
359 case (trS_form, trS_by) of
429− (ThenForm, Nothing) -> do
360+ (ThenForm, Nothing) -> located trS_using $ \x -> do
430 txt "then"
361 txt "then"
431 breakpoint
362 breakpoint
432− inci $ located trS_using p_hsExpr
363+ inci (p_hsExpr x)
433 (ThenForm, Just e) -> do
364 (ThenForm, Just e) -> do
434− txt "then"
435− breakpoint
436− inci $ located trS_using p_hsExpr
365+ located trS_using $ \x -> do
437− breakpoint
366+ txt "then"
438− txt "by"
367+ breakpoint
368+ inci (p_hsExpr x)
439 breakpoint
369 breakpoint
440− inci $ located e p_hsExpr
370+ located e $ \x -> do
371+ txt "by"
372+ breakpoint
373+ inci (p_hsExpr x)
441− (GroupForm, Nothing) -> do
374+ (GroupForm, Nothing) -> located trS_using $ \x -> do
442 txt "then group using"
375 txt "then group using"
443 breakpoint
376 breakpoint
444− inci $ located trS_using p_hsExpr
377+ inci (p_hsExpr x)
445 (GroupForm, Just e) -> do
378 (GroupForm, Just e) -> do
379+ located e $ \x -> do
446− txt "then group by"
380+ txt "then group by"
447− breakpoint
381+ breakpoint
448− inci $ located e p_hsExpr
382+ inci (p_hsExpr x)
449− breakpoint
450− txt "using"
451 breakpoint
383 breakpoint
452− inci $ located trS_using p_hsExpr
384+ located trS_using $ \x -> do
385+ txt "using"
386+ breakpoint
387+ inci (p_hsExpr x)
453 RecStmt {..} -> do
388 RecStmt {..} -> do
454− txt "rec"
389+ txt "rec "
455− space
456− sitcc $ sepSemi (withSpacing (p_stmt' placer render)) recS_stmts
390+ sitcc $ sepSemi (located' (p_stmt' pretty)) recS_stmts
457− XStmtLR c -> noExtCon c
391+ XStmtLR {} -> notImplemented "XStmtLR"
458
392
459gatherStmt :: ExprLStmt GhcPs -> [[ExprLStmt GhcPs]]
393gatherStmt :: ExprLStmt GhcPs -> [[ExprLStmt GhcPs]]
460−gatherStmt (L _ (ParStmt NoExtField block _ _)) =
394+gatherStmt (L _ (ParStmt NoExt block _ _)) =
461 foldr ((<>) . gatherStmtBlock) [] block
395 foldr ((<>) . gatherStmtBlock) [] block
462gatherStmt (L s stmt@TransStmt {..}) =
396gatherStmt (L s stmt@TransStmt {..}) =
463 foldr liftAppend [] ((gatherStmt <$> trS_stmts) <> pure [[L s stmt]])
397 foldr liftAppend [] ((gatherStmt <$> trS_stmts) <> pure [[L s stmt]])
@@ -466,337 +400,266 @@ gatherStmt stmt = [[stmt]]
466gatherStmtBlock :: ParStmtBlock GhcPs GhcPs -> [[ExprLStmt GhcPs]]
400gatherStmtBlock :: ParStmtBlock GhcPs GhcPs -> [[ExprLStmt GhcPs]]
467gatherStmtBlock (ParStmtBlock _ stmts _ _) =
401gatherStmtBlock (ParStmtBlock _ stmts _ _) =
468 foldr (liftAppend . gatherStmt) [] stmts
402 foldr (liftAppend . gatherStmt) [] stmts
469−gatherStmtBlock (XParStmtBlock x) = noExtCon x
403+gatherStmtBlock XParStmtBlock {} = notImplemented "XParStmtBlock"
470
404
471p_hsLocalBinds :: HsLocalBindsLR GhcPs GhcPs -> R ()
405p_hsLocalBinds :: HsLocalBindsLR GhcPs GhcPs -> R ()
472p_hsLocalBinds = \case
406p_hsLocalBinds = \case
473− HsValBinds NoExtField (ValBinds NoExtField bag lsigs) -> do
407+ HsValBinds NoExt (ValBinds NoExt bag lsigs) -> do
408+ let ssStart = either
409+ (srcSpanStart . getLoc)
410+ (srcSpanStart . getLoc)
411+ items =
412+ (Left <$> bagToList bag) ++ (Right <$> lsigs)
413+ p_item (Left x) = located x p_valDecl
414+ p_item (Right x) = located x p_sigDecl
415+ -- Assigns 'False' to the last element, 'True' to the rest.
416+ markInit :: [a] -> [(Bool, a)]
417+ markInit [] = []
418+ markInit (x:[]) = [(False, x)]
419+ markInit (x:xs) = (True, x) : markInit xs
474− -- When in a single-line layout, there is a chance that the inner
420+ -- NOTE When in a single-line layout, there is a chance that the inner
475 -- elements will also contain semicolons and they will confuse the
421 -- elements will also contain semicolons and they will confuse the
476 -- parser. so we request braces around every element except the last.
422 -- parser. so we request braces around every element except the last.
477− br <- layoutToBraces <$> getLayout
423+ br <- vlayout (return useBraces) (return id)
478− let items =
424+ sitcc $ sepSemi
479− let injectLeft (L l x) = L l (Left x)
425+ (\(m, i) -> (if m then br else id) $ p_item i)
480− injectRight (L l x) = L l (Right x)
426+ (markInit $ sortOn ssStart items)
481− in (injectLeft <$> bagToList bag) ++ (injectRight <$> lsigs)
482− positionToBracing = \case
483− SinglePos -> id
484− FirstPos -> br
485− MiddlePos -> br
486− LastPos -> id
487− p_item' (p, item) =
488− positionToBracing p $
489− withSpacing (either p_valDecl p_sigDecl) item
490− binds = sortOn (srcSpanStart . getLoc) items
491− sitcc $ sepSemi p_item' (attachRelativePos binds)
492− HsValBinds NoExtField _ -> notImplemented "HsValBinds"
427+ HsValBinds NoExt _ -> notImplemented "HsValBinds"
493− HsIPBinds NoExtField (IPBinds NoExtField xs) ->
428+ HsIPBinds NoExt (IPBinds NoExt xs) ->
494 -- Second argument of IPBind is always Left before type-checking.
429 -- Second argument of IPBind is always Left before type-checking.
495− let p_ipBind (IPBind NoExtField (Left name) expr) = do
430+ let p_ipBind (IPBind NoExt (Left name) expr) = do
496 atom name
431 atom name
497− space
432+ txt " ="
498− equals
499 breakpoint
433 breakpoint
500 useBraces $ inci $ located expr p_hsExpr
434 useBraces $ inci $ located expr p_hsExpr
501− p_ipBind (IPBind NoExtField (Right _) _) =
502− -- Should only occur after the type checker
503− notImplemented "IPBind _ (Right _) _"
435+ p_ipBind _ = notImplemented "XHsIPBinds"
504− p_ipBind (XIPBind x) = noExtCon x
505 in sepSemi (located' p_ipBind) xs
436 in sepSemi (located' p_ipBind) xs
506− HsIPBinds NoExtField _ -> notImplemented "HsIpBinds"
437+ HsIPBinds NoExt _ -> notImplemented "HsIpBinds"
507− EmptyLocalBinds NoExtField -> return ()
438+ EmptyLocalBinds NoExt -> return ()
508− XHsLocalBindsLR x -> noExtCon x
439+ XHsLocalBindsLR _ -> notImplemented "XHsLocalBindsLR"
509−
440+
510−p_hsRecField ::
441+p_hsRecField
442+ :: (Data id, Outputable id)
511− HsRecField' RdrName (LHsExpr GhcPs) ->
443+ => HsRecField' id (LHsExpr GhcPs)
512− R ()
444+ -> R ()
513−p_hsRecField HsRecField {..} = do
445+p_hsRecField = \HsRecField {..} -> do
514− p_rdrName hsRecFieldLbl
446+ located hsRecFieldLbl atom
515 unless hsRecPun $ do
447 unless hsRecPun $ do
516− space
448+ txt " ="
517− equals
518− let placement =
519− if onTheSameLine (getLoc hsRecFieldLbl) (getLoc hsRecFieldArg)
520− then exprPlacement (unLoc hsRecFieldArg)
449+ let placement = exprPlacement (unLoc hsRecFieldArg)
521− else Normal
522− placeHanging placement (located hsRecFieldArg p_hsExpr)
450+ placeHanging placement $ located hsRecFieldArg p_hsExpr
523
451
524−p_hsExpr :: HsExpr GhcPs -> R ()
452+p_hsTupArg :: HsTupArg GhcPs -> R ()
525−p_hsExpr = p_hsExpr' N
453+p_hsTupArg = \case
454+ Present NoExt x -> located x p_hsExpr
455+ Missing NoExt -> pure ()
456+ XTupArg {} -> notImplemented "XTupArg"
526
457
527−p_hsExpr' :: BracketStyle -> HsExpr GhcPs -> R ()
458+p_hsExpr :: HsExpr GhcPs -> R ()
528−p_hsExpr' s = \case
459+p_hsExpr = \case
529− HsVar NoExtField name -> p_rdrName name
460+ HsVar NoExt name -> p_rdrName name
530− HsUnboundVar NoExtField v -> atom (unboundVarOcc v)
461+ HsUnboundVar NoExt _ -> notImplemented "HsUnboundVar"
531− HsConLikeOut NoExtField _ -> notImplemented "HsConLikeOut"
462+ HsConLikeOut NoExt _ -> notImplemented "HsConLikeOut"
532− HsRecFld NoExtField x ->
463+ HsRecFld NoExt x ->
533 case x of
464 case x of
534− Unambiguous NoExtField name -> p_rdrName name
465+ Unambiguous NoExt name -> p_rdrName name
535− Ambiguous NoExtField name -> p_rdrName name
466+ Ambiguous NoExt name -> p_rdrName name
536− XAmbiguousFieldOcc xx -> noExtCon xx
467+ XAmbiguousFieldOcc NoExt -> notImplemented "XAmbiguousFieldOcc"
537− HsOverLabel NoExtField _ v -> do
468+ HsOverLabel NoExt _ v -> do
538 txt "#"
469 txt "#"
539 atom v
470 atom v
540− HsIPVar NoExtField (HsIPName name) -> do
471+ HsIPVar NoExt (HsIPName name) -> do
541 txt "?"
472 txt "?"
542 atom name
473 atom name
543− HsOverLit NoExtField v -> atom (ol_val v)
474+ HsOverLit NoExt v -> atom (ol_val v)
544− HsLit NoExtField lit ->
475+ HsLit NoExt lit -> atom lit
545− case lit of
546− HsString (SourceText stxt) _ -> p_stringLit stxt
547− HsStringPrim (SourceText stxt) _ -> p_stringLit stxt
548− r -> atom r
549− HsLam NoExtField mgroup ->
476+ HsLam NoExt mgroup ->
550 p_matchGroup Lambda mgroup
477 p_matchGroup Lambda mgroup
551− HsLamCase NoExtField mgroup -> do
478+ HsLamCase NoExt mgroup -> do
552 txt "\\case"
479 txt "\\case"
553− breakpoint
480+ newline
554 inci (p_matchGroup LambdaCase mgroup)
481 inci (p_matchGroup LambdaCase mgroup)
555− HsApp NoExtField f x -> do
482+ HsApp NoExt f x -> sitcc $ do
556− let -- In order to format function applications with multiple parameters
483+ located f p_hsExpr
557− -- nicer, traverse the AST to gather the function and all the
484+ -- Second argument can be a `do` or `case` block with `-XBlockArguments`.
558− -- parameters together.
559− gatherArgs f' knownArgs =
560− case f' of
561− L _ (HsApp _ l r) -> gatherArgs l (r <| knownArgs)
562− _ -> (f', knownArgs)
563− (func, args) = gatherArgs f (x :| [])
564− -- We need to handle the last argument specially if it is a
565− -- hanging construct, so separate it from the rest.
566− (initp, lastp) = (NE.init args, NE.last args)
567− initSpan =
568− combineSrcSpans' $
569− getLoc f :| [(srcLocSpan . srcSpanStart . getLoc) lastp]
570− -- Hang the last argument only if the initial arguments span one
571− -- line.
572− placement =
573− if isOneLineSpan initSpan
574− then exprPlacement (unLoc lastp)
485+ placeHanging (exprPlacement (unLoc x)) $
575− else Normal
576− -- If the last argument is not hanging, just separate every argument as
577− -- usual. If it is hanging, print the initial arguments and hang the
578− -- last one. Also, use braces around the every argument except the last
579− -- one.
580− case placement of
581− Normal -> do
582− let -- Usually we want to bump indentation for arguments for the
583− -- sake of readability. However, when the function itself is a
584− -- do-block or case expression it is not a good idea. It seems
585− -- to be safe to always bump indentation when the function
586− -- expression is parenthesised.
587− doIndent =
588− case func of
589− L _ (HsPar NoExtField _) -> True
590− L _ (HsAppType NoExtField _ _) -> True
591− L _ (HsMultiIf NoExtField _) -> True
592− L spn _ -> isOneLineSpan spn
593− ub <-
594− getLayout <&> \case
595− SingleLine -> useBraces
596− MultiLine -> id
597− ub $ do
598− located func (p_hsExpr' s)
599− breakpoint
600− inciIf doIndent $ sep breakpoint (located' p_hsExpr) initp
601− inciIf doIndent $ do
602− unless (null initp) breakpoint
603− located lastp p_hsExpr
604− Hanging -> do
605− useBraces . switchLayout [initSpan] $ do
606− located func (p_hsExpr' s)
607− breakpoint
608− sep breakpoint (located' p_hsExpr) initp
609− placeHanging placement $
610− located lastp p_hsExpr
486+ located x p_hsExpr
611− HsAppType NoExtField e a -> do
487+ HsAppType a e -> do
612 located e p_hsExpr
488 located e p_hsExpr
613 breakpoint
489 breakpoint
614 inci $ do
490 inci $ do
615 txt "@"
491 txt "@"
616− -- Insert a space when the type is represented as a TH splice to avoid
617− -- gluing @ and $ together.
618− case unLoc (hswc_body a) of
619− HsSpliceTy {} -> space
620− _ -> return ()
621 located (hswc_body a) p_hsType
492 located (hswc_body a) p_hsType
622− OpApp NoExtField x op y -> do
493+ OpApp NoExt x op y -> do
623− let opTree = OpBranch (exprOpTree x) op (exprOpTree y)
494+ -- NOTE If the beginning of the first argument and the second argument
624− p_exprOpTree s (reassociateOpTree getOpName opTree)
495+ -- are on the same line, and the second argument has a hanging form, use
496+ -- hanging placement.
497+ let placement =
498+ if isOneLineSpan
499+ (mkSrcSpan (srcSpanStart (getLoc x)) (srcSpanStart (getLoc y)))
500+ then exprPlacement (unLoc y)
501+ else Normal
502+ opWrapper = case unLoc op of
503+ EWildPat NoExt -> backticks
504+ _ -> id
505+ ub <- vlayout
506+ (return useBraces)
507+ (return $ case placement of
508+ Hanging -> useBraces
509+ Normal -> dontUseBraces)
510+ ub $ located x p_hsExpr
511+ placeHanging placement $ do
512+ located op (opWrapper . p_hsExpr)
513+ space
514+ located y p_hsExpr
625− NegApp NoExtField e _ -> do
515+ NegApp NoExt e _ -> do
626− txt "-"
516+ txt "- "
627− space
628 located e p_hsExpr
517 located e p_hsExpr
629− HsPar NoExtField e ->
630− parens s (located e (dontUseBraces . p_hsExpr))
518+ HsPar NoExt e -> parens (located e p_hsExpr)
631− SectionL NoExtField x op -> do
519+ SectionL NoExt x op -> do
632 located x p_hsExpr
520 located x p_hsExpr
633 breakpoint
521 breakpoint
634 inci (located op p_hsExpr)
522 inci (located op p_hsExpr)
635− SectionR NoExtField op x -> do
523+ SectionR NoExt op x -> do
636 located op p_hsExpr
524 located op p_hsExpr
637− useRecordDot' <- useRecordDot
638− let isRecordDot' = isRecordDot (unLoc op) (getLoc x)
639− unless (useRecordDot' && isRecordDot') breakpoint
525+ breakpoint
640 inci (located x p_hsExpr)
526 inci (located x p_hsExpr)
641− ExplicitTuple NoExtField args boxity ->
527+ ExplicitTuple NoExt args boxity -> do
642 let isSection = any (isMissing . unLoc) args
528 let isSection = any (isMissing . unLoc) args
643 isMissing = \case
529 isMissing = \case
644− Missing NoExtField -> True
530+ Missing NoExt -> True
645 _ -> False
531 _ -> False
646− p_arg = \case
647− Present NoExtField x -> located x p_hsExpr
648− Missing NoExtField -> pure ()
649− XTupArg x -> noExtCon x
650− p_larg = sitcc . located' p_arg
651− parens' =
532+ let parens' =
652 case boxity of
533 case boxity of
653 Boxed -> parens
534 Boxed -> parens
654 Unboxed -> parensHash
535 Unboxed -> parensHash
655− in if isSection
536+ if isSection
656− then
657− switchLayout [] . parens' s $
537+ then switchLayout [] . parens' $
658− sep comma p_larg args
538+ sep comma (located' p_hsTupArg) args
659− else
660− switchLayout (getLoc <$> args) . parens' s $
539+ else switchLayout (getLoc <$> args) . parens' . sitcc $
661− sep commaDel p_larg args
540+ sep (comma >> breakpoint) (sitcc . located' p_hsTupArg) args
662− ExplicitSum NoExtField tag arity e ->
541+ ExplicitSum NoExt tag arity e ->
663− p_unboxedSum N tag arity (located e p_hsExpr)
542+ p_unboxedSum tag arity (located e p_hsExpr)
664− HsCase NoExtField e mgroup ->
543+ HsCase NoExt e mgroup -> do
665− p_case exprPlacement p_hsExpr e mgroup
544+ txt "case "
545+ located e p_hsExpr
546+ txt " of"
547+ breakpoint
548+ inci (p_matchGroup Case mgroup)
666− HsIf NoExtField _ if' then' else' ->
549+ HsIf NoExt _ if' then' else' -> do
667− p_if exprPlacement p_hsExpr if' then' else'
550+ txt "if "
551+ located if' p_hsExpr
552+ breakpoint
553+ inci $ do
554+ txt "then"
555+ located then' $ \x ->
556+ placeHanging (exprPlacement x) (p_hsExpr x)
557+ breakpoint
558+ txt "else"
559+ located else' $ \x ->
560+ placeHanging (exprPlacement x) (p_hsExpr x)
668− HsMultiIf NoExtField guards -> do
561+ HsMultiIf NoExt guards -> do
669 txt "if"
562 txt "if"
670 breakpoint
563 breakpoint
671− inci . inci $ sep newline (located' (p_grhs RightArrow)) guards
564+ inci . sitcc $ sep newline (located' (p_grhs RightArrow)) guards
672− HsLet NoExtField localBinds e ->
565+ HsLet NoExt localBinds e -> do
673− p_let p_hsExpr localBinds e
566+ txt "let "
567+ dontUseBraces $ sitcc (located localBinds p_hsLocalBinds)
568+ vlayout space (newline >> space)
569+ txt "in "
570+ sitcc (located e p_hsExpr)
674− HsDo NoExtField ctx es -> do
571+ HsDo NoExt ctx es -> do
675 let doBody header = do
572 let doBody header = do
676 txt header
573 txt header
677 breakpoint
574 breakpoint
678− ub <- layoutToBraces <$> getLayout
575+ ub <- vlayout (return useBraces) (return id)
679− inci $
576+ inci $ sepSemi (located' (ub . p_stmt)) (unLoc es)
680− sepSemi
681− (ub . withSpacing (p_stmt' exprPlacement (p_hsExpr' S)))
682− (unLoc es)
683− compBody = brackets N . located es $ \xs -> do
577+ compBody = brackets $ located es $ \xs -> do
684− let p_parBody =
578+ let p_parBody = sep
685− sep
686− (breakpoint >> txt "|" >> space)
579+ (breakpoint >> txt "| ")
687− p_seqBody
580+ p_seqBody
688− p_seqBody =
581+ p_seqBody = sitcc . sep
689− sitcc
582+ (comma >> breakpoint)
690− . sep
691− commaDel
692− (located' (sitcc . p_stmt))
583+ (located' (sitcc . p_stmt))
693 stmts = init xs
584 stmts = init xs
694 yield = last xs
585 yield = last xs
695 lists = foldr (liftAppend . gatherStmt) [] stmts
586 lists = foldr (liftAppend . gatherStmt) [] stmts
696 located yield p_stmt
587 located yield p_stmt
697 breakpoint
588 breakpoint
698− txt "|"
589+ txt "| "
699− space
700 p_parBody lists
590 p_parBody lists
701 case ctx of
591 case ctx of
702 DoExpr -> doBody "do"
592 DoExpr -> doBody "do"
703 MDoExpr -> doBody "mdo"
593 MDoExpr -> doBody "mdo"
704 ListComp -> compBody
594 ListComp -> compBody
705 MonadComp -> notImplemented "MonadComp"
595 MonadComp -> notImplemented "MonadComp"
706− ArrowExpr -> notImplemented "ArrowExpr"
596+ ArrowExpr -> notImplemented "ArrowExpr"
707 GhciStmtCtxt -> notImplemented "GhciStmtCtxt"
597 GhciStmtCtxt -> notImplemented "GhciStmtCtxt"
708 PatGuard _ -> notImplemented "PatGuard"
598 PatGuard _ -> notImplemented "PatGuard"
709 ParStmtCtxt _ -> notImplemented "ParStmtCtxt"
599 ParStmtCtxt _ -> notImplemented "ParStmtCtxt"
710 TransStmtCtxt _ -> notImplemented "TransStmtCtxt"
600 TransStmtCtxt _ -> notImplemented "TransStmtCtxt"
711 ExplicitList _ _ xs ->
601 ExplicitList _ _ xs ->
712− brackets s $
713− sep commaDel (sitcc . located' p_hsExpr) xs
602+ brackets . sitcc $ sep (comma >> breakpoint) (sitcc . located' p_hsExpr) xs
714 RecordCon {..} -> do
603 RecordCon {..} -> do
715 located rcon_con_name atom
604 located rcon_con_name atom
716 breakpoint
605 breakpoint
717 let HsRecFields {..} = rcon_flds
606 let HsRecFields {..} = rcon_flds
718− updName f =
719− (f :: HsRecField GhcPs (LHsExpr GhcPs))
720− { hsRecFieldLbl = case unLoc $ hsRecFieldLbl f of
721− FieldOcc _ n -> n
722− XFieldOcc x -> noExtCon x
723− }
724− fields = located' (p_hsRecField . updName) <$> rec_flds
607+ fields = located' p_hsRecField <$> rec_flds
725 dotdot =
608 dotdot =
726 case rec_dotdot of
609 case rec_dotdot of
727 Just {} -> [txt ".."]
610 Just {} -> [txt ".."]
728 Nothing -> []
611 Nothing -> []
729− inci . braces N $
730− sep commaDel sitcc (fields <> dotdot)
612+ inci . braces . sitcc $ sep (comma >> breakpoint) sitcc (fields <> dotdot)
731 RecordUpd {..} -> do
613 RecordUpd {..} -> do
732 located rupd_expr p_hsExpr
614 located rupd_expr p_hsExpr
733− useRecordDot' <- useRecordDot
734− let mrs sp = case getLoc sp of
735− RealSrcSpan r -> Just r
736− _ -> Nothing
737− let isPluginForm =
738− ((1 +) . srcSpanEndCol <$> mrs rupd_expr)
739− == (srcSpanStartCol <$> mrs (head rupd_flds))
740− unless (useRecordDot' && isPluginForm) breakpoint
615+ breakpoint
741− let updName f =
742− (f :: HsRecUpdField GhcPs)
743− { hsRecFieldLbl = case unLoc $ hsRecFieldLbl f of
744− Ambiguous _ n -> n
745− Unambiguous _ n -> n
746− XAmbiguousFieldOcc x -> noExtCon x
747− }
748− inci . braces N $
616+ inci . braces . sitcc $
749− sep
750− commaDel
751− (sitcc . located' (p_hsRecField . updName))
617+ sep (comma >> breakpoint) (sitcc . located' p_hsRecField) rupd_flds
752− rupd_flds
753− ExprWithTySig NoExtField x HsWC {hswc_body = HsIB {..}} -> sitcc $ do
618+ ExprWithTySig affix x -> sitcc $ do
754 located x p_hsExpr
619 located x p_hsExpr
755− space
756− txt "::"
757 breakpoint
620 breakpoint
621+ inci $ do
622+ txt ":: "
623+ let HsWC {..} = affix
624+ HsIB {..} = hswc_body
758− inci $ located hsib_body p_hsType
625+ located hsib_body p_hsType
759− ExprWithTySig NoExtField _ HsWC {hswc_body = XHsImplicitBndrs x} -> noExtCon x
760− ExprWithTySig NoExtField _ (XHsWildCardBndrs x) -> noExtCon x
761− ArithSeq NoExtField _ x ->
626+ ArithSeq NoExt _ x -> do
762 case x of
627 case x of
763− From from -> brackets s $ do
628+ From from -> brackets . sitcc $ do
764 located from p_hsExpr
629 located from p_hsExpr
765 breakpoint
630 breakpoint
766 txt ".."
631 txt ".."
767− FromThen from next -> brackets s $ do
632+ FromThen from next -> brackets . sitcc $ do
768− sep commaDel (located' p_hsExpr) [from, next]
633+ sitcc $ sep (comma >> breakpoint) (located' p_hsExpr) [from, next]
769 breakpoint
634 breakpoint
770 txt ".."
635 txt ".."
771− FromTo from to -> brackets s $ do
636+ FromTo from to -> brackets . sitcc $ do
772 located from p_hsExpr
637 located from p_hsExpr
773 breakpoint
638 breakpoint
774− txt ".."
639+ txt ".. "
775− space
776 located to p_hsExpr
640 located to p_hsExpr
777− FromThenTo from next to -> brackets s $ do
641+ FromThenTo from next to -> brackets . sitcc $ do
778− sep commaDel (located' p_hsExpr) [from, next]
642+ sitcc $ sep (comma >> breakpoint) (located' p_hsExpr) [from, next]
779 breakpoint
643 breakpoint
780− txt ".."
644+ txt ".. "
781− space
782 located to p_hsExpr
645 located to p_hsExpr
783− HsSCC NoExtField _ name x -> do
646+ HsSCC NoExt _ name x -> do
784 txt "{-# SCC "
647 txt "{-# SCC "
785 atom name
648 atom name
786 txt " #-}"
649 txt " #-}"
787 breakpoint
650 breakpoint
788 located x p_hsExpr
651 located x p_hsExpr
789− HsCoreAnn NoExtField _ value x -> do
652+ HsCoreAnn NoExt _ value x -> do
790 txt "{-# CORE "
653 txt "{-# CORE "
791 atom value
654 atom value
792 txt " #-}"
655 txt " #-}"
793 breakpoint
656 breakpoint
794 located x p_hsExpr
657 located x p_hsExpr
795− HsBracket NoExtField x -> p_hsBracket x
658+ HsBracket NoExt x -> p_hsBracket x
796 HsRnBracketOut {} -> notImplemented "HsRnBracketOut"
659 HsRnBracketOut {} -> notImplemented "HsRnBracketOut"
797 HsTcBracketOut {} -> notImplemented "HsTcBracketOut"
660 HsTcBracketOut {} -> notImplemented "HsTcBracketOut"
798− HsSpliceE NoExtField splice -> p_hsSplice splice
661+ HsSpliceE NoExt splice -> p_hsSplice splice
799− HsProc NoExtField p e -> do
662+ HsProc NoExt p e -> do
800 txt "proc"
663 txt "proc"
801 located p $ \x -> do
664 located p $ \x -> do
802 breakpoint
665 breakpoint
@@ -805,159 +668,92 @@ p_hsExpr' s = \case
805 txt "->"
668 txt "->"
806 placeHanging (cmdTopPlacement (unLoc e)) $
669 placeHanging (cmdTopPlacement (unLoc e)) $
807 located e p_hsCmdTop
670 located e p_hsCmdTop
808− HsStatic _ e -> do
671+ HsStatic _ e -> do
809 txt "static"
672 txt "static"
810 breakpoint
673 breakpoint
811 inci (located e p_hsExpr)
674 inci (located e p_hsExpr)
675+ HsArrApp NoExt body input arrType cond ->
676+ p_hsCmd (HsCmdArrApp NoExt body input arrType cond)
677+ HsArrForm NoExt form mfixity cmds ->
678+ p_hsCmd (HsCmdArrForm NoExt form Prefix mfixity cmds)
812 HsTick {} -> notImplemented "HsTick"
679 HsTick {} -> notImplemented "HsTick"
813 HsBinTick {} -> notImplemented "HsBinTick"
680 HsBinTick {} -> notImplemented "HsBinTick"
814 HsTickPragma {} -> notImplemented "HsTickPragma"
681 HsTickPragma {} -> notImplemented "HsTickPragma"
682+ EWildPat NoExt -> txt "_"
683+ EAsPat {} -> notImplemented "EAsPat"
684+ EViewPat {} -> notImplemented "EViewPat"
685+ ELazyPat {} -> notImplemented "ELazyPat"
815 HsWrap {} -> notImplemented "HsWrap"
686 HsWrap {} -> notImplemented "HsWrap"
816− XExpr x -> noExtCon x
687+ XExpr {} -> notImplemented "XExpr"
817
688
818p_patSynBind :: PatSynBind GhcPs GhcPs -> R ()
689p_patSynBind :: PatSynBind GhcPs GhcPs -> R ()
819p_patSynBind PSB {..} = do
690p_patSynBind PSB {..} = do
820− let rhs = do
691+ txt "pattern "
821− space
822− case psb_dir of
692+ case psb_dir of
823− Unidirectional -> do
693+ Unidirectional -> do
824− txt "<-"
825− breakpoint
826− located psb_def p_pat
827− ImplicitBidirectional -> do
828− equals
829− breakpoint
830− located psb_def p_pat
831− ExplicitBidirectional mgroup -> do
832− txt "<-"
833− breakpoint
834− located psb_def p_pat
835− newline
836− txt "where"
837− newline
838− inci (p_matchGroup (Function psb_id) mgroup)
839− txt "pattern"
840− case psb_args of
841− PrefixCon xs -> do
842− space
843 p_rdrName psb_id
694 p_rdrName psb_id
844 inci $ do
695 inci $ do
845− switchLayout (getLoc <$> xs) $ do
696+ p_patSynDetails psb_args
846− unless (null xs) breakpoint
697+ txt " <-"
847− sitcc (sep breakpoint p_rdrName xs)
698+ breakpoint
848− rhs
699+ located psb_def p_pat
849− RecCon xs -> do
700+ ImplicitBidirectional -> do
850− space
851 p_rdrName psb_id
701 p_rdrName psb_id
852 inci $ do
702 inci $ do
853− switchLayout (getLoc . recordPatSynPatVar <$> xs) $ do
703+ p_patSynDetails psb_args
854− unless (null xs) breakpoint
704+ txt " ="
855− braces N $
856− sep commaDel (p_rdrName . recordPatSynPatVar) xs
857− rhs
858− InfixCon l r -> do
859− switchLayout [getLoc l, getLoc r] $ do
860− space
861− p_rdrName l
862 breakpoint
705 breakpoint
863− inci $ do
706+ located psb_def p_pat
707+ ExplicitBidirectional mgroup -> do
864− p_rdrName psb_id
708+ p_rdrName psb_id
865− space
709+ inci $ do
866− p_rdrName r
710+ p_patSynDetails psb_args
867− inci rhs
711+ txt " <-"
712+ breakpoint
713+ located psb_def p_pat
714+ newline
715+ line (txt "where")
716+ inci (p_matchGroup (Function psb_id) mgroup)
868−p_patSynBind (XPatSynBind x) = noExtCon x
717+p_patSynBind (XPatSynBind NoExt) = notImplemented "XPatSynBind"
869−
718+
870−p_case ::
719+p_patSynDetails :: HsPatSynDetails (Located RdrName) -> R ()
871− Data body =>
720+p_patSynDetails = \case
872− -- | Placer
721+ PrefixCon xs ->
873− (body -> Placement) ->
722+ switchLayout (getLoc <$> xs) $ do
874− -- | Render
723+ unless (null xs) breakpoint
875− (body -> R ()) ->
724+ sitcc (sep breakpoint p_rdrName xs)
876− -- | Expression
725+ RecCon xs ->
877− LHsExpr GhcPs ->
726+ switchLayout (getLoc . recordPatSynPatVar <$> xs) $ do
878− -- | Match group
879− MatchGroup GhcPs (Located body) ->
880− R ()
881−p_case placer render e mgroup = do
882− txt "case"
883− space
884− located e p_hsExpr
885− space
886− txt "of"
887− breakpoint
888− inci (p_matchGroup' placer render Case mgroup)
889−
890−p_if ::
891− Data body =>
892− -- | Placer
893− (body -> Placement) ->
894− -- | Render
895− (body -> R ()) ->
896− -- | If
897− LHsExpr GhcPs ->
898− -- | Then
899− Located body ->
900− -- | Else
901− Located body ->
902− R ()
903−p_if placer render if' then' else' = do
904− txt "if"
905− space
906− located if' p_hsExpr
907− breakpoint
908− inci $ do
909− txt "then"
910− space
911− located then' $ \x ->
912− placeHanging (placer x) (render x)
913− breakpoint
727+ unless (null xs) breakpoint
914− txt "else"
728+ braces . sitcc $ sep (comma >> breakpoint) (p_rdrName . recordPatSynPatVar) xs
915− space
729+ InfixCon _ _ -> notImplemented "InfixCon"
916− located else' $ \x ->
917− placeHanging (placer x) (render x)
918−
919−p_let ::
920− Data body =>
921− -- | Render
922− (body -> R ()) ->
923− Located (HsLocalBindsLR GhcPs GhcPs) ->
924− Located body ->
925− R ()
926−p_let render localBinds e = sitcc $ do
927− txt "let"
928− space
929− dontUseBraces $ sitcc (located localBinds p_hsLocalBinds)
930− vlayout space (newline >> txt " ")
931− txt "in"
932− space
933− sitcc (located e render)
934
730
935p_pat :: Pat GhcPs -> R ()
731p_pat :: Pat GhcPs -> R ()
936p_pat = \case
732p_pat = \case
937− WildPat NoExtField -> txt "_"
733+ WildPat NoExt -> txt "_"
938− VarPat NoExtField name -> p_rdrName name
734+ VarPat NoExt name -> p_rdrName name
939− LazyPat NoExtField pat -> do
735+ LazyPat NoExt pat -> do
940 txt "~"
736 txt "~"
941 located pat p_pat
737 located pat p_pat
942− AsPat NoExtField name pat -> do
738+ AsPat NoExt name pat -> do
943 p_rdrName name
739 p_rdrName name
944 txt "@"
740 txt "@"
945 located pat p_pat
741 located pat p_pat
946− ParPat NoExtField pat ->
742+ ParPat NoExt pat ->
947− located pat (parens S . p_pat)
743+ located pat (parens . p_pat)
948− BangPat NoExtField pat -> do
744+ BangPat NoExt pat -> do
949 txt "!"
745 txt "!"
950 located pat p_pat
746 located pat p_pat
951− ListPat NoExtField pats ->
747+ ListPat NoExt pats -> do
952− brackets S $ sep commaDel (located' p_pat) pats
748+ brackets . sitcc $ sep (comma >> breakpoint) (located' p_pat) pats
953− TuplePat NoExtField pats boxing -> do
749+ TuplePat NoExt pats boxing -> do
954− let parens' =
750+ let f =
955 case boxing of
751 case boxing of
956− Boxed -> parens S
752+ Boxed -> parens
957− Unboxed -> parensHash S
753+ Unboxed -> parensHash
958− parens' $ sep commaDel (sitcc . located' p_pat) pats
754+ f . sitcc $ sep (comma >> breakpoint) (sitcc . located' p_pat) pats
959− SumPat NoExtField pat tag arity ->
755+ SumPat NoExt pat tag arity ->
960− p_unboxedSum S tag arity (located pat p_pat)
756+ p_unboxedSum tag arity (located pat p_pat)
961 ConPatIn pat details ->
757 ConPatIn pat details ->
962 case details of
758 case details of
963 PrefixCon xs -> sitcc $ do
759 PrefixCon xs -> sitcc $ do
@@ -971,115 +767,107 @@ p_pat = \case
971 let f = \case
767 let f = \case
972 Nothing -> txt ".."
768 Nothing -> txt ".."
973 Just x -> located x p_pat_hsRecField
769 Just x -> located x p_pat_hsRecField
974− inci . braces N . sep commaDel f $
975− case dotdot of
770+ inci . braces . sitcc . sep (comma >> breakpoint) f $ case dotdot of
976− Nothing -> Just <$> fields
771+ Nothing -> Just <$> fields
977− Just (L _ n) -> (Just <$> take n fields) ++ [Nothing]
772+ Just n -> (Just <$> take n fields) ++ [Nothing]
978− InfixCon l r -> do
773+ InfixCon x y -> do
979− switchLayout [getLoc l, getLoc r] $ do
980− located l p_pat
774+ located x p_pat
981− breakpoint
775+ space
982− inci $ do
983− p_rdrName pat
776+ p_rdrName pat
984− space
777+ breakpoint
985− located r p_pat
778+ inci (located y p_pat)
986 ConPatOut {} -> notImplemented "ConPatOut" -- presumably created by renamer?
779 ConPatOut {} -> notImplemented "ConPatOut" -- presumably created by renamer?
987− ViewPat NoExtField expr pat -> sitcc $ do
780+ ViewPat NoExt expr pat -> sitcc $ do
988 located expr p_hsExpr
781 located expr p_hsExpr
989− space
990− txt "->"
782+ txt " ->"
991 breakpoint
783 breakpoint
992 inci (located pat p_pat)
784 inci (located pat p_pat)
993− SplicePat NoExtField splice -> p_hsSplice splice
785+ SplicePat NoExt splice -> p_hsSplice splice
994− LitPat NoExtField p -> atom p
786+ LitPat NoExt p -> atom p
995− NPat NoExtField v _ _ -> located v (atom . ol_val)
787+ NPat NoExt v _ _ -> located v (atom . ol_val)
996− NPlusKPat NoExtField n k _ _ _ -> sitcc $ do
788+ NPlusKPat NoExt n k _ _ _ -> sitcc $ do
997 p_rdrName n
789 p_rdrName n
998 breakpoint
790 breakpoint
999 inci $ do
791 inci $ do
1000− txt "+"
792+ txt "+ "
1001− space
1002 located k (atom . ol_val)
793 located k (atom . ol_val)
1003− SigPat NoExtField pat hswc -> do
794+ SigPat hswc pat -> do
1004 located pat p_pat
795 located pat p_pat
1005 p_typeAscription hswc
796 p_typeAscription hswc
1006 CoPat {} -> notImplemented "CoPat" -- apparently created at some later stage
797 CoPat {} -> notImplemented "CoPat" -- apparently created at some later stage
1007− XPat x -> noExtCon x
798+ XPat NoExt -> notImplemented "XPat"
1008
799
1009p_pat_hsRecField :: HsRecField' (FieldOcc GhcPs) (LPat GhcPs) -> R ()
800p_pat_hsRecField :: HsRecField' (FieldOcc GhcPs) (LPat GhcPs) -> R ()
1010p_pat_hsRecField HsRecField {..} = do
801p_pat_hsRecField HsRecField {..} = do
1011 located hsRecFieldLbl $ \x ->
802 located hsRecFieldLbl $ \x ->
1012 p_rdrName (rdrNameFieldOcc x)
803 p_rdrName (rdrNameFieldOcc x)
1013 unless hsRecPun $ do
804 unless hsRecPun $ do
1014− space
805+ txt " ="
1015− equals
1016 breakpoint
806 breakpoint
1017 inci (located hsRecFieldArg p_pat)
807 inci (located hsRecFieldArg p_pat)
1018
808
1019−p_unboxedSum :: BracketStyle -> ConTag -> Arity -> R () -> R ()
809+p_unboxedSum :: ConTag -> Arity -> R () -> R ()
1020−p_unboxedSum s tag arity m = do
810+p_unboxedSum tag arity m = do
1021 let before = tag - 1
811 let before = tag - 1
1022 after = arity - before - 1
812 after = arity - before - 1
1023 args = replicate before Nothing <> [Just m] <> replicate after Nothing
813 args = replicate before Nothing <> [Just m] <> replicate after Nothing
1024− f x =
814+ f (x,i) = do
815+ let isFirst = i == 0
816+ isLast = i == arity - 1
1025 case x :: Maybe (R ()) of
817 case x :: Maybe (R ()) of
1026 Nothing ->
818 Nothing ->
1027− space
819+ unless (isFirst || isLast) space
1028 Just m' -> do
820 Just m' -> do
1029− space
821+ unless isFirst space
1030 m'
822 m'
1031− space
823+ unless isLast space
1032− parensHash s $ sep (txt "|") f args
824+ parensHash $ sep (txt "|") f (zip args [0..])
1033
825
1034p_hsSplice :: HsSplice GhcPs -> R ()
826p_hsSplice :: HsSplice GhcPs -> R ()
1035p_hsSplice = \case
827p_hsSplice = \case
1036− HsTypedSplice NoExtField deco _ expr -> p_hsSpliceTH True expr deco
828+ HsTypedSplice NoExt deco _ expr -> p_hsSpliceTH True expr deco
1037− HsUntypedSplice NoExtField deco _ expr -> p_hsSpliceTH False expr deco
829+ HsUntypedSplice NoExt deco _ expr -> p_hsSpliceTH False expr deco
1038− HsQuasiQuote NoExtField _ quoterName srcSpan str -> do
830+ HsQuasiQuote NoExt _ quoterName srcSpan str -> do
1039 txt "["
831 txt "["
1040 p_rdrName (L srcSpan quoterName)
832 p_rdrName (L srcSpan quoterName)
1041 txt "|"
833 txt "|"
1042− -- QuasiQuoters often rely on precise custom strings. We cannot do any
834+ -- NOTE QuasiQuoters often rely on precise custom strings. We cannot do
1043− -- formatting here without potentially breaking someone's code.
835+ -- any formatting here without potentially breaking someone's code.
1044 atom str
836 atom str
1045 txt "|]"
837 txt "|]"
1046 HsSpliced {} -> notImplemented "HsSpliced"
838 HsSpliced {} -> notImplemented "HsSpliced"
1047− HsSplicedT {} -> notImplemented "HsSplicedT"
839+ XSplice {} -> notImplemented "XSplice"
1048− XSplice x -> noExtCon x
1049
840
1050−p_hsSpliceTH ::
841+p_hsSpliceTH
1051− -- | Typed splice?
842+ :: Bool -- ^ Typed splice?
1052− Bool ->
1053− -- | Splice expression
1054− LHsExpr GhcPs ->
843+ -> LHsExpr GhcPs -- ^ Splice expression
1055− -- | Splice decoration
1056− SpliceDecoration ->
844+ -> SpliceDecoration -- ^ Splice decoration
1057− R ()
845+ -> R ()
1058p_hsSpliceTH isTyped expr = \case
846p_hsSpliceTH isTyped expr = \case
1059 HasParens -> do
847 HasParens -> do
1060 txt decoSymbol
848 txt decoSymbol
1061− parens N (located expr (sitcc . p_hsExpr))
849+ parens (located expr (sitcc . p_hsExpr))
1062 HasDollar -> do
850 HasDollar -> do
1063 txt decoSymbol
851 txt decoSymbol
1064 located expr (sitcc . p_hsExpr)
852 located expr (sitcc . p_hsExpr)
1065− NoParens ->
853+ NoParens -> do
1066 located expr (sitcc . p_hsExpr)
854 located expr (sitcc . p_hsExpr)
1067 where
855 where
1068 decoSymbol = if isTyped then "$$" else "$"
856 decoSymbol = if isTyped then "$$" else "$"
1069
857
1070p_hsBracket :: HsBracket GhcPs -> R ()
858p_hsBracket :: HsBracket GhcPs -> R ()
1071p_hsBracket = \case
859p_hsBracket = \case
1072− ExpBr NoExtField expr -> do
860+ ExpBr NoExt expr -> do
1073 anns <- getEnclosingAnns
861 anns <- getEnclosingAnns
1074 let name = case anns of
862 let name = case anns of
1075− AnnOpenEQ : _ -> ""
863+ AnnOpenEQ:_ -> ""
1076 _ -> "e"
864 _ -> "e"
1077 quote name (located expr p_hsExpr)
865 quote name (located expr p_hsExpr)
1078− PatBr NoExtField pat -> located pat (quote "p" . p_pat)
866+ PatBr NoExt pat -> quote "p" (located pat p_pat)
1079− DecBrL NoExtField decls -> quote "d" (p_hsDecls Free decls)
867+ DecBrL NoExt decls -> quote "d" (p_hsDecls Free decls)
1080− DecBrG NoExtField _ -> notImplemented "DecBrG" -- result of renamer
868+ DecBrG NoExt _ -> notImplemented "DecBrG" -- result of renamer
1081− TypBr NoExtField ty -> quote "t" (located ty p_hsType)
869+ TypBr NoExt ty -> quote "t" (located ty p_hsType)
1082− VarBr NoExtField isSingleQuote name -> do
870+ VarBr NoExt isSingleQuote name -> do
1083 txt (bool "''" "'" isSingleQuote)
871 txt (bool "''" "'" isSingleQuote)
1084 -- HACK As you can see we use 'noLoc' here to be able to pass name into
872 -- HACK As you can see we use 'noLoc' here to be able to pass name into
1085 -- 'p_rdrName' since the latter expects a "located" thing. The problem
873 -- 'p_rdrName' since the latter expects a "located" thing. The problem
@@ -1087,20 +875,19 @@ p_hsBracket = \case
1087 -- turn makes it impossible to detect if there are parentheses around
875 -- turn makes it impossible to detect if there are parentheses around
1088 -- it, etc. So we have to add parentheses manually assuming they are
876 -- it, etc. So we have to add parentheses manually assuming they are
1089 -- necessary for all operators.
877 -- necessary for all operators.
1090− let isOperator =
878+ let isOperator = all
1091− all
1092− (\i -> isPunctuation i || isSymbol i)
879+ (\i -> isPunctuation i || isSymbol i)
1093− (showOutputable (rdrNameOcc name))
880+ (showOutputable (rdrNameOcc name))
1094− && not (doesNotNeedExtraParens name)
881+ && not (doesNotNeedExtraParens name)
1095− wrapper = if isOperator then parens N else id
882+ wrapper = if isOperator then parens else id
1096 wrapper $ p_rdrName (noLoc name)
883 wrapper $ p_rdrName (noLoc name)
1097− TExpBr NoExtField expr -> do
884+ TExpBr NoExt expr -> do
1098 txt "[||"
885 txt "[||"
1099 breakpoint'
886 breakpoint'
1100 located expr p_hsExpr
887 located expr p_hsExpr
1101 breakpoint'
888 breakpoint'
1102 txt "||]"
889 txt "||]"
1103− XBracket x -> noExtCon x
890+ XBracket {} -> notImplemented "XBracket"
1104 where
891 where
1105 quote :: Text -> R () -> R ()
892 quote :: Text -> R () -> R ()
1106 quote name body = do
893 quote name body = do
@@ -1113,65 +900,12 @@ p_hsBracket = \case
1113 breakpoint'
900 breakpoint'
1114 txt "|]"
901 txt "|]"
1115
902
1116−-- Print the source text of a string literal while indenting
1117−-- gaps correctly.
1118−
1119−p_stringLit :: String -> R ()
1120−p_stringLit src =
1121− let s = splitGaps src
1122− singleLine =
1123− txt $ Text.pack (mconcat s)
1124− multiLine =
1125− sitcc $ sep breakpoint (txt . Text.pack) (backslashes s)
1126− in vlayout singleLine multiLine
1127− where
1128− -- Split a string on gaps (backslash delimited whitespaces)
1129− --
1130− -- > splitGaps "bar\\ \\fo\\&o" == ["bar", "fo\\&o"]
1131− splitGaps :: String -> [String]
1132− splitGaps "" = []
1133− splitGaps s =
1134− let -- A backslash and a whitespace starts a "gap"
1135− p (Just '\\', _, _) = True
1136− p (_, '\\', Just c) | ghcSpace c = False
1137− p _ = True
1138− in case span p (zipPrevNext s) of
1139− (l, r) ->
1140− let -- drop the initial '\', any amount of 'ghcSpace', and another '\'
1141− r' = drop 1 . dropWhile ghcSpace . drop 1 $ map orig r
1142− in map orig l : splitGaps r'
1143− -- GHC's definition of whitespaces in strings
1144− -- See: https://gitlab.haskell.org/ghc/ghc/blob/86753475/compiler/parser/Lexer.x#L1653
1145− ghcSpace :: Char -> Bool
1146− ghcSpace c = c <= '\x7f' && is_space c
1147− -- Add backslashes to the inner side of the strings
1148− --
1149− -- > backslashes ["a", "b", "c"] == ["a\\", "\\b\\", "\\c"]
1150− backslashes :: [String] -> [String]
1151− backslashes (x : y : xs) = (x ++ "\\") : backslashes (('\\' : y) : xs)
1152− backslashes xs = xs
1153− -- Attaches previous and next items to each list element
1154− zipPrevNext :: [a] -> [(Maybe a, a, Maybe a)]
1155− zipPrevNext xs =
1156− let z =
1157− zip
1158− (zip (Nothing : map Just xs) xs)
1159− (map Just (tail xs) ++ repeat Nothing)
1160− in map (\((p, x), n) -> (p, x, n)) z
1161− orig (_, x, _) = x
1162−
1163----------------------------------------------------------------------------
903----------------------------------------------------------------------------
1164-- Helpers
904-- Helpers
1165
905
1166−-- | Return the wrapping function controlling the use of braces according to
1167−-- the current layout.
1168−layoutToBraces :: Layout -> R () -> R ()
1169−layoutToBraces = \case
1170− SingleLine -> useBraces
1171− MultiLine -> id
1172−
1173-- | Append each element in both lists with semigroups. If one list is shorter
906-- | Append each element in both lists with semigroups. If one list is shorter
1174-- than the other, return the rest of the longer list unchanged.
907-- than the other, return the rest of the longer list unchanged.
908+
1175liftAppend :: Semigroup a => [a] -> [a] -> [a]
909liftAppend :: Semigroup a => [a] -> [a] -> [a]
1176liftAppend [] [] = []
910liftAppend [] [] = []
1177liftAppend [] (y : ys) = y : ys
911liftAppend [] (y : ys) = y : ys
@@ -1179,15 +913,16 @@ liftAppend (x : xs) [] = x : xs
1179liftAppend (x : xs) (y : ys) = x <> y : liftAppend xs ys
913liftAppend (x : xs) (y : ys) = x <> y : liftAppend xs ys
1180
914
1181getGRHSSpan :: GRHS GhcPs (Located body) -> SrcSpan
915getGRHSSpan :: GRHS GhcPs (Located body) -> SrcSpan
1182−getGRHSSpan (GRHS NoExtField guards body) =
916+getGRHSSpan (GRHS NoExt guards body) =
1183 combineSrcSpans' $ getLoc body :| map getLoc guards
917 combineSrcSpans' $ getLoc body :| map getLoc guards
1184−getGRHSSpan (XGRHS x) = noExtCon x
918+getGRHSSpan (XGRHS NoExt) = notImplemented "XGRHS"
1185
919
1186-- | Place a thing that may have a hanging form. This function handles how
920-- | Place a thing that may have a hanging form. This function handles how
1187-- to separate it from preceding expressions and whether to bump indentation
921-- to separate it from preceding expressions and whether to bump indentation
1188-- depending on what sort of expression we have.
922-- depending on what sort of expression we have.
923+
1189placeHanging :: Placement -> R () -> R ()
924placeHanging :: Placement -> R () -> R ()
1190−placeHanging placement m =
925+placeHanging placement m = do
1191 case placement of
926 case placement of
1192 Hanging -> do
927 Hanging -> do
1193 space
928 space
@@ -1198,165 +933,67 @@ placeHanging placement m =
1198
933
1199-- | Check if given block contains single expression which has a hanging
934-- | Check if given block contains single expression which has a hanging
1200-- form.
935-- form.
936+
1201−blockPlacement ::
937+blockPlacement
1202− (body -> Placement) ->
938+ :: (body -> Placement)
1203− [LGRHS GhcPs (Located body)] ->
939+ -> [LGRHS GhcPs (Located body)]
1204− Placement
940+ -> Placement
1205−blockPlacement placer [L _ (GRHS NoExtField _ (L _ x))] = placer x
941+blockPlacement placer [(L _ (GRHS NoExt _ (L _ x)))] = placer x
1206blockPlacement _ _ = Normal
942blockPlacement _ _ = Normal
1207
943
1208-- | Check if given command has a hanging form.
944-- | Check if given command has a hanging form.
945+
1209cmdPlacement :: HsCmd GhcPs -> Placement
946cmdPlacement :: HsCmd GhcPs -> Placement
1210cmdPlacement = \case
947cmdPlacement = \case
1211− HsCmdLam NoExtField _ -> Hanging
948+ HsCmdLam NoExt _ -> Hanging
1212− HsCmdCase NoExtField _ _ -> Hanging
949+ HsCmdCase NoExt _ _ -> Hanging
1213− HsCmdDo NoExtField _ -> Hanging
950+ HsCmdDo NoExt _ -> Hanging
1214 _ -> Normal
951 _ -> Normal
1215
952
1216cmdTopPlacement :: HsCmdTop GhcPs -> Placement
953cmdTopPlacement :: HsCmdTop GhcPs -> Placement
1217cmdTopPlacement = \case
954cmdTopPlacement = \case
1218− HsCmdTop NoExtField (L _ x) -> cmdPlacement x
955+ HsCmdTop NoExt (L _ x) -> cmdPlacement x
1219− XCmdTop x -> noExtCon x
956+ XCmdTop {} -> notImplemented "XCmdTop"
1220
957
1221-- | Check if given expression has a hanging form.
958-- | Check if given expression has a hanging form.
959+
1222exprPlacement :: HsExpr GhcPs -> Placement
960exprPlacement :: HsExpr GhcPs -> Placement
1223exprPlacement = \case
961exprPlacement = \case
1224 -- Only hang lambdas with single line parameter lists
962 -- Only hang lambdas with single line parameter lists
1225− HsLam NoExtField mg -> case mg of
963+ HsLam NoExt mg -> case mg of
1226− MG _ (L _ [L _ (Match NoExtField _ (x : xs) _)]) _
964+ MG _ (L _ [L _ (Match NoExt _ (x:xs) _)]) _
1227− | isOneLineSpan (combineSrcSpans' $ fmap getLoc (x :| xs)) ->
965+ | isOneLineSpan (combineSrcSpans' $ fmap getLoc (x :| xs))
1228− Hanging
966+ -> Hanging
1229 _ -> Normal
967 _ -> Normal
1230− HsLamCase NoExtField _ -> Hanging
968+ HsLamCase NoExt _ -> Hanging
1231− HsCase NoExtField _ _ -> Hanging
969+ HsCase NoExt _ _ -> Hanging
1232− HsDo NoExtField DoExpr _ -> Hanging
970+ HsDo NoExt DoExpr _ -> Hanging
1233− HsDo NoExtField MDoExpr _ -> Hanging
971+ HsDo NoExt MDoExpr _ -> Hanging
1234− OpApp NoExtField _ op y ->
972+ RecordCon NoExt _ _ -> Hanging
1235− case (fmap getOpNameStr . getOpName . unLoc) op of
973+ -- If the rightmost expression in an operator chain is hanging, make the
1236− Just "$" -> exprPlacement (unLoc y)
974+ -- whole block hanging; so that we can use the common @f = foo $ do@
1237− _ -> Normal
975+ -- style.
1238− HsApp NoExtField _ y -> exprPlacement (unLoc y)
976+ OpApp NoExt _ _ y -> exprPlacement (unLoc y)
1239− HsProc NoExtField p _ ->
977+ HsProc NoExt (L s _) _ ->
1240 -- Indentation breaks if pattern is longer than one line and left
978 -- Indentation breaks if pattern is longer than one line and left
1241 -- hanging. Consequently, only apply hanging when it is safe.
979 -- hanging. Consequently, only apply hanging when it is safe.
1242− if isOneLineSpan (getLoc p)
980+ if isOneLineSpan s
1243− then Hanging
981+ then Hanging
1244− else Normal
982+ else Normal
1245 _ -> Normal
983 _ -> Normal
1246
984
1247withGuards :: [LGRHS GhcPs (Located body)] -> Bool
985withGuards :: [LGRHS GhcPs (Located body)] -> Bool
1248withGuards = any (checkOne . unLoc)
986withGuards = any (checkOne . unLoc)
1249 where
987 where
1250 checkOne :: GRHS GhcPs (Located body) -> Bool
988 checkOne :: GRHS GhcPs (Located body) -> Bool
1251− checkOne (GRHS NoExtField [] _) = False
989+ checkOne (GRHS NoExt [] _) = False
1252 checkOne _ = True
990 checkOne _ = True
1253
991
1254−exprOpTree :: LHsExpr GhcPs -> OpTree (LHsExpr GhcPs) (LHsExpr GhcPs)
1255−exprOpTree (L _ (OpApp NoExtField x op y)) = OpBranch (exprOpTree x) op (exprOpTree y)
1256−exprOpTree n = OpNode n
1257−
1258−getOpName :: HsExpr GhcPs -> Maybe RdrName
1259−getOpName = \case
1260− HsVar NoExtField (L _ a) -> Just a
1261− _ -> Nothing
1262−
1263−getOpNameStr :: RdrName -> String
1264−getOpNameStr = occNameString . rdrNameOcc
1265−
1266−p_exprOpTree ::
1267− -- | Bracket style to use
1268− BracketStyle ->
1269− OpTree (LHsExpr GhcPs) (LHsExpr GhcPs) ->
1270− R ()
1271−p_exprOpTree s (OpNode x) = located x (p_hsExpr' s)
1272−p_exprOpTree s (OpBranch x op y) = do
1273− -- If the beginning of the first argument and the second argument are on
1274− -- the same line, and the second argument has a hanging form, use hanging
1275− -- placement.
1276− let placement =
1277− if isOneLineSpan
1278− (mkSrcSpan (srcSpanStart (opTreeLoc x)) (srcSpanStart (opTreeLoc y)))
1279− then case y of
1280− OpNode (L _ n) -> exprPlacement n
1281− _ -> Normal
1282− else Normal
1283− -- Distinguish holes used in infix notation.
1284− -- eg. '1 _foo 2' and '1 `_foo` 2'
1285− opWrapper = case unLoc op of
1286− HsUnboundVar NoExtField _ -> backticks
1287− _ -> id
1288− layout <- getLayout
1289− let ub = case layout of
1290− SingleLine -> useBraces
1291− MultiLine -> case placement of
1292− Hanging -> useBraces
1293− Normal -> dontUseBraces
1294− opNameStr = (fmap getOpNameStr . getOpName . unLoc) op
1295− gotDollar = opNameStr == Just "$"
1296− gotColon = opNameStr == Just ":"
1297− gotRecordDot = isRecordDot (unLoc op) (opTreeLoc y)
1298− lhs =
1299− switchLayout [opTreeLoc x] $
1300− p_exprOpTree s x
1301− p_op = located op (opWrapper . p_hsExpr)
1302− p_y = switchLayout [opTreeLoc y] (p_exprOpTree N y)
1303− isSection = case (opTreeLoc x, getLoc op) of
1304− (RealSrcSpan treeSpan, RealSrcSpan opSpan) ->
1305− srcSpanEndCol treeSpan /= srcSpanStartCol opSpan
1306− _ -> False
1307− isDoBlock = \case
1308− OpNode (L _ HsDo {}) -> True
1309− _ -> False
1310− useRecordDot' <- useRecordDot
1311− if
1312− | gotColon -> do
1313− lhs
1314− space
1315− p_op
1316− case placement of
1317− Hanging -> do
1318− space
1319− p_y
1320− Normal -> do
1321− breakpoint
1322− inciIf (isDoBlock y) p_y
1323− | gotDollar
1324− && isOneLineSpan (opTreeLoc x)
1325− && placement == Normal -> do
1326− useBraces lhs
1327− space
1328− p_op
1329− breakpoint
1330− inci p_y
1331− | useRecordDot' && gotRecordDot -> do
1332− lhs
1333− when isSection space
1334− p_op
1335− p_y
1336− | otherwise -> do
1337− ub lhs
1338− placeHanging placement $ do
1339− p_op
1340− space
1341− p_y
1342−
1343−-- | Return 'True' if given expression is a record-dot operator expression.
1344−isRecordDot ::
1345− -- | Operator expression
1346− HsExpr GhcPs ->
1347− -- | Span of the expression on the right-hand side of the operator
1348− SrcSpan ->
1349− Bool
1350−isRecordDot op (RealSrcSpan ySpan) = case op of
1351− HsVar NoExtField (L (RealSrcSpan opSpan) opName) ->
1352− (getOpNameStr opName == ".") && (srcSpanEndCol opSpan == srcSpanStartCol ySpan)
1353− _ -> False
1354−isRecordDot _ _ = False
1355−
1356-- | Get annotations for the enclosing element.
992-- | Get annotations for the enclosing element.
993+
1357getEnclosingAnns :: R [AnnKeywordId]
994getEnclosingAnns :: R [AnnKeywordId]
1358getEnclosingAnns = do
995getEnclosingAnns = do
1359 e <- getEnclosingSpan (const True)
996 e <- getEnclosingSpan (const True)
1360 case e of
997 case e of
1361 Nothing -> return []
998 Nothing -> return []
1362− Just e' -> getAnns (RealSrcSpan e')
999+ Just e' -> getAnns (RealSrcSpan e')
src/Ormolu/Printer/Meat/Declaration/Value.hs-boot+7−6
@@ -1,9 +1,8 @@
1module Ormolu.Printer.Meat.Declaration.Value
1module Ormolu.Printer.Meat.Declaration.Value
2− ( p_valDecl,
2+ ( p_valDecl
3− p_pat,
3+ , p_pat
4− p_hsExpr,
4+ , p_hsExpr
5− p_hsSplice,
5+ , p_hsSplice
6− p_stringLit,
7 )
6 )
8where
7where
9
8
@@ -11,7 +10,9 @@ import GHC
11import Ormolu.Printer.Combinators
10import Ormolu.Printer.Combinators
12
11
13p_valDecl :: HsBindLR GhcPs GhcPs -> R ()
12p_valDecl :: HsBindLR GhcPs GhcPs -> R ()
13+
14p_pat :: Pat GhcPs -> R ()
14p_pat :: Pat GhcPs -> R ()
15+
15p_hsExpr :: HsExpr GhcPs -> R ()
16p_hsExpr :: HsExpr GhcPs -> R ()
17+
16p_hsSplice :: HsSplice GhcPs -> R ()
18p_hsSplice :: HsSplice GhcPs -> R ()
17−p_stringLit :: String -> R ()
src/Ormolu/Printer/Meat/Declaration/Warning.hs+13−11
@@ -1,9 +1,9 @@
1−{-# LANGUAGE LambdaCase #-}
1+{-# LANGUAGE LambdaCase #-}
2{-# LANGUAGE OverloadedStrings #-}
2{-# LANGUAGE OverloadedStrings #-}
3
3
4module Ormolu.Printer.Meat.Declaration.Warning
4module Ormolu.Printer.Meat.Declaration.Warning
5− ( p_warnDecls,
5+ ( p_warnDecls
6− p_moduleWarning,
6+ , p_moduleWarning
7 )
7 )
8where
8where
9
9
@@ -13,28 +13,30 @@ import Data.Text (Text)
13import GHC
13import GHC
14import Ormolu.Printer.Combinators
14import Ormolu.Printer.Combinators
15import Ormolu.Printer.Meat.Common
15import Ormolu.Printer.Meat.Common
16+import Ormolu.Utils
16
17
17p_warnDecls :: WarnDecls GhcPs -> R ()
18p_warnDecls :: WarnDecls GhcPs -> R ()
18−p_warnDecls (Warnings NoExtField _ warnings) =
19+p_warnDecls (Warnings NoExt _ warnings) =
19 traverse_ (located' p_warnDecl) warnings
20 traverse_ (located' p_warnDecl) warnings
20−p_warnDecls (XWarnDecls x) = noExtCon x
21+p_warnDecls XWarnDecls {} = notImplemented "XWarnDecls"
21
22
22p_warnDecl :: WarnDecl GhcPs -> R ()
23p_warnDecl :: WarnDecl GhcPs -> R ()
23−p_warnDecl (Warning NoExtField functions warningTxt) =
24+p_warnDecl (Warning NoExt functions warningTxt) =
24 p_topLevelWarning functions warningTxt
25 p_topLevelWarning functions warningTxt
25−p_warnDecl (XWarnDecl x) = noExtCon x
26+p_warnDecl XWarnDecl {} = notImplemented "XWarnDecl"
26
27
27p_moduleWarning :: WarningTxt -> R ()
28p_moduleWarning :: WarningTxt -> R ()
28p_moduleWarning wtxt = do
29p_moduleWarning wtxt = do
29 let (pragmaText, lits) = warningText wtxt
30 let (pragmaText, lits) = warningText wtxt
31+ switchLayout (getLoc <$> lits) $ do
30− inci $ pragma pragmaText $ inci $ p_lits lits
32+ inci $ pragma pragmaText (inci $ p_lits lits)
31
33
32p_topLevelWarning :: [Located RdrName] -> WarningTxt -> R ()
34p_topLevelWarning :: [Located RdrName] -> WarningTxt -> R ()
33p_topLevelWarning fnames wtxt = do
35p_topLevelWarning fnames wtxt = do
34 let (pragmaText, lits) = warningText wtxt
36 let (pragmaText, lits) = warningText wtxt
35− switchLayout (fmap getLoc fnames ++ fmap getLoc lits) $
37+ switchLayout (fmap getLoc fnames ++ fmap getLoc lits) $ do
36 pragma pragmaText . inci $ do
38 pragma pragmaText . inci $ do
37− sep commaDel p_rdrName fnames
39+ sitcc $ sep (comma >> breakpoint) p_rdrName fnames
38 breakpoint
40 breakpoint
39 p_lits lits
41 p_lits lits
40
42
@@ -46,4 +48,4 @@ warningText = \case
46p_lits :: [Located StringLiteral] -> R ()
48p_lits :: [Located StringLiteral] -> R ()
47p_lits = \case
49p_lits = \case
48 [l] -> atom l
50 [l] -> atom l
49− ls -> brackets N $ sep commaDel atom ls
51+ ls -> brackets . sitcc $ sep (comma >> breakpoint) atom ls
src/Ormolu/Printer/Meat/ImportExport.hs+54−94
@@ -1,19 +1,21 @@
1−{-# LANGUAGE LambdaCase #-}
1+{-# LANGUAGE LambdaCase #-}
2{-# LANGUAGE OverloadedStrings #-}
2{-# LANGUAGE OverloadedStrings #-}
3−{-# LANGUAGE RecordWildCards #-}
3+{-# LANGUAGE RecordWildCards #-}
4
4
5-- | Rendering of import and export lists.
5-- | Rendering of import and export lists.
6+
6module Ormolu.Printer.Meat.ImportExport
7module Ormolu.Printer.Meat.ImportExport
7− ( p_hsmodExports,
8+ ( p_hsmodExports
8− p_hsmodImport,
9+ , p_hsmodImport
9 )
10 )
10where
11where
11
12
12import Control.Monad
13import Control.Monad
13import GHC
14import GHC
15+import HsImpExp (IE (..))
14import Ormolu.Printer.Combinators
16import Ormolu.Printer.Combinators
15import Ormolu.Printer.Meat.Common
17import Ormolu.Printer.Meat.Common
16−import Ormolu.Utils (RelativePos (..), attachRelativePos)
18+import Ormolu.Utils
17
19
18p_hsmodExports :: [LIE GhcPs] -> R ()
20p_hsmodExports :: [LIE GhcPs] -> R ()
19p_hsmodExports [] = do
21p_hsmodExports [] = do
@@ -21,106 +23,64 @@ p_hsmodExports [] = do
21 breakpoint'
23 breakpoint'
22 txt ")"
24 txt ")"
23p_hsmodExports xs =
25p_hsmodExports xs =
24− parens N $ do
25− layout <- getLayout
26− sep
27− breakpoint
28− (\(p, l) -> sitcc (located l (p_lie layout p)))
26+ parens . sitcc $ sep (comma >> breakpoint) (sitcc . located' p_lie) xs
29− (attachRelativePos xs)
30
27
31−p_hsmodImport :: Bool -> ImportDecl GhcPs -> R ()
28+p_hsmodImport :: ImportDecl GhcPs -> R ()
32−p_hsmodImport useQualifiedPost ImportDecl {..} = do
29+p_hsmodImport ImportDecl {..} = line $ do
33− txt "import"
30+ txt "import "
34− space
35− when ideclSource (txt "{-# SOURCE #-}")
31+ when ideclSource $
36− space
32+ txt "{-# SOURCE #-} "
37− when ideclSafe (txt "safe")
33+ when ideclSafe $
38− space
34+ txt "safe "
39− when
35+ when ideclQualified $
40− (isImportDeclQualified ideclQualified && not useQualifiedPost)
41− (txt "qualified")
36+ txt "qualified "
42− space
43 case ideclPkgQual of
37 case ideclPkgQual of
44 Nothing -> return ()
38 Nothing -> return ()
39+ Just slit -> do
45− Just slit -> atom slit
40+ atom slit
46− space
41+ space
47− inci $ do
48− located ideclName atom
42+ located ideclName atom
49− when
50− (isImportDeclQualified ideclQualified && useQualifiedPost)
51− (space >> txt "qualified")
52− case ideclAs of
43+ case ideclAs of
53− Nothing -> return ()
44+ Nothing -> return ()
54− Just l -> do
45+ Just l -> do
55− space
56− txt "as"
46+ txt " as "
57− space
58− located l atom
47+ located l atom
59− space
60− case ideclHiding of
48+ case ideclHiding of
61− Nothing -> return ()
49+ Nothing -> return ()
62− Just (hiding, _) ->
50+ Just (hiding, _) ->
63− when hiding (txt "hiding")
51+ when hiding $
52+ txt " hiding"
64− case ideclHiding of
53+ case ideclHiding of
65− Nothing -> return ()
54+ Nothing -> return ()
66− Just (_, L _ xs) -> do
55+ Just (_, (L _ a)) -> do
67− breakpoint
56+ breakpoint
68− parens N $ do
57+ inci . parens . sitcc $
69− layout <- getLayout
70− sep
71− breakpoint
72− (\(p, l) -> sitcc (located l (p_lie layout p)))
58+ sep (comma >> breakpoint) (sitcc . located' p_lie) a
73− (attachRelativePos xs)
74− newline
75−p_hsmodImport _ (XImportDecl x) = noExtCon x
59+p_hsmodImport (XImportDecl NoExt) = notImplemented "XImportDecl"
76
60
77−p_lie :: Layout -> RelativePos -> IE GhcPs -> R ()
61+p_lie :: IE GhcPs -> R ()
78−p_lie encLayout relativePos = \case
62+p_lie = \case
79− IEVar NoExtField l1 -> do
80− located l1 p_ieWrappedName
63+ IEVar NoExt l1 -> located l1 p_ieWrappedName
81− p_comma
82− IEThingAbs NoExtField l1 -> do
83− located l1 p_ieWrappedName
64+ IEThingAbs NoExt l1 -> located l1 p_ieWrappedName
84− p_comma
85− IEThingAll NoExtField l1 -> do
65+ IEThingAll NoExt l1 -> do
86 located l1 p_ieWrappedName
66 located l1 p_ieWrappedName
87− space
88− txt "(..)"
67+ txt " (..)"
89− p_comma
90− IEThingWith NoExtField l1 w xs _ -> sitcc $ do
68+ IEThingWith NoExt l1 w xs _ -> sitcc $ do
69+ -- XXX I have no idea what field labels are in this context.
91 located l1 p_ieWrappedName
70 located l1 p_ieWrappedName
92 breakpoint
71 breakpoint
93 inci $ do
72 inci $ do
94 let names :: [R ()]
73 let names :: [R ()]
95 names = located' p_ieWrappedName <$> xs
74 names = located' p_ieWrappedName <$> xs
96− parens N . sep commaDel sitcc $
75+ parens . sitcc . sep (comma >> breakpoint) sitcc $
97 case w of
76 case w of
98 NoIEWildcard -> names
77 NoIEWildcard -> names
99 IEWildcard n ->
78 IEWildcard n ->
100 let (before, after) = splitAt n names
79 let (before, after) = splitAt n names
101− in before ++ [txt ".."] ++ after
80+ in before ++ [txt ".."] ++ after
102− p_comma
103− IEModuleContents NoExtField l1 -> do
104− located l1 p_hsmodName
81+ IEModuleContents NoExt l1 -> located l1 p_hsmodName
105− p_comma
82+ -- XXX I have no idea what these things are for.
106− IEGroup NoExtField n str -> do
83+ IEGroup NoExt _ _ -> return ()
107− case relativePos of
84+ IEDoc NoExt _ -> return ()
108− SinglePos -> return ()
85+ IEDocNamed NoExt _ -> return ()
109− FirstPos -> return ()
86+ XIE NoExt -> notImplemented "XIE"
110− MiddlePos -> newline
111− LastPos -> newline
112− p_hsDocString (Asterisk n) False (noLoc str)
113− IEDoc NoExtField str ->
114− p_hsDocString Pipe False (noLoc str)
115− IEDocNamed NoExtField str -> p_hsDocName str
116− XIE x -> noExtCon x
117− where
118− p_comma =
119− case encLayout of
120− SingleLine ->
121− case relativePos of
122− SinglePos -> return ()
123− FirstPos -> comma
124− MiddlePos -> comma
125− LastPos -> return ()
126− MultiLine -> comma
src/Ormolu/Printer/Meat/Module.hs+42−49
@@ -1,20 +1,19 @@
1−{-# LANGUAGE LambdaCase #-}
1+{-# LANGUAGE LambdaCase #-}
2{-# LANGUAGE OverloadedStrings #-}
2{-# LANGUAGE OverloadedStrings #-}
3−{-# LANGUAGE RecordWildCards #-}
3+{-# LANGUAGE RecordWildCards #-}
4
4
5-- | Rendering of modules.
5-- | Rendering of modules.
6+
6module Ormolu.Printer.Meat.Module
7module Ormolu.Printer.Meat.Module
7− ( p_hsModule,
8+ ( p_hsModule
8 )
9 )
9where
10where
10
11
11import Control.Monad
12import Control.Monad
12−import qualified Data.Text as T
13+import Data.Maybe (isJust)
13import GHC
14import GHC
14−import Ormolu.Imports (normalizeImports)
15+import Ormolu.Imports
15−import Ormolu.Parser.CommentStream
16import Ormolu.Parser.Pragma
16import Ormolu.Parser.Pragma
17−import Ormolu.Parser.Shebang
18import Ormolu.Printer.Combinators
17import Ormolu.Printer.Combinators
19import Ormolu.Printer.Comments
18import Ormolu.Printer.Comments
20import Ormolu.Printer.Meat.Common
19import Ormolu.Printer.Meat.Common
@@ -23,55 +22,49 @@ import Ormolu.Printer.Meat.Declaration.Warning
23import Ormolu.Printer.Meat.ImportExport
22import Ormolu.Printer.Meat.ImportExport
24import Ormolu.Printer.Meat.Pragma
23import Ormolu.Printer.Meat.Pragma
25
24
26−-- | Render a module.
25+p_hsModule :: [Pragma] -> ParsedSource -> R ()
27−p_hsModule ::
26+p_hsModule pragmas (L moduleSpan HsModule {..}) = do
28− -- | Stack header
27+ -- NOTE If span of exports in multiline, the whole thing is multiline.
29− Maybe (RealLocated Comment) ->
28+ -- This is especially important because span of module itself always seems
30− -- | Shebangs
29+ -- to have length zero, so it's not reliable for layout selection.
31− [Shebang] ->
30+ let exportSpans = maybe [] (\(L s _) -> [s]) hsmodExports
32− -- | Pragmas and the associated comments
31+ deprecSpan = maybe [] (\(L s _) -> [s]) hsmodDeprecMessage
33− [([RealLocated Comment], Pragma)] ->
32+ spans' = exportSpans ++ deprecSpan ++ [moduleSpan]
34− -- | Whether to use postfix qualified imports
33+ switchLayout spans' $ do
35− Bool ->
34+ let hasLangPragmas = not (null pragmas)
36− -- | AST to print
35+ hasModuleHeader = isJust hsmodName
37− HsModule GhcPs ->
36+ hasImports = not (null hsmodImports)
38− R ()
37+ hasDecls = not (null hsmodDecls)
39−p_hsModule mstackHeader shebangs pragmas qualifiedPost HsModule {..} = do
40− let deprecSpan = maybe [] (\(L s _) -> [s]) hsmodDeprecMessage
41− exportSpans = maybe [] (\(L s _) -> [s]) hsmodExports
42− switchLayout (deprecSpan <> exportSpans) $ do
43− forM_ shebangs $ \(Shebang x) ->
44− located x $ \shebang -> do
45− txt (T.pack shebang)
46− newline
47− forM_ mstackHeader $ \(L spn comment) -> do
48− spitCommentNow spn comment
49− newline
50− newline
51 p_pragmas pragmas
38 p_pragmas pragmas
52− newline
39+ when (hasLangPragmas &&
40+ (hasModuleHeader || hasImports || hasDecls)) $
41+ newline
53 case hsmodName of
42 case hsmodName of
54− Nothing -> return ()
43+ Nothing -> pure ()
55− Just hsmodName' -> do
44+ Just hsmodName' -> line $ do
56− located hsmodName' $ \name -> do
45+ located hsmodName' p_hsmodName
57− forM_ hsmodHaddockModHeader (p_hsDocString Pipe True)
58− p_hsmodName name
59− breakpoint
60 forM_ hsmodDeprecMessage $ \w -> do
46 forM_ hsmodDeprecMessage $ \w -> do
61− located' p_moduleWarning w
62 breakpoint
47 breakpoint
48+ located' p_moduleWarning w
63 case hsmodExports of
49 case hsmodExports of
64 Nothing -> return ()
50 Nothing -> return ()
65− Just l -> do
51+ Just hsmodExports' -> do
66− located l $ \exports -> do
67− inci (p_hsmodExports exports)
68 breakpoint
52 breakpoint
53+ inci (p_hsmodExports (unLoc hsmodExports'))
54+ breakpoint
69 txt "where"
55 txt "where"
70− newline
56+ when (hasImports || hasDecls) newline
71− newline
57+ forM_ (sortImports hsmodImports) (located' p_hsmodImport)
72− forM_ (normalizeImports hsmodImports) (located' (p_hsmodImport qualifiedPost))
58+ when (hasImports && hasDecls) newline
73− newline
59+ switchLayout (map getLoc hsmodDecls) $ do
74− switchLayout (getLoc <$> hsmodDecls) $ do
75 p_hsDecls Free hsmodDecls
60 p_hsDecls Free hsmodDecls
76− newline
61+ trailingComments <- hasMoreComments
62+ when hasDecls $ do
63+ newlineModified <- isNewlineModified
64+ newline
65+ -- In this case we need to insert a newline between the comments
66+ -- output as a side effect of the previous newline and trailing
67+ -- comments to prevent them from merging.
68+ when (newlineModified && trailingComments) newline
69+ when (trailingComments && hasModuleHeader) newline
77 spitRemainingComments
70 spitRemainingComments
src/Ormolu/Printer/Meat/Pragma.hs+20−74
@@ -1,91 +1,37 @@
1−{-# LANGUAGE LambdaCase #-}
1+-- | Pretty-printing of language pragmas.
2+
3+{-# LANGUAGE LambdaCase #-}
2{-# LANGUAGE OverloadedStrings #-}
4{-# LANGUAGE OverloadedStrings #-}
3−{-# LANGUAGE TupleSections #-}
5+{-# LANGUAGE TupleSections #-}
4
6
5−-- | Pretty-printing of language pragmas.
6module Ormolu.Printer.Meat.Pragma
7module Ormolu.Printer.Meat.Pragma
7− ( p_pragmas,
8+ ( p_pragmas
8 )
9 )
9where
10where
10
11
11−import Control.Monad
12−import Data.Char (isUpper)
13−import qualified Data.List as L
14−import Data.Maybe (listToMaybe)
15−import qualified Data.Text as T
16−import Ormolu.Parser.CommentStream
17−import Ormolu.Parser.Pragma (Pragma (..))
18import Ormolu.Printer.Combinators
12import Ormolu.Printer.Combinators
19−import Ormolu.Printer.Comments
13+import Ormolu.Parser.Pragma (Pragma (..))
20−import SrcLoc
14+import qualified Data.Set as S
21−
15+import qualified Data.Text as T
22−-- | Pragma classification.
23−data PragmaTy
24− = Language LanguagePragmaClass
25− | OptionsGHC
26− | OptionsHaddock
27− deriving (Eq, Ord)
28
16
29−-- | Language pragma classification.
17+data PragmaTy = Language | OptionsGHC | OptionsHaddock
30−--
31−-- The order in which language pragmas are put in the input sometimes
32−-- matters. This is because some language extensions can enable other
33−-- extensions, yet the extensions coming later in the list have the ability
34−-- to change it. So here we classify all extensions by assigning one of the
35−-- four groups to them. Then we only sort inside of the groups.
36−--
37−-- 'Ord' instance of this data type is what affects the sorting.
38−--
39−-- See also: <https://github.com/tweag/ormolu/issues/404>
40−data LanguagePragmaClass
41− = -- | All other extensions
42− Normal
43− | -- | Extensions starting with "No"
44− Disabling
45− | -- | Extensions that should go after everything else
46− Final
47 deriving (Eq, Ord)
18 deriving (Eq, Ord)
48
19
49−-- | Print a collection of 'Pragma's with their associated comments.
20+p_pragmas :: [Pragma] -> R ()
50−p_pragmas :: [([RealLocated Comment], Pragma)] -> R ()
21+p_pragmas ps =
51−p_pragmas ps = do
22+ let prepare = concatMap $ \case
52− let prepare = L.sortOn snd . L.nub . concatMap analyze
23+ PragmaLanguage xs -> (Language,) <$> xs
53− analyze = \case
24+ PragmaOptionsGHC x -> [(OptionsGHC, x)]
54− (cs, PragmaLanguage xs) ->
25+ PragmaOptionsHaddock x -> [(OptionsHaddock, x)]
55− let f x = (cs, (Language (classifyLanguagePragma x), x))
26+ in mapM_ (uncurry p_pragma) (S.toAscList . S.fromList . prepare $ ps)
56− in f <$> xs
57− (cs, PragmaOptionsGHC x) -> [(cs, (OptionsGHC, x))]
58− (cs, PragmaOptionsHaddock x) -> [(cs, (OptionsHaddock, x))]
59− forM_ (prepare ps) $ \(cs, (pragmaTy, x)) ->
60− p_pragma cs pragmaTy x
61
27
62−p_pragma :: [RealLocated Comment] -> PragmaTy -> String -> R ()
28+p_pragma :: PragmaTy -> String -> R ()
63−p_pragma comments ty x = do
29+p_pragma ty c = line $ do
64− forM_ comments $ \(L l comment) -> do
65− spitCommentNow l comment
66− newline
67 txt "{-# "
30 txt "{-# "
68 txt $ case ty of
31 txt $ case ty of
69− Language _ -> "LANGUAGE"
32+ Language -> "LANGUAGE"
70 OptionsGHC -> "OPTIONS_GHC"
33 OptionsGHC -> "OPTIONS_GHC"
71 OptionsHaddock -> "OPTIONS_HADDOCK"
34 OptionsHaddock -> "OPTIONS_HADDOCK"
72 space
35 space
73− txt (T.pack x)
36+ txt (T.pack c)
74 txt " #-}"
37 txt " #-}"
75− newline
76−
77−-- | Classify a 'LanguagePragma'.
78−classifyLanguagePragma :: String -> LanguagePragmaClass
79−classifyLanguagePragma = \case
80− "ImplicitPrelude" -> Final
81− "CUSKs" -> Final
82− str ->
83− case splitAt 2 str of
84− ("No", rest) ->
85− case listToMaybe rest of
86− Nothing -> Normal
87− Just x ->
88− if isUpper x
89− then Disabling
90− else Normal
91− _ -> Normal
src/Ormolu/Printer/Meat/Type.hs+130−201
@@ -1,257 +1,191 @@
1−{-# LANGUAGE LambdaCase #-}
1+{-# LANGUAGE LambdaCase #-}
2{-# LANGUAGE OverloadedStrings #-}
2{-# LANGUAGE OverloadedStrings #-}
3−{-# LANGUAGE RecordWildCards #-}
3+{-# LANGUAGE RecordWildCards #-}
4
4
5-- | Rendering of types.
5-- | Rendering of types.
6+
6module Ormolu.Printer.Meat.Type
7module Ormolu.Printer.Meat.Type
7− ( p_hsType,
8+ ( p_hsType
8− p_hsTypePostDoc,
9+ , p_hsContext
9− hasDocStrings,
10+ , p_hsTyVarBndr
10− p_hsContext,
11+ , p_conDeclFields
11− p_hsTyVarBndr,
12+ , tyVarsToTypes
12− p_forallBndrs,
13− p_conDeclFields,
14− tyVarsToTypes,
15 )
13 )
16where
14where
17
15
18−import Data.Data (Data)
16+import GHC
19−import GHC hiding (isPromoted)
20import Ormolu.Printer.Combinators
17import Ormolu.Printer.Combinators
21import Ormolu.Printer.Meat.Common
18import Ormolu.Printer.Meat.Common
22−import {-# SOURCE #-} Ormolu.Printer.Meat.Declaration.Value (p_hsSplice, p_stringLit)
23−import Ormolu.Printer.Operators
24import Ormolu.Utils
19import Ormolu.Utils
20+import SrcLoc (combineSrcSpans)
21+import {-# SOURCE #-} Ormolu.Printer.Meat.Declaration.Value (p_hsSplice)
25
22
26p_hsType :: HsType GhcPs -> R ()
23p_hsType :: HsType GhcPs -> R ()
27−p_hsType t = p_hsType' (hasDocStrings t) PipeStyle t
24+p_hsType = \case
28−
25+ HsForAllTy NoExt bndrs t -> do
29−p_hsTypePostDoc :: HsType GhcPs -> R ()
26+ txt "forall "
30−p_hsTypePostDoc t = p_hsType' (hasDocStrings t) CaretStyle t
27+ sep space (located' p_hsTyVarBndr) bndrs
31−
28+ txt ". "
32−-- | How to render Haddocks associated with a type.
29+ p_hsType (unLoc t)
33−data TypeDocStyle
30+ HsQualTy NoExt qs t -> do
34− = PipeStyle
35− | CaretStyle
36−
37−p_hsType' :: Bool -> TypeDocStyle -> HsType GhcPs -> R ()
38−p_hsType' multilineArgs docStyle = \case
39− HsForAllTy NoExtField visibility bndrs t -> do
40− p_forallBndrs visibility p_hsTyVarBndr bndrs
41− interArgBreak
42− p_hsTypeR (unLoc t)
43− HsQualTy NoExtField qs t -> do
44 located qs p_hsContext
31 located qs p_hsContext
45− space
32+ breakpoint
46− txt "=>"
33+ txt "=> "
47− interArgBreak
48 case unLoc t of
34 case unLoc t of
49− HsQualTy {} -> p_hsTypeR (unLoc t)
35+ HsQualTy {} -> p_hsType (unLoc t)
50− HsFunTy {} -> p_hsTypeR (unLoc t)
36+ HsFunTy {} -> p_hsType (unLoc t)
51− _ -> located t p_hsTypeR
37+ _ -> located t p_hsType
52− HsTyVar NoExtField p n -> do
38+ HsTyVar NoExt p n -> do
53 case p of
39 case p of
54− IsPromoted -> do
40+ Promoted -> txt "'"
55− txt "'"
56− case showOutputable (unLoc n) of
57− _ : '\'' : _ -> space
58− _ -> return ()
59 NotPromoted -> return ()
41 NotPromoted -> return ()
42+ case showOutputable (unLoc n) of
43+ _ : '\'' : _ -> space
44+ _ -> return ()
60 p_rdrName n
45 p_rdrName n
61− HsAppTy NoExtField f x -> do
46+ HsAppTy NoExt f x -> sitcc $ do
62− let -- In order to format type applications with multiple parameters
47+ located f p_hsType
63− -- nicer, traverse the AST to gather the function and all the
64− -- parameters together.
65− gatherArgs f' knownArgs =
66− case f' of
67− L _ (HsAppTy _ l r) -> gatherArgs l (r : knownArgs)
68− _ -> (f', knownArgs)
69− (func, args) = gatherArgs f [x]
70− switchLayout (getLoc f : fmap getLoc args) . sitcc $ do
71− located func p_hsType
72− breakpoint
73− inci $
74− sep breakpoint (located' p_hsType) args
75− HsAppKindTy _ ty kd -> sitcc $ do
76− -- The first argument is the location of the "@..." part. Not 100% sure,
77− -- but I think we can ignore it as long as we use 'located' on both the
78− -- type and the kind.
79− located ty p_hsType
80 breakpoint
48 breakpoint
81− inci $ do
49+ inci (located x p_hsType)
82− txt "@"
50+ HsFunTy NoExt x y@(L _ y') -> do
83− located kd p_hsType
84− HsFunTy NoExtField x y@(L _ y') -> do
85 located x p_hsType
51 located x p_hsType
86− space
52+ breakpoint
87− txt "->"
53+ txt "-> "
88− interArgBreak
89 case y' of
54 case y' of
90− HsFunTy {} -> p_hsTypeR y'
55+ HsFunTy{} -> p_hsType y'
91− _ -> located y p_hsTypeR
56+ _ -> located y p_hsType
92− HsListTy NoExtField t ->
57+ HsListTy NoExt t -> located t (brackets . p_hsType)
93− located t (brackets N . p_hsType)
58+ HsTupleTy NoExt tsort xs ->
94− HsTupleTy NoExtField tsort xs ->
95 let parens' =
59 let parens' =
96 case tsort of
60 case tsort of
97− HsUnboxedTuple -> parensHash N
61+ HsUnboxedTuple -> parensHash
98− HsBoxedTuple -> parens N
62+ HsBoxedTuple -> parens
99− HsConstraintTuple -> parens N
63+ HsConstraintTuple -> parens
100− HsBoxedOrConstraintTuple -> parens N
64+ HsBoxedOrConstraintTuple -> parens
101− in parens' $ sep commaDel (sitcc . located' p_hsType) xs
65+ in parens' . sitcc $
102− HsSumTy NoExtField xs ->
66+ sep (comma >> breakpoint) (sitcc . located' p_hsType) xs
103− parensHash N $
67+ HsSumTy NoExt xs ->
104− sep (txt "|" >> breakpoint) (sitcc . located' p_hsType) xs
68+ parensHash . sitcc $
105− HsOpTy NoExtField x op y ->
69+ sep (txt "| " >> breakpoint') (sitcc . located' p_hsType) xs
106− sitcc $
70+ HsOpTy NoExt x op y -> sitcc $ do
107− let opTree = OpBranch (tyOpTree x) op (tyOpTree y)
71+ -- In the AST, type operators are right-associative instead of left-associative
108− in p_tyOpTree (reassociateOpTree Just opTree)
72+ -- like value level operators. This makes similar constructs look inconsistent.
109− HsParTy NoExtField t ->
73+ -- Here, we shake the AST to convert right-associative tree to a left-associative
110− parens N (located t p_hsType)
74+ -- one.
111− HsIParamTy NoExtField n t -> sitcc $ do
75+ case unLoc y of
76+ HsOpTy NoExt x' op' y' ->
77+ p_hsType $
78+ HsOpTy
79+ NoExt
80+ (L (combineSrcSpans (getLoc x) (getLoc x')) (HsOpTy NoExt x op x'))
81+ op'
82+ y'
83+ _ -> do
84+ located x p_hsType
85+ breakpoint
86+ inci $ do
87+ p_rdrName op
88+ space
89+ located y p_hsType
90+ HsParTy NoExt (L _ t@HsKindSig {}) ->
91+ -- NOTE Kind signatures already put parentheses around in all cases, so
92+ -- skip this layer of parentheses. The reason for this behavior is that
93+ -- parentheses are not always encoded with 'HsParTy', but seem to be
94+ -- always necessary when we have kind signatures in place.
95+ p_hsType t
96+ HsParTy NoExt t ->
97+ parens (located t p_hsType)
98+ HsIParamTy NoExt n t -> sitcc $ do
112 located n atom
99 located n atom
113− space
114− txt "::"
115 breakpoint
100 breakpoint
116− inci (located t p_hsType)
101+ inci $ do
117− HsStarTy NoExtField _ -> txt "*"
102+ txt ":: "
118− HsKindSig NoExtField t k -> sitcc $ do
103+ located t p_hsType
119− located t p_hsType
104+ HsStarTy NoExt _ -> txt "*"
120− space
105+ HsKindSig NoExt t k ->
121− txt "::"
106+ -- NOTE Also see the comment for 'HsParTy'.
122− breakpoint
107+ parens . sitcc $ do
123− inci (located k p_hsType)
108+ located t p_hsType
124− HsSpliceTy NoExtField splice -> p_hsSplice splice
109+ space -- FIXME
125− HsDocTy NoExtField t str ->
110+ inci $ do
126− case docStyle of
111+ txt ":: "
127− PipeStyle -> do
112+ located k p_hsType
128− p_hsDocString Pipe True str
113+ HsSpliceTy NoExt splice -> p_hsSplice splice
129− located t p_hsType
114+ HsDocTy NoExt _ _ -> error "HsDocTy"
130− CaretStyle -> do
115+ HsBangTy NoExt (HsSrcBang _ u s) t -> do
131− located t p_hsType
132− newline
133− p_hsDocString Caret False str
134− HsBangTy NoExtField (HsSrcBang _ u s) t -> do
135 case u of
116 case u of
136− SrcUnpack -> txt "{-# UNPACK #-}" >> space
117+ SrcUnpack -> txt "{-# UNPACK #-} "
137− SrcNoUnpack -> txt "{-# NOUNPACK #-}" >> space
118+ SrcNoUnpack -> txt "{-# NOUNPACK #-} "
138 NoSrcUnpack -> return ()
119 NoSrcUnpack -> return ()
139 case s of
120 case s of
140 SrcLazy -> txt "~"
121 SrcLazy -> txt "~"
141 SrcStrict -> txt "!"
122 SrcStrict -> txt "!"
142 NoSrcStrict -> return ()
123 NoSrcStrict -> return ()
143 located t p_hsType
124 located t p_hsType
144− HsRecTy NoExtField fields ->
125+ HsRecTy NoExt fields ->
145 p_conDeclFields fields
126 p_conDeclFields fields
146− HsExplicitListTy NoExtField p xs -> do
127+ HsExplicitListTy NoExt p xs -> do
147 case p of
128 case p of
148− IsPromoted -> txt "'"
129+ Promoted -> txt "'"
149 NotPromoted -> return ()
130 NotPromoted -> return ()
150− brackets N $ do
131+ brackets $ do
151 -- If both this list itself and the first element is promoted,
132 -- If both this list itself and the first element is promoted,
152 -- we need to put a space in between or it fails to parse.
133 -- we need to put a space in between or it fails to parse.
153 case (p, xs) of
134 case (p, xs) of
154− (IsPromoted, L _ t : _) | isPromoted t -> space
135+ (Promoted, ((L _ t):_)) | isPromoted t -> space
155 _ -> return ()
136 _ -> return ()
156− sep commaDel (sitcc . located' p_hsType) xs
137+ sitcc $ sep (comma >> breakpoint) (sitcc . located' p_hsType) xs
157− HsExplicitTupleTy NoExtField xs -> do
138+ HsExplicitTupleTy NoExt xs -> do
158 txt "'"
139 txt "'"
159− parens N $ do
140+ parens $ do
160 case xs of
141 case xs of
161− L _ t : _ | isPromoted t -> space
142+ ((L _ t):_) | isPromoted t -> space
162 _ -> return ()
143 _ -> return ()
163− sep commaDel (located' p_hsType) xs
144+ sep (comma >> breakpoint) (located' p_hsType) xs
164− HsTyLit NoExtField t ->
145+ HsTyLit NoExt t -> atom t
165− case t of
146+ HsWildCardTy NoExt -> txt "_"
166− HsStrTy (SourceText s) _ -> p_stringLit s
167− a -> atom a
168− HsWildCardTy NoExtField -> txt "_"
169 XHsType (NHsCoreTy t) -> atom t
147 XHsType (NHsCoreTy t) -> atom t
170 where
148 where
171 isPromoted = \case
149 isPromoted = \case
172− HsTyVar _ IsPromoted _ -> True
150+ HsTyVar _ Promoted _ -> True
173− HsExplicitTupleTy {} -> True
151+ HsExplicitListTy _ _ _ -> True
174− HsExplicitListTy {} -> True
152+ HsExplicitTupleTy _ _ -> True
175 _ -> False
153 _ -> False
176− interArgBreak =
177− if multilineArgs
178− then newline
179− else breakpoint
180− p_hsTypeR = p_hsType' multilineArgs docStyle
181
154
182−-- | Return 'True' if at least one argument in 'HsType' has a doc string
183−-- attached to it.
184−hasDocStrings :: HsType GhcPs -> Bool
185−hasDocStrings = \case
186− HsDocTy {} -> True
187− HsFunTy _ (L _ x) (L _ y) -> hasDocStrings x || hasDocStrings y
188− _ -> False
189
155
190p_hsContext :: HsContext GhcPs -> R ()
156p_hsContext :: HsContext GhcPs -> R ()
191p_hsContext = \case
157p_hsContext = \case
192 [] -> txt "()"
158 [] -> txt "()"
193 [x] -> located x p_hsType
159 [x] -> located x p_hsType
194− xs -> parens N $ sep commaDel (sitcc . located' p_hsType) xs
160+ xs -> parens . sitcc $
161+ sep (comma >> breakpoint) (sitcc . located' p_hsType) xs
195
162
196p_hsTyVarBndr :: HsTyVarBndr GhcPs -> R ()
163p_hsTyVarBndr :: HsTyVarBndr GhcPs -> R ()
197p_hsTyVarBndr = \case
164p_hsTyVarBndr = \case
198− UserTyVar NoExtField x ->
165+ UserTyVar NoExt x ->
199 p_rdrName x
166 p_rdrName x
200− KindedTyVar NoExtField l k -> parens N $ do
167+ KindedTyVar NoExt l k -> parens $ do
201 located l atom
168 located l atom
202− space
203− txt "::"
204− breakpoint
205− inci (located k p_hsType)
206− XTyVarBndr x -> noExtCon x
207−
208−-- | Render several @forall@-ed variables.
209−p_forallBndrs :: Data a => ForallVisFlag -> (a -> R ()) -> [Located a] -> R ()
210−p_forallBndrs ForallInvis _ [] = txt "forall."
211−p_forallBndrs ForallVis _ [] = txt "forall ->"
212−p_forallBndrs vis p tyvars =
213− switchLayout (getLoc <$> tyvars) $ do
214− txt "forall"
215 breakpoint
169 breakpoint
216 inci $ do
170 inci $ do
217− sitcc $ sep breakpoint (sitcc . located' p) tyvars
171+ txt ":: "
218− case vis of
172+ located k p_hsType
219− ForallInvis -> txt "."
173+ XTyVarBndr NoExt -> notImplemented "XTyVarBndr"
220− ForallVis -> space >> txt "->"
221
174
222p_conDeclFields :: [LConDeclField GhcPs] -> R ()
175p_conDeclFields :: [LConDeclField GhcPs] -> R ()
223−p_conDeclFields xs =
176+p_conDeclFields xs = braces . sitcc $
224− braces N $ sep commaDel (sitcc . located' p_conDeclField) xs
177+ sep (comma >> breakpoint) (sitcc . located' p_conDeclField) xs
225
178
226p_conDeclField :: ConDeclField GhcPs -> R ()
179p_conDeclField :: ConDeclField GhcPs -> R ()
227p_conDeclField ConDeclField {..} = do
180p_conDeclField ConDeclField {..} = do
228− mapM_ (p_hsDocString Pipe True) cd_fld_doc
181+ sitcc $ sep (comma >> breakpoint)
229− sitcc $
182+ (located' (p_rdrName . rdrNameFieldOcc))
230− sep
183+ cd_fld_names
231− commaDel
232− (located' (p_rdrName . rdrNameFieldOcc))
233− cd_fld_names
234− space
235− txt "::"
236− breakpoint
237− sitcc . inci $ p_hsType (unLoc cd_fld_type)
238−p_conDeclField (XConDeclField x) = noExtCon x
239−
240−tyOpTree :: LHsType GhcPs -> OpTree (LHsType GhcPs) (Located RdrName)
241−tyOpTree (L _ (HsOpTy NoExtField l op r)) =
242− OpBranch (tyOpTree l) op (tyOpTree r)
243−tyOpTree n = OpNode n
244−
245−p_tyOpTree :: OpTree (LHsType GhcPs) (Located RdrName) -> R ()
246−p_tyOpTree (OpNode n) = located n p_hsType
247−p_tyOpTree (OpBranch l op r) = do
248− switchLayout [opTreeLoc l] $
249− p_tyOpTree l
250 breakpoint
184 breakpoint
251− inci . switchLayout [opTreeLoc r] $ do
185+ sitcc . inci $ do
252− p_rdrName op
186+ txt ":: "
253− space
187+ p_hsType (unLoc cd_fld_type)
254− p_tyOpTree r
188+p_conDeclField (XConDeclField NoExt) = notImplemented "XConDeclField"
255
189
256----------------------------------------------------------------------------
190----------------------------------------------------------------------------
257-- Conversion functions
191-- Conversion functions
@@ -259,17 +193,12 @@ p_tyOpTree (OpBranch l op r) = do
259tyVarsToTypes :: LHsQTyVars GhcPs -> [LHsType GhcPs]
193tyVarsToTypes :: LHsQTyVars GhcPs -> [LHsType GhcPs]
260tyVarsToTypes = \case
194tyVarsToTypes = \case
261 HsQTvs {..} -> fmap tyVarToType <$> hsq_explicit
195 HsQTvs {..} -> fmap tyVarToType <$> hsq_explicit
262− XLHsQTyVars x -> noExtCon x
196+ XLHsQTyVars {} -> notImplemented "XLHsQTyVars"
263
197
264tyVarToType :: HsTyVarBndr GhcPs -> HsType GhcPs
198tyVarToType :: HsTyVarBndr GhcPs -> HsType GhcPs
265tyVarToType = \case
199tyVarToType = \case
266− UserTyVar NoExtField tvar -> HsTyVar NoExtField NotPromoted tvar
200+ UserTyVar NoExt tvar -> HsTyVar NoExt NotPromoted tvar
267− KindedTyVar NoExtField tvar kind ->
201+ KindedTyVar NoExt tvar kind ->
268− -- Note: we always add parentheses because for whatever reason GHC does
202+ HsParTy NoExt $ noLoc $
269− -- not use HsParTy for left-hand sides of declarations. Please see
203+ HsKindSig NoExt (noLoc (HsTyVar NoExt NotPromoted tvar)) kind
270− -- <https://gitlab.haskell.org/ghc/ghc/issues/17404>. This is fine as
204+ XTyVarBndr {} -> notImplemented "XTyVarBndr"
271− -- long as 'tyVarToType' does not get applied to right-hand sides of
272− -- declarations.
273− HsParTy NoExtField . noLoc $
274− HsKindSig NoExtField (noLoc (HsTyVar NoExtField NotPromoted tvar)) kind
275− XTyVarBndr x -> noExtCon x
src/Ormolu/Printer/Operators.hsdeleted−177
@@ -1,177 +0,0 @@
1−{-# LANGUAGE LambdaCase #-}
2−{-# LANGUAGE ScopedTypeVariables #-}
3−
4−-- | This module helps handle operator chains composed of different
5−-- operators that may have different precedence and fixities.
6−module Ormolu.Printer.Operators
7− ( OpTree (..),
8− opTreeLoc,
9− reassociateOpTree,
10− )
11−where
12−
13−import Data.Function (on)
14−import qualified Data.List as L
15−import Data.Map.Strict (Map)
16−import qualified Data.Map.Strict as M
17−import Data.Maybe (fromMaybe, mapMaybe)
18−import GHC
19−import OccName (occNameString)
20−import Ormolu.Utils (unSrcSpan)
21−
22−-- | Intermediate representation of operator trees. It has two type
23−-- parameters: @ty@ is the type of sub-expressions, while @op@ is the type
24−-- of operators.
25−data OpTree ty op
26− = OpNode ty
27− | OpBranch
28− (OpTree ty op)
29− op
30− (OpTree ty op)
31−
32−-- | Return combined 'SrcSpan's of all elements in this 'OpTree'.
33−opTreeLoc :: OpTree (Located a) b -> SrcSpan
34−opTreeLoc (OpNode (L l _)) = l
35−opTreeLoc (OpBranch l _ r) = combineSrcSpans (opTreeLoc l) (opTreeLoc r)
36−
37−-- | Re-associate an 'OpTree' taking into account automagically inferred
38−-- relative precedence of operators. Users are expected to first construct
39−-- an initial 'OpTree', then re-associate it using this function before
40−-- printing.
41−reassociateOpTree ::
42− -- | How to get name of an operator
43− (op -> Maybe RdrName) ->
44− -- | Original 'OpTree'
45− OpTree (Located ty) (Located op) ->
46− -- | Re-associated 'OpTree'
47− OpTree (Located ty) (Located op)
48−reassociateOpTree getOpName opTree =
49− reassociateOpTreeWith
50− (buildFixityMap getOpName normOpTree)
51− (getOpName . unLoc)
52− normOpTree
53− where
54− normOpTree = normalizeOpTree opTree
55−
56−-- | Re-associate an 'OpTree' given the map with operator fixities.
57−reassociateOpTreeWith ::
58− forall ty op.
59− -- | Fixity map for operators
60− Map String Fixity ->
61− -- | How to get the name of an operator
62− (op -> Maybe RdrName) ->
63− -- | Original 'OpTree'
64− OpTree ty op ->
65− -- | Re-associated 'OpTree'
66− OpTree ty op
67−reassociateOpTreeWith fixityMap getOpName = go
68− where
69− fixityOf :: op -> Fixity
70− fixityOf op = fromMaybe defaultFixity $ do
71− s <- occNameString . rdrNameOcc <$> getOpName op
72− M.lookup s fixityMap
73− -- Here, left branch is already associated and the root alongside with
74− -- the right branch is right-associated. This function picks up one item
75− -- from the right and inserts it correctly to the left.
76− --
77− -- Also, we are using the 'compareFixity' function which tells if the
78− -- expression should associate to right.
79− go :: OpTree ty op -> OpTree ty op
80− -- base cases
81− go t@(OpNode _) = t
82− go t@(OpBranch (OpNode _) _ (OpNode _)) = t
83− -- shift one operator to the left at the beginning
84− go (OpBranch l@(OpNode _) op (OpBranch l' op' r')) =
85− go (OpBranch (OpBranch l op l') op' r')
86− -- at the last operator, place the operator and don't recurse
87− go (OpBranch (OpBranch l op r) op' r'@(OpNode _)) =
88− if snd $ compareFixity (fixityOf op) (fixityOf op')
89− then OpBranch l op (go $ OpBranch r op' r')
90− else OpBranch (OpBranch l op r) op' r'
91− -- else, shift one operator to left and recurse.
92− go (OpBranch (OpBranch l op r) op' (OpBranch l' op'' r')) =
93− if snd $ compareFixity (fixityOf op) (fixityOf op')
94− then go $ OpBranch (OpBranch l op (go $ OpBranch r op' l')) op'' r'
95− else go $ OpBranch (OpBranch (OpBranch l op r) op' l') op'' r'
96−
97−-- | A score assigned to an operator.
98−data Score
99− = -- | The operator was placed at the beginning of a line
100− AtBeginning Int
101− | -- | The operator was placed at the end of a line
102− AtEnd
103− | -- | The operator was placed in between arguments on a single line
104− InBetween
105− deriving (Eq, Ord)
106−
107−-- | Build a map of inferred 'Fixity's from an 'OpTree'.
108−buildFixityMap ::
109− forall ty op.
110− -- | How to get the name of an operator
111− (op -> Maybe RdrName) ->
112− -- | Operator tree
113− OpTree (Located ty) (Located op) ->
114− -- | Fixity map
115− Map String Fixity
116−buildFixityMap getOpName opTree =
117− addOverrides
118− . M.fromList
119− . concatMap (\(i, ns) -> map (\(n, _) -> (n, fixity i InfixL)) ns)
120− . zip [2 ..]
121− . L.groupBy ((==) `on` snd)
122− . selectScores
123− $ score opTree
124− where
125− addOverrides :: Map String Fixity -> Map String Fixity
126− addOverrides m =
127− M.fromList
128− [ ("$", fixity 0 InfixR),
129− (":", fixity 1 InfixR),
130− (".", fixity 100 InfixL)
131− ]
132− `M.union` m
133− fixity = Fixity NoSourceText
134− score :: OpTree (Located ty) (Located op) -> [(String, Score)]
135− score (OpNode _) = []
136− score (OpBranch l o r) = fromMaybe (score r) $ do
137− -- If we fail to get any of these, 'defaultFixity' will be used by
138− -- 'reassociateOpTreeWith'.
139− le <- srcSpanEndLine <$> unSrcSpan (opTreeLoc l) -- left end
140− ob <- srcSpanStartLine <$> unSrcSpan (getLoc o) -- operator begin
141− oe <- srcSpanEndLine <$> unSrcSpan (getLoc o) -- operator end
142− rb <- srcSpanStartLine <$> unSrcSpan (opTreeLoc r) -- right begin
143− oc <- srcSpanStartCol <$> unSrcSpan (getLoc o) -- operator column
144− opName <- occNameString . rdrNameOcc <$> getOpName (unLoc o)
145− let s
146− | le < ob = AtBeginning oc
147− | oe < rb = AtEnd
148− | otherwise = InBetween
149− return $ (opName, s) : score r
150− selectScores :: [(String, Score)] -> [(String, Score)]
151− selectScores =
152− L.sortOn snd
153− . mapMaybe
154− ( \case
155− [] -> Nothing
156− xs@((n, _) : _) -> Just (n, selectScore $ map snd xs)
157− )
158− . L.groupBy ((==) `on` fst)
159− . L.sort
160− selectScore :: [Score] -> Score
161− selectScore xs =
162− case filter (/= InBetween) xs of
163− [] -> InBetween
164− xs' -> maximum xs'
165−
166−----------------------------------------------------------------------------
167−-- Helpers
168−
169−-- | Convert an 'OpTree' to with all operators having the same fixity and
170−-- associativity (left infix).
171−normalizeOpTree :: OpTree ty op -> OpTree ty op
172−normalizeOpTree (OpNode n) =
173− OpNode n
174−normalizeOpTree (OpBranch (OpNode l) lop r) =
175− OpBranch (OpNode l) lop (normalizeOpTree r)
176−normalizeOpTree (OpBranch (OpBranch l' lop' r') lop r) =
177− normalizeOpTree (OpBranch l' lop' (OpBranch r' lop r))
src/Ormolu/Printer/SpanStream.hs+20−18
@@ -1,44 +1,46 @@
1−{-# LANGUAGE DeriveDataTypeable #-}
1+{-# LANGUAGE DeriveDataTypeable #-}
2{-# LANGUAGE GeneralizedNewtypeDeriving #-}
2{-# LANGUAGE GeneralizedNewtypeDeriving #-}
3
3
4-- | Build span stream from AST.
4-- | Build span stream from AST.
5+
5module Ormolu.Printer.SpanStream
6module Ormolu.Printer.SpanStream
6− ( SpanStream (..),
7+ ( SpanStream (..)
7− mkSpanStream,
8+ , mkSpanStream
8 )
9 )
9where
10where
10
11
11import Data.DList (DList)
12import Data.DList (DList)
12−import qualified Data.DList as D
13import Data.Data (Data)
13import Data.Data (Data)
14import Data.Generics (everything, ext2Q)
14import Data.Generics (everything, ext2Q)
15import Data.List (sortOn)
15import Data.List (sortOn)
16import Data.Typeable (cast)
16import Data.Typeable (cast)
17import SrcLoc
17import SrcLoc
18+import qualified Data.DList as D
18
19
19-- | A stream of 'RealSrcSpan's in ascending order. This allows us to tell
20-- | A stream of 'RealSrcSpan's in ascending order. This allows us to tell
20-- e.g. whether there is another \"located\" element of AST between current
21-- e.g. whether there is another \"located\" element of AST between current
21-- element and comment we're considering for printing.
22-- element and comment we're considering for printing.
23+
22newtype SpanStream = SpanStream [RealSrcSpan]
24newtype SpanStream = SpanStream [RealSrcSpan]
23 deriving (Eq, Show, Data, Semigroup, Monoid)
25 deriving (Eq, Show, Data, Semigroup, Monoid)
24
26
25-- | Create 'SpanStream' from a data structure containing \"located\"
27-- | Create 'SpanStream' from a data structure containing \"located\"
26-- elements.
28-- elements.
27−mkSpanStream ::
29+
28− Data a =>
30+mkSpanStream
29− -- | Data structure to inspect (AST)
31+ :: Data a
30− a ->
32+ => a -- ^ Data structure to inspect (AST)
31− SpanStream
33+ -> SpanStream
32−mkSpanStream a =
34+mkSpanStream a
33− SpanStream
35+ = SpanStream
34− . sortOn realSrcSpanStart
36+ . sortOn realSrcSpanStart
35− . D.toList
37+ . D.toList
36− $ everything mappend (const mempty `ext2Q` queryLocated) a
38+ $ everything mappend (const mempty `ext2Q` queryLocated) a
37 where
39 where
38− queryLocated ::
40+ queryLocated
39− (Data e0) =>
41+ :: (Data e0, Data e1)
40− GenLocated e0 e1 ->
42+ => GenLocated e0 e1
41− DList RealSrcSpan
43+ -> DList RealSrcSpan
42 queryLocated (L mspn _) =
44 queryLocated (L mspn _) =
43 case cast mspn :: Maybe SrcSpan of
45 case cast mspn :: Maybe SrcSpan of
44 Nothing -> mempty
46 Nothing -> mempty
src/Ormolu/Processing/Common.hsdeleted−27
@@ -1,27 +0,0 @@
1−{-# LANGUAGE OverloadedStrings #-}
2−
3−-- | Common definitions for pre- and post- processing.
4−module Ormolu.Processing.Common
5− ( OrmoluState (..),
6− startDisabling,
7− endDisabling,
8− )
9−where
10−
11−import Data.String (IsString (..))
12−
13−-- | Ormolu state.
14−data OrmoluState
15− = -- | Enabled
16− OrmoluEnabled
17− | -- | Disabled
18− OrmoluDisabled
19− deriving (Eq, Show)
20−
21−-- | Marker for the beginning of the region where Ormolu should be disabled.
22−startDisabling :: IsString s => s
23−startDisabling = "{- ORMOLU_DISABLE_START"
24−
25−-- | Marker for the end of the region where Ormolu should be disabled.
26−endDisabling :: IsString s => s
27−endDisabling = "ORMOLU_DISABLE_END -}"
src/Ormolu/Processing/Cpp.hsdeleted−70
@@ -1,70 +0,0 @@
1−{-# LANGUAGE OverloadedStrings #-}
2−
3−-- | Support for CPP.
4−module Ormolu.Processing.Cpp
5− ( State (..),
6− processLine,
7− unmaskLine,
8− )
9−where
10−
11−import Control.Monad
12−import Data.Char (isSpace)
13−import qualified Data.List as L
14−import Data.Maybe (isJust)
15−import Data.String
16−import Data.Text (Text)
17−import qualified Data.Text as T
18−
19−-- | State of the CPP processor.
20−data State
21− = -- | Outside of CPP directives
22− Outside
23− | -- | In a conditional expression
24− InConditional
25− | -- | In a continuation (after @\\@)
26− InContinuation
27− deriving (Eq, Show)
28−
29−-- | Automatically mask the line when needed and update the 'State'.
30−processLine :: String -> State -> (String, State)
31−processLine line state
32− | for "define " = (masked, state')
33− | for "include " = (masked, state')
34− | for "undef " = (masked, state')
35− | for "ifdef " = (masked, InConditional)
36− | for "ifndef " = (masked, InConditional)
37− | for "if " = (masked, InConditional)
38− | for "else" = (masked, InConditional)
39− | for "elif" = (masked, InConditional)
40− | for "endif" = (masked, state')
41− | otherwise =
42− case state of
43− Outside -> (line, Outside)
44− InConditional -> (masked, InConditional)
45− InContinuation -> (masked, state')
46− where
47− for directive = isJust $ do
48− s <- dropWhile isSpace <$> L.stripPrefix "#" line
49− void (L.stripPrefix directive s)
50− masked = maskLine line
51− state' =
52− if "\\" `L.isSuffixOf` line
53− then InContinuation
54− else Outside
55−
56−-- | Mask the given line.
57−maskLine :: String -> String
58−maskLine x = maskPrefix ++ x
59−
60−-- | If the given line is masked, unmask it. Otherwise return the line
61−-- unchanged.
62−unmaskLine :: Text -> Text
63−unmaskLine x =
64− case T.stripPrefix maskPrefix (T.stripStart x) of
65− Nothing -> x
66− Just x' -> x'
67−
68−-- | Mask prefix for CPP.
69−maskPrefix :: IsString s => s
70−maskPrefix = "-- ORMOLU_CPP_MASK"
src/Ormolu/Processing/Postprocess.hsdeleted−31
@@ -1,31 +0,0 @@
1−{-# LANGUAGE OverloadedStrings #-}
2−{-# LANGUAGE ViewPatterns #-}
3−
4−-- | Postprocessing for the results of printing.
5−module Ormolu.Processing.Postprocess
6− ( postprocess,
7− )
8−where
9−
10−import Data.Text (Text)
11−import qualified Data.Text as T
12−import Ormolu.Processing.Common
13−import qualified Ormolu.Processing.Cpp as Cpp
14−
15−-- | Postprocess output of the formatter.
16−postprocess ::
17− -- | Desired indentation level
18− Int ->
19− -- | Input to process
20− Text ->
21− Text
22−postprocess indent =
23− T.unlines
24− . fmap indentLine
25− . fmap Cpp.unmaskLine
26− . filter (not . magicComment)
27− . T.lines
28− where
29− magicComment (T.stripStart -> x) =
30− x == startDisabling || x == endDisabling
31− indentLine x = T.replicate indent " " <> x
src/Ormolu/Processing/Preprocess.hsdeleted−149
@@ -1,149 +0,0 @@
1−{-# LANGUAGE BangPatterns #-}
2−{-# LANGUAGE LambdaCase #-}
3−{-# LANGUAGE RecordWildCards #-}
4−
5−-- | Preprocessing for input source code.
6−module Ormolu.Processing.Preprocess
7− ( preprocess,
8− )
9−where
10−
11−import Control.Monad
12−import Data.Char (isSpace)
13−import qualified Data.List as L
14−import Data.Maybe (isJust, maybeToList)
15−import FastString
16−import Ormolu.Config (RegionDeltas (..))
17−import Ormolu.Parser.Shebang (isShebang)
18−import Ormolu.Processing.Common
19−import qualified Ormolu.Processing.Cpp as Cpp
20−import SrcLoc
21−
22−-- | Transform given input possibly returning comments extracted from it.
23−-- This handles LINE pragmas, CPP, shebangs, and the magic comments for
24−-- enabling\/disabling of Ormolu.
25−preprocess ::
26− -- | File name, just to use in the spans
27− FilePath ->
28− -- | Input to process
29− String ->
30− -- | Region deltas
31− RegionDeltas ->
32− -- | Literal prefix, pre-processed input, literal suffix, extra comments
33− (String, String, String, [Located String])
34−preprocess path input RegionDeltas {..} =
35− go 1 OrmoluEnabled Cpp.Outside id id regionLines
36− where
37− (prefixLines, otherLines) = splitAt regionPrefixLength (lines input)
38− (regionLines, suffixLines) =
39− let regionLength = length otherLines - regionSuffixLength
40− in splitAt regionLength otherLines
41− go !n ormoluState cppState inputSoFar csSoFar = \case
42− [] ->
43− let input' = unlines (inputSoFar [])
44− in ( unlines prefixLines,
45− case ormoluState of
46− OrmoluEnabled -> input'
47− OrmoluDisabled -> input' ++ endDisabling,
48− unlines suffixLines,
49− csSoFar []
50− )
51− (x : xs) ->
52− let (x', ormoluState', cppState', cs) =
53− processLine path n ormoluState cppState x
54− in go
55− (n + 1)
56− ormoluState'
57− cppState'
58− (inputSoFar . (x' :))
59− (csSoFar . (maybeToList cs ++))
60− xs
61−
62−-- | Transform a given line possibly returning a comment extracted from it.
63−processLine ::
64− -- | File name, just to use in the spans
65− FilePath ->
66− -- | Line number of this line
67− Int ->
68− -- | Whether Ormolu is currently enabled
69− OrmoluState ->
70− -- | CPP state
71− Cpp.State ->
72− -- | The actual line
73− String ->
74− -- | Adjusted line and possibly a comment extracted from it
75− (String, OrmoluState, Cpp.State, Maybe (Located String))
76−processLine path n ormoluState Cpp.Outside line
77− | "{-# LINE" `L.isPrefixOf` line =
78− let (pragma, res) = getPragma line
79− size = length pragma
80− ss = mkSrcSpan (mkSrcLoc' 1) (mkSrcLoc' (size + 1))
81− in (res, ormoluState, Cpp.Outside, Just (L ss pragma))
82− | isOrmoluEnable line =
83− case ormoluState of
84− OrmoluEnabled ->
85− (enableMarker, OrmoluEnabled, Cpp.Outside, Nothing)
86− OrmoluDisabled ->
87− (endDisabling ++ enableMarker, OrmoluEnabled, Cpp.Outside, Nothing)
88− | isOrmoluDisable line =
89− case ormoluState of
90− OrmoluEnabled ->
91− (disableMarker ++ startDisabling, OrmoluDisabled, Cpp.Outside, Nothing)
92− OrmoluDisabled ->
93− (disableMarker, OrmoluDisabled, Cpp.Outside, Nothing)
94− | isShebang line =
95− let ss = mkSrcSpan (mkSrcLoc' 1) (mkSrcLoc' (length line))
96− in ("", ormoluState, Cpp.Outside, Just (L ss line))
97− | otherwise =
98− let (line', cppState') = Cpp.processLine line Cpp.Outside
99− in (line', ormoluState, cppState', Nothing)
100− where
101− mkSrcLoc' = mkSrcLoc (mkFastString path) n
102−processLine _ _ ormoluState cppState line =
103− let (line', cppState') = Cpp.processLine line cppState
104− in (line', ormoluState, cppState', Nothing)
105−
106−-- | Take a line pragma and output its replacement (where line pragma is
107−-- replaced with spaces) and the contents of the pragma itself.
108−getPragma ::
109− -- | Pragma line to analyze
110− String ->
111− -- | Contents of the pragma and its replacement line
112− (String, String)
113−getPragma [] = error "Ormolu.Preprocess.getPragma: input must not be empty"
114−getPragma s@(x : xs)
115− | "#-}" `L.isPrefixOf` s = ("#-}", " " ++ drop 3 s)
116− | otherwise =
117− let (prag, remline) = getPragma xs
118− in (x : prag, ' ' : remline)
119−
120−-- | Canonical enable marker.
121−enableMarker :: String
122−enableMarker = "{- ORMOLU_ENABLE -}"
123−
124−-- | Canonical disable marker.
125−disableMarker :: String
126−disableMarker = "{- ORMOLU_DISABLE -}"
127−
128−-- | Return 'True' if the given string is an enabling marker.
129−isOrmoluEnable :: String -> Bool
130−isOrmoluEnable = magicComment "ORMOLU_ENABLE"
131−
132−-- | Return 'True' if the given string is a disabling marker.
133−isOrmoluDisable :: String -> Bool
134−isOrmoluDisable = magicComment "ORMOLU_DISABLE"
135−
136−-- | Construct a function for whitespace-insensitive matching of string.
137−magicComment ::
138− -- | What to expect
139− String ->
140− -- | String to test
141− String ->
142− -- | Whether or not the two strings watch
143− Bool
144−magicComment expected s0 = isJust $ do
145− let trim = dropWhile isSpace
146− s1 <- trim <$> L.stripPrefix "{-" (trim s0)
147− s2 <- trim <$> L.stripPrefix expected s1
148− s3 <- L.stripPrefix "-}" s2
149− guard (all isSpace s3)
src/Ormolu/Utils.hs+18−137
@@ -1,155 +1,36 @@
1+-- | Random utilities used by the code.
2+
1{-# LANGUAGE LambdaCase #-}
3{-# LANGUAGE LambdaCase #-}
2−{-# LANGUAGE OverloadedStrings #-}
3−{-# LANGUAGE ViewPatterns #-}
4
4
5−-- | Random utilities used by the code.
6module Ormolu.Utils
5module Ormolu.Utils
7− ( RelativePos (..),
6+ ( combineSrcSpans'
8− attachRelativePos,
7+ , isModule
9− combineSrcSpans',
8+ , notImplemented
10− notImplemented,
9+ , showOutputable
11− showOutputable,
12− splitDocString,
13− typeArgToType,
14− unSrcSpan,
15− incSpanLine,
16− separatedByBlank,
17− separatedByBlankNE,
18− onTheSameLine,
19− removeIndentation,
20 )
10 )
21where
11where
22
12
23−import Data.Char (isSpace)
13+import Data.Data (Data, showConstr, toConstr)
24−import Data.List (dropWhileEnd)
25import Data.List.NonEmpty (NonEmpty (..))
14import Data.List.NonEmpty (NonEmpty (..))
26−import qualified Data.List.NonEmpty as NE
15+import SrcLoc
27−import Data.Maybe (fromMaybe)
28−import Data.Text (Text)
29−import qualified Data.Text as T
30−import GHC
31−import GHC.DynFlags (baseDynFlags)
32import qualified Outputable as GHC
16import qualified Outputable as GHC
33
17
34−-- | Relative positions in a list.
35−data RelativePos
36− = SinglePos
37− | FirstPos
38− | MiddlePos
39− | LastPos
40− deriving (Eq, Show)
41−
42−-- | Attach 'RelativePos'es to elements of a given list.
43−attachRelativePos :: [a] -> [(RelativePos, a)]
44−attachRelativePos = \case
45− [] -> []
46− [x] -> [(SinglePos, x)]
47− (x : xs) -> (FirstPos, x) : markLast xs
48− where
49− markLast [] = []
50− markLast [x] = [(LastPos, x)]
51− markLast (x : xs) = (MiddlePos, x) : markLast xs
52−
53-- | Combine all source spans from the given list.
18-- | Combine all source spans from the given list.
19+
54combineSrcSpans' :: NonEmpty SrcSpan -> SrcSpan
20combineSrcSpans' :: NonEmpty SrcSpan -> SrcSpan
55−combineSrcSpans' (x :| xs) = foldr combineSrcSpans x xs
21+combineSrcSpans' (x:|xs) = foldr combineSrcSpans x xs
22+
23+-- | Return 'True' if given element of AST is module.
24+
25+isModule :: Data a => a -> Bool
26+isModule x = showConstr (toConstr x) == "HsModule"
56
27
57-- | Placeholder for things that are not yet implemented.
28-- | Placeholder for things that are not yet implemented.
29+
58notImplemented :: String -> a
30notImplemented :: String -> a
59notImplemented msg = error $ "not implemented yet: " ++ msg
31notImplemented msg = error $ "not implemented yet: " ++ msg
60
32
61-- | Pretty-print an 'GHC.Outputable' thing.
33-- | Pretty-print an 'GHC.Outputable' thing.
62−showOutputable :: GHC.Outputable o => o -> String
63−showOutputable = GHC.showSDoc baseDynFlags . GHC.ppr
64−
65−-- | Split and normalize a doc string. The result is a list of lines that
66−-- make up the comment.
67−splitDocString :: HsDocString -> [Text]
68−splitDocString docStr =
69− case r of
70− [] -> [""]
71− _ -> r
72− where
73− r =
74− fmap escapeLeadingDollar
75− . dropPaddingSpace
76− . dropWhileEnd T.null
77− . fmap (T.stripEnd . T.pack)
78− . lines
79− $ unpackHDS docStr
80− -- We cannot have the first character to be a dollar because in that
81− -- case it'll be a parse error (apparently collides with named docs
82− -- syntax @-- $name@ somehow).
83− escapeLeadingDollar txt =
84− case T.uncons txt of
85− Just ('$', _) -> T.cons '\\' txt
86− _ -> txt
87− dropPaddingSpace xs =
88− case dropWhile T.null xs of
89− [] -> []
90− (x : _) ->
91− let leadingSpace txt = case T.uncons txt of
92− Just (' ', _) -> True
93− _ -> False
94− dropSpace txt =
95− if leadingSpace txt
96− then T.drop 1 txt
97− else txt
98− in if leadingSpace x
99− then dropSpace <$> xs
100− else xs
101−
102−-- | Get 'LHsType' out of 'LHsTypeArg'.
103−typeArgToType :: LHsTypeArg p -> LHsType p
104−typeArgToType = \case
105− HsValArg tm -> tm
106− HsTypeArg _ ty -> ty
107− HsArgPar _ -> notImplemented "HsArgPar"
108−
109−-- | Get 'RealSrcSpan' out of 'SrcSpan' if the span is “helpful”.
110−unSrcSpan :: SrcSpan -> Maybe RealSrcSpan
111−unSrcSpan = \case
112− RealSrcSpan r -> Just r
113− UnhelpfulSpan _ -> Nothing
114−
115−-- | Increment line number in a 'SrcSpan'.
116−incSpanLine :: Int -> SrcSpan -> SrcSpan
117−incSpanLine i = \case
118− RealSrcSpan s ->
119− let start = realSrcSpanStart s
120− end = realSrcSpanEnd s
121− incLine x =
122− let file = srcLocFile x
123− line = srcLocLine x
124− col = srcLocCol x
125− in mkRealSrcLoc file (line + i) col
126− in RealSrcSpan (mkRealSrcSpan (incLine start) (incLine end))
127− UnhelpfulSpan x -> UnhelpfulSpan x
128
34
129−-- | Do two declarations have a blank between them?
35+showOutputable :: GHC.Outputable o => o -> String
130−separatedByBlank :: (a -> SrcSpan) -> a -> a -> Bool
36+showOutputable = GHC.showSDocUnsafe . GHC.ppr
131−separatedByBlank loc a b =
132− fromMaybe False $ do
133− endA <- srcSpanEndLine <$> unSrcSpan (loc a)
134− startB <- srcSpanStartLine <$> unSrcSpan (loc b)
135− pure (startB - endA >= 2)
136−
137−-- | Do two declaration groups have a blank between them?
138−separatedByBlankNE :: (a -> SrcSpan) -> NonEmpty a -> NonEmpty a -> Bool
139−separatedByBlankNE loc a b = separatedByBlank loc (NE.last a) (NE.head b)
140−
141−-- | Return 'True' if one span ends on the same line the second one starts.
142−onTheSameLine :: SrcSpan -> SrcSpan -> Bool
143−onTheSameLine a b =
144− isOneLineSpan (mkSrcSpan (srcSpanEnd a) (srcSpanStart b))
145−
146−-- | Remove indentation from a given 'String'. Return the input with
147−-- indentation removed and the detected indentation level.
148−removeIndentation :: String -> (String, Int)
149−removeIndentation (lines -> xs) = (unlines (drop n <$> xs), n)
150− where
151− n = minimum (getIndent <$> xs)
152− getIndent y =
153− if all isSpace y
154− then 0
155− else length (takeWhile isSpace y)
tests/Ormolu/Parser/PragmaSpec.hs+3−4
@@ -4,7 +4,7 @@ import Ormolu.Parser.Pragma
4import Test.Hspec
4import Test.Hspec
5
5
6spec :: Spec
6spec :: Spec
7−spec =
7+spec = do
8 describe "parsePragma" $ do
8 describe "parsePragma" $ do
9 stdTest "{-# LANGUAGE Foo #-}" (Just (PragmaLanguage ["Foo"]))
9 stdTest "{-# LANGUAGE Foo #-}" (Just (PragmaLanguage ["Foo"]))
10 stdTest "{-# language Foo #-}" (Just (PragmaLanguage ["Foo"]))
10 stdTest "{-# language Foo #-}" (Just (PragmaLanguage ["Foo"]))
@@ -21,6 +21,5 @@ spec =
21 stdTest "{-#OPTIONS_HADDOCK foo, bar, baz #-}" (Just $ PragmaOptionsHaddock "foo, bar, baz")
21 stdTest "{-#OPTIONS_HADDOCK foo, bar, baz #-}" (Just $ PragmaOptionsHaddock "foo, bar, baz")
22
22
23stdTest :: String -> Maybe Pragma -> Spec
23stdTest :: String -> Maybe Pragma -> Spec
24−stdTest input result =
24+stdTest input result = it input $
25− it input $
25+ parsePragma input `shouldBe` result
26− parsePragma input `shouldBe` result
tests/Ormolu/Printer/CombinatorsSpec.hsnew file+112
@@ -0,0 +1,112 @@
1+{-# LANGUAGE OverloadedStrings #-}
2+
3+module Ormolu.Printer.CombinatorsSpec (spec) where
4+
5+import Ormolu.Parser.Anns
6+import Ormolu.Printer.Combinators
7+import Ormolu.Printer.Internal
8+import Test.Hspec
9+import qualified Data.Text.IO as T
10+
11+-- NOTE Testing combinators in separation is easy, but it's not very useful
12+-- either because interesting things happen only when combinators are used
13+-- together. However, there are too many combinations to test, so we test
14+-- just a few things here and expect new tests to be added on demand when
15+-- particularly tricky or problematic use cases are discovered.
16+--
17+-- The printing logic is indirectly tested in the main bulk of reformatting
18+-- tests.
19+
20+spec :: Spec
21+spec = do
22+ stdTest "simple signature" rSimpleSig "ssig"
23+ stdTest "list" rList0 "list0"
24+ stdTest "list with annotated name in it" rList1 "list1"
25+ stdTest "module header" rModuleHeader "mhdr"
26+
27+-- | Do a standard test prodedure testing both single-line and multi-line
28+-- layouts.
29+
30+stdTest
31+ :: String -- ^ Test name
32+ -> R () -- ^ Computation to test
33+ -> FilePath -- ^ Base file name where expected result is stored
34+ -> Spec
35+stdTest name m path = describe name $ do
36+ let spath = "data/printer/" ++ path ++ "-single.hs"
37+ mpath = "data/printer/" ++ path ++ "-multi.hs"
38+ it "single-line works" $
39+ singleLine m `shouldRender` spath
40+ it "multi-line works" $
41+ multiLine m `shouldRender` mpath
42+
43+----------------------------------------------------------------------------
44+-- Test computations
45+
46+rSimpleSig :: R ()
47+rSimpleSig = line rFn
48+
49+rList0 :: R ()
50+rList0 = line . brackets . sitcc $
51+ sep (comma >> breakpoint) id
52+ [ txt "foo"
53+ , txt "bar"
54+ , txt "baz"
55+ ]
56+
57+rList1 :: R ()
58+rList1 = line . brackets . sitcc $
59+ sep (comma >> breakpoint) id
60+ [ txt "foo"
61+ , txt "bar"
62+ , rFn
63+ ]
64+
65+rFn :: R ()
66+rFn = sitcc $ sep breakpoint sitcc
67+ [ txt "foo"
68+ , inci . sitcc $ sep breakpoint sitcc
69+ [ do txt ":: "
70+ parens . sitcc $ sep breakpoint sitcc
71+ [ txt "Int"
72+ , txt "-> " >> txt "Int"
73+ ]
74+ , txt "-> " >> txt "Bool"
75+ ]
76+ ]
77+
78+rModuleHeader :: R ()
79+rModuleHeader = do
80+ line $ do
81+ txt "module "
82+ txt "MyModule"
83+ line . inci . parens . sitcc . sep (comma >> breakpoint) sitcc $
84+ [ txt "R"
85+ , txt "runR"
86+ , txt "txt"
87+ , txt "blah"
88+ ]
89+ line (txt "where")
90+
91+----------------------------------------------------------------------------
92+-- Helpers
93+
94+-- | Run given computation in @'R' ()@ monad and compare result of rendering
95+-- with contents of a given file.
96+
97+shouldRender :: R () -> FilePath -> Expectation
98+shouldRender m path = do
99+ let rendered = runR False m mempty mempty emptyAnns
100+ -- T.writeFile path rendered
101+ expected <- T.readFile path
102+ rendered `shouldBe` expected
103+
104+-- | Render using single-line layout.
105+
106+singleLine :: R () -> R ()
107+singleLine = enterLayout SingleLine
108+
109+-- | Render using multi-line layout.
110+
111+multiLine :: R () -> R ()
112+multiLine = enterLayout MultiLine
tests/Ormolu/PrinterSpec.hs+22−31
@@ -2,18 +2,17 @@
2
2
3module Ormolu.PrinterSpec (spec) where
3module Ormolu.PrinterSpec (spec) where
4
4
5−import Control.Exception
6import Control.Monad
5import Control.Monad
7import Control.Monad.IO.Class
6import Control.Monad.IO.Class
8import Data.List (isSuffixOf)
7import Data.List (isSuffixOf)
9import Data.Text (Text)
8import Data.Text (Text)
10−import qualified Data.Text as T
11−import qualified Data.Text.IO as T
12import Ormolu
9import Ormolu
13import Path
10import Path
14import Path.IO
11import Path.IO
15−import qualified System.FilePath as F
12+import System.FilePath (addExtension, dropExtensions, splitExtensions)
16import Test.Hspec
13import Test.Hspec
14+import qualified Data.Text as T
15+import qualified Data.Text.IO as T
17
16
18spec :: Spec
17spec :: Spec
19spec = do
18spec = do
@@ -21,8 +20,9 @@ spec = do
21 forM_ es checkExample
20 forM_ es checkExample
22
21
23-- | Check a single given example.
22-- | Check a single given example.
23+
24checkExample :: Path Rel File -> Spec
24checkExample :: Path Rel File -> Spec
25−checkExample srcPath' = it (fromRelFile srcPath' ++ " works") . withNiceExceptions $ do
25+checkExample srcPath' = it (fromRelFile srcPath' ++ " works") $ do
26 let srcPath = examplesDir </> srcPath'
26 let srcPath = examplesDir </> srcPath'
27 expectedOutputPath <- deriveOutput srcPath
27 expectedOutputPath <- deriveOutput srcPath
28 -- 1. Given input snippet of source code parse it and pretty print it.
28 -- 1. Given input snippet of source code parse it and pretty print it.
@@ -41,51 +41,42 @@ checkExample srcPath' = it (fromRelFile srcPath' ++ " works") . withNiceExceptio
41 shouldMatch True formatted1 formatted0
41 shouldMatch True formatted1 formatted0
42
42
43-- | Build list of examples for testing.
43-- | Build list of examples for testing.
44+
44locateExamples :: IO [Path Rel File]
45locateExamples :: IO [Path Rel File]
45locateExamples =
46locateExamples =
46 filter isInput . snd <$> listDirRecurRel examplesDir
47 filter isInput . snd <$> listDirRecurRel examplesDir
47
48
48-- | Does given path look like input path (as opposed to expected output
49-- | Does given path look like input path (as opposed to expected output
49-- path)?
50-- path)?
51+
50isInput :: Path Rel File -> Bool
52isInput :: Path Rel File -> Bool
51isInput path =
53isInput path =
52 let s = fromRelFile path
54 let s = fromRelFile path
53− (s', exts) = F.splitExtensions s
55+ (s', exts) = splitExtensions s
54− in exts == ".hs" && not ("-out" `isSuffixOf` s')
56+ in exts == ".hs" && not ("-out" `isSuffixOf` s')
55
57
56-- | For given path of input file return expected name of output.
58-- | For given path of input file return expected name of output.
59+
57deriveOutput :: Path Rel File -> IO (Path Rel File)
60deriveOutput :: Path Rel File -> IO (Path Rel File)
58−deriveOutput path =
61+deriveOutput path = parseRelFile $
59− parseRelFile $
62+ addExtension (dropExtensions (fromRelFile path) ++ "-out") "hs"
60− F.addExtension (F.dropExtensions (fromRelFile path) ++ "-out") "hs"
61
63
62-- | A version of 'shouldBe' that is specialized to comparing 'Text' values.
64-- | A version of 'shouldBe' that is specialized to comparing 'Text' values.
63-- It also prints multi-line snippets in a more readable form.
65-- It also prints multi-line snippets in a more readable form.
66+
64shouldMatch :: Bool -> Text -> Text -> Expectation
67shouldMatch :: Bool -> Text -> Text -> Expectation
65−shouldMatch idempotenceTest actual expected =
68+shouldMatch idempotencyTest actual expected =
66− when (actual /= expected) . expectationFailure $
69+ when (actual /= expected) . expectationFailure $ unlines
67− unlines
70+ [ ">>>>>>>>>>>>>>>>>>>>>> expected (" ++ pass ++ "):"
68− [ ">>>>>>>>>>>>>>>>>>>>>> expected (" ++ pass ++ "):",
71+ , T.unpack expected
69− T.unpack expected,
72+ , ">>>>>>>>>>>>>>>>>>>>>> but got:"
70− ">>>>>>>>>>>>>>>>>>>>>> but got:",
73+ , T.unpack actual
71− T.unpack actual
74+ ]
72− ]
73 where
75 where
74 pass =
76 pass =
75− if idempotenceTest
77+ if idempotencyTest
76− then "idempotence pass"
78+ then "idempotency pass"
77 else "first pass"
79 else "first pass"
78
80
79examplesDir :: Path Rel Dir
81examplesDir :: Path Rel Dir
80examplesDir = $(mkRelDir "data/examples")
82examplesDir = $(mkRelDir "data/examples")
81−
82−-- | Inside this wrapper 'OrmoluException' will be caught and displayed
83−-- nicely using 'displayException'.
84−withNiceExceptions ::
85− -- | Action that may throw the exception
86− Expectation ->
87− Expectation
88−withNiceExceptions m = m `catch` h
89− where
90− h :: OrmoluException -> IO ()
91− h = expectationFailure . displayException