diff --git a/cabal.project b/cabal.project index e4097d484c..6061dff263 100644 --- a/cabal.project +++ b/cabal.project @@ -57,6 +57,11 @@ source-repository-package tag: 7a0af7a8fd38045fd15fb13445bdcc7085325460 -- END DELETE +source-repository-package + type:git + location: https://github.com/jhrcek/HieDb + tag: e70eb8eab42dddc6d7eb00be7222b62a4cf5c0a6 + if impl(ghc >= 9.1) -- ekg packagess are old and unmaintained, but we -- don't rely on them for the mainline build, so diff --git a/plugins/hls-rename-plugin/src/Ide/Plugin/Rename.hs b/plugins/hls-rename-plugin/src/Ide/Plugin/Rename.hs index c25da1bd46..359cd676ef 100644 --- a/plugins/hls-rename-plugin/src/Ide/Plugin/Rename.hs +++ b/plugins/hls-rename-plugin/src/Ide/Plugin/Rename.hs @@ -25,7 +25,6 @@ import Data.List.NonEmpty (NonEmpty ((:|)), import qualified Data.Map as M import Data.Maybe import Data.Mod.Word -import qualified Data.Set as S import qualified Data.Text as T import Development.IDE (Recorder, WithPriority, usePropertyAction) @@ -34,6 +33,7 @@ import Development.IDE.Core.PositionMapping import Development.IDE.Core.RuleTypes import Development.IDE.Core.Service import Development.IDE.Core.Shake +import qualified Development.IDE.GHC.Compat as Compat import Development.IDE.GHC.Compat.Core import Development.IDE.GHC.Compat.ExactPrint import Development.IDE.GHC.Compat.Parser @@ -212,12 +212,20 @@ handleGetHieAst state nfp = -- | We don't want to rename in code generated by GHC as this gives false positives. -- So we restrict the HIE file to remove all the generated code. removeGenerated :: HieAstResult -> HieAstResult -removeGenerated HAR{..} = HAR{hieAst = go hieAst,..} +removeGenerated HAR{..} = HAR{hieAst = sourceOnlyAsts, refMap = sourceOnlyRefMap, ..} where - go :: HieASTs a -> HieASTs a - go hf = - HieASTs (fmap goAst (getAsts hf)) - goAst (Node nsi sp xs) = Node (SourcedNodeInfo $ M.restrictKeys (getSourcedNodeInfo nsi) (S.singleton SourceInfo)) sp (map goAst xs) + goAsts :: HieASTs a -> HieASTs a + goAsts (HieASTs asts) = HieASTs (fmap goAst asts) + + goAst :: HieAST a -> HieAST a + goAst (Node (SourcedNodeInfo sniMap) sp children) = + let sourceOnlyNodeInfos = SourcedNodeInfo $ M.delete GeneratedInfo sniMap + in Node sourceOnlyNodeInfos sp $ map goAst children + + sourceOnlyAsts = goAsts hieAst + -- Also need to regenerate the RefMap, because the one in HAR + -- is generated from HieASTs containing GeneratedInfo + sourceOnlyRefMap = Compat.generateReferencesMap $ Compat.getAsts sourceOnlyAsts collectWith :: (Hashable a, Eq b) => (a -> b) -> HashSet a -> [(b, HashSet a)] collectWith f = map (\(a :| as) -> (f a, HS.fromList (a:as))) . groupWith f . HS.toList diff --git a/plugins/hls-rename-plugin/test/Main.hs b/plugins/hls-rename-plugin/test/Main.hs index 2a34ab1a43..2889d6e872 100644 --- a/plugins/hls-rename-plugin/test/Main.hs +++ b/plugins/hls-rename-plugin/test/Main.hs @@ -23,6 +23,8 @@ tests :: TestTree tests = testGroup "Rename" [ goldenWithRename "Data constructor" "DataConstructor" $ \doc -> rename doc (Position 0 15) "Op" + , goldenWithRename "Data constructor with fields" "DataConstructorWithFields" $ \doc -> + rename doc (Position 1 13) "FooRenamed" , goldenWithRename "Exported function" "ExportedFunction" $ \doc -> rename doc (Position 2 1) "quux" , ignoreForGhcVersions [GHC90, GHC92] recordConstructorIssue $ diff --git a/plugins/hls-rename-plugin/test/testdata/DataConstructorWithFields.expected.hs b/plugins/hls-rename-plugin/test/testdata/DataConstructorWithFields.expected.hs new file mode 100644 index 0000000000..5fc38c7f01 --- /dev/null +++ b/plugins/hls-rename-plugin/test/testdata/DataConstructorWithFields.expected.hs @@ -0,0 +1,14 @@ +{-# LANGUAGE NamedFieldPuns #-} +data Foo = FooRenamed { a :: Int, b :: Bool } + +foo1 :: Foo +foo1 = FooRenamed { a = 1, b = True } + +foo2 :: Foo +foo2 = FooRenamed 1 True + +fun1 :: Foo -> Int +fun1 FooRenamed {a} = a + +fun2 :: Foo -> Int +fun2 FooRenamed {a = i} = i diff --git a/plugins/hls-rename-plugin/test/testdata/DataConstructorWithFields.hs b/plugins/hls-rename-plugin/test/testdata/DataConstructorWithFields.hs new file mode 100644 index 0000000000..abd8031096 --- /dev/null +++ b/plugins/hls-rename-plugin/test/testdata/DataConstructorWithFields.hs @@ -0,0 +1,14 @@ +{-# LANGUAGE NamedFieldPuns #-} +data Foo = Foo { a :: Int, b :: Bool } + +foo1 :: Foo +foo1 = Foo { a = 1, b = True } + +foo2 :: Foo +foo2 = Foo 1 True + +fun1 :: Foo -> Int +fun1 Foo {a} = a + +fun2 :: Foo -> Int +fun2 Foo {a = i} = i diff --git a/stack-lts21.yaml b/stack-lts21.yaml index 6b5c0c71ab..014db01ec3 100644 --- a/stack-lts21.yaml +++ b/stack-lts21.yaml @@ -18,7 +18,7 @@ allow-newer: true extra-deps: - floskell-0.11.1 -- hiedb-0.6.0.0 +- url: https://github.com/jhrcek/HieDb/archive/e70eb8eab42dddc6d7eb00be7222b62a4cf5c0a6.tar.gz - hie-bios-0.13.1 - implicit-hie-0.1.4.0 - monad-dijkstra-0.1.1.3 diff --git a/stack.yaml b/stack.yaml index 3eb2d809d6..ddfc6951c9 100644 --- a/stack.yaml +++ b/stack.yaml @@ -18,7 +18,7 @@ allow-newer: true extra-deps: - floskell-0.11.1 - retrie-1.2.2 -- hiedb-0.6.0.0 +- url: https://github.com/jhrcek/HieDb/archive/e70eb8eab42dddc6d7eb00be7222b62a4cf5c0a6.tar.gz - implicit-hie-0.1.4.0 - lsp-2.4.0.0 - lsp-test-0.17.0.0