Skip to content

Commit cd959ae

Browse files
soulomoonmichaelpj
andauthored
fix isClassNodeIdentifier in hls-class-plugin (#4020)
Partially fix #3942, by handling isClassNodeIdentifier correctly. --------- Co-authored-by: Michael Peyton Jones <[email protected]>
1 parent c2a7952 commit cd959ae

File tree

3 files changed

+30
-3
lines changed

3 files changed

+30
-3
lines changed

Diff for: plugins/hls-class-plugin/src/Ide/Plugin/Class/CodeAction.hs

+5-3
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ codeAction recorder state plId (CodeActionParams _ _ docId _ context) = do
159159
$ listToMaybe
160160
$ mapMaybe listToMaybe
161161
$ pointCommand hf instancePosition
162-
( (Map.keys . Map.filter isClassNodeIdentifier . getNodeIds)
162+
( (Map.keys . Map.filterWithKey isClassNodeIdentifier . getNodeIds)
163163
<=< nodeChildren
164164
)
165165

@@ -198,8 +198,10 @@ codeAction recorder state plId (CodeActionParams _ _ docId _ context) = do
198198
_ -> fail "Ide.Plugin.Class.findClassFromIdentifier"
199199
findClassFromIdentifier _ (Left _) = throwError (PluginInternalError "Ide.Plugin.Class.findClassIdentifier")
200200

201-
isClassNodeIdentifier :: IdentifierDetails a -> Bool
202-
isClassNodeIdentifier ident = (isNothing . identType) ident && Use `Set.member` identInfo ident
201+
-- see https://hackage.haskell.org/package/ghc-9.8.1/docs/src/GHC.Types.Name.Occurrence.html#mkClassDataConOcc
202+
isClassNodeIdentifier :: Identifier -> IdentifierDetails a -> Bool
203+
isClassNodeIdentifier (Right i) ident | 'C':':':_ <- unpackFS $ occNameFS $ occName i = (isNothing . identType) ident && Use `Set.member` identInfo ident
204+
isClassNodeIdentifier _ _ = False
203205

204206
isClassMethodWarning :: T.Text -> Bool
205207
isClassMethodWarning = T.isPrefixOf "• No explicit implementation for"

Diff for: plugins/hls-class-plugin/test/Main.hs

+12
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ module Main
99
( main
1010
) where
1111

12+
import Control.Exception (catch)
1213
import Control.Lens (Prism', prism', view, (^.),
1314
(^..), (^?))
1415
import Control.Monad (void)
@@ -120,6 +121,17 @@ codeLensTests = testGroup
120121
doc <- openDoc "TH.hs" "haskell"
121122
lens <- getAndResolveCodeLenses doc
122123
liftIO $ length lens @?= 0
124+
, testCase "Do not construct error action!, Ticket3942one" $ do
125+
runSessionWithServer def classPlugin testDataDir $ do
126+
doc <- openDoc "Ticket3942one.hs" "haskell"
127+
_ <- waitForDiagnosticsFromSource doc (T.unpack sourceTypecheck)
128+
lens <- getAllCodeActions doc
129+
-- should switch to `liftIO $ length lens @?= 2, when Ticket3942 is entirely fixed`
130+
-- current fix is just to make sure the code does not throw an exception that would mess up
131+
-- the client UI.
132+
liftIO $ length lens > 0 @?= True
133+
`catch` \(e :: SessionException) -> do
134+
liftIO $ assertFailure $ "classPluginTestError: "++ show e
123135
, goldenCodeLens "Apply code lens" "CodeLensSimple" 1
124136
, goldenCodeLens "Apply code lens for local class" "LocalClassDefine" 0
125137
, goldenCodeLens "Apply code lens on the same line" "Inline" 0
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{-# LANGUAGE DeriveAnyClass #-}
2+
3+
module Ticket3942one where
4+
5+
class C a where
6+
foo :: a -> Int
7+
8+
newtype Foo = MkFoo Int deriving (C)
9+
instance Show Foo where
10+
11+
12+
main :: IO ()
13+
main = return ()

0 commit comments

Comments
 (0)