Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Preserve comments on language pragmas #216

Closed
neongreen opened this issue Jul 14, 2019 · 11 comments · Fixed by #553
Closed

Preserve comments on language pragmas #216

neongreen opened this issue Jul 14, 2019 · 11 comments · Fixed by #553
Assignees
Labels
comments Issues related to comment placement feature-request style Nitpicking and things related to purely visual aspect for formatting.

Comments

@neongreen
Copy link
Collaborator

Input:

{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE PackageImports #-}

-- FIXME: We need this for such-and-such stupid reason. Ideally we should
-- fix it with this-and-this approach.
{-# LANGUAGE ExtendedDefaultRules #-}

module Foo where

Output:

{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE ExtendedDefaultRules #-}
{-# LANGUAGE PackageImports #-}

-- FIXME: We need this for such-and-such stupid reason. Ideally we should
-- fix it with this-and-this approach.
module Foo where

This means that I can't document tricky/unpleasant exceptions for other code readers.

@mrkkrp mrkkrp added the style Nitpicking and things related to purely visual aspect for formatting. label Jul 14, 2019
@mrkkrp
Copy link
Member

mrkkrp commented Jul 14, 2019

This seems to be in a conflict with the idea of automated grouping of language pragmas.

@basile-henry
Copy link
Collaborator

The pragmas could only be sorted by groups split using comments as delimiters.

This is similar to what stylish-haskell does with imports (and maybe also language pragmas) as far as I remember. Though it uses any amount of empty lines or comments as group delimiter as opposed to just comments.

@mrkkrp
Copy link
Member

mrkkrp commented Aug 16, 2019

I don't see a good way to implement it. What we currently do is we check every comment to detect those that are language pragmas. Keeping track of comments between pragmas would require more state. Seems to be quite troublesome for little benefit. I'm keeping this one with low priority.

@recursion-ninja
Copy link

recursion-ninja commented Sep 16, 2019

There are semantic problems with this approach.

Some language extensions enable other language extensions implicitly. If you want to disable them, you must specify that after the extension that implicitly enables them is specified.

Consider this input:

{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies        #-}
-- This gap is necessary for stylish Haskell not to re-arrange                                           
-- NoMonoLocalBinds before TypeFamilies
{-# LANGUAGE NoMonoLocalBinds    #-}

module Foo (
  , bar
  ) where

This module will not have MonoLocalBinds enabled becaue the NoMonoLocalBinds language extension occurs after the TypeFamilies language pragma which implicitly enables MonoLocalBinds.

If the styler groups the language extensions and alphabetizes them like so, there will be problems:

{-# LANGUAGE NoMonoLocalBinds    #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies        #-}
-- This gap is necessary for stylish Haskell not to re-arrange                                           
-- NoMonoLocalBinds before TypeFamilies

module Foo (
  , bar
  ) where

Because NoMonoLocalBinds appears before Typefamilies, GHC considers it "disabled." GHC then continues to fold over the list of language extensions and when it encounters TypeFamilies, MonoLocalBinds is implicitly enabled.

This grouping and alphabetizing of language extensions will cause semantic differences in the input and output modules. The former does not have MonoLocalBinds enabled, while the latter does.

@mboes
Copy link
Member

mboes commented Sep 16, 2019

In light of this, perhaps we should reorder only inside groups separated by a newline.

@neongreen
Copy link
Collaborator Author

neongreen commented Sep 16, 2019 via email

@neongreen
Copy link
Collaborator Author

neongreen commented Sep 16, 2019 via email

@recursion-ninja
Copy link

recursion-ninja commented Sep 16, 2019

The problem is that a list of language extensions is not always a list of commutative elements, however it often is a list of commutative elements and users will likely expect the alphabetized behavior in the latter case.

If one were to take care to note which language extensions were implied by which other ones, we can determine which elements in the list of language extensions could not be commuted "past" one another when alphabetizing. If this bookkeepping was performed, we could indempotently output a mostly alphabetized list of language extensions when one or more elements cannot commute "past" each other or a completely alphabetized list when all elements can be commuted, preserving the module's semantics in either case.

While this approach would require much more work to implement and maintain, it is the most correct option for an opinionated code styler.

@mrkkrp
Copy link
Member

mrkkrp commented Sep 16, 2019

I agree we should not abandon sorting with single group of extensions in the output, we just should make it more clever.

@mrkkrp
Copy link
Member

mrkkrp commented Oct 5, 2019

@recursion-ninja Now there is a separate issue about sorting: #404. I think it's a different problem.

@lrworth
Copy link
Contributor

lrworth commented Dec 2, 2019

Just noting that the same goes for OPTIONS_GHC

-- Avoid warning produced by TH.
{-# OPTIONS_GHC -fno-warn-overlapping-patterns #-}

@mrkkrp mrkkrp changed the title Adding comments to language pragmas is impossible Preserve comments on language pragmas Mar 11, 2020
@mrkkrp mrkkrp added the comments Issues related to comment placement label Apr 9, 2020
@mrkkrp mrkkrp self-assigned this Apr 15, 2020
mheinzel added a commit to wireapp/wire-server that referenced this issue Apr 27, 2020
* update ormolu version

* run new ormolu

* don't exclude CPP anymore

* format Sodium.Crypt.Sign

Changelog:
https://github.com/tweag/ormolu/blob/master/CHANGELOG.md

Most changes are caused by:

* Records with a single data constructor are now formatted more compactly. [Issue 425](tweag/ormolu#425).

* Added experimental support for simple CPP. [Issue 415](tweag/ormolu#415).

Other notable changes we can start making use of:

* Grouping of statements in `do`-blocks is now preserved. [Issue 74](tweag/ormolu#74).

* Comments on pragmas are now preserved. [Issue 216](tweag/ormolu#216).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
comments Issues related to comment placement feature-request style Nitpicking and things related to purely visual aspect for formatting.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants