GithubHelp home page GithubHelp logo

apply-refact's People

Contributors

9999years avatar alanz avatar avi-d-coder avatar cocreature avatar fendor avatar ivan-m avatar july541 avatar mpickering avatar ndmitchell avatar niteria avatar nponeccop avatar phadej avatar rvion avatar rwe avatar soiamsong avatar wavewave avatar yairchu avatar zliu41 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

apply-refact's Issues

Failed to build 0.7.0.0 due to ghc-exactprint-0.6.3

  • 0.7is needed to build with ghc < 8.10
  • There is no upper bound over ghc-exactprint
  • cabal build hls-ghc-lib -w ghc-8.8.3:
[1 of 3] Compiling Refact.Utils     ( src\Refact\Utils.hs, dist\build\Refact\Utils.o )
[2 of 3] Compiling Refact.Fixity    ( src\Refact\Fixity.hs, dist\build\Refact\Fixity.o )

src\Refact\Fixity.hs:59:27: error:
    Ambiguous occurrence ‘noExt’
    It could refer to
       either ‘HsExtension.noExt’,
              imported from ‘HsExtension’ at src\Refact\Fixity.hs:12:1-18
           or ‘Language.Haskell.GHC.ExactPrint.Types.noExt’,
              imported from ‘Language.Haskell.GHC.ExactPrint.Types’ at src\Refact\Fixity.hs:16:1-73
   |
59 |   = return $ L loc (OpApp noExt e1 op2 e2)
   |                           ^^^^^

src\Refact\Fixity.hs:74:26: error:
    Ambiguous occurrence ‘noExt’
    It could refer to
       either ‘HsExtension.noExt’,
              imported from ‘HsExtension’ at src\Refact\Fixity.hs:12:1-18
           or ‘Language.Haskell.GHC.ExactPrint.Types.noExt’,
              imported from ‘Language.Haskell.GHC.ExactPrint.Types’ at src\Refact\Fixity.hs:16:1-73
   |
74 |   = return (L loc (OpApp noExt e1 op2 e2))
   |                          ^^^^^

src\Refact\Fixity.hs:80:31: error:
    Ambiguous occurrence ‘noExt’
    It could refer to
       either ‘HsExtension.noExt’,
              imported from ‘HsExtension’ at src\Refact\Fixity.hs:12:1-18
           or ‘Language.Haskell.GHC.ExactPrint.Types.noExt’,
              imported from ‘Language.Haskell.GHC.ExactPrint.Types’ at src\Refact\Fixity.hs:16:1-73
   |
80 |       let res = L loc (NegApp noExt new_e neg_name)
   |                               ^^^^^

src\Refact\Fixity.hs:96:27: error:
    Ambiguous occurrence ‘noExt’
    It could refer to
       either ‘HsExtension.noExt’,
              imported from ‘HsExtension’ at src\Refact\Fixity.hs:12:1-18
           or ‘Language.Haskell.GHC.ExactPrint.Types.noExt’,
              imported from ‘Language.Haskell.GHC.ExactPrint.Types’ at src\Refact\Fixity.hs:16:1-73
   |
96 |   = return $ L loc (OpApp noExt e1 op1 e2)
   |                           ^^^^^

src\Refact\Fixity.hs:103:27: error:
    Ambiguous occurrence ‘noExt’
    It could refer to
       either ‘HsExtension.noExt’,
              imported from ‘HsExtension’ at src\Refact\Fixity.hs:12:1-18
           or ‘Language.Haskell.GHC.ExactPrint.Types.noExt’,
              imported from ‘Language.Haskell.GHC.ExactPrint.Types’ at src\Refact\Fixity.hs:16:1-73
    |
103 |   = return $ L loc (OpApp noExt e1 op e2)
    |                           ^^^^^
cabal.exe: Failed to build apply-refact-0.7.0.0 (which is required by
lib:hls-ghc-lib from haskell-language-server-0.1.0.0). See the build log above
for details.
  • cabal build hls-ghc-lib -w ghc-8.8.3 --constraint="ghc-exactprint == 0.6.2" builds it succesfully
  • Maybe adding a cabal revision with the upper bound would fix the issue

Refactor option --pos does not work with warning location

When calling hlint Bug.hs with Bug.hs containing:

module Bug where
bar n = 1 + (bar n)

I get:

Bug.hs:2:9: Warning: Redundant bracket
Found:
  1 + (bar n)
Why not:
  1 + bar n

1 suggestion

Fine, that's what I expected. Now lets apply the hint with --refactor but also with the --pos suggested by the warning.

$ hlint Bug.hs --refactor  --refactor-options="--pos 2,9" 

module Bug where
bar n = 1 + (bar n)

The hint is not applied! Only with --pos 2,13-20 do the brackets disappear.
I don't think the location of the warning is wrong, --pos should work with 2,9, as it is the start of the hint.

Error building apply-refact-0.3.0.0 in macOS

Hi guys, I can't install the apply-refact package.

System: macOS Sierra
Cabal version: 1.24.0.0
GHC version: 8.0.1

I've installed the Haskell Platform from: https://www.haskell.org/platform/mac.html.
I've added $HOME/Library/Haskell/bin and $HOME/.cabal/bin to the path.
Packages that I've installed manually with cabal:

hlint stylish-haskell hasktags hoogle happy

Full Log Error:

cabal: Entering directory '/var/folders/08/r90yw21s7gddgp9pq4x6wyvc0000gn/T/cabal-tmp-37889/apply-refact-0.3.0.0'
Configuring apply-refact-0.3.0.0...
Building apply-refact-0.3.0.0...
Preprocessing library apply-refact-0.3.0.0...
[1 of 3] Compiling Refact.Utils     ( src/Refact/Utils.hs, dist/build/Refact/Utils.o )
[2 of 3] Compiling Refact.Fixity    ( src/Refact/Fixity.hs, dist/build/Refact/Fixity.o )
[3 of 3] Compiling Refact.Apply     ( src/Refact/Apply.hs, dist/build/Refact/Apply.o )
[1 of 3] Compiling Refact.Utils     ( src/Refact/Utils.hs, dist/build/Refact/Utils.p_o )
[2 of 3] Compiling Refact.Fixity    ( src/Refact/Fixity.hs, dist/build/Refact/Fixity.p_o )
[3 of 3] Compiling Refact.Apply     ( src/Refact/Apply.hs, dist/build/Refact/Apply.p_o )
Preprocessing executable 'refactor' for apply-refact-0.3.0.0...
[1 of 5] Compiling Paths_apply_refact ( dist/build/autogen/Paths_apply_refact.hs, dist/build/refactor/refactor-tmp/Paths_apply_refact.o )
[2 of 5] Compiling Refact.Utils     ( src/Refact/Utils.hs, dist/build/refactor/refactor-tmp/Refact/Utils.o )
[3 of 5] Compiling Refact.Fixity    ( src/Refact/Fixity.hs, dist/build/refactor/refactor-tmp/Refact/Fixity.o )
[4 of 5] Compiling Refact.Apply     ( src/Refact/Apply.hs, dist/build/refactor/refactor-tmp/Refact/Apply.o )
[5 of 5] Compiling Main             ( src/Main.hs, dist/build/refactor/refactor-tmp/Main.o )

src/Main.hs:91:7: error:
    • Variable not in scope:
        (<>) :: Mod f0 a0 -> Mod f1 (Maybe a1) -> t0
    • Perhaps you meant one of these:
        ‘<*>’ (imported from Options.Applicative),
        ‘*>’ (imported from Options.Applicative),
        ‘>>’ (imported from Control.Monad.Identity)

src/Main.hs:92:7: error:
    • Variable not in scope:
        (<>) :: t0 -> Mod f2 a2 -> Mod OptionFields (Maybe String)
    • Perhaps you meant one of these:
        ‘<*>’ (imported from Options.Applicative),
        ‘*>’ (imported from Options.Applicative),
        ‘>>’ (imported from Control.Monad.Identity)

src/Main.hs:96:12: error:
    • Variable not in scope: (<>) :: Mod f3 a3 -> Mod f4 a4 -> t1
    • Perhaps you meant one of these:
        ‘<*>’ (imported from Options.Applicative),
        ‘*>’ (imported from Options.Applicative),
        ‘>>’ (imported from Control.Monad.Identity)

src/Main.hs:97:12: error:
    • Variable not in scope:
        (<>) :: t1 -> Mod f5 a5 -> Mod FlagFields Bool
    • Perhaps you meant one of these:
        ‘<*>’ (imported from Options.Applicative),
        ‘*>’ (imported from Options.Applicative),
        ‘>>’ (imported from Control.Monad.Identity)

src/Main.hs:100:25: error:
    • Variable not in scope: (<>) :: Mod f6 a6 -> Mod f7 a7 -> t3
    • Perhaps you meant one of these:
        ‘<*>’ (imported from Options.Applicative),
        ‘*>’ (imported from Options.Applicative),
        ‘>>’ (imported from Control.Monad.Identity)

src/Main.hs:101:25: error:
    • Variable not in scope: (<>) :: t3 -> Mod f8 a8 -> t2
    • Perhaps you meant one of these:
        ‘<*>’ (imported from Options.Applicative),
        ‘*>’ (imported from Options.Applicative),
        ‘>>’ (imported from Control.Monad.Identity)

src/Main.hs:102:25: error:
    • Variable not in scope:
        (<>) :: t2 -> Mod f9 a9 -> Mod OptionFields String
    • Perhaps you meant one of these:
        ‘<*>’ (imported from Options.Applicative),
        ‘*>’ (imported from Options.Applicative),
        ‘>>’ (imported from Control.Monad.Identity)

src/Main.hs:106:12: error:
    • Variable not in scope: (<>) :: Mod f10 a10 -> Mod f11 a11 -> t5
    • Perhaps you meant one of these:
        ‘<*>’ (imported from Options.Applicative),
        ‘*>’ (imported from Options.Applicative),
        ‘>>’ (imported from Control.Monad.Identity)

src/Main.hs:107:12: error:
    • Variable not in scope: (<>) :: t5 -> Mod f12 Verbosity -> t4
    • Perhaps you meant one of these:
        ‘<*>’ (imported from Options.Applicative),
        ‘*>’ (imported from Options.Applicative),
        ‘>>’ (imported from Control.Monad.Identity)

src/Main.hs:108:12: error:
    • Variable not in scope:
        (<>) :: t4 -> Mod f13 a12 -> Mod OptionFields Verbosity
    • Perhaps you meant one of these:
        ‘<*>’ (imported from Options.Applicative),
        ‘*>’ (imported from Options.Applicative),
        ‘>>’ (imported from Control.Monad.Identity)

src/Main.hs:111:12: error:
    • Variable not in scope: (<>) :: Mod f14 a13 -> Mod f15 a14 -> t6
    • Perhaps you meant one of these:
        ‘<*>’ (imported from Options.Applicative),
        ‘*>’ (imported from Options.Applicative),
        ‘>>’ (imported from Control.Monad.Identity)

src/Main.hs:112:12: error:
    • Variable not in scope:
        (<>) :: t6 -> Mod f16 a15 -> Mod FlagFields Bool
    • Perhaps you meant one of these:
        ‘<*>’ (imported from Options.Applicative),
        ‘*>’ (imported from Options.Applicative),
        ‘>>’ (imported from Control.Monad.Identity)

src/Main.hs:115:12: error:
    • Variable not in scope: (<>) :: Mod f17 a16 -> Mod f18 a17 -> t7
    • Perhaps you meant one of these:
        ‘<*>’ (imported from Options.Applicative),
        ‘*>’ (imported from Options.Applicative),
        ‘>>’ (imported from Control.Monad.Identity)

src/Main.hs:116:12: error:
    • Variable not in scope:
        (<>) :: t7 -> Mod f19 a18 -> Mod FlagFields Bool
    • Perhaps you meant one of these:
        ‘<*>’ (imported from Options.Applicative),
        ‘*>’ (imported from Options.Applicative),
        ‘>>’ (imported from Control.Monad.Identity)

src/Main.hs:119:12: error:
    • Variable not in scope: (<>) :: Mod f20 a19 -> Mod f21 a20 -> t8
    • Perhaps you meant one of these:
        ‘<*>’ (imported from Options.Applicative),
        ‘*>’ (imported from Options.Applicative),
        ‘>>’ (imported from Control.Monad.Identity)

src/Main.hs:120:12: error:
    • Variable not in scope:
        (<>) :: t8 -> Mod f22 a21 -> Mod FlagFields Bool
    • Perhaps you meant one of these:
        ‘<*>’ (imported from Options.Applicative),
        ‘*>’ (imported from Options.Applicative),
        ‘>>’ (imported from Control.Monad.Identity)

src/Main.hs:123:12: error:
    • Variable not in scope:
        (<>) :: Mod f23 a22 -> Mod f24 a23 -> Mod FlagFields Bool
    • Perhaps you meant one of these:
        ‘<*>’ (imported from Options.Applicative),
        ‘*>’ (imported from Options.Applicative),
        ‘>>’ (imported from Control.Monad.Identity)

src/Main.hs:127:12: error:
    • Variable not in scope:
        (<>) :: Mod f25 a24 -> Mod f26 (Maybe a25) -> t10
    • Perhaps you meant one of these:
        ‘<*>’ (imported from Options.Applicative),
        ‘*>’ (imported from Options.Applicative),
        ‘>>’ (imported from Control.Monad.Identity)

src/Main.hs:128:12: error:
    • Variable not in scope: (<>) :: t10 -> Mod f27 a26 -> t9
    • Perhaps you meant one of these:
        ‘<*>’ (imported from Options.Applicative),
        ‘*>’ (imported from Options.Applicative),
        ‘>>’ (imported from Control.Monad.Identity)

src/Main.hs:129:12: error:
    • Variable not in scope:
        (<>) :: t9 -> Mod f28 a27 -> Mod OptionFields (Maybe (Int, Int))
    • Perhaps you meant one of these:
        ‘<*>’ (imported from Options.Applicative),
        ‘*>’ (imported from Options.Applicative),
        ‘>>’ (imported from Control.Monad.Identity)

src/Main.hs:137:11: error:
    • Variable not in scope: (<>) :: InfoMod a28 -> InfoMod a29 -> t11
    • Perhaps you meant one of these:
        ‘<*>’ (imported from Options.Applicative),
        ‘*>’ (imported from Options.Applicative),
        ‘>>’ (imported from Control.Monad.Identity)

src/Main.hs:138:11: error:
    • Variable not in scope:
        (<>) :: t11 -> InfoMod a30 -> InfoMod Options
    • Perhaps you meant one of these:
        ‘<*>’ (imported from Options.Applicative),
        ‘*>’ (imported from Options.Applicative),
        ‘>>’ (imported from Control.Monad.Identity)
cabal: Leaving directory '/var/folders/08/r90yw21s7gddgp9pq4x6wyvc0000gn/T/cabal-tmp-37889/apply-refact-0.3.0.0'

InsertComment

Does the InsertComment refactoring work? It requires a SrcSpan and I'm trying to figure out how to calculate that. Should it be a zero length span at the right line and column?

When I tried to use it, I got an error from findGen, which looks like it is trying to find an expression for replacement. Or do I just need to find an expression to attach the comment to? (It vaguely looks like this is what is going on, but I don't yet understand annotations.)

Stackage

Would you consider adding apply-refact to stackage? I see that refact itself is in there.

Applying "Use &&" leaves a comma

Thank you for the awesome tool! Combined with HLint it's really powerful.

Repro.hs:

athing = and [a, b]

The suggestion:

Repro.hs:2:5: Warning: Use &&
Found:
  and [a, b]
Why not:
  a && b

1 suggestion

Result (~/local/hlint/dist/build/hlint/hlint --refactor --with-refactor=$HOME/local/apply-refact/dist/build/refactor/refactor ~/Repro.hs):

athing = a, && b

Shebangs are stripped if invoked with prefixed paths

If calling refactor with a path argument like ./x, ../x, or /x, any shebang lines are stripped in the output. If invoked with just x or x/y, it works. I ran into this through the ALE Vim plugin, which calls HLint, which calls refactor with an absolute-path tempfile.

Setup:

% echo '[]' > empty.txt
% cat > example <<'EOM'
\`heredoc> #!/usr/bin/env stack
\`heredoc> {- stack --resolver lts-16.10 script -}
\`heredoc> module Main (main) where
\`heredoc> main :: IO ()
\`heredoc> main = putStrLn "hi"
\`heredoc> EOM
% chmod +x example
% ./example
hi
% stack exec refactor -- --version
v0.7.0.0%   

Repro:

% stack exec refactor -- ./example --refact-file empty.txt
Applying 0 hints

{- stack --resolver lts-16.10 script -}
module Main (main) where
main :: IO ()
main = putStrLn "hi"

Working fine with example:

% stack exec refactor -- example --refact-file empty.txt
Applying 0 hints
#!/usr/bin/env stack
{- stack --resolver lts-16.10 script -}
module Main (main) where
main :: IO ()
main = putStrLn "hi"

Note that it's not a "first line" problem; it's specifically a shebang. Everything works fine in files without shebangs, even when invoked as ./example:

% tail -n +2 example | sponge example
% cat example
{- stack --resolver lts-16.10 script -}
module Main (main) where
main :: IO ()
main = putStrLn "hi"
% stack exec refactor -- ./example --refact-file empty.txt
Applying 0 hints
{- stack --resolver lts-16.10 script -}
module Main (main) where
main :: IO ()
main = putStrLn "hi"
%
% { echo "#\!something"; cat example; } | sponge example
% cat example
#!something
{- stack --resolver lts-16.10 script -}
module Main (main) where
main :: IO ()
main = putStrLn "hi"
% stack exec refactor -- ./example --refact-file empty.txt
Applying 0 hints

{- stack --resolver lts-16.10 script -}
module Main (main) where
main :: IO ()
main = putStrLn "hi"

Note that Brittany has the same bug, so possibly the same root cause?

Release apply-refact 0.8.1.0

@mpickering I fixed some bugs that I was aware of, and I'm ready to release 0.8.1.0. The main changes are:

  • #68, support GHC 8.6
  • #63, support GHC 8.8
  • #64, add LANGUAGE pragmas to DynFlag
  • #62, fix a bug where "y = f(x)" is refactored into "y = fx"
  • #61, fix a bug where "x < -2 * 3" is printed as "x < 2 * 3"
  • #51, fix a bug where [1,2..5] is printed as [12..5]
  • #59, do not process the target file if there's no hint

If you are OK with the changes, do you mind uploading 0.8.1.0 to Hackage, or adding me (zliu41) to the maintainer group so that I can upload? Thanks!

cc @ndmitchell

when -> unless refactor drops parens

-  when (not $ isStaffMail email) ($(logThrow) Unauthorized)
+  unless isStaffMail email ($(logThrow) Unauthorized)

This happens when the unless refactor is applied. Not sure if related to the TH splice.

Expected result:

unless (isStaffMail email) ($(logThrow) Unauthorized)

Windows files are written in CRLF newlines

Given a file on Windows with LF newlines, when I run it through apply-refact, it comes out with CRLF newlines. It would be better if apply-refact (or maybe ghc-exactprint?) could preserve whatever type of newline I have, in addition to everything else.

Parse error on LambdaCase

When I try to apply hlint suggestions to a file that contains \case -> ... expressions, apply-refact throws a parser error when LambdaCase is not in a LANGUAGE pragma inside the source file:

refactor: (RealSrcSpan SrcSpanOneLine "src/Main.hs" 6 6 10,"parse error on input \8216case\8217")
CallStack (from HasCallStack):
  error, called at src/Main.hs:189:22 in main:Main

Steps to reproduce:

  • stack new test simple && cd test
  • Edit src/Main.hs to:
module Main where

main = putStrLn "hello world"

f = \case [] -> 0
  • Run refactor src/Main.hs and observe the error mentioned above.
  • Now add {-# LANGUAGE LambdaCase #-} to the Main module, try again, the error disappears.

What confuses me is that this behavior seems to be unique to LambdaCase. For other extensions (like RecordWildCards or TypeApplications) hlint works just fine even without the appropriate LANGUAGE pragmas. It would be really nice to use hlint with refactorings on projects where LambdaCase is in the default-extensions section in a cabal-file and thus not declared in any source file.

`stack.yaml` in error (3.12 in stead of 13.12)

The stack.yaml file is in error. it says lts-3.12, but should probably say 13.12.
the extra-deps are also old.
it should say:
resolver: lts-13.12

packages:

  • '.'
    extra-deps:

flags: {}

sorry for not sending a PR - issues with githup protection on my side.

Parse error on unspecified QuasiQuotes

I like to omit the {-# LANGUAGE QuasiQuotes #-} section at the top of my files, and instead enable QuasiQuotes universally by putting it in default-extensions.

But when I try to use hlint --refactor on such files, I get refactor: (RealSrcSpan SrcSpanOneLine ...,"parse error on input \8216]\8217") on lines that contain QuasiQuotes.

I notice that hlint itself can accept an -XQuasiQuotes argument which tells it to always parse them--it seems like there needs to be a similar way to enable default extensions for the refactor package? See also ndmitchell/hlint#504

Apply-Refact not applying HLint suggestions.

I recently added some refactorings to some HLint suggestions (https://github.com/ndmitchell/hlint/pull/614/files). The suggestions were related to list comprehensions, and function names adhering to the camelCase naming convention.

In the case of camelCase, while HLint provides the right refactorings and apply-refact, using the -s refactor option, detects that a change is available to be made, the apply-refact package refuses to make the necessary change.

For reference, here is a sample piece of code that I used to test this behaviour:

memoized_fib = (map fib [0 ..] !!)
  where
    fib 0 = 0
    fib 1 = 1
    fib n = memoized_fib (n - 2) + memoized_fib (n - 1)

fast_fib n = fib' 0 1 n
  where
    fib' a _ 0 = a
    fib' a b n = fib' b (a + b) (n - 1)

slow_fib 0 = 0
slow_fib 1 = 1
slow_fib n = slow_fib (n - 2) + slow_fib (n - 1)

Is this not working because this is a Bind type refactoring, or could there be an alternative reason?

Please let me know if you need any further information from my side.

Allow apply refactorings to an already parsed module

Hi, we added recently hlint support in haskell-language-server, including the apply of refactorings usgins appy-refact, via applyRefactorings
The actual integration could be improved if the api would expose a function to apply them to an already parsed module.
Now we have to use a temporary file and ask apply-refact to parse it again:

res <- liftIO $ withSystemTempFile (takeFileName fp) $ \temp h -> do
            hClose h
            writeFileUTF8NoNewLineTranslation temp oldContent
            (Right <$> applyRefactorings Nothing commands temp) `catches`
                    [ Handler $ \e -> return (Left (show (e :: IOException)))
                    , Handler $ \e -> return (Left (show (e :: ErrorCall)))
                    ]

As we are using ghc-lib to parse for ghc < 8.10 and the real ghc for 8.10, following hlint, maybe only we can take advantage in the latter path, but i think it still will worth it.

Refact.Internal.runRefactoring is exposed but maybe a higher endpoint, closer to applyRefactorings would be handy for downstream packages.

For ghc < 8.10 we will continue to need delegate the parsing to apply-refact. In that case it would be handy be able to inform the parser option, to, for example, pass custom language extensions not included in the module as pragmas.
Let me know if you think that should be in another issue.

//cc @ndmitchell @alanz

Refactoring may introduce not imported name

module Test (foo) where

foo :: (Int, a) -> (Int, b)
foo (x, y) = (\(x, y) -> (abs x, y)) (x + 1, y + 1)

is refactored into

module Test (foo) where

foo :: (Int, a) -> (Int, b)
foo (x, y) = (Control.Arrow.first abs) (x + 1, y + 1)

Applying eta reduce does not work

For example:
foo x = (+1) x

Hint gives suggestion to eta reduce to:
foo = (+1)

stack exec -- hlint Foo.hs --refactor --refactor-options="--pos 30,1"
returns no changes.

Command line extensions should not override LANGUAGE pragmas

-- Foo.hs
{-# LANGUAGE NoStarIsType, ExplicitNamespaces #-}
import GHC.TypeLits(KnownNat, type (+), type (*))
$ refactor Foo.hs -X StarIsType
refactor: (RealSrcSpan SrcSpanOneLine "Foo.hs" 3 47 48,"parse error on input \8216*\8217")
CallStack (from HasCallStack):
  error, called at src/Refact/Run.hs:205:22 in main:Refact.Run

This should not fail - although the command line argument has -X StarIsType, the code has the NoStarIsType pragma, which should take precedence.

Use ghc-lib to support a range of GHC versions

Did you try to make it work?

Simply changing ghc dependency to ghc-lib doesn't work because of ghc-exactprint type mismatches, so presumably ghc-exactprint would also need to use ghc-lib.

Stack Installation Error: Plan Construction Fails with GHC 8.0.2

Hi,
Forgive my ignorance, I am new to Haskell, but I am having trouble installing apply-refact with stack. I am using GHC 8.0.2 and receive the following message during installation:
apply_refact

Any assistance would be great, I am trying to install apply-refact as a dependency of using the spacemacs Haskell layer.

Thanks in advance.

The suggestion "Avoid lambda" does not add parenthesis around code blocks when it should

Sorry that this is not a minimal working example.

Original code

buildIndex :: [(Output, [ByteString])] -> Map ByteString [Output]
buildIndex =
  foldl'
    ( \m (out, libs) ->
        foldl'
          ( \m' lib ->
              M.alter
                ( \case
                    Nothing -> Just [out]
                    Just outs -> Just (out : outs)
                )
                lib
                m'
          )
          m
          libs
    )
    mempty

After refactoring

buildIndex :: [(Output, [ByteString])] -> Map ByteString [Output]
buildIndex =
  foldl'
    ( \m (out, libs) ->
        foldl'
          ( flip M.alter
                ( \case
                    Nothing -> Just [out]
                    Just outs -> Just (out : outs)
                )
          )
          m
          libs
    )
    mempty

The correct code to generate

buildIndex :: [(Output, [ByteString])] -> Map ByteString [Output]
buildIndex =
  foldl'
    ( \m (out, libs) ->
        foldl'
          ( flip (M.alter
                ( \case
                    Nothing -> Just [out]
                    Just outs -> Just (out : outs)
                ))
          )
          m
          libs
    )
    mempty

I'm using apply-refact from haskell-language-server version 0.6.0.0

Language pragmas aren't picked if there are comments before them

Minimal example:

-- Let's trick you
{-# LANGUAGE ExplicitForAll #-}
module Test (foo) where

foo :: forall a. a -> a
foo x = x
% hlint --refactor --refactor-options="-i -s" forall.hs
refactor: (RealSrcSpan SrcSpanOneLine "forall.hs" 5 16 17,"Illegal symbol '.' in type\nPerhaps you intended to use RankNTypes or a similar language\nextension to enable explicit-forall syntax: forall <tvs>. <type>")

Compilation error

On CI https://travis-ci.org/github/ndmitchell/hlint/jobs/667865822 I'm getting:

Building executable 'refactor' for apply-refact-0.6.0.0..
[1 of 6] Compiling Paths_apply_refact ( dist/build/refactor/autogen/Paths_apply_refact.hs, dist/build/refactor/refactor-tmp/Paths_apply_refact.o )
[2 of 6] Compiling Refact.Utils     ( src/Refact/Utils.hs, dist/build/refactor/refactor-tmp/Refact/Utils.o )
[3 of 6] Compiling Refact.Fixity    ( src/Refact/Fixity.hs, dist/build/refactor/refactor-tmp/Refact/Fixity.o )
src/Refact/Fixity.hs:59:27: error:
    Ambiguous occurrence ‘noExt’
    It could refer to either ‘HsExtension.noExt’,
                             imported from ‘HsExtension’ at src/Refact/Fixity.hs:12:1-18
                          or ‘Language.Haskell.GHC.ExactPrint.Types.noExt’,
                             imported from ‘Language.Haskell.GHC.ExactPrint.Types’ at src/Refact/Fixity.hs:16:1-73
   |
59 |   = return $ L loc (OpApp noExt e1 op2 e2)
   |                           ^^^^^

Is the issue a change to ghc-exactprint-0.6.3?

Apply hint: eta reduce breaks where block identation

Hi, using hls-hlint-plugin an user has detected that apply "eta reduce" removes the identation of a where block, making the code throw parser errors

PS D:\dev\ws\haskell\cabal-test> cat .\src\HlintTests.hs
module HlintTests where

f  :: String -> String
f x = show x
  where y :: String
        y = "foo"

PS D:\dev\ws\haskell\cabal-test> hlint .\src\HlintTests.hs --refactor
module HlintTests where

f  :: String -> String
f = show
  where
y = "foo" y :: String

PS D:\dev\ws\haskell\cabal-test> hlint --version
HLint v3.2.1, (C) Neil Mitchell 2006-2020

PS D:\dev\ws\haskell\cabal-test> refactor --version
v0.8.2.1

Thanks in advance.

GHC 8.8 support

GHC 8.8.1 is out now -- any idea how to get apply-refact to build with it? It seems like some internals might have changed.

apply-refact ate my imports

This might be a problem with hlint, without learning about the format of the serialized representation it's hard to know.

module Foo where

import A (foo)
import A (bar)
import A (baz)

hlint Foo.hs --refactor, where did baz go?

module Foo where

import A ( foo, bar )

hlint Foo.hs, correct

Foo.hs:3:1: Warning: Use fewer imports
Found:
  import A ( foo )
  import A ( bar )
  import A ( baz )
Perhaps:
  import A ( foo, bar, baz )

1 hint

hlint Foo.hs --serialise

[ ( "Foo.hs:3:1: Warning: Use fewer imports\nFound:\n  import A ( foo )\n  import A ( bar )\n  import A ( baz )\nPerhaps:\n  import A ( foo, bar, baz )\n"
  , [ Replace
        { rtype = Import
        , pos =
            SrcSpan
              { startLine = -1 , startCol = -1 , endLine = -1 , endCol = -1 }
        , subts = []
        , orig = "import A ( foo, bar, baz )"
        }
    , Delete
        { rtype = Import
        , pos =
            SrcSpan
              { startLine = 5 , startCol = 1 , endLine = 5 , endCol = 15 }
        }
    , Replace
        { rtype = Import
        , pos =
            SrcSpan
              { startLine = 3 , startCol = 1 , endLine = 3 , endCol = 15 }
        , subts = []
        , orig = "import A ( foo, bar )"
        }
    , Delete
        { rtype = Import
        , pos =
            SrcSpan
              { startLine = 4 , startCol = 1 , endLine = 4 , endCol = 15 }
        }
    ]
  )
]

a = -b/c round-trips to a =b/c

$ cat ~/Repro.hs
a = -b/c
$ echo [] | $HOME/local/apply-refact/dist/build/refactor/refactor --roundtrip ~/Repro.hs
Applying 0 hints
a =b/c

Strange CPP expansions

Given https://gitlab.haskell.org/ghc/ghc/blob/ba4e3934abc82e0ba2bec51842315819910d1018/libraries/integer-simple/GHC/Integer/Type.hs

and a file refact.txt with the contents

[]

the command

refactor libraries/integer-simple/GHC/Integer/Type.hs --refact-file refact.txt --inplace

produces the following diff:

--- a/libraries/integer-simple/GHC/Integer/Type.hs
+++ b/libraries/integer-simple/GHC/Integer/Type.hs
@@ -144,7 +144,7 @@ encodeDoubleInteger (Positive ds0) e0 = f 0.0## ds0 e0
                                       ds
                                       -- XXX We assume that this adding to e
                                       -- isn't going to overflow
-                                      (e +# WORD_SIZE_IN_BITS#)
+                                      (e +# 64#WORD_SIZE_IN_BITS#)              )
 encodeDoubleInteger (Negative ds) e
     = negateDouble# (encodeDoubleInteger (Positive ds) e)
 encodeDoubleInteger Naught _ = 0.0##
@@ -160,7 +160,7 @@ encodeFloatInteger (Positive ds0) e0 = f 0.0# ds0 e0
                                       ds
                                       -- XXX We assume that this adding to e
                                       -- isn't going to overflow
-                                      (e +# WORD_SIZE_IN_BITS#)
+                                      (e +# 64#WORD_SIZE_IN_BITS#)              )
 encodeFloatInteger (Negative ds) e
     = negateFloat# (encodeFloatInteger (Positive ds) e)
 encodeFloatInteger Naught _ = 0.0#
@@ -343,8 +343,8 @@ bitInteger i# = if isTrue# (i# <# 0#)
 -- Assumes 0 <= i
 bitPositive :: Int# -> Positive
 bitPositive i#
-    = if isTrue# (i# >=# WORD_SIZE_IN_BITS#)
-      then Some 0## (bitPositive (i# -# WORD_SIZE_IN_BITS#))
+    = if isTrue# (i# >=# 64#WORD_SIZE_IN_BITS#)              )
+      then Some 0## (bitPositive (i# -# 64#WORD_SIZE_IN_BITS#))             ))
       else Some (uncheckedShiftL# 1## i#) None
 
 {-# NOINLINE testBitInteger #-}
@@ -358,8 +358,8 @@ testBitInteger (Positive p) i# = isTrue# (testBitPositive p i#)
   testBitPositive :: Positive -> Int# -> Int#
   testBitPositive None          _ = 0#
   testBitPositive (Some w# ws)  j#
-    = if isTrue# (j# >=# WORD_SIZE_IN_BITS#)
-      then testBitPositive ws (j# -# WORD_SIZE_IN_BITS#)
+    = if isTrue# (j# >=# 64#WORD_SIZE_IN_BITS#)              )
+      then testBitPositive ws (j# -# 64#WORD_SIZE_IN_BITS#)              )
       else neWord# (uncheckedShiftL# 1## j# `and#` w#) 0##
 testBitInteger (Negative n) i# = isTrue# (testBitNegative n i#)
   where
@@ -371,8 +371,8 @@ testBitInteger (Negative n) i# = isTrue# (testBitNegative n i#)
     -- If the number starts (on the low end) with a bunch of '0##' and 'j#'
     -- falls in those, we know that @n - 1@ would have flipped all those
     -- bits, so @!(n - 1) & i@ is false.
-    = if isTrue# (j# >=# WORD_SIZE_IN_BITS#)
-      then testBitNegative ws (j# -# WORD_SIZE_IN_BITS#)
+    = if isTrue# (j# >=# 64#WORD_SIZE_IN_BITS#)              )
+      then testBitNegative ws (j# -# 64#WORD_SIZE_IN_BITS#)              )
       else 1#
   testBitNegative (Some w# ws) j#
     -- Yet, as soon as we find something that isn't a '0##', we can subtract
@@ -383,8 +383,8 @@ testBitInteger (Negative n) i# = isTrue# (testBitNegative n i#)
   testBitNegativeMinus1 :: Positive -> Int# -> Int#
   testBitNegativeMinus1 None         _ = 1#
   testBitNegativeMinus1 (Some w# ws) j#
-    = if isTrue# (j# >=# WORD_SIZE_IN_BITS#)
-      then testBitNegativeMinus1 ws (j# -# WORD_SIZE_IN_BITS#)
+    = if isTrue# (j# >=# 64#WORD_SIZE_IN_BITS#)              )
+      then testBitNegativeMinus1 ws (j# -# 64#WORD_SIZE_IN_BITS#)              )
       else neWord# (uncheckedShiftL# 1## j# `and#` not# w#) 0##
 
 twosComplementPositive :: Positive -> DigitsOnes
@@ -825,15 +825,15 @@ splitHalves (!x) = (# x `uncheckedShiftRL#` highHalfShift (),
 -- Assumes 0 <= i
 shiftLPositive :: Positive -> Int# -> Positive
 shiftLPositive p i
-    = if isTrue# (i >=# WORD_SIZE_IN_BITS#)
-      then shiftLPositive (Some 0## p) (i -# WORD_SIZE_IN_BITS#)
+    = if isTrue# (i >=# 64#WORD_SIZE_IN_BITS#)              )
+      then shiftLPositive (Some 0## p) (i -# 64#WORD_SIZE_IN_BITS#)              )
       else smallShiftLPositive p i
 
--- Assumes 0 <= i < WORD_SIZE_IN_BITS#
+-- Assumes 0 <= i < 64#-- Assumes 0 <= i < WORD_SIZE_IN_BITS#
 smallShiftLPositive :: Positive -> Int# -> Positive
 smallShiftLPositive (!p) 0# = p
 smallShiftLPositive (!p) (!i) =
-    case WORD_SIZE_IN_BITS# -# i of
+    case 64#WORD_SIZE_IN_BITS# i of        -# i of
     j -> let f carry None = if isTrue# (carry `eqWord#` 0##)
                             then None
                             else Some carry None
@@ -848,16 +848,16 @@ smallShiftLPositive (!p) (!i) =
 shiftRPositive :: Positive -> Int# -> Integer
 shiftRPositive None _ = Naught
 shiftRPositive p@(Some _ q) i
-    = if isTrue# (i >=# WORD_SIZE_IN_BITS#)
-      then shiftRPositive q (i -# WORD_SIZE_IN_BITS#)
+    = if isTrue# (i >=# 64#WORD_SIZE_IN_BITS#)              )
+      then shiftRPositive q (i -# 64#WORD_SIZE_IN_BITS#)              )
       else smallShiftRPositive p i
 
--- Assumes 0 <= i < WORD_SIZE_IN_BITS#
+-- Assumes 0 <= i < 64#-- Assumes 0 <= i < WORD_SIZE_IN_BITS#
 smallShiftRPositive :: Positive -> Int# -> Integer
 smallShiftRPositive (!p) (!i) =
     if isTrue# (i ==# 0#)
     then Positive p
-    else case smallShiftLPositive p (WORD_SIZE_IN_BITS# -# i) of
+    else case smallShiftLPositive p (64#WORD_SIZE_IN_BITS# i) of       -# i) of
          Some _ p'@(Some _ _) -> Positive p'
          _                    -> Naught
 
@@ -869,7 +869,7 @@ quotRemPositive :: Positive -> Positive -> (# Integer, Integer #)
                        digitsMaybeZeroToInteger m #)
     where
           subtractors :: Positives
-          subtractors = mkSubtractors (WORD_SIZE_IN_BITS# -# 1#)
+          subtractors = mkSubtractors (64#WORD_SIZE_IN_BITS# 1#)         -# 1#)
 
           mkSubtractors (!n) = if isTrue# (n ==# 0#)
                                then Cons ys Nil
@@ -945,7 +945,7 @@ doubleFromPositive None = 0.0##
 doubleFromPositive (Some w ds)
     = case splitHalves w of
       (# h, l #) ->
-       (doubleFromPositive ds *## (2.0## **## WORD_SIZE_IN_BITS_FLOAT##))
+       (doubleFromPositive ds *## (2.0## **## 64.0##WORD_SIZE_IN_BITS_FLOAT##))                 ))
        +## (int2Double# (word2Int# h) *##
               (2.0## **## int2Double# (highHalfShift ())))
        +## int2Double# (word2Int# l)
@@ -956,7 +956,7 @@ floatFromPositive None = 0.0#
 floatFromPositive (Some w ds)
     = case splitHalves w of
       (# h, l #) ->
-       (floatFromPositive ds `timesFloat#` (2.0# `powerFloat#` WORD_SIZE_IN_BITS_FLOAT#))
+       (floatFromPositive ds `timesFloat#` (2.0# `powerFloat#` 64.0#WORD_SIZE_IN_BITS_FLOAT#))                 ))
        `plusFloat#` (int2Float# (word2Int# h) `timesFloat#`
              (2.0# `powerFloat#` int2Float# (highHalfShift ())))
        `plusFloat#` int2Float# (word2Int# l)
≻ refactor --version
v0.6.0.0

Apply hint: use guards remove comments above

Hi, using hls-hlint-plugin an user has detected that apply "use guards" remove comments above the inserted guard:

PS D:\dev\ws\haskell\cabal-test> cat .\src\HlintTests.hs
module HlintTests where

bar :: Maybe Int -> [Int] -> String
bar x y =
  -- this is a comment
  if isJust x then "1"
  else if Prelude.null y then "2"
  else "3"

PS D:\dev\ws\haskell\cabal-test> hlint .\src\HlintTests.hs --refactor
module HlintTests where

bar :: Maybe Int -> [Int] -> String
bar x y
  | isJust x = "1"
  | Prelude.null y = "2"
  | otherwise = "3"

PS D:\dev\ws\haskell\cabal-test> hlint --version
HLint v3.2.1, (C) Neil Mitchell 2006-2020
PS D:\dev\ws\haskell\cabal-test> refactor --version
v0.8.2.

Thanks in advance!

Installation with nix package manager fails

I noticed the installation with nix-env is currently failing. The cause seems to be the constraint, that ghc has to be >= 8.10.1 and I think this is currently not the case with nix.

It is likely that this issue has to be fixed in the nixpkgs repository instead, or forcing the incompatibility might even be intended. I wanted to notify you, that this is currently and issue, and I handled it by rolling back.

nix-env -f "<nixpkgs>" -iA haskellPackages.apply-refact

replacing old 'apply-refact-0.6.0.0'
installing 'apply-refact-0.8.0.0'
these derivations will be built:
  /nix/store/9bzq6sgwc9m5s46lfr312amzakhal3w7-apply-refact-0.8.0.0.drv
building '/nix/store/9bzq6sgwc9m5s46lfr312amzakhal3w7-apply-refact-0.8.0.0.drv'...
setupCompilerEnvironmentPhase
Build with /nix/store/zdy255cgf82lzhkm36ixxl50yv446bh5-ghc-8.8.3.
unpacking sources
unpacking source archive /nix/store/0mfwslszxq8wgzkqla739g4l5gg2ci9v-apply-refact-0.8.0.0.tar.gz
source root is apply-refact-0.8.0.0
setting SOURCE_DATE_EPOCH to timestamp 1000000000 of file apply-refact-0.8.0.0/tests/Test.hs
patching sources
compileBuildDriverPhase
setupCompileFlags: -package-db=/build/setup-package.conf.d -j4 -threaded
[1 of 1] Compiling Main             ( Setup.hs, /build/Main.o )
Linking Setup ...
configuring
configureFlags: --verbose --prefix=/nix/store/sjavafml23y18fry4g069j8shvph9z5q-apply-refact-0.8.0.0 --libdir=$prefix/lib/$compiler --libsubdir=$abi/$libname --docdir=/nix/store/d1iph962hq82gqhz68xmj3191gj0phrh-apply-refact-0.8.0.0-doc/share/doc/apply-refact-0.8.0.0 --with-gcc=gcc --package-db=/build/package.conf.d --ghc-option=-j4 --disable-split-objs --enable-library-profiling --profiling-detail=exported-functions --disable-profiling --enable-shared --disable-coverage --enable-static --disable-executable-dynamic --enable-tests --disable-benchmarks --enable-library-vanilla --disable-library-for-ghci --ghc-option=-split-sections --extra-lib-dirs=/nix/store/0i4wbhkj6663nlh63ydhr01vx8w90s49-ncurses-6.2/lib --extra-lib-dirs=/nix/store/dfs0i8z58m64zak8102hf7g0w9skhdw6-libffi-3.3/lib --extra-lib-dirs=/nix/store/js28swbiimjvd139x6kr7nc68s81fdg6-gmp-6.2.0/lib --extra-lib-dirs=/nix/store/zdy255cgf82lzhkm36ixxl50yv446bh5-ghc-8.8.3/lib
Using Parsec parser
Configuring apply-refact-0.8.0.0...
CallStack (from HasCallStack):
  die', called at libraries/Cabal/Cabal/Distribution/Simple/Configure.hs:1022:20 in Cabal-3.0.1.0:Distribution.Simple.Configure
  configureFinalizedPackage, called at libraries/Cabal/Cabal/Distribution/Simple/Configure.hs:475:12 in Cabal-3.0.1.0:Distribution.Simple.Configure
  configure, called at libraries/Cabal/Cabal/Distribution/Simple.hs:625:20 in Cabal-3.0.1.0:Distribution.Simple
  confHook, called at libraries/Cabal/Cabal/Distribution/Simple/UserHooks.hs:65:5 in Cabal-3.0.1.0:Distribution.Simple.UserHooks
  configureAction, called at libraries/Cabal/Cabal/Distribution/Simple.hs:180:19 in Cabal-3.0.1.0:Distribution.Simple
  defaultMainHelper, called at libraries/Cabal/Cabal/Distribution/Simple.hs:116:27 in Cabal-3.0.1.0:Distribution.Simple
  defaultMain, called at Setup.hs:2:8 in main:Main
Setup: Encountered missing or private dependencies:
ghc >=8.10.1, ghc-exactprint >=0.6.3

builder for '/nix/store/9bzq6sgwc9m5s46lfr312amzakhal3w7-apply-refact-0.8.0.0.drv' failed with exit code 1
error: build of '/nix/store/9bzq6sgwc9m5s46lfr312amzakhal3w7-apply-refact-0.8.0.0.drv' failed

GHC 8.10 Support

When trying to build apply-refact with GHC-8.10, I see the following error:

src/Refact/Utils.hs:33:1: error:
    Could not find module ‘HsExpr’
    Perhaps you meant
      DsExpr (from ghc-8.10.1)
      RnExpr (from ghc-8.10.1)
      TcExpr (from ghc-8.10.1)
    Use -v (or `:set -v` in ghci) to see a list of the files searched for.
   |
33 | import HsExpr as GHC hiding (Stmt)
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

src/Refact/Utils.hs:37:1: error:
    Could not find module ‘HsExtension’
    Use -v (or `:set -v` in ghci) to see a list of the files searched for.
   |
37 | import qualified HsExtension as GHC
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

src/Refact/Utils.hs:41:1: error:
    Could not find module ‘HsImpExp’
    Use -v (or `:set -v` in ghci) to see a list of the files searched for.
   |
41 | import HsImpExp
   | ^^^^^^^^^^^^^^^

Update to work with GHC 8

I've tried lifting the constraint on base and I got this:

/data/users/bnitka/stackage-ghc8/test/apply-refact-0.2.0.0/src/Refact/Utils.hs:48:1: warning: [-Wunused-imports]
    The import of ‘Refact.Types’ is redundant
      except perhaps to import instances from ‘Refact.Types’
    To import instances alone, use: import Refact.Types()

/data/users/bnitka/stackage-ghc8/test/apply-refact-0.2.0.0/src/Refact/Utils.hs:116:1: warning: [-Wredundant-constraints]
    • Redundant constraint: Typeable a
    • In the type signature for:
           findParentWorker :: (Typeable a, Data a) =>
                               SrcSpan -> a -> Maybe AnnKey
[2 of 3] Compiling Refact.Fixity    ( src/Refact/Fixity.hs, .stack-work/dist/x86_64-linux-gmp4/Cabal-1.24.0.0/build/Refact/Fixity.o )

/data/users/bnitka/stackage-ghc8/test/apply-refact-0.2.0.0/src/Refact/Fixity.hs:35:60: error:
    • Couldn't match type ‘GenLocated SrcSpan RdrName’ with ‘RdrName’
      Expected type: RdrName
        Actual type: Located RdrName
    • In the second argument of ‘($)’, namely ‘n’
      In the expression: occNameString . rdrNameOcc $ n
      In an equation for ‘getIdent’:
          getIdent (unLoc -> HsVar n) = occNameString . rdrNameOcc $ n

/data/users/bnitka/stackage-ghc8/test/apply-refact-0.2.0.0/src/Refact/Fixity.hs:164:14: error:
    • Couldn't match type ‘FixityDirection -> Fixity’ with ‘Fixity’
      Expected type: [String] -> [(String, Fixity)]
        Actual type: [String] -> [(String, FixityDirection -> Fixity)]
    • In the expression: map (, Fixity p a)
      In an equation for ‘fixity’: fixity a p = map (, Fixity p a)

/data/users/bnitka/stackage-ghc8/test/apply-refact-0.2.0.0/src/Refact/Fixity.hs:164:27: error:
    • Couldn't match type ‘Int’ with ‘[Char]’
      Expected type: BasicTypes.SourceText
        Actual type: Int
    • In the first argument of ‘Fixity’, namely ‘p’
      In the expression: Fixity p a
      In the first argument of ‘map’, namely ‘(, Fixity p a)’

/data/users/bnitka/stackage-ghc8/test/apply-refact-0.2.0.0/src/Refact/Fixity.hs:164:29: error:
    • Couldn't match expected type ‘Int’
                  with actual type ‘FixityDirection’
    • In the second argument of ‘Fixity’, namely ‘a’
      In the expression: Fixity p a
      In the first argument of ‘map’, namely ‘(, Fixity p a)’
Completed 10 action(s).

--  While building package apply-refact-0.2.0.0 using:
      /home/bnitka/.stack/setup-exe-cache/x86_64-linux-gmp4/setup-Simple-Cabal-1.24.0.0-ghc-8.0.1 --builddir=.stack-work/dist/x86_64-linux-gmp4/Cabal-1.24.0.0 build lib:apply-refact exe:refactor --ghc-options " -ddump-hi -ddump-to-file"
    Process exited with code: ExitFailure 1

uncurry (.=) p HLint suggestion turns into uncurry .= p

$ cat ~/Repro.hs
f p = fst p .= snd p
$ ~/local/hlint/dist/build/hlint/hlint ~/Repro.hs
Repro.hs:1:7: Error: Evaluate
Found:
  fst p .= snd p
Why not:
  uncurry (.=) p

1 suggestion
$ ~/local/hlint/dist/build/hlint/hlint --refactor --with-refactor=$HOME/local/apply-refact/dist/build/refactor/refactor ~/Repro.hs
f p = uncurry .= p

Imports get removed when they have unnecessary hiding statements

When hlint finds an import that has an unnecessary hiding statement, apply-refact removes the entire statement instead of just removing the unnecessary hidings. For example, in the following code apply-refact removes the entire line which makes the code fail to compile.

import Data.List hiding (sort)

test :: [String]
test = group "aaabb"

Build failure on GHC 9.0.1 on macOS

I encountered the following error when running stack install apply-refact:

apply-refact        > /private/var/folders/2s/gzz0f5_n20g1pc2mnnbf_1c40000gn/T/stack-242b9b3cdfbd8b5c/apply-refact-0.9.0.0/src/Refact/Internal.hs:405:53: error:
apply-refact        >     • Variable not in scope: noExt :: NoExt
apply-refact        >     • Perhaps you meant one of these:
apply-refact        >         ‘GHC.noExt’ (imported from GHC),
apply-refact        >         data constructor ‘NoExt’ (imported from HsSyn)
apply-refact        >       Perhaps you want to remove ‘noExt’ from the explicit hiding list
apply-refact        >       in the import of ‘HsSyn’ (src/Refact/Internal.hs:74:1-38).
apply-refact        >     |
apply-refact        > 405 |           fakeExpr = GHC.L (getLoc new) (GHC.VarPat noExt new)
apply-refact        >     |                                                     ^^^^^
apply-refact        >
apply-refact        > /private/var/folders/2s/gzz0f5_n20g1pc2mnnbf_1c40000gn/T/stack-242b9b3cdfbd8b5c/apply-refact-0.9.0.0/src/Refact/Internal.hs:561:68: error:
apply-refact        >     • Variable not in scope: noExt :: NoExt
apply-refact        >     • Perhaps you meant one of these:
apply-refact        >         ‘GHC.noExt’ (imported from GHC),
apply-refact        >         data constructor ‘NoExt’ (imported from HsSyn)
apply-refact        >       Perhaps you want to remove ‘noExt’ from the explicit hiding list
apply-refact        >       in the import of ‘HsSyn’ (src/Refact/Internal.hs:74:1-38).
apply-refact        >     |
apply-refact        > 561 |           withoutLocalBinds = setLocalBind (noLoc (EmptyLocalBinds noExt)) xvald origBind newLoc origMG locMG
apply-refact        >     |                                                                    ^^^^^
apply-refact        >
Completed 31 action(s).

--  While building package apply-refact-0.9.0.0 (scroll up to its section to see the error) using:
      /Users/cadenhaustein/.stack/setup-exe-cache/x86_64-osx/Cabal-simple_mPHDZzAJ_3.0.1.0_ghc-8.8.4 --builddir=.stack-work/dist/x86_64-osx/Cabal-3.0.1.0 build --ghc-options " -fdiagnostics-color=always"
    Process exited with code: ExitFailure 1

ghc -V returns The Glorious Glasgow Haskell Compilation System, version 9.0.1, and stack --version returns Version 2.5.1, Git revision d6ab861544918185236cf826cb2028abb266d6d5 x86_64 hpack-0.33.0

I am on macOS Big Sur

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.