{-# LANGUAGE RankNTypes   #-}
{-# LANGUAGE TypeFamilies #-}
module Development.IDE.Core.Actions
( getAtPoint
, getDefinition
, getTypeDefinition
, highlightAtPoint
, refsAtPoint
, workspaceSymbols
, lookupMod
) where

import           Control.Monad.Extra                  (mapMaybeM)
import           Control.Monad.Reader
import           Control.Monad.Trans.Maybe
import qualified Data.HashMap.Strict                  as HM
import           Data.Maybe
import qualified Data.Text                            as T
import           Data.Tuple.Extra
import           Development.IDE.Core.OfInterest
import           Development.IDE.Core.PluginUtils
import           Development.IDE.Core.PositionMapping
import           Development.IDE.Core.RuleTypes
import           Development.IDE.Core.Service
import           Development.IDE.Core.Shake
import           Development.IDE.GHC.Compat           hiding (writeHieFile)
import           Development.IDE.Graph
import qualified Development.IDE.Spans.AtPoint        as AtPoint
import           Development.IDE.Types.HscEnvEq       (hscEnv)
import           Development.IDE.Types.Location
import qualified HieDb
import           Language.LSP.Protocol.Types          (DocumentHighlight (..),
                                                       SymbolInformation (..),
                                                       normalizedFilePathToUri,
                                                       uriToNormalizedFilePath)


-- | Eventually this will lookup/generate URIs for files in dependencies, but not in the
-- project. Right now, this is just a stub.
lookupMod
  :: HieDbWriter -- ^ access the database
  -> FilePath -- ^ The `.hie` file we got from the database
  -> ModuleName
  -> Unit
  -> Bool -- ^ Is this file a boot file?
  -> MaybeT IdeAction Uri
lookupMod :: HieDbWriter
-> FilePath -> ModuleName -> Unit -> Bool -> MaybeT IdeAction Uri
lookupMod HieDbWriter
_dbchan FilePath
_hie_f ModuleName
_mod Unit
_uid Bool
_boot = IdeAction (Maybe Uri) -> MaybeT IdeAction Uri
forall (m :: * -> *) a. m (Maybe a) -> MaybeT m a
MaybeT (IdeAction (Maybe Uri) -> MaybeT IdeAction Uri)
-> IdeAction (Maybe Uri) -> MaybeT IdeAction Uri
forall a b. (a -> b) -> a -> b
$ Maybe Uri -> IdeAction (Maybe Uri)
forall a. a -> IdeAction a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe Uri
forall a. Maybe a
Nothing


-- IMPORTANT NOTE : make sure all rules `useWithStaleFastMT`d by these have a "Persistent Stale" rule defined,
-- so we can quickly answer as soon as the IDE is opened
-- Even if we don't have persistent information on disk for these rules, the persistent rule
-- should just return an empty result
-- It is imperative that the result of the persistent rule succeed in such a case, or we will
-- block waiting for the rule to be properly computed.

-- | Try to get hover text for the name under point.
getAtPoint :: NormalizedFilePath -> Position -> IdeAction (Maybe (Maybe Range, [T.Text]))
getAtPoint :: NormalizedFilePath
-> Position -> IdeAction (Maybe (Maybe Range, [Text]))
getAtPoint NormalizedFilePath
file Position
pos = MaybeT IdeAction (Maybe Range, [Text])
-> IdeAction (Maybe (Maybe Range, [Text]))
forall (m :: * -> *) a. MaybeT m a -> m (Maybe a)
runMaybeT (MaybeT IdeAction (Maybe Range, [Text])
 -> IdeAction (Maybe (Maybe Range, [Text])))
-> MaybeT IdeAction (Maybe Range, [Text])
-> IdeAction (Maybe (Maybe Range, [Text]))
forall a b. (a -> b) -> a -> b
$ do
  ShakeExtras
ide <- MaybeT IdeAction ShakeExtras
forall r (m :: * -> *). MonadReader r m => m r
ask
  IdeOptions
opts <- IO IdeOptions -> MaybeT IdeAction IdeOptions
forall a. IO a -> MaybeT IdeAction a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO IdeOptions -> MaybeT IdeAction IdeOptions)
-> IO IdeOptions -> MaybeT IdeAction IdeOptions
forall a b. (a -> b) -> a -> b
$ ShakeExtras -> IO IdeOptions
getIdeOptionsIO ShakeExtras
ide

  (HieAstResult
hf, PositionMapping
mapping) <- GetHieAst
-> NormalizedFilePath
-> MaybeT IdeAction (HieAstResult, PositionMapping)
forall k v.
IdeRule k v =>
k -> NormalizedFilePath -> MaybeT IdeAction (v, PositionMapping)
useWithStaleFastMT GetHieAst
GetHieAst NormalizedFilePath
file
  HscEnv
env <- HscEnvEq -> HscEnv
hscEnv (HscEnvEq -> HscEnv)
-> ((HscEnvEq, PositionMapping) -> HscEnvEq)
-> (HscEnvEq, PositionMapping)
-> HscEnv
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (HscEnvEq, PositionMapping) -> HscEnvEq
forall a b. (a, b) -> a
fst ((HscEnvEq, PositionMapping) -> HscEnv)
-> MaybeT IdeAction (HscEnvEq, PositionMapping)
-> MaybeT IdeAction HscEnv
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> GhcSession
-> NormalizedFilePath
-> MaybeT IdeAction (HscEnvEq, PositionMapping)
forall k v.
IdeRule k v =>
k -> NormalizedFilePath -> MaybeT IdeAction (v, PositionMapping)
useWithStaleFastMT GhcSession
GhcSession NormalizedFilePath
file
  DocAndTyThingMap
dkMap <- IdeAction DocAndTyThingMap -> MaybeT IdeAction DocAndTyThingMap
forall (m :: * -> *) a. Monad m => m a -> MaybeT m a
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (IdeAction DocAndTyThingMap -> MaybeT IdeAction DocAndTyThingMap)
-> IdeAction DocAndTyThingMap -> MaybeT IdeAction DocAndTyThingMap
forall a b. (a -> b) -> a -> b
$ DocAndTyThingMap
-> ((DocAndTyThingMap, PositionMapping) -> DocAndTyThingMap)
-> Maybe (DocAndTyThingMap, PositionMapping)
-> DocAndTyThingMap
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (DocMap -> TyThingMap -> DocAndTyThingMap
DKMap DocMap
forall a. Monoid a => a
mempty TyThingMap
forall a. Monoid a => a
mempty) (DocAndTyThingMap, PositionMapping) -> DocAndTyThingMap
forall a b. (a, b) -> a
fst (Maybe (DocAndTyThingMap, PositionMapping) -> DocAndTyThingMap)
-> IdeAction (Maybe (DocAndTyThingMap, PositionMapping))
-> IdeAction DocAndTyThingMap
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> MaybeT IdeAction (DocAndTyThingMap, PositionMapping)
-> IdeAction (Maybe (DocAndTyThingMap, PositionMapping))
forall (m :: * -> *) a. MaybeT m a -> m (Maybe a)
runMaybeT (GetDocMap
-> NormalizedFilePath
-> MaybeT IdeAction (DocAndTyThingMap, PositionMapping)
forall k v.
IdeRule k v =>
k -> NormalizedFilePath -> MaybeT IdeAction (v, PositionMapping)
useWithStaleFastMT GetDocMap
GetDocMap NormalizedFilePath
file)

  !Position
pos' <- IdeAction (Maybe Position) -> MaybeT IdeAction Position
forall (m :: * -> *) a. m (Maybe a) -> MaybeT m a
MaybeT (Maybe Position -> IdeAction (Maybe Position)
forall a. a -> IdeAction a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Position -> IdeAction (Maybe Position))
-> Maybe Position -> IdeAction (Maybe Position)
forall a b. (a -> b) -> a -> b
$ PositionMapping -> Position -> Maybe Position
fromCurrentPosition PositionMapping
mapping Position
pos)
  IdeAction (Maybe (Maybe Range, [Text]))
-> MaybeT IdeAction (Maybe Range, [Text])
forall (m :: * -> *) a. m (Maybe a) -> MaybeT m a
MaybeT (IdeAction (Maybe (Maybe Range, [Text]))
 -> MaybeT IdeAction (Maybe Range, [Text]))
-> IdeAction (Maybe (Maybe Range, [Text]))
-> MaybeT IdeAction (Maybe Range, [Text])
forall a b. (a -> b) -> a -> b
$ IO (Maybe (Maybe Range, [Text]))
-> IdeAction (Maybe (Maybe Range, [Text]))
forall a. IO a -> IdeAction a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Maybe (Maybe Range, [Text]))
 -> IdeAction (Maybe (Maybe Range, [Text])))
-> IO (Maybe (Maybe Range, [Text]))
-> IdeAction (Maybe (Maybe Range, [Text]))
forall a b. (a -> b) -> a -> b
$ ((Maybe Range, [Text]) -> (Maybe Range, [Text]))
-> Maybe (Maybe Range, [Text]) -> Maybe (Maybe Range, [Text])
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((Maybe Range -> Maybe Range)
-> (Maybe Range, [Text]) -> (Maybe Range, [Text])
forall a a' b. (a -> a') -> (a, b) -> (a', b)
first (PositionMapping -> Range -> Maybe Range
toCurrentRange PositionMapping
mapping (Range -> Maybe Range) -> Maybe Range -> Maybe Range
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<<)) (Maybe (Maybe Range, [Text]) -> Maybe (Maybe Range, [Text]))
-> IO (Maybe (Maybe Range, [Text]))
-> IO (Maybe (Maybe Range, [Text]))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IdeOptions
-> HieAstResult
-> DocAndTyThingMap
-> HscEnv
-> Position
-> IO (Maybe (Maybe Range, [Text]))
AtPoint.atPoint IdeOptions
opts HieAstResult
hf DocAndTyThingMap
dkMap HscEnv
env Position
pos'

-- | For each Location, determine if we have the PositionMapping
-- for the correct file. If not, get the correct position mapping
-- and then apply the position mapping to the location.
toCurrentLocations
  :: PositionMapping
  -> NormalizedFilePath
  -> [Location]
  -> IdeAction [Location]
toCurrentLocations :: PositionMapping
-> NormalizedFilePath -> [Location] -> IdeAction [Location]
toCurrentLocations PositionMapping
mapping NormalizedFilePath
file = (Location -> IdeAction (Maybe Location))
-> [Location] -> IdeAction [Location]
forall (m :: * -> *) a b.
Monad m =>
(a -> m (Maybe b)) -> [a] -> m [b]
mapMaybeM Location -> IdeAction (Maybe Location)
go
  where
    go :: Location -> IdeAction (Maybe Location)
    go :: Location -> IdeAction (Maybe Location)
go (Location Uri
uri Range
range) =
      -- The Location we are going to might be in a different
      -- file than the one we are calling gotoDefinition from.
      -- So we check that the location file matches the file
      -- we are in.
      if NormalizedUri
nUri NormalizedUri -> NormalizedUri -> Bool
forall a. Eq a => a -> a -> Bool
== NormalizedFilePath -> NormalizedUri
normalizedFilePathToUri NormalizedFilePath
file
      -- The Location matches the file, so use the PositionMapping
      -- we have.
      then Maybe Location -> IdeAction (Maybe Location)
forall a. a -> IdeAction a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe Location -> IdeAction (Maybe Location))
-> Maybe Location -> IdeAction (Maybe Location)
forall a b. (a -> b) -> a -> b
$ Uri -> Range -> Location
Location Uri
uri (Range -> Location) -> Maybe Range -> Maybe Location
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> PositionMapping -> Range -> Maybe Range
toCurrentRange PositionMapping
mapping Range
range
      -- The Location does not match the file, so get the correct
      -- PositionMapping and use that instead.
      else do
        Maybe PositionMapping
otherLocationMapping <- (Maybe (HieAstResult, PositionMapping) -> Maybe PositionMapping)
-> IdeAction (Maybe (HieAstResult, PositionMapping))
-> IdeAction (Maybe PositionMapping)
forall a b. (a -> b) -> IdeAction a -> IdeAction b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((HieAstResult, PositionMapping) -> PositionMapping)
-> Maybe (HieAstResult, PositionMapping) -> Maybe PositionMapping
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (HieAstResult, PositionMapping) -> PositionMapping
forall a b. (a, b) -> b
snd) (IdeAction (Maybe (HieAstResult, PositionMapping))
 -> IdeAction (Maybe PositionMapping))
-> IdeAction (Maybe (HieAstResult, PositionMapping))
-> IdeAction (Maybe PositionMapping)
forall a b. (a -> b) -> a -> b
$ MaybeT IdeAction (HieAstResult, PositionMapping)
-> IdeAction (Maybe (HieAstResult, PositionMapping))
forall (m :: * -> *) a. MaybeT m a -> m (Maybe a)
runMaybeT (MaybeT IdeAction (HieAstResult, PositionMapping)
 -> IdeAction (Maybe (HieAstResult, PositionMapping)))
-> MaybeT IdeAction (HieAstResult, PositionMapping)
-> IdeAction (Maybe (HieAstResult, PositionMapping))
forall a b. (a -> b) -> a -> b
$ do
          NormalizedFilePath
otherLocationFile <- IdeAction (Maybe NormalizedFilePath)
-> MaybeT IdeAction NormalizedFilePath
forall (m :: * -> *) a. m (Maybe a) -> MaybeT m a
MaybeT (IdeAction (Maybe NormalizedFilePath)
 -> MaybeT IdeAction NormalizedFilePath)
-> IdeAction (Maybe NormalizedFilePath)
-> MaybeT IdeAction NormalizedFilePath
forall a b. (a -> b) -> a -> b
$ Maybe NormalizedFilePath -> IdeAction (Maybe NormalizedFilePath)
forall a. a -> IdeAction a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe NormalizedFilePath -> IdeAction (Maybe NormalizedFilePath))
-> Maybe NormalizedFilePath -> IdeAction (Maybe NormalizedFilePath)
forall a b. (a -> b) -> a -> b
$ NormalizedUri -> Maybe NormalizedFilePath
uriToNormalizedFilePath NormalizedUri
nUri
          GetHieAst
-> NormalizedFilePath
-> MaybeT IdeAction (HieAstResult, PositionMapping)
forall k v.
IdeRule k v =>
k -> NormalizedFilePath -> MaybeT IdeAction (v, PositionMapping)
useWithStaleFastMT GetHieAst
GetHieAst NormalizedFilePath
otherLocationFile
        Maybe Location -> IdeAction (Maybe Location)
forall a. a -> IdeAction a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe Location -> IdeAction (Maybe Location))
-> Maybe Location -> IdeAction (Maybe Location)
forall a b. (a -> b) -> a -> b
$ Uri -> Range -> Location
Location Uri
uri (Range -> Location) -> Maybe Range -> Maybe Location
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ((PositionMapping -> Range -> Maybe Range)
-> Range -> PositionMapping -> Maybe Range
forall a b c. (a -> b -> c) -> b -> a -> c
flip PositionMapping -> Range -> Maybe Range
toCurrentRange Range
range (PositionMapping -> Maybe Range)
-> Maybe PositionMapping -> Maybe Range
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< Maybe PositionMapping
otherLocationMapping)
      where
        nUri :: NormalizedUri
        nUri :: NormalizedUri
nUri = Uri -> NormalizedUri
toNormalizedUri Uri
uri

-- | Goto Definition.
getDefinition :: NormalizedFilePath -> Position -> IdeAction (Maybe [Location])
getDefinition :: NormalizedFilePath -> Position -> IdeAction (Maybe [Location])
getDefinition NormalizedFilePath
file Position
pos = MaybeT IdeAction [Location] -> IdeAction (Maybe [Location])
forall (m :: * -> *) a. MaybeT m a -> m (Maybe a)
runMaybeT (MaybeT IdeAction [Location] -> IdeAction (Maybe [Location]))
-> MaybeT IdeAction [Location] -> IdeAction (Maybe [Location])
forall a b. (a -> b) -> a -> b
$ do
    ide :: ShakeExtras
ide@ShakeExtras{ WithHieDb
withHieDb :: WithHieDb
$sel:withHieDb:ShakeExtras :: ShakeExtras -> WithHieDb
withHieDb, HieDbWriter
hiedbWriter :: HieDbWriter
$sel:hiedbWriter:ShakeExtras :: ShakeExtras -> HieDbWriter
hiedbWriter } <- MaybeT IdeAction ShakeExtras
forall r (m :: * -> *). MonadReader r m => m r
ask
    IdeOptions
opts <- IO IdeOptions -> MaybeT IdeAction IdeOptions
forall a. IO a -> MaybeT IdeAction a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO IdeOptions -> MaybeT IdeAction IdeOptions)
-> IO IdeOptions -> MaybeT IdeAction IdeOptions
forall a b. (a -> b) -> a -> b
$ ShakeExtras -> IO IdeOptions
getIdeOptionsIO ShakeExtras
ide
    (HAR Module
_ HieASTs a
hf RefMap a
_ Map Name [RealSrcSpan]
_ HieKind a
_, PositionMapping
mapping) <- GetHieAst
-> NormalizedFilePath
-> MaybeT IdeAction (HieAstResult, PositionMapping)
forall k v.
IdeRule k v =>
k -> NormalizedFilePath -> MaybeT IdeAction (v, PositionMapping)
useWithStaleFastMT GetHieAst
GetHieAst NormalizedFilePath
file
    (ImportMap Map ModuleName NormalizedFilePath
imports, PositionMapping
_) <- GetImportMap
-> NormalizedFilePath
-> MaybeT IdeAction (ImportMap, PositionMapping)
forall k v.
IdeRule k v =>
k -> NormalizedFilePath -> MaybeT IdeAction (v, PositionMapping)
useWithStaleFastMT GetImportMap
GetImportMap NormalizedFilePath
file
    !Position
pos' <- IdeAction (Maybe Position) -> MaybeT IdeAction Position
forall (m :: * -> *) a. m (Maybe a) -> MaybeT m a
MaybeT (Maybe Position -> IdeAction (Maybe Position)
forall a. a -> IdeAction a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe Position -> IdeAction (Maybe Position))
-> Maybe Position -> IdeAction (Maybe Position)
forall a b. (a -> b) -> a -> b
$ PositionMapping -> Position -> Maybe Position
fromCurrentPosition PositionMapping
mapping Position
pos)
    [Location]
locations <- WithHieDb
-> (FilePath -> ModuleName -> Unit -> Bool -> MaybeT IdeAction Uri)
-> IdeOptions
-> Map ModuleName NormalizedFilePath
-> HieASTs a
-> Position
-> MaybeT IdeAction [Location]
forall (m :: * -> *) a.
MonadIO m =>
WithHieDb
-> LookupModule m
-> IdeOptions
-> Map ModuleName NormalizedFilePath
-> HieASTs a
-> Position
-> MaybeT m [Location]
AtPoint.gotoDefinition (HieDb -> IO a) -> IO a
WithHieDb
withHieDb (HieDbWriter
-> FilePath -> ModuleName -> Unit -> Bool -> MaybeT IdeAction Uri
lookupMod HieDbWriter
hiedbWriter) IdeOptions
opts Map ModuleName NormalizedFilePath
imports HieASTs a
hf Position
pos'
    IdeAction (Maybe [Location]) -> MaybeT IdeAction [Location]
forall (m :: * -> *) a. m (Maybe a) -> MaybeT m a
MaybeT (IdeAction (Maybe [Location]) -> MaybeT IdeAction [Location])
-> IdeAction (Maybe [Location]) -> MaybeT IdeAction [Location]
forall a b. (a -> b) -> a -> b
$ [Location] -> Maybe [Location]
forall a. a -> Maybe a
Just ([Location] -> Maybe [Location])
-> IdeAction [Location] -> IdeAction (Maybe [Location])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> PositionMapping
-> NormalizedFilePath -> [Location] -> IdeAction [Location]
toCurrentLocations PositionMapping
mapping NormalizedFilePath
file [Location]
locations

getTypeDefinition :: NormalizedFilePath -> Position -> IdeAction (Maybe [Location])
getTypeDefinition :: NormalizedFilePath -> Position -> IdeAction (Maybe [Location])
getTypeDefinition NormalizedFilePath
file Position
pos = MaybeT IdeAction [Location] -> IdeAction (Maybe [Location])
forall (m :: * -> *) a. MaybeT m a -> m (Maybe a)
runMaybeT (MaybeT IdeAction [Location] -> IdeAction (Maybe [Location]))
-> MaybeT IdeAction [Location] -> IdeAction (Maybe [Location])
forall a b. (a -> b) -> a -> b
$ do
    ide :: ShakeExtras
ide@ShakeExtras{ WithHieDb
$sel:withHieDb:ShakeExtras :: ShakeExtras -> WithHieDb
withHieDb :: WithHieDb
withHieDb, HieDbWriter
$sel:hiedbWriter:ShakeExtras :: ShakeExtras -> HieDbWriter
hiedbWriter :: HieDbWriter
hiedbWriter } <- MaybeT IdeAction ShakeExtras
forall r (m :: * -> *). MonadReader r m => m r
ask
    IdeOptions
opts <- IO IdeOptions -> MaybeT IdeAction IdeOptions
forall a. IO a -> MaybeT IdeAction a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO IdeOptions -> MaybeT IdeAction IdeOptions)
-> IO IdeOptions -> MaybeT IdeAction IdeOptions
forall a b. (a -> b) -> a -> b
$ ShakeExtras -> IO IdeOptions
getIdeOptionsIO ShakeExtras
ide
    (HieAstResult
hf, PositionMapping
mapping) <- GetHieAst
-> NormalizedFilePath
-> MaybeT IdeAction (HieAstResult, PositionMapping)
forall k v.
IdeRule k v =>
k -> NormalizedFilePath -> MaybeT IdeAction (v, PositionMapping)
useWithStaleFastMT GetHieAst
GetHieAst NormalizedFilePath
file
    !Position
pos' <- IdeAction (Maybe Position) -> MaybeT IdeAction Position
forall (m :: * -> *) a. m (Maybe a) -> MaybeT m a
MaybeT (Maybe Position -> IdeAction (Maybe Position)
forall a. a -> IdeAction a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Position -> IdeAction (Maybe Position))
-> Maybe Position -> IdeAction (Maybe Position)
forall a b. (a -> b) -> a -> b
$ PositionMapping -> Position -> Maybe Position
fromCurrentPosition PositionMapping
mapping Position
pos)
    [Location]
locations <- WithHieDb
-> (FilePath -> ModuleName -> Unit -> Bool -> MaybeT IdeAction Uri)
-> IdeOptions
-> HieAstResult
-> Position
-> MaybeT IdeAction [Location]
forall (m :: * -> *).
MonadIO m =>
WithHieDb
-> LookupModule m
-> IdeOptions
-> HieAstResult
-> Position
-> MaybeT m [Location]
AtPoint.gotoTypeDefinition (HieDb -> IO a) -> IO a
WithHieDb
withHieDb (HieDbWriter
-> FilePath -> ModuleName -> Unit -> Bool -> MaybeT IdeAction Uri
lookupMod HieDbWriter
hiedbWriter) IdeOptions
opts HieAstResult
hf Position
pos'
    IdeAction (Maybe [Location]) -> MaybeT IdeAction [Location]
forall (m :: * -> *) a. m (Maybe a) -> MaybeT m a
MaybeT (IdeAction (Maybe [Location]) -> MaybeT IdeAction [Location])
-> IdeAction (Maybe [Location]) -> MaybeT IdeAction [Location]
forall a b. (a -> b) -> a -> b
$ [Location] -> Maybe [Location]
forall a. a -> Maybe a
Just ([Location] -> Maybe [Location])
-> IdeAction [Location] -> IdeAction (Maybe [Location])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> PositionMapping
-> NormalizedFilePath -> [Location] -> IdeAction [Location]
toCurrentLocations PositionMapping
mapping NormalizedFilePath
file [Location]
locations

highlightAtPoint :: NormalizedFilePath -> Position -> IdeAction (Maybe [DocumentHighlight])
highlightAtPoint :: NormalizedFilePath
-> Position -> IdeAction (Maybe [DocumentHighlight])
highlightAtPoint NormalizedFilePath
file Position
pos = MaybeT IdeAction [DocumentHighlight]
-> IdeAction (Maybe [DocumentHighlight])
forall (m :: * -> *) a. MaybeT m a -> m (Maybe a)
runMaybeT (MaybeT IdeAction [DocumentHighlight]
 -> IdeAction (Maybe [DocumentHighlight]))
-> MaybeT IdeAction [DocumentHighlight]
-> IdeAction (Maybe [DocumentHighlight])
forall a b. (a -> b) -> a -> b
$ do
    (HAR Module
_ HieASTs a
hf RefMap a
rf Map Name [RealSrcSpan]
_ HieKind a
_,PositionMapping
mapping) <- GetHieAst
-> NormalizedFilePath
-> MaybeT IdeAction (HieAstResult, PositionMapping)
forall k v.
IdeRule k v =>
k -> NormalizedFilePath -> MaybeT IdeAction (v, PositionMapping)
useWithStaleFastMT GetHieAst
GetHieAst NormalizedFilePath
file
    !Position
pos' <- IdeAction (Maybe Position) -> MaybeT IdeAction Position
forall (m :: * -> *) a. m (Maybe a) -> MaybeT m a
MaybeT (Maybe Position -> IdeAction (Maybe Position)
forall a. a -> IdeAction a
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Position -> IdeAction (Maybe Position))
-> Maybe Position -> IdeAction (Maybe Position)
forall a b. (a -> b) -> a -> b
$ PositionMapping -> Position -> Maybe Position
fromCurrentPosition PositionMapping
mapping Position
pos)
    let toCurrentHighlight :: DocumentHighlight -> Maybe DocumentHighlight
toCurrentHighlight (DocumentHighlight Range
range Maybe DocumentHighlightKind
t) = (Range -> Maybe DocumentHighlightKind -> DocumentHighlight)
-> Maybe DocumentHighlightKind -> Range -> DocumentHighlight
forall a b c. (a -> b -> c) -> b -> a -> c
flip Range -> Maybe DocumentHighlightKind -> DocumentHighlight
DocumentHighlight Maybe DocumentHighlightKind
t (Range -> DocumentHighlight)
-> Maybe Range -> Maybe DocumentHighlight
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> PositionMapping -> Range -> Maybe Range
toCurrentRange PositionMapping
mapping Range
range
    (DocumentHighlight -> Maybe DocumentHighlight)
-> [DocumentHighlight] -> [DocumentHighlight]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe DocumentHighlight -> Maybe DocumentHighlight
toCurrentHighlight ([DocumentHighlight] -> [DocumentHighlight])
-> MaybeT IdeAction [DocumentHighlight]
-> MaybeT IdeAction [DocumentHighlight]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>HieASTs a
-> RefMap a -> Position -> MaybeT IdeAction [DocumentHighlight]
forall (m :: * -> *) a.
Monad m =>
HieASTs a -> RefMap a -> Position -> MaybeT m [DocumentHighlight]
AtPoint.documentHighlight HieASTs a
hf RefMap a
rf Position
pos'

-- Refs are not an IDE action, so it is OK to be slow and (more) accurate
refsAtPoint :: NormalizedFilePath -> Position -> Action [Location]
refsAtPoint :: NormalizedFilePath -> Position -> Action [Location]
refsAtPoint NormalizedFilePath
file Position
pos = do
    ShakeExtras{WithHieDb
$sel:withHieDb:ShakeExtras :: ShakeExtras -> WithHieDb
withHieDb :: WithHieDb
withHieDb} <- Action ShakeExtras
getShakeExtras
    [NormalizedFilePath]
fs <- HashMap NormalizedFilePath FileOfInterestStatus
-> [NormalizedFilePath]
forall k v. HashMap k v -> [k]
HM.keys (HashMap NormalizedFilePath FileOfInterestStatus
 -> [NormalizedFilePath])
-> Action (HashMap NormalizedFilePath FileOfInterestStatus)
-> Action [NormalizedFilePath]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Action (HashMap NormalizedFilePath FileOfInterestStatus)
getFilesOfInterestUntracked
    HashMap NormalizedFilePath (HieAstResult, PositionMapping)
asts <- [(NormalizedFilePath, (HieAstResult, PositionMapping))]
-> HashMap NormalizedFilePath (HieAstResult, PositionMapping)
forall k v. (Eq k, Hashable k) => [(k, v)] -> HashMap k v
HM.fromList ([(NormalizedFilePath, (HieAstResult, PositionMapping))]
 -> HashMap NormalizedFilePath (HieAstResult, PositionMapping))
-> ([Maybe (HieAstResult, PositionMapping)]
    -> [(NormalizedFilePath, (HieAstResult, PositionMapping))])
-> [Maybe (HieAstResult, PositionMapping)]
-> HashMap NormalizedFilePath (HieAstResult, PositionMapping)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((NormalizedFilePath, Maybe (HieAstResult, PositionMapping))
 -> Maybe (NormalizedFilePath, (HieAstResult, PositionMapping)))
-> [(NormalizedFilePath, Maybe (HieAstResult, PositionMapping))]
-> [(NormalizedFilePath, (HieAstResult, PositionMapping))]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe (NormalizedFilePath, Maybe (HieAstResult, PositionMapping))
-> Maybe (NormalizedFilePath, (HieAstResult, PositionMapping))
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
forall (m :: * -> *) a.
Monad m =>
(NormalizedFilePath, m a) -> m (NormalizedFilePath, a)
sequence ([(NormalizedFilePath, Maybe (HieAstResult, PositionMapping))]
 -> [(NormalizedFilePath, (HieAstResult, PositionMapping))])
-> ([Maybe (HieAstResult, PositionMapping)]
    -> [(NormalizedFilePath, Maybe (HieAstResult, PositionMapping))])
-> [Maybe (HieAstResult, PositionMapping)]
-> [(NormalizedFilePath, (HieAstResult, PositionMapping))]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [NormalizedFilePath]
-> [Maybe (HieAstResult, PositionMapping)]
-> [(NormalizedFilePath, Maybe (HieAstResult, PositionMapping))]
forall a b. [a] -> [b] -> [(a, b)]
zip [NormalizedFilePath]
fs ([Maybe (HieAstResult, PositionMapping)]
 -> HashMap NormalizedFilePath (HieAstResult, PositionMapping))
-> Action [Maybe (HieAstResult, PositionMapping)]
-> Action
     (HashMap NormalizedFilePath (HieAstResult, PositionMapping))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> GetHieAst
-> [NormalizedFilePath]
-> Action [Maybe (HieAstResult, PositionMapping)]
forall (f :: * -> *) k v.
(Traversable f, IdeRule k v) =>
k
-> f NormalizedFilePath -> Action (f (Maybe (v, PositionMapping)))
usesWithStale GetHieAst
GetHieAst [NormalizedFilePath]
fs
    WithHieDb
-> NormalizedFilePath
-> Position
-> FOIReferences
-> Action [Location]
forall (m :: * -> *).
MonadIO m =>
WithHieDb
-> NormalizedFilePath -> Position -> FOIReferences -> m [Location]
AtPoint.referencesAtPoint (HieDb -> IO a) -> IO a
WithHieDb
withHieDb NormalizedFilePath
file Position
pos (HashMap NormalizedFilePath (HieAstResult, PositionMapping)
-> FOIReferences
AtPoint.FOIReferences HashMap NormalizedFilePath (HieAstResult, PositionMapping)
asts)

workspaceSymbols :: T.Text -> IdeAction (Maybe [SymbolInformation])
workspaceSymbols :: Text -> IdeAction (Maybe [SymbolInformation])
workspaceSymbols Text
query = MaybeT IdeAction [SymbolInformation]
-> IdeAction (Maybe [SymbolInformation])
forall (m :: * -> *) a. MaybeT m a -> m (Maybe a)
runMaybeT (MaybeT IdeAction [SymbolInformation]
 -> IdeAction (Maybe [SymbolInformation]))
-> MaybeT IdeAction [SymbolInformation]
-> IdeAction (Maybe [SymbolInformation])
forall a b. (a -> b) -> a -> b
$ do
  ShakeExtras{WithHieDb
$sel:withHieDb:ShakeExtras :: ShakeExtras -> WithHieDb
withHieDb :: WithHieDb
withHieDb} <- MaybeT IdeAction ShakeExtras
forall r (m :: * -> *). MonadReader r m => m r
ask
  [Res DefRow]
res <- IO [Res DefRow] -> MaybeT IdeAction [Res DefRow]
forall a. IO a -> MaybeT IdeAction a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO [Res DefRow] -> MaybeT IdeAction [Res DefRow])
-> IO [Res DefRow] -> MaybeT IdeAction [Res DefRow]
forall a b. (a -> b) -> a -> b
$ (HieDb -> IO [Res DefRow]) -> IO [Res DefRow]
WithHieDb
withHieDb (\HieDb
hieDb -> HieDb -> FilePath -> IO [Res DefRow]
HieDb.searchDef HieDb
hieDb (FilePath -> IO [Res DefRow]) -> FilePath -> IO [Res DefRow]
forall a b. (a -> b) -> a -> b
$ Text -> FilePath
T.unpack Text
query)
  [SymbolInformation] -> MaybeT IdeAction [SymbolInformation]
forall a. a -> MaybeT IdeAction a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([SymbolInformation] -> MaybeT IdeAction [SymbolInformation])
-> [SymbolInformation] -> MaybeT IdeAction [SymbolInformation]
forall a b. (a -> b) -> a -> b
$ (Res DefRow -> Maybe SymbolInformation)
-> [Res DefRow] -> [SymbolInformation]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe Res DefRow -> Maybe SymbolInformation
AtPoint.defRowToSymbolInfo [Res DefRow]
res