@@ -57,43 +57,49 @@ import Language.LSP.Server
57
57
instance Hashable (Mod a ) where hash n = hash (unMod n)
58
58
59
59
descriptor :: Recorder (WithPriority E. Log ) -> PluginId -> PluginDescriptor IdeState
60
- descriptor recorder pluginId = mkExactprintPluginDescriptor recorder $ (defaultPluginDescriptor pluginId " Provides renaming of Haskell identifiers" )
61
- { pluginHandlers = mkPluginHandler SMethod_TextDocumentRename renameProvider
62
- , pluginConfigDescriptor = defaultConfigDescriptor
63
- { configCustomConfig = mkCustomConfig properties }
64
- }
60
+ descriptor recorder pluginId = mkExactprintPluginDescriptor recorder $
61
+ (defaultPluginDescriptor pluginId " Provides renaming of Haskell identifiers" )
62
+ { pluginHandlers = mkPluginHandler SMethod_TextDocumentRename renameProvider
63
+ , pluginConfigDescriptor = defaultConfigDescriptor
64
+ { configCustomConfig = mkCustomConfig properties }
65
+ }
65
66
66
67
renameProvider :: PluginMethodHandler IdeState Method_TextDocumentRename
67
68
renameProvider state pluginId (RenameParams _prog (TextDocumentIdentifier uri) pos newNameText) = do
68
- nfp <- getNormalizedFilePathE uri
69
- directOldNames <- getNamesAtPos state nfp pos
70
- directRefs <- concat <$> mapM (refsAtName state nfp) directOldNames
71
-
72
- {- References in HieDB are not necessarily transitive. With `NamedFieldPuns`, we can have
73
- indirect references through punned names. To find the transitive closure, we do a pass of
74
- the direct references to find the references for any punned names.
75
- See the `IndirectPuns` test for an example. -}
76
- indirectOldNames <- concat . filter ((> 1 ) . length ) <$>
77
- mapM (uncurry (getNamesAtPos state) <=< locToFilePos) directRefs
78
- let oldNames = filter matchesDirect indirectOldNames ++ directOldNames
79
- matchesDirect n = occNameFS (nameOccName n) `elem` directFS
80
- where
81
- directFS = map (occNameFS. nameOccName) directOldNames
82
- refs <- HS. fromList . concat <$> mapM (refsAtName state nfp) oldNames
83
-
84
- -- Validate rename
85
- crossModuleEnabled <- liftIO $ runAction " rename: config" state $ usePropertyAction # crossModule pluginId properties
86
- unless crossModuleEnabled $ failWhenImportOrExport state nfp refs oldNames
87
- when (any isBuiltInSyntax oldNames) $ throwError $ PluginInternalError " Invalid rename of built-in syntax"
88
-
89
- -- Perform rename
90
- let newName = mkTcOcc $ T. unpack newNameText
91
- filesRefs = collectWith locToUri refs
92
- getFileEdit (uri, locations) = do
93
- verTxtDocId <- lift $ getVersionedTextDoc (TextDocumentIdentifier uri)
94
- getSrcEdit state verTxtDocId (replaceRefs newName locations)
95
- fileEdits <- mapM getFileEdit filesRefs
96
- pure $ InL $ fold fileEdits
69
+ nfp <- getNormalizedFilePathE uri
70
+ directOldNames <- getNamesAtPos state nfp pos
71
+ directRefs <- concat <$> mapM (refsAtName state nfp) directOldNames
72
+
73
+ {- References in HieDB are not necessarily transitive. With `NamedFieldPuns`, we can have
74
+ indirect references through punned names. To find the transitive closure, we do a pass of
75
+ the direct references to find the references for any punned names.
76
+ See the `IndirectPuns` test for an example. -}
77
+ indirectOldNames <- concat . filter ((> 1 ) . length ) <$>
78
+ mapM (uncurry (getNamesAtPos state) <=< locToFilePos) directRefs
79
+ let oldNames = filter matchesDirect indirectOldNames ++ directOldNames
80
+ where
81
+ matchesDirect n = occNameFS (nameOccName n) `elem` directFS
82
+ directFS = map (occNameFS . nameOccName) directOldNames
83
+
84
+ case oldNames of
85
+ -- There was no symbol at given position (e.g. rename triggered within a comment)
86
+ [] -> throwError $ PluginInvalidParams " No symbol to rename at given position"
87
+ _ -> do
88
+ refs <- HS. fromList . concat <$> mapM (refsAtName state nfp) oldNames
89
+
90
+ -- Validate rename
91
+ crossModuleEnabled <- liftIO $ runAction " rename: config" state $ usePropertyAction # crossModule pluginId properties
92
+ unless crossModuleEnabled $ failWhenImportOrExport state nfp refs oldNames
93
+ when (any isBuiltInSyntax oldNames) $ throwError $ PluginInternalError " Invalid rename of built-in syntax"
94
+
95
+ -- Perform rename
96
+ let newName = mkTcOcc $ T. unpack newNameText
97
+ filesRefs = collectWith locToUri refs
98
+ getFileEdit (uri, locations) = do
99
+ verTxtDocId <- lift $ getVersionedTextDoc (TextDocumentIdentifier uri)
100
+ getSrcEdit state verTxtDocId (replaceRefs newName locations)
101
+ fileEdits <- mapM getFileEdit filesRefs
102
+ pure $ InL $ fold fileEdits
97
103
98
104
-- | Limit renaming across modules.
99
105
failWhenImportOrExport ::
0 commit comments