Skip to content

Commit f81ab41

Browse files
committed
WAP
1 parent e429304 commit f81ab41

File tree

4 files changed

+47
-14
lines changed

4 files changed

+47
-14
lines changed

plugins/hls-rename-plugin/src/Ide/Plugin/Rename.hs

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ import Data.List.NonEmpty (NonEmpty ((:|)),
2525
import qualified Data.Map as M
2626
import Data.Maybe
2727
import Data.Mod.Word
28-
import qualified Data.Set as S
2928
import qualified Data.Text as T
3029
import Development.IDE (Recorder, WithPriority,
3130
usePropertyAction)
@@ -52,7 +51,6 @@ import Ide.Types
5251
import qualified Language.LSP.Protocol.Lens as L
5352
import Language.LSP.Protocol.Message
5453
import Language.LSP.Protocol.Types
55-
import Data.List
5654

5755
instance Hashable (Mod a) where hash n = hash (unMod n)
5856

@@ -103,7 +101,6 @@ renameProvider state pluginId (RenameParams _prog (TextDocumentIdentifier uri) p
103101
[] -> throwError $ PluginInvalidParams "No symbol to rename at given position"
104102
_ -> do
105103
refs <- HS.fromList . concat <$> mapM (refsAtName state nfp) oldNames
106-
107104
-- Validate rename
108105
crossModuleEnabled <- liftIO $ runAction "rename: config" state $ usePropertyAction #crossModule pluginId properties
109106
unless crossModuleEnabled $ failWhenImportOrExport state nfp refs oldNames
@@ -198,22 +195,19 @@ refsAtName state nfp name = do
198195
ast <- handleGetHieAst state nfp
199196
dbRefs <- case nameModule_maybe name of
200197
Nothing -> pure []
201-
Just mod -> liftIO $ mapMaybe rowToLoc <$> withHieDb (\hieDb -> do
198+
Just mod -> liftIO $ mapMaybe rowToLoc <$> withHieDb (\hieDb ->
202199
-- GHC inserts `Use`s of record constructor everywhere where its record selectors are used,
203200
-- which leads to fields being renamed whenever corresponding constructor is renamed.
204201
-- see https://github.com/haskell/haskell-language-server/issues/2915
205202
-- To work around this, we filter out compiler-generated references.
206-
207-
xs <- findReferences
203+
filter (\(refRow HieDb.:. _) -> refIsGenerated refRow) <$>
204+
findReferences
208205
hieDb
209206
True
210207
(nameOccName name)
211208
(Just $ moduleName mod)
212209
(Just $ moduleUnit mod)
213210
[fromNormalizedFilePath nfp]
214-
let (gen,notGen) = partition (\(refRow HieDb.:. _) -> refIsGenerated refRow) xs
215-
putStrLn $ "Found " ++ show (length xs) ++ " references in HieDb: " ++ show (length xs) ++ ", of which " ++ show (length gen) ++ " are generated"
216-
pure notGen
217211
)
218212
pure $ nameLocs name ast ++ dbRefs
219213

@@ -244,12 +238,21 @@ handleGetHieAst state nfp =
244238
-- | We don't want to rename in code generated by GHC as this gives false positives.
245239
-- So we restrict the HIE file to remove all the generated code.
246240
removeGenerated :: HieAstResult -> HieAstResult
247-
removeGenerated HAR{..} = HAR{hieAst = go hieAst,..}
241+
removeGenerated HAR{..} =
242+
HAR{hieAst = sourceOnlyAsts, refMap = sourceOnlyRefMap, ..}
248243
where
249-
go :: HieASTs a -> HieASTs a
250-
go hf =
251-
HieASTs (fmap goAst (getAsts hf))
252-
goAst (Node nsi sp xs) = Node (SourcedNodeInfo $ M.restrictKeys (getSourcedNodeInfo nsi) (S.singleton SourceInfo)) sp (map goAst xs)
244+
goAsts :: HieASTs a -> HieASTs a
245+
goAsts (HieASTs asts) = HieASTs (fmap goAst asts)
246+
247+
goAst :: HieAST a -> HieAST a
248+
goAst (Node (SourcedNodeInfo sniMap) sp children) =
249+
let sourceOnlyNodeInfos = SourcedNodeInfo $ M.delete GeneratedInfo sniMap
250+
in Node sourceOnlyNodeInfos sp $ map goAst children
251+
252+
sourceOnlyAsts = goAsts hieAst
253+
-- Also need to regenerate the RefMap, because the one in HAR
254+
-- is generated from HieASTs containing GeneratedInfo
255+
sourceOnlyRefMap = generateReferencesMap $ getAsts sourceOnlyAsts
253256

254257
collectWith :: (Hashable a, Eq b) => (a -> b) -> HashSet a -> [(b, HashSet a)]
255258
collectWith f = map (\(a :| as) -> (f a, HS.fromList (a:as))) . groupWith f . HS.toList

plugins/hls-rename-plugin/test/Main.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ tests :: TestTree
2424
tests = testGroup "Rename"
2525
[ goldenWithRename "Data constructor" "DataConstructor" $ \doc ->
2626
rename doc (Position 0 15) "Op"
27+
, goldenWithRename "Data constructor with fields" "DataConstructorWithFields" $ \doc ->
28+
rename doc (Position 1 13) "FooRenamed"
2729
, goldenWithRename "Exported function" "ExportedFunction" $ \doc ->
2830
rename doc (Position 2 1) "quux"
2931
, goldenWithRename "Field Puns" "FieldPuns" $ \doc ->
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{-# LANGUAGE NamedFieldPuns #-}
2+
data Foo = FooRenamed { FooRenamed :: Int, FooRenamed :: Bool }
3+
4+
foo1 :: Foo
5+
foo1 = FooRenamed { a = 1, b = True }
6+
7+
foo2 :: Foo
8+
foo2 = FooRenamed 1 True
9+
10+
fun1 :: Foo -> Int
11+
fun1 FooRenamed {a} = a
12+
13+
fun2 :: Foo -> Int
14+
fun2 FooRenamed {a = i} = i
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{-# LANGUAGE NamedFieldPuns #-}
2+
data Foo = Foo { a :: Int, b :: Bool }
3+
4+
foo1 :: Foo
5+
foo1 = Foo { a = 1, b = True }
6+
7+
foo2 :: Foo
8+
foo2 = Foo 1 True
9+
10+
fun1 :: Foo -> Int
11+
fun1 Foo {a} = a
12+
13+
fun2 :: Foo -> Int
14+
fun2 Foo {a = i} = i

0 commit comments

Comments
 (0)