static-ls-0.1.2: src/StaticLS/IDE/References.hs
module StaticLS.IDE.References (findRefs) where
import Control.Monad (join)
import Control.Monad.IO.Class
import Control.Monad.Trans.Class (lift)
import Control.Monad.Trans.Maybe (MaybeT (..), runMaybeT)
import Data.Maybe (catMaybes, fromMaybe)
import qualified GHC.Plugins as GHC
import qualified HieDb
import qualified Language.LSP.Protocol.Types as LSP
import StaticLS.Except
import StaticLS.HIE
import StaticLS.HIE.File
import StaticLS.Maybe
import StaticLS.StaticEnv
findRefs :: (HasStaticEnv m, MonadIO m) => LSP.TextDocumentIdentifier -> LSP.Position -> m [LSP.Location]
findRefs tdi position = do
mLocList <- runMaybeT $ do
hieFile <- getHieFileFromTdi tdi
let hiedbPosition = lspPositionToHieDbCoords position
names = namesAtPoint hieFile hiedbPosition
occNamesAndModNamesAtPoint =
(\name -> (GHC.occName name, fmap GHC.moduleName . GHC.nameModule_maybe $ name))
<$> names
refResRows <-
lift $ fmap (fromMaybe []) $ runMaybeT $ runHieDbMaybeT $ \hieDb -> do
join
<$> mapM
( \(occ, mModName) -> do
HieDb.findReferences hieDb False occ mModName Nothing []
)
occNamesAndModNamesAtPoint
lift $ catMaybes <$> mapM (runMaybeT . refRowToLocation) refResRows
pure $ fromMaybe [] mLocList
refRowToLocation :: (HasStaticEnv m, MonadIO m) => HieDb.Res HieDb.RefRow -> MaybeT m LSP.Location
refRowToLocation (refRow HieDb.:. _) = do
let start = exceptToMaybe $ hiedbCoordsToLspPosition (refRow.refSLine, refRow.refSCol)
end = exceptToMaybe $ hiedbCoordsToLspPosition (refRow.refELine, refRow.refECol)
range = LSP.Range <$> start <*> end
hieFilePath = refRow.refSrc
file <- hieFilePathToSrcFilePath hieFilePath
let lspUri = LSP.fromNormalizedUri . LSP.normalizedFilePathToUri . LSP.toNormalizedFilePath $ file
toAlt $ LSP.Location lspUri <$> range