rikvdkleij / intellij-haskell

IntelliJ plugin for Haskell
https://rikvdkleij.github.io/intellij-haskell/
Apache License 2.0
1.31k stars 94 forks source link

Fixed how the replacement text is produced from a hlint output #671

Closed Thecentury closed 2 years ago

Thecentury commented 2 years ago

Consider the following Haskell code:

renameStreets :: (String -> String) -> Person -> Person
renameStreets f p = over (born . bornAt . street) f . over (address . street) f $ p

For it hlint produces the following json output:

[
   {
      "module":[
         "Person"
      ],
      "decl":[
         "renameStreets"
      ],
      "severity":"Warning",
      "hint":"Eta reduce",
      "file":"src/Person.hs",
      "startLine":57,
      "startColumn":1,
      "endLine":57,
      "endColumn":84,
      "from":"renameStreets f p\n  = over (born . bornAt . street) f . over (address . street) f $ p",
      "to":"renameStreets f\n  = over (born . bornAt . street) f . over (address . street) f",
      "note":[

      ],
      "refactorings":"[Replace {rtype = Decl, pos = SrcSpan {startLine = 57, startCol = 1, endLine = 57, endCol = 84}, subts = [(\"body\",SrcSpan {startLine = 57, startCol = 21, endLine = 57, endCol = 80}),(\"a\",SrcSpan {startLine = 57, startCol = 15, endLine = 57, endCol = 16})], orig = \"renameStreets a = body\"}]"
   }
]

Refactorings section looks like this:

[
    Replace {
        rtype = Decl, 
        pos = SrcSpan {startLine = 57, startCol = 1, endLine = 57, endCol = 84}, 
        subts = [
            (\"body\",SrcSpan {startLine = 57, startCol = 21, endLine = 57, endCol = 80}),
            (\"a\",SrcSpan {startLine = 57, startCol = 15, endLine = 57, endCol = 16})
        ], 
        orig = \"renameStreets a = body\"}
]

Currently, intellij-haskell produces the following code after applying the "Eta reduce" fix:

renfmeStreets f = over (born . bornAt . street) f . over (fddress . street) f

We can see that it replaced every occurrence of a from the subst section of hlint output with f, which is the current contents of this text span.

I propose to replace not every occurrence, but only those of them which are surrounded with word boundaries.

With this fix, the produced code is correct:

renameStreets f = over (born . bornAt . street) f . over (address . street) f