@@ -5,8 +5,8 @@ module Ide.Plugin.SignatureHelp (descriptor) where
55
66import Control.Arrow ((>>>) )
77import Data.Bifunctor (bimap )
8+ import Data.Function ((&) )
89import qualified Data.Map.Strict as M
9- import Data.Maybe (mapMaybe )
1010import qualified Data.Set as S
1111import Data.Text (Text )
1212import qualified Data.Text as T
@@ -34,10 +34,12 @@ import Development.IDE.GHC.Compat (ContextInfo (Use),
3434 mkRealSrcLoc ,
3535 mkRealSrcSpan ,
3636 nodeChildren , nodeSpan ,
37- ppr , recoverFullType ,
37+ nodeType , ppr ,
38+ recoverFullType ,
3839 smallestContainingSatisfying ,
3940 sourceNodeInfo )
4041import Development.IDE.GHC.Compat.Util (LexicalFastString (LexicalFastString ))
42+ import GHC.Core.Map.Type (deBruijnize )
4143import GHC.Data.Maybe (rightToMaybe )
4244import GHC.Types.SrcLoc (isRealSubspanOf )
4345import Ide.Plugin.Error (getNormalizedFilePathE )
@@ -86,28 +88,30 @@ signatureHelpProvider ideState _pluginId (SignatureHelpParams (TextDocumentIdent
8688 hieAst
8789 ( \ span hieAst -> do
8890 let functionNode = getLeftMostNode hieAst
89- functionName <- getNodeName span functionNode
90- functionType <- getNodeType hieKind span functionNode
91+ (functionName, functionTypes) <- getNodeNameAndTypes hieKind functionNode
9192 argumentNumber <- getArgumentNumber span hieAst
92- Just (functionName, functionType , argumentNumber)
93+ Just (functionName, functionTypes , argumentNumber)
9394 )
9495 case results of
9596 -- TODO(@linj) what does non-singleton list mean?
96- [(functionName, functionType , argumentNumber)] ->
97- pure $ InL $ mkSignatureHelp functionName functionType (fromIntegral argumentNumber - 1 )
97+ [(functionName, functionTypes , argumentNumber)] ->
98+ pure $ InL $ mkSignatureHelp (fromIntegral argumentNumber - 1 ) functionName functionTypes
9899 _ -> pure $ InR Null
99100
100- mkSignatureHelp :: Name -> Text -> UInt -> SignatureHelp
101- mkSignatureHelp functionName functionType argumentNumber =
101+ mkSignatureHelp :: UInt -> Name -> [Text ] -> SignatureHelp
102+ mkSignatureHelp argumentNumber functionName functionTypes =
103+ SignatureHelp
104+ (mkSignatureInformation argumentNumber functionName <$> functionTypes)
105+ (Just 0 )
106+ (Just $ InL argumentNumber)
107+
108+ mkSignatureInformation :: UInt -> Name -> Text -> SignatureInformation
109+ mkSignatureInformation argumentNumber functionName functionType =
102110 let functionNameLabelPrefix = printOutputable (ppr functionName) <> " :: "
103- in SignatureHelp
104- [ SignatureInformation
105- (functionNameLabelPrefix <> functionType)
106- Nothing
107- (Just $ mkArguments (fromIntegral $ T. length functionNameLabelPrefix) functionType)
108- (Just $ InL argumentNumber)
109- ]
110- (Just 0 )
111+ in SignatureInformation
112+ (functionNameLabelPrefix <> functionType)
113+ Nothing
114+ (Just $ mkArguments (fromIntegral $ T. length functionNameLabelPrefix) functionType)
111115 (Just $ InL argumentNumber)
112116
113117-- TODO(@linj) can type string be a multi-line string?
@@ -154,27 +158,33 @@ getLeftMostNode thisNode =
154158 [] -> thisNode
155159 leftChild: _ -> getLeftMostNode leftChild
156160
157- getNodeName :: RealSrcSpan -> HieAST a -> Maybe Name
158- getNodeName _span hieAst =
161+ getNodeNameAndTypes :: forall a . HieKind a -> HieAST a -> Maybe ( Name , [ Text ])
162+ getNodeNameAndTypes hieKind hieAst =
159163 if nodeHasAnnotation (" HsVar" , " HsExpr" ) hieAst
160- then
161- case mapMaybe extractName $ M. keys $ M. filter isUse $ getSourceNodeIds hieAst of
162- [name] -> Just name -- TODO(@linj) will there be more than one name?
163- _ -> Nothing
164+ then case hieAst & getSourceNodeIds & M. filter isUse & M. assocs of
165+ [(identifier, identifierDetails)] ->
166+ case extractName identifier of
167+ Nothing -> Nothing
168+ Just name ->
169+ let mTypeOfName = identType identifierDetails
170+ typesOfNode = case sourceNodeInfo hieAst of
171+ Nothing -> []
172+ Just nodeInfo -> nodeType nodeInfo
173+ allTypes = case mTypeOfName of
174+ Nothing -> typesOfNode
175+ Just typeOfName -> typeOfName : filter (isDifferentType typeOfName) typesOfNode
176+ in Just (name, prettyType <$> allTypes)
177+ [] -> Nothing
178+ _ -> Nothing -- seems impossible
164179 else Nothing -- TODO(@linj) must function node be HsVar?
165180 where
166181 extractName = rightToMaybe
167182
168- -- TODO(@linj) share code with getNodeName
169- getNodeType :: HieKind a -> RealSrcSpan -> HieAST a -> Maybe Text
170- getNodeType (hieKind :: HieKind a ) _span hieAst =
171- if nodeHasAnnotation (" HsVar" , " HsExpr" ) hieAst
172- then
173- case M. elems $ M. filter isUse $ getSourceNodeIds hieAst of
174- [identifierDetails] -> identType identifierDetails >>= (prettyType >>> Just )
175- _ -> Nothing -- TODO(@linj) will there be more than one identifierDetails?
176- else Nothing
177- where
183+ isDifferentType :: a -> a -> Bool
184+ isDifferentType type1 type2 = case hieKind of
185+ HieFresh -> deBruijnize type1 /= deBruijnize type2
186+ HieFromDisk _hieFile -> type1 /= type2
187+
178188 -- modified from Development.IDE.Spans.AtPoint.atPoint
179189 prettyType :: a -> Text
180190 prettyType = expandType >>> printOutputable
0 commit comments