diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 3a02d2763d..4ad4d30000 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -208,3 +208,7 @@ jobs: - if: ${{ needs.pre_job.outputs.should_skip != 'true' && matrix.test}} name: Test hls-call-hierarchy-plugin test suite run: cabal test hls-call-hierarchy-plugin --test-options="-j1 --rerun-update" || cabal test hls-call-hierarchy-plugin --test-options="-j1 --rerun" || LSP_TEST_LOG_COLOR=0 LSP_TEST_LOG_MESSAGES=true LSP_TEST_LOG_STDERR=true cabal test hls-call-hierarchy-plugin --test-options="-j1 --rerun" + + - if: ${{ needs.pre_job.outputs.should_skip != 'true' && matrix.test}} + name: Test hls-rename-plugin test suite + run: cabal test hls-rename-plugin --test-options="-j1 --rerun-update" || cabal test hls-rename-plugin --test-options="-j1 --rerun" || LSP_TEST_LOG_COLOR=0 LSP_TEST_LOG_MESSAGES=true LSP_TEST_LOG_STDERR=true cabal test hls-rename-plugin --test-options="-j1 --rerun" diff --git a/cabal-ghc901.project b/cabal-ghc901.project index 5cd90914b3..1396db52b6 100644 --- a/cabal-ghc901.project +++ b/cabal-ghc901.project @@ -15,6 +15,7 @@ packages: ./plugins/hls-explicit-imports-plugin ./plugins/hls-refine-imports-plugin ./plugins/hls-hlint-plugin + ./plugins/hls-rename-plugin ./plugins/hls-retrie-plugin ./plugins/hls-haddock-comments-plugin -- ./plugins/hls-splice-plugin diff --git a/cabal.project b/cabal.project index 12055ec9da..446a3ee956 100644 --- a/cabal.project +++ b/cabal.project @@ -15,6 +15,7 @@ packages: ./plugins/hls-explicit-imports-plugin ./plugins/hls-refine-imports-plugin ./plugins/hls-hlint-plugin + ./plugins/hls-rename-plugin ./plugins/hls-retrie-plugin ./plugins/hls-haddock-comments-plugin ./plugins/hls-splice-plugin diff --git a/exe/Plugins.hs b/exe/Plugins.hs index 8b2c3178d6..5e4a6165d9 100644 --- a/exe/Plugins.hs +++ b/exe/Plugins.hs @@ -37,6 +37,10 @@ import Ide.Plugin.ExplicitImports as ExplicitImports import Ide.Plugin.RefineImports as RefineImports #endif +#if rename +import Ide.Plugin.Rename as Rename +#endif + #if retrie import Ide.Plugin.Retrie as Retrie #endif @@ -115,6 +119,9 @@ idePlugins includeExamples = pluginDescToIdePlugins allPlugins #if stylishHaskell StylishHaskell.descriptor "stylish-haskell" : #endif +#if rename + Rename.descriptor "rename" : +#endif #if retrie Retrie.descriptor "retrie" : #endif diff --git a/ghcide/session-loader/Development/IDE/Session.hs b/ghcide/session-loader/Development/IDE/Session.hs index b5a7ba893c..b769ed916a 100644 --- a/ghcide/session-loader/Development/IDE/Session.hs +++ b/ghcide/session-loader/Development/IDE/Session.hs @@ -501,9 +501,8 @@ cradleToOptsAndLibDir :: Show a => Cradle a -> FilePath -> IO (Either [CradleError] (ComponentOptions, FilePath)) cradleToOptsAndLibDir cradle file = do -- Start off by getting the session options - let showLine s = hPutStrLn stderr ("> " ++ s) hPutStrLn stderr $ "Output from setting up the cradle " <> show cradle - cradleRes <- runCradle (cradleOptsProg cradle) showLine file + cradleRes <- HieBios.getCompilerOptions file cradle case cradleRes of CradleSuccess r -> do -- Now get the GHC lib dir diff --git a/ghcide/src/Development/IDE/Spans/AtPoint.hs b/ghcide/src/Development/IDE/Spans/AtPoint.hs index da49cc1a54..2c878ebe1b 100644 --- a/ghcide/src/Development/IDE/Spans/AtPoint.hs +++ b/ghcide/src/Development/IDE/Spans/AtPoint.hs @@ -16,6 +16,9 @@ module Development.IDE.Spans.AtPoint ( , computeTypeReferences , FOIReferences(..) , defRowToSymbolInfo + , getAstNamesAtPoint + , toCurrentLocation + , rowToLoc ) where import Development.IDE.GHC.Error @@ -90,8 +93,7 @@ foiReferencesAtPoint file pos (FOIReferences asts) = case HM.lookup file asts of Nothing -> ([],[],[]) Just (HAR _ hf _ _ _,mapping) -> - let posFile = fromMaybe pos $ fromCurrentPosition mapping pos - names = concat $ pointCommand hf posFile (rights . M.keys . getNodeIds) + let names = getAstNamesAtPoint hf pos mapping adjustedLocs = HM.foldr go [] asts go (HAR _ _ rf tr _, mapping) xs = refs ++ typerefs ++ xs where @@ -99,9 +101,18 @@ foiReferencesAtPoint file pos (FOIReferences asts) = $ concat $ mapMaybe (\n -> M.lookup (Right n) rf) names typerefs = mapMaybe (toCurrentLocation mapping . realSrcSpanToLocation) $ concat $ mapMaybe (`M.lookup` tr) names - toCurrentLocation mapping (Location uri range) = Location uri <$> toCurrentRange mapping range in (names, adjustedLocs,map fromNormalizedFilePath $ HM.keys asts) +getAstNamesAtPoint :: HieASTs a -> Position -> PositionMapping -> [Name] +getAstNamesAtPoint hf pos mapping = + concat $ pointCommand hf posFile (rights . M.keys . getNodeIds) + where + posFile = fromMaybe pos $ fromCurrentPosition mapping pos + +toCurrentLocation :: PositionMapping -> Location -> Maybe Location +toCurrentLocation mapping (Location uri range) = + Location uri <$> toCurrentRange mapping range + referencesAtPoint :: MonadIO m => HieDb diff --git a/haskell-language-server.cabal b/haskell-language-server.cabal index fd8c5473c2..0cf7d7d30e 100644 --- a/haskell-language-server.cabal +++ b/haskell-language-server.cabal @@ -131,6 +131,11 @@ flag refineImports default: True manual: True +flag rename + description: Enable rename plugin + default: False + manual: True + flag retrie description: Enable retrie plugin default: True @@ -223,6 +228,11 @@ common refineImports build-depends: hls-refine-imports-plugin ^>=1.0.0.0 cpp-options: -DrefineImports +common rename + if flag(rename) || flag(all-plugins) + build-depends: hls-rename-plugin ^>= 1.0.0.0 + cpp-options: -Drename + common retrie if flag(retrie) || flag(all-plugins) build-depends: hls-retrie-plugin ^>=1.0.0.1 @@ -290,6 +300,7 @@ executable haskell-language-server , eval , importLens , refineImports + , rename , retrie , tactic , hlint @@ -424,7 +435,6 @@ test-suite func-test Highlight Progress Reference - Rename Symbol TypeDefinition Test.Hls.Command @@ -447,6 +457,8 @@ test-suite func-test cpp-options: -Deval if flag(importLens) || flag(all-plugins) cpp-options: -DimportLens + if flag(rename) || flag(all-plugins) + cpp-options: -Drename if flag(retrie) || flag(all-plugins) cpp-options: -Dretrie if flag(tactic) || flag(all-plugins) diff --git a/plugins/hls-rename-plugin/LICENSE b/plugins/hls-rename-plugin/LICENSE new file mode 100644 index 0000000000..261eeb9e9f --- /dev/null +++ b/plugins/hls-rename-plugin/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/plugins/hls-rename-plugin/hls-rename-plugin.cabal b/plugins/hls-rename-plugin/hls-rename-plugin.cabal new file mode 100644 index 0000000000..1d1499d44f --- /dev/null +++ b/plugins/hls-rename-plugin/hls-rename-plugin.cabal @@ -0,0 +1,50 @@ +cabal-version: 2.4 +name: hls-rename-plugin +version: 1.0.0.0 +synopsis: Rename plugin for Haskell Language Server +description: + Please see the README on GitHub at + +license: Apache-2.0 +license-file: LICENSE +author: Oliver Madine +maintainer: madine.oliver@gmail.com +category: Development +build-type: Simple +extra-source-files: + LICENSE + test/testdata/*.hs + test/testdata/*.yaml + +library + exposed-modules: Ide.Plugin.Rename + hs-source-dirs: src + build-depends: + , base >=4.12 && <5 + , containers + , extra + , ghc + , ghc-exactprint + , ghcide >=1.4 && <1.5 + , hiedb + , hls-plugin-api ^>=1.2 + , hls-retrie-plugin >=1.0.1.1 + , lsp + , lsp-types + , syb + , text + , transformers + + default-language: Haskell2010 + +test-suite tests + type: exitcode-stdio-1.0 + default-language: Haskell2010 + hs-source-dirs: test + main-is: Main.hs + ghc-options: -threaded -rtsopts -with-rtsopts=-N + build-depends: + , base + , filepath + , hls-rename-plugin + , hls-test-utils >=1.0 && <1.2 diff --git a/plugins/hls-rename-plugin/src/Ide/Plugin/Rename.hs b/plugins/hls-rename-plugin/src/Ide/Plugin/Rename.hs new file mode 100644 index 0000000000..dca7a66346 --- /dev/null +++ b/plugins/hls-rename-plugin/src/Ide/Plugin/Rename.hs @@ -0,0 +1,160 @@ +{-# LANGUAGE CPP #-} +{-# LANGUAGE DataKinds #-} +{-# LANGUAGE GADTs #-} +{-# LANGUAGE NamedFieldPuns #-} + +module Ide.Plugin.Rename (descriptor) where + +import Control.Monad +import Control.Monad.IO.Class (MonadIO (liftIO)) +import Control.Monad.Trans.Class +import Control.Monad.Trans.Except +import Data.Containers.ListUtils +import Data.Generics +import Data.List.Extra hiding (nubOrd) +import qualified Data.Map as M +import Data.Maybe +import qualified Data.Text as T +import Development.IDE hiding (pluginHandlers) +import Development.IDE.Core.PositionMapping +import Development.IDE.Core.Shake +import Development.IDE.GHC.Compat +import Development.IDE.Spans.AtPoint +#if MIN_VERSION_ghc(9,0,1) +import GHC.Types.Name +#else +import Name +#endif +import HieDb.Query +import Ide.Plugin.Config +import Ide.Plugin.Retrie hiding (descriptor) +import Ide.PluginUtils +import Ide.Types +import Language.Haskell.GHC.ExactPrint +import Language.LSP.Server +import Language.LSP.Types + +descriptor :: PluginId -> PluginDescriptor IdeState +descriptor pluginId = (defaultPluginDescriptor pluginId) { + pluginHandlers = mkPluginHandler STextDocumentRename renameProvider +} + +renameProvider :: PluginMethodHandler IdeState TextDocumentRename +renameProvider state pluginId (RenameParams (TextDocumentIdentifier uri) pos _prog newNameText) = + response $ do + nfp <- safeUriToNfp uri + oldName <- getNameAtPos state nfp pos + workspaceRefs <- refsAtName state nfp oldName + let filesRefs = groupOn locToUri workspaceRefs + getFileEdits = ap (getSrcEdits state . renameModRefs newNameText) (locToUri . head) + + fileEdits <- mapM getFileEdits filesRefs + pure $ foldl1 (<>) fileEdits + +------------------------------------------------------------------------------- +-- Source renaming + +-- | Compute a `WorkspaceEdit` by applying a given function to the `ParsedModule` for a given `Uri`. +getSrcEdits :: + (MonadLsp config m) => + IdeState -> +#if MIN_VERSION_ghc(9,0,1) + (HsModule -> HsModule) -> +#else + (HsModule GhcPs -> HsModule GhcPs) -> +#endif + Uri -> + ExceptT String m WorkspaceEdit +getSrcEdits state updateMod uri = do + ccs <- lift getClientCapabilities + nfp <- safeUriToNfp uri + ParsedModule{pm_parsed_source = ps, pm_annotations = apiAnns} <- + handleMaybeM "Error: could not get parsed source" $ liftIO $ runAction + "Rename.GetParsedModuleWithComments" + state + (use GetParsedModuleWithComments nfp) + + let anns = relativiseApiAnns ps apiAnns + src = T.pack $ exactPrint ps anns + res = T.pack $ exactPrint (updateMod <$> ps) anns + + pure $ diffText ccs (uri, src) res IncludeDeletions + +-- | Replace a name at every given `Location` (in a given `HsModule`) with a given new name. +renameModRefs :: + T.Text -> + [Location] -> +#if MIN_VERSION_ghc(9,0,1) + HsModule + -> HsModule +#else + HsModule GhcPs + -> HsModule GhcPs +#endif +renameModRefs newNameText refs = everywhere $ mkT replace + where + replace :: Located RdrName -> Located RdrName + replace (L srcSpan oldRdrName) + | isRef srcSpan = L srcSpan $ newRdrName oldRdrName + replace lOldRdrName = lOldRdrName + + newRdrName :: RdrName -> RdrName + newRdrName oldRdrName = case oldRdrName of + Qual modName _ -> Qual modName newOccName + _ -> Unqual newOccName + + newOccName = mkTcOcc $ T.unpack newNameText + + isRef :: SrcSpan -> Bool + isRef = (`elem` refs) . fromJust . srcSpanToLocation + +------------------------------------------------------------------------------- +-- Reference finding + +-- | Note: We only find exact name occurences (i.e. type reference "depth" is 0). +refsAtName :: IdeState -> NormalizedFilePath -> Name -> ExceptT [Char] (LspT Config IO) [Location] +refsAtName state nfp name = do + ShakeExtras{hiedb} <- liftIO $ runAction "Rename.HieDb" state getShakeExtras + ast <- safeGetHieAst state nfp + astRefs <- handleMaybe "Error: Could not get name AST references" $ getNameAstLocations name ast + dbRefs <- case nameModule_maybe name of + Nothing -> pure [] + Just mod -> liftIO $ mapMaybe rowToLoc <$> + findReferences + hiedb + True + (nameOccName name) + (Just $ moduleName mod) + (Just $ moduleUnitId mod) + [fromNormalizedFilePath nfp] + pure $ nubOrd $ astRefs ++ dbRefs + +getNameAstLocations :: Name -> (HieAstResult, PositionMapping) -> Maybe [Location] +getNameAstLocations name (HAR _ _ rm _ _, mapping) = + mapMaybe (toCurrentLocation mapping . realSrcSpanToLocation . fst) <$> M.lookup (Right name) rm + +------------------------------------------------------------------------------- +-- Util + +getNameAtPos :: IdeState -> NormalizedFilePath -> Position -> ExceptT String (LspT Config IO) Name +getNameAtPos state nfp pos = do + (HAR{hieAst}, mapping) <- safeGetHieAst state nfp + handleMaybe "Error: could not find name at position" $ listToMaybe $ + getAstNamesAtPoint hieAst pos mapping + +nfpToUri :: NormalizedFilePath -> Uri +nfpToUri = filePathToUri . fromNormalizedFilePath + +safeUriToNfp :: (Monad m) => Uri -> ExceptT String m NormalizedFilePath +safeUriToNfp = handleMaybe "Error: Could not get uri" . fmap toNormalizedFilePath . uriToFilePath + +safeGetHieAst :: + MonadIO m => + IdeState -> + NormalizedFilePath -> + ExceptT String m (HieAstResult, PositionMapping) +safeGetHieAst state = handleMaybeM "Error: Could not get AST" . liftIO . + runAction "Rename.GetHieAst" state . useWithStale GetHieAst + +locToUri :: Location -> Uri +locToUri (Location uri _) = uri diff --git a/plugins/hls-rename-plugin/test/Main.hs b/plugins/hls-rename-plugin/test/Main.hs new file mode 100644 index 0000000000..31baec621c --- /dev/null +++ b/plugins/hls-rename-plugin/test/Main.hs @@ -0,0 +1,60 @@ +{-# LANGUAGE OverloadedStrings #-} + +module Main (main) where + +import qualified Ide.Plugin.Rename as Rename +import System.FilePath +import Test.Hls + +main :: IO () +main = defaultTestRunner tests + +renamePlugin :: PluginDescriptor IdeState +renamePlugin = Rename.descriptor "rename" + +tests :: TestTree +tests = testGroup "Rename" + [ goldenWithRename "Data constructor" "DataConstructor" $ \doc -> do + rename doc (Position 0 15) "Op" + , goldenWithRename "Exported function" "ExportedFunction" $ \doc -> do + rename doc (Position 2 1) "quux" + , goldenWithRename "Function argument" "FunctionArgument" $ \doc -> do + rename doc (Position 3 4) "y" + , goldenWithRename "Function name" "FunctionName" $ \doc -> do + rename doc (Position 3 1) "baz" + , goldenWithRename "GADT" "Gadt" $ \doc -> do + rename doc (Position 6 37) "Expr" + , goldenWithRename "Hidden function" "HiddenFunction" $ \doc -> do + rename doc (Position 0 32) "quux" + , goldenWithRename "Imported function" "ImportedFunction" $ \doc -> do + rename doc (Position 3 8) "baz" + , goldenWithRename "Import hiding" "ImportHiding" $ \doc -> do + rename doc (Position 0 22) "hiddenFoo" + , goldenWithRename "Let expression" "LetExpression" $ \doc -> do + rename doc (Position 5 11) "foobar" + , goldenWithRename "Qualified as" "QualifiedAs" $ \doc -> do + rename doc (Position 3 10) "baz" + , goldenWithRename "Qualified shadowing" "QualifiedShadowing" $ \doc -> do + rename doc (Position 3 12) "foobar" + , goldenWithRename "Qualified function" "QualifiedFunction" $ \doc -> do + rename doc (Position 3 12) "baz" + , goldenWithRename "Realigns do block indentation" "RealignDo" $ \doc -> do + rename doc (Position 0 2) "fooBarQuux" + , goldenWithRename "Record field" "RecordField" $ \doc -> do + rename doc (Position 6 9) "number" + , goldenWithRename "Shadowed name" "ShadowedName" $ \doc -> do + rename doc (Position 1 1) "baz" + , goldenWithRename "Typeclass" "Typeclass" $ \doc -> do + rename doc (Position 8 15) "Equal" + , goldenWithRename "Type constructor" "TypeConstructor" $ \doc -> do + rename doc (Position 2 17) "BinaryTree" + , goldenWithRename "Type variable" "TypeVariable" $ \doc -> do + rename doc (Position 0 13) "b" + ] + +goldenWithRename :: TestName -> FilePath -> (TextDocumentIdentifier -> Session ()) -> TestTree +goldenWithRename title path = + goldenWithHaskellDoc renamePlugin title testDataDir path "expected" "hs" + +testDataDir :: FilePath +testDataDir = "test" "testdata" diff --git a/plugins/hls-rename-plugin/test/testdata/DataConstructor.expected.hs b/plugins/hls-rename-plugin/test/testdata/DataConstructor.expected.hs new file mode 100644 index 0000000000..d1ee10a6d1 --- /dev/null +++ b/plugins/hls-rename-plugin/test/testdata/DataConstructor.expected.hs @@ -0,0 +1,4 @@ +data Expr = Op Int Int + +plus :: Expr -> Expr +plus (Op n m) = Op (n + m) 0 diff --git a/plugins/hls-rename-plugin/test/testdata/DataConstructor.hs b/plugins/hls-rename-plugin/test/testdata/DataConstructor.hs new file mode 100644 index 0000000000..b614d72291 --- /dev/null +++ b/plugins/hls-rename-plugin/test/testdata/DataConstructor.hs @@ -0,0 +1,4 @@ +data Expr = Apply Int Int + +plus :: Expr -> Expr +plus (Apply n m) = Apply (n + m) 0 diff --git a/plugins/hls-rename-plugin/test/testdata/ExportedFunction.expected.hs b/plugins/hls-rename-plugin/test/testdata/ExportedFunction.expected.hs new file mode 100644 index 0000000000..568edb36db --- /dev/null +++ b/plugins/hls-rename-plugin/test/testdata/ExportedFunction.expected.hs @@ -0,0 +1,5 @@ +module ExportedFunction (quux) where + +quux :: Num p => [a] -> p +quux [] = 0 +quux xs = 1 diff --git a/plugins/hls-rename-plugin/test/testdata/ExportedFunction.hs b/plugins/hls-rename-plugin/test/testdata/ExportedFunction.hs new file mode 100644 index 0000000000..3adb72dc9f --- /dev/null +++ b/plugins/hls-rename-plugin/test/testdata/ExportedFunction.hs @@ -0,0 +1,5 @@ +module ExportedFunction (foo) where + +foo :: Num p => [a] -> p +foo [] = 0 +foo xs = 1 diff --git a/plugins/hls-rename-plugin/test/testdata/Foo.hs b/plugins/hls-rename-plugin/test/testdata/Foo.hs new file mode 100644 index 0000000000..c4850149b4 --- /dev/null +++ b/plugins/hls-rename-plugin/test/testdata/Foo.hs @@ -0,0 +1,4 @@ +module Foo where + +foo :: Int -> Int +foo x = 0 diff --git a/plugins/hls-rename-plugin/test/testdata/FunctionArgument.expected.hs b/plugins/hls-rename-plugin/test/testdata/FunctionArgument.expected.hs new file mode 100644 index 0000000000..bd8d83b334 --- /dev/null +++ b/plugins/hls-rename-plugin/test/testdata/FunctionArgument.expected.hs @@ -0,0 +1,4 @@ +module FunctionArgument where + +foo :: Int -> Int +foo y = y + 1 diff --git a/plugins/hls-rename-plugin/test/testdata/FunctionArgument.hs b/plugins/hls-rename-plugin/test/testdata/FunctionArgument.hs new file mode 100644 index 0000000000..a6006e6fac --- /dev/null +++ b/plugins/hls-rename-plugin/test/testdata/FunctionArgument.hs @@ -0,0 +1,4 @@ +module FunctionArgument where + +foo :: Int -> Int +foo x = x + 1 diff --git a/plugins/hls-rename-plugin/test/testdata/FunctionName.expected.hs b/plugins/hls-rename-plugin/test/testdata/FunctionName.expected.hs new file mode 100644 index 0000000000..c02f55937b --- /dev/null +++ b/plugins/hls-rename-plugin/test/testdata/FunctionName.expected.hs @@ -0,0 +1,6 @@ +main = do + x <- return $ baz 42 + return (baz x) +baz, bar :: Int -> Int +baz x = x + 1 +bar = (+ 1) . baz diff --git a/plugins/hls-rename-plugin/test/testdata/FunctionName.hs b/plugins/hls-rename-plugin/test/testdata/FunctionName.hs new file mode 100644 index 0000000000..61bdc5e03c --- /dev/null +++ b/plugins/hls-rename-plugin/test/testdata/FunctionName.hs @@ -0,0 +1,6 @@ +main = do + x <- return $ foo 42 + return (foo x) +foo, bar :: Int -> Int +foo x = x + 1 +bar = (+ 1) . foo diff --git a/plugins/hls-rename-plugin/test/testdata/Gadt.expected.hs b/plugins/hls-rename-plugin/test/testdata/Gadt.expected.hs new file mode 100644 index 0000000000..65115d42d7 --- /dev/null +++ b/plugins/hls-rename-plugin/test/testdata/Gadt.expected.hs @@ -0,0 +1,17 @@ +{-# LANGUAGE GADTs #-} + +data Expr a where + Number :: Int -> Expr Int + Boolean :: Bool -> Expr Bool + Not :: Expr Bool -> Expr Bool + Even :: Expr Int -> Expr Bool + Add :: Enum a => Expr a -> Expr a -> Expr Int + Max :: Ord a => Expr a -> Expr a -> Expr a + +evaluate :: Expr a -> a +evaluate (Number n) = n +evaluate (Boolean p) = p +evaluate (Add n m) = fromEnum (evaluate n) + fromEnum (evaluate m) +evaluate (Even n) = even $ evaluate n +evaluate (Not p) = not $ evaluate p +evaluate (Max x y) = max (evaluate x) (evaluate y) diff --git a/plugins/hls-rename-plugin/test/testdata/Gadt.hs b/plugins/hls-rename-plugin/test/testdata/Gadt.hs new file mode 100644 index 0000000000..408f516900 --- /dev/null +++ b/plugins/hls-rename-plugin/test/testdata/Gadt.hs @@ -0,0 +1,17 @@ +{-# LANGUAGE GADTs #-} + +data Expression a where + Number :: Int -> Expression Int + Boolean :: Bool -> Expression Bool + Not :: Expression Bool -> Expression Bool + Even :: Expression Int -> Expression Bool + Add :: Enum a => Expression a -> Expression a -> Expression Int + Max :: Ord a => Expression a -> Expression a -> Expression a + +evaluate :: Expression a -> a +evaluate (Number n) = n +evaluate (Boolean p) = p +evaluate (Add n m) = fromEnum (evaluate n) + fromEnum (evaluate m) +evaluate (Even n) = even $ evaluate n +evaluate (Not p) = not $ evaluate p +evaluate (Max x y) = max (evaluate x) (evaluate y) diff --git a/plugins/hls-rename-plugin/test/testdata/HiddenFunction.expected.hs b/plugins/hls-rename-plugin/test/testdata/HiddenFunction.expected.hs new file mode 100644 index 0000000000..3195291c66 --- /dev/null +++ b/plugins/hls-rename-plugin/test/testdata/HiddenFunction.expected.hs @@ -0,0 +1,4 @@ +import Foo hiding (quux) + +foo :: Int -> Int +foo x = 0 diff --git a/plugins/hls-rename-plugin/test/testdata/HiddenFunction.hs b/plugins/hls-rename-plugin/test/testdata/HiddenFunction.hs new file mode 100644 index 0000000000..eacb9d1a4c --- /dev/null +++ b/plugins/hls-rename-plugin/test/testdata/HiddenFunction.hs @@ -0,0 +1,4 @@ +import Foo hiding (foo) + +foo :: Int -> Int +foo x = 0 diff --git a/plugins/hls-rename-plugin/test/testdata/ImportHiding.expected.hs b/plugins/hls-rename-plugin/test/testdata/ImportHiding.expected.hs new file mode 100644 index 0000000000..e1b600aa1c --- /dev/null +++ b/plugins/hls-rename-plugin/test/testdata/ImportHiding.expected.hs @@ -0,0 +1,4 @@ +import Foo hiding (hiddenFoo) + +foo :: Int -> Int +foo _ = 5 diff --git a/plugins/hls-rename-plugin/test/testdata/ImportHiding.hs b/plugins/hls-rename-plugin/test/testdata/ImportHiding.hs new file mode 100644 index 0000000000..c14099e68b --- /dev/null +++ b/plugins/hls-rename-plugin/test/testdata/ImportHiding.hs @@ -0,0 +1,4 @@ +import Foo hiding (foo) + +foo :: Int -> Int +foo _ = 5 diff --git a/plugins/hls-rename-plugin/test/testdata/ImportedFunction.expected.hs b/plugins/hls-rename-plugin/test/testdata/ImportedFunction.expected.hs new file mode 100644 index 0000000000..8f0cbcf888 --- /dev/null +++ b/plugins/hls-rename-plugin/test/testdata/ImportedFunction.expected.hs @@ -0,0 +1,4 @@ +import Foo (baz) + +bar :: Int -> Int +bar = baz diff --git a/plugins/hls-rename-plugin/test/testdata/ImportedFunction.hs b/plugins/hls-rename-plugin/test/testdata/ImportedFunction.hs new file mode 100644 index 0000000000..56361fc64b --- /dev/null +++ b/plugins/hls-rename-plugin/test/testdata/ImportedFunction.hs @@ -0,0 +1,4 @@ +import Foo (foo) + +bar :: Int -> Int +bar = foo diff --git a/plugins/hls-rename-plugin/test/testdata/LetExpression.expected.hs b/plugins/hls-rename-plugin/test/testdata/LetExpression.expected.hs new file mode 100644 index 0000000000..437fac2c96 --- /dev/null +++ b/plugins/hls-rename-plugin/test/testdata/LetExpression.expected.hs @@ -0,0 +1,10 @@ +module Let where + +import Foo + +bar :: Int +bar = let foobar = 5 in + foobar * foobar + +quux :: Int +quux = Foo.foo 4 diff --git a/plugins/hls-rename-plugin/test/testdata/LetExpression.hs b/plugins/hls-rename-plugin/test/testdata/LetExpression.hs new file mode 100644 index 0000000000..cbd5868de6 --- /dev/null +++ b/plugins/hls-rename-plugin/test/testdata/LetExpression.hs @@ -0,0 +1,10 @@ +module Let where + +import Foo + +bar :: Int +bar = let foo = 5 in + foo * foo + +quux :: Int +quux = Foo.foo 4 diff --git a/plugins/hls-rename-plugin/test/testdata/QualifiedAs.expected.hs b/plugins/hls-rename-plugin/test/testdata/QualifiedAs.expected.hs new file mode 100644 index 0000000000..a864119ef2 --- /dev/null +++ b/plugins/hls-rename-plugin/test/testdata/QualifiedAs.expected.hs @@ -0,0 +1,4 @@ +import qualified Foo as F + +bar :: Int -> Int +bar = F.baz diff --git a/plugins/hls-rename-plugin/test/testdata/QualifiedAs.hs b/plugins/hls-rename-plugin/test/testdata/QualifiedAs.hs new file mode 100644 index 0000000000..022b2f8e31 --- /dev/null +++ b/plugins/hls-rename-plugin/test/testdata/QualifiedAs.hs @@ -0,0 +1,4 @@ +import qualified Foo as F + +bar :: Int -> Int +bar = F.foo diff --git a/plugins/hls-rename-plugin/test/testdata/QualifiedFunction.expected.hs b/plugins/hls-rename-plugin/test/testdata/QualifiedFunction.expected.hs new file mode 100644 index 0000000000..808c12b066 --- /dev/null +++ b/plugins/hls-rename-plugin/test/testdata/QualifiedFunction.expected.hs @@ -0,0 +1,4 @@ +import qualified Foo + +bar :: Int -> Int +bar = Foo.baz diff --git a/plugins/hls-rename-plugin/test/testdata/QualifiedFunction.hs b/plugins/hls-rename-plugin/test/testdata/QualifiedFunction.hs new file mode 100644 index 0000000000..01581c0c8d --- /dev/null +++ b/plugins/hls-rename-plugin/test/testdata/QualifiedFunction.hs @@ -0,0 +1,4 @@ +import qualified Foo + +bar :: Int -> Int +bar = Foo.foo diff --git a/plugins/hls-rename-plugin/test/testdata/QualifiedShadowing.expected.hs b/plugins/hls-rename-plugin/test/testdata/QualifiedShadowing.expected.hs new file mode 100644 index 0000000000..52dbcea2b0 --- /dev/null +++ b/plugins/hls-rename-plugin/test/testdata/QualifiedShadowing.expected.hs @@ -0,0 +1,7 @@ +import qualified Foo as F + +bar :: Int -> Int +bar x = F.foobar x + foo x + +foo :: Int -> Int +foo _ = 5 diff --git a/plugins/hls-rename-plugin/test/testdata/QualifiedShadowing.hs b/plugins/hls-rename-plugin/test/testdata/QualifiedShadowing.hs new file mode 100644 index 0000000000..aa5e50caf6 --- /dev/null +++ b/plugins/hls-rename-plugin/test/testdata/QualifiedShadowing.hs @@ -0,0 +1,7 @@ +import qualified Foo as F + +bar :: Int -> Int +bar x = F.foo x + foo x + +foo :: Int -> Int +foo _ = 5 diff --git a/plugins/hls-rename-plugin/test/testdata/RealignDo.expected.hs b/plugins/hls-rename-plugin/test/testdata/RealignDo.expected.hs new file mode 100644 index 0000000000..9033a89d87 --- /dev/null +++ b/plugins/hls-rename-plugin/test/testdata/RealignDo.expected.hs @@ -0,0 +1,4 @@ +fooBarQuux :: Maybe Integer +fooBarQuux = do x <- Just 5 + t <- Just 10 + pure $ x + t diff --git a/plugins/hls-rename-plugin/test/testdata/RealignDo.hs b/plugins/hls-rename-plugin/test/testdata/RealignDo.hs new file mode 100644 index 0000000000..aa121ac984 --- /dev/null +++ b/plugins/hls-rename-plugin/test/testdata/RealignDo.hs @@ -0,0 +1,4 @@ +foo :: Maybe Integer +foo = do x <- Just 5 + t <- Just 10 + pure $ x + t diff --git a/plugins/hls-rename-plugin/test/testdata/RecordField.expected.hs b/plugins/hls-rename-plugin/test/testdata/RecordField.expected.hs new file mode 100644 index 0000000000..6646df611c --- /dev/null +++ b/plugins/hls-rename-plugin/test/testdata/RecordField.expected.hs @@ -0,0 +1,7 @@ +data Bam = Bam { + number :: Int, + s :: String +} + +foo :: Bam -> Bam +foo Bam {number = y} = Bam {number = y + 5, s = ""} diff --git a/plugins/hls-rename-plugin/test/testdata/RecordField.hs b/plugins/hls-rename-plugin/test/testdata/RecordField.hs new file mode 100644 index 0000000000..873150935d --- /dev/null +++ b/plugins/hls-rename-plugin/test/testdata/RecordField.hs @@ -0,0 +1,7 @@ +data Bam = Bam { + n :: Int, + s :: String +} + +foo :: Bam -> Bam +foo Bam {n = y} = Bam {n = y + 5, s = ""} diff --git a/plugins/hls-rename-plugin/test/testdata/ShadowedName.expected.hs b/plugins/hls-rename-plugin/test/testdata/ShadowedName.expected.hs new file mode 100644 index 0000000000..7c6391176a --- /dev/null +++ b/plugins/hls-rename-plugin/test/testdata/ShadowedName.expected.hs @@ -0,0 +1,4 @@ +baz :: Int -> Int +baz x = foo + 10 + where + foo = 20 diff --git a/plugins/hls-rename-plugin/test/testdata/ShadowedName.hs b/plugins/hls-rename-plugin/test/testdata/ShadowedName.hs new file mode 100644 index 0000000000..513f8fa89f --- /dev/null +++ b/plugins/hls-rename-plugin/test/testdata/ShadowedName.hs @@ -0,0 +1,4 @@ +foo :: Int -> Int +foo x = foo + 10 + where + foo = 20 diff --git a/plugins/hls-rename-plugin/test/testdata/TypeConstructor.expected.hs b/plugins/hls-rename-plugin/test/testdata/TypeConstructor.expected.hs new file mode 100644 index 0000000000..0c46ffa077 --- /dev/null +++ b/plugins/hls-rename-plugin/test/testdata/TypeConstructor.expected.hs @@ -0,0 +1,5 @@ +data BinaryTree a = Node a (BinaryTree a) (BinaryTree a) | Leaf a + +rotateRight :: BinaryTree a -> BinaryTree a +rotateRight (Node v (Node v' l' r') r) = Node v' l' (Node v r' r) +rotateRight t = t diff --git a/plugins/hls-rename-plugin/test/testdata/TypeConstructor.hs b/plugins/hls-rename-plugin/test/testdata/TypeConstructor.hs new file mode 100644 index 0000000000..4e728aa1a4 --- /dev/null +++ b/plugins/hls-rename-plugin/test/testdata/TypeConstructor.hs @@ -0,0 +1,5 @@ +data Tree a = Node a (Tree a) (Tree a) | Leaf a + +rotateRight :: Tree a -> Tree a +rotateRight (Node v (Node v' l' r') r) = Node v' l' (Node v r' r) +rotateRight t = t diff --git a/plugins/hls-rename-plugin/test/testdata/TypeVariable.expected.hs b/plugins/hls-rename-plugin/test/testdata/TypeVariable.expected.hs new file mode 100644 index 0000000000..75891f4290 --- /dev/null +++ b/plugins/hls-rename-plugin/test/testdata/TypeVariable.expected.hs @@ -0,0 +1,2 @@ +bar :: Maybe b -> Maybe b +bar a = a diff --git a/plugins/hls-rename-plugin/test/testdata/TypeVariable.hs b/plugins/hls-rename-plugin/test/testdata/TypeVariable.hs new file mode 100644 index 0000000000..782be9a7f3 --- /dev/null +++ b/plugins/hls-rename-plugin/test/testdata/TypeVariable.hs @@ -0,0 +1,2 @@ +bar :: Maybe a -> Maybe a +bar a = a diff --git a/plugins/hls-rename-plugin/test/testdata/Typeclass.expected.hs b/plugins/hls-rename-plugin/test/testdata/Typeclass.expected.hs new file mode 100644 index 0000000000..73199ec83e --- /dev/null +++ b/plugins/hls-rename-plugin/test/testdata/Typeclass.expected.hs @@ -0,0 +1,10 @@ +module Typeclass where + +class Equal a where + equals :: a -> a -> Bool + +instance Equal Int where + equals = (==) + +allEqual :: Equal a => [a] -> Bool +allEqual = all =<< equals . head diff --git a/plugins/hls-rename-plugin/test/testdata/Typeclass.hs b/plugins/hls-rename-plugin/test/testdata/Typeclass.hs new file mode 100644 index 0000000000..57667128dd --- /dev/null +++ b/plugins/hls-rename-plugin/test/testdata/Typeclass.hs @@ -0,0 +1,10 @@ +module Typeclass where + +class Equality a where + equals :: a -> a -> Bool + +instance Equality Int where + equals = (==) + +allEqual :: Equality a => [a] -> Bool +allEqual = all =<< equals . head diff --git a/plugins/hls-rename-plugin/test/testdata/hie.yaml b/plugins/hls-rename-plugin/test/testdata/hie.yaml new file mode 100644 index 0000000000..4c184b3c33 --- /dev/null +++ b/plugins/hls-rename-plugin/test/testdata/hie.yaml @@ -0,0 +1,22 @@ +cradle: + direct: + arguments: + - "DataConstructor" + - "ExportedFunction" + - "Foo" + - "FunctionArgument" + - "FunctionName" + - "Gadt" + - "HiddenFunction" + - "ImportHiding" + - "ImportedFunction" + - "LetExpression" + - "QualifiedAs" + - "QualifiedFunction" + - "QualifiedShadowing" + - "RealignDo" + - "RecordField" + - "ShadowedName" + - "TypeClass" + - "TypeConstructor" + - "TypeVariable" diff --git a/plugins/hls-retrie-plugin/src/Ide/Plugin/Retrie.hs b/plugins/hls-retrie-plugin/src/Ide/Plugin/Retrie.hs index f1c3487138..cf41005407 100644 --- a/plugins/hls-retrie-plugin/src/Ide/Plugin/Retrie.hs +++ b/plugins/hls-retrie-plugin/src/Ide/Plugin/Retrie.hs @@ -14,7 +14,7 @@ {-# OPTIONS -Wno-orphans #-} -module Ide.Plugin.Retrie (descriptor) where +module Ide.Plugin.Retrie (descriptor, response, handleMaybe, handleMaybeM) where import Control.Concurrent.Extra (readVar) import Control.Exception.Safe (Exception (..), diff --git a/stack-8.10.2.yaml b/stack-8.10.2.yaml index 0e86582024..39472406a0 100644 --- a/stack-8.10.2.yaml +++ b/stack-8.10.2.yaml @@ -15,6 +15,7 @@ packages: - ./plugins/hls-explicit-imports-plugin - ./plugins/hls-refine-imports-plugin - ./plugins/hls-hlint-plugin + - ./plugins/hls-rename-plugin - ./plugins/hls-retrie-plugin - ./plugins/hls-splice-plugin - ./plugins/hls-tactics-plugin diff --git a/stack-8.10.3.yaml b/stack-8.10.3.yaml index 98d3fada74..f75339cd27 100644 --- a/stack-8.10.3.yaml +++ b/stack-8.10.3.yaml @@ -15,6 +15,7 @@ packages: - ./plugins/hls-explicit-imports-plugin - ./plugins/hls-refine-imports-plugin - ./plugins/hls-hlint-plugin + - ./plugins/hls-rename-plugin - ./plugins/hls-retrie-plugin - ./plugins/hls-splice-plugin - ./plugins/hls-tactics-plugin diff --git a/stack-8.10.4.yaml b/stack-8.10.4.yaml index 4f29bcd1a7..ea43367c51 100644 --- a/stack-8.10.4.yaml +++ b/stack-8.10.4.yaml @@ -15,6 +15,7 @@ packages: - ./plugins/hls-explicit-imports-plugin - ./plugins/hls-refine-imports-plugin - ./plugins/hls-hlint-plugin + - ./plugins/hls-rename-plugin - ./plugins/hls-retrie-plugin - ./plugins/hls-splice-plugin - ./plugins/hls-tactics-plugin diff --git a/stack-8.10.5.yaml b/stack-8.10.5.yaml index 8795b39451..7f23bb9242 100644 --- a/stack-8.10.5.yaml +++ b/stack-8.10.5.yaml @@ -17,6 +17,7 @@ packages: - ./plugins/hls-explicit-imports-plugin - ./plugins/hls-refine-imports-plugin - ./plugins/hls-hlint-plugin + - ./plugins/hls-rename-plugin - ./plugins/hls-retrie-plugin - ./plugins/hls-splice-plugin - ./plugins/hls-tactics-plugin @@ -50,7 +51,7 @@ extra-deps: - implicit-hie-0.1.2.6 - monad-dijkstra-0.1.1.2 - refinery-0.4.0.0 - - retrie-1.0.0.0 + - retrie-0.1.1.1 - stylish-haskell-0.12.2.0 - semigroups-0.18.5 - temporary-1.2.1.1 diff --git a/stack-8.6.4.yaml b/stack-8.6.4.yaml index 75f8903f12..0104e76d85 100644 --- a/stack-8.6.4.yaml +++ b/stack-8.6.4.yaml @@ -16,6 +16,7 @@ packages: - ./plugins/hls-explicit-imports-plugin - ./plugins/hls-refine-imports-plugin - ./plugins/hls-hlint-plugin + - ./plugins/hls-rename-plugin - ./plugins/hls-retrie-plugin - ./plugins/hls-splice-plugin - ./plugins/hls-tactics-plugin diff --git a/stack-8.6.5.yaml b/stack-8.6.5.yaml index cb9078fcd2..13a5a41289 100644 --- a/stack-8.6.5.yaml +++ b/stack-8.6.5.yaml @@ -15,6 +15,7 @@ packages: - ./plugins/hls-explicit-imports-plugin - ./plugins/hls-refine-imports-plugin - ./plugins/hls-hlint-plugin + - ./plugins/hls-rename-plugin - ./plugins/hls-retrie-plugin - ./plugins/hls-splice-plugin - ./plugins/hls-tactics-plugin diff --git a/stack-8.8.3.yaml b/stack-8.8.3.yaml index b6eb8ab1b9..85983a25d4 100644 --- a/stack-8.8.3.yaml +++ b/stack-8.8.3.yaml @@ -15,6 +15,7 @@ packages: - ./plugins/hls-explicit-imports-plugin - ./plugins/hls-refine-imports-plugin - ./plugins/hls-hlint-plugin + - ./plugins/hls-rename-plugin - ./plugins/hls-retrie-plugin - ./plugins/hls-splice-plugin - ./plugins/hls-tactics-plugin diff --git a/stack-8.8.4.yaml b/stack-8.8.4.yaml index 465f7249f0..ff7a7d0dfe 100644 --- a/stack-8.8.4.yaml +++ b/stack-8.8.4.yaml @@ -15,6 +15,7 @@ packages: - ./plugins/hls-explicit-imports-plugin - ./plugins/hls-refine-imports-plugin - ./plugins/hls-hlint-plugin + - ./plugins/hls-rename-plugin - ./plugins/hls-retrie-plugin - ./plugins/hls-splice-plugin - ./plugins/hls-tactics-plugin diff --git a/stack-9.0.1.yaml b/stack-9.0.1.yaml index e425811633..07080395a1 100644 --- a/stack-9.0.1.yaml +++ b/stack-9.0.1.yaml @@ -16,6 +16,7 @@ packages: - ./plugins/hls-explicit-imports-plugin # - ./plugins/hls-refine-imports-plugin - ./plugins/hls-hlint-plugin + - ./plugins/hls-rename-plugin - ./plugins/hls-retrie-plugin # - ./plugins/hls-splice-plugin # - ./plugins/hls-tactics-plugin diff --git a/stack.yaml b/stack.yaml index 472af005d7..67e3104e9f 100644 --- a/stack.yaml +++ b/stack.yaml @@ -15,6 +15,7 @@ packages: - ./plugins/hls-explicit-imports-plugin - ./plugins/hls-refine-imports-plugin - ./plugins/hls-hlint-plugin + - ./plugins/hls-rename-plugin - ./plugins/hls-retrie-plugin - ./plugins/hls-splice-plugin - ./plugins/hls-tactics-plugin diff --git a/test/functional/Main.hs b/test/functional/Main.hs index 8da258b708..ff9473e56c 100644 --- a/test/functional/Main.hs +++ b/test/functional/Main.hs @@ -14,7 +14,6 @@ import HieBios import Highlight import Progress import Reference -import Rename import Symbol import Test.Hls import TypeDefinition @@ -37,7 +36,6 @@ main = defaultTestRunner , Highlight.tests , Progress.tests , Reference.tests - , Rename.tests , Symbol.tests , TypeDefinition.tests ] diff --git a/test/functional/Rename.hs b/test/functional/Rename.hs deleted file mode 100644 index 08de8a63d9..0000000000 --- a/test/functional/Rename.hs +++ /dev/null @@ -1,23 +0,0 @@ -{-# LANGUAGE OverloadedStrings #-} -module Rename (tests) where - -import Test.Hls -import Test.Hls.Command - -tests :: TestTree -tests = testGroup "rename" [ - ignoreTestBecause "no symbol renaming (yet!)" $ - testCase "works" $ - runSession hlsCommand fullCaps "test/testdata/rename" $ do - doc <- openDoc "Rename.hs" "haskell" - rename doc (Position 3 1) "baz" -- foo :: Int -> Int - contents <- documentContents doc - let expected = - "main = do\n\ - \ x <- return $ baz 42\n\ - \ return (baz x)\n\ - \baz :: Int -> Int\n\ - \baz x = x + 1\n\ - \bar = (+ 1) . baz\n" - liftIO $ contents @?= expected - ] diff --git a/test/testdata/rename/Rename.hs b/test/testdata/rename/Rename.hs deleted file mode 100644 index 19f566795f..0000000000 --- a/test/testdata/rename/Rename.hs +++ /dev/null @@ -1,6 +0,0 @@ -main = do - x <- return $ foo 42 - return (foo x) -foo :: Int -> Int -foo x = x + 1 -bar = (+ 1) . foo diff --git a/test/utils/Test/Hls/Flags.hs b/test/utils/Test/Hls/Flags.hs index 84ff263f76..ce17c7568e 100644 --- a/test/utils/Test/Hls/Flags.hs +++ b/test/utils/Test/Hls/Flags.hs @@ -39,6 +39,14 @@ requiresImportLensPlugin = id requiresImportLensPlugin = ignoreTestBecause "ImportLens plugin disabled" #endif +-- | Disable test unless the rename flag is set +requiresRenamePlugin :: TestTree -> TestTree +#if rename +requiresRenamePlugin = id +#else +requiresRenamePlugin = ignoreTestBecause "Rename plugin disabled" +#endif + -- | Disable test unless the retrie flag is set requiresRetriePlugin :: TestTree -> TestTree #if retrie