Skip to content
This repository was archived by the owner on Oct 7, 2020. It is now read-only.

Commit ab5e0d9

Browse files
committed
Prefer ExcepT over MaybeT
Also add documentation and extract functions
1 parent 2edbc23 commit ab5e0d9

File tree

1 file changed

+49
-51
lines changed

1 file changed

+49
-51
lines changed

src/Haskell/Ide/Engine/Plugin/HieExtras.hs

Lines changed: 49 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,11 @@ import Control.Lens.Prism ( _Just )
3030
import Control.Lens.Setter ((%~))
3131
import Control.Lens.Traversal (traverseOf)
3232
import Control.Monad.Reader
33-
import Control.Monad.Trans.Maybe
33+
import Control.Monad.Except
3434
import Data.Aeson
3535
import qualified Data.Aeson.Types as J
3636
import Data.Char
37-
import qualified Data.Generics as SYB
37+
import qualified Data.Generics as SYB
3838
import Data.IORef
3939
import qualified Data.List as List
4040
import qualified Data.Map as Map
@@ -600,41 +600,29 @@ findTypeDef uri pos = pluginGetFile "findTypeDef: " uri $ \file ->
600600
--
601601
-- Otherwise, searches for the Type of the given position
602602
-- and retrieves its SrcSpan.
603-
getSrcSpanFromPosition :: Maybe Position -> MaybeT IdeDeferM SrcSpan
604-
getSrcSpanFromPosition oldPosition = do
605-
(_, n) <- MaybeT $ return $ symbolFromTypecheckedModule lm =<< oldPosition
606-
t <- MaybeT $ lift $ getTypeForName' tm n
607-
tyCon <- MaybeT $ return $ tyConAppTyCon_maybe t
603+
getSrcSpanFromPosition :: Maybe Position -> ExceptT () IdeDeferM SrcSpan
604+
getSrcSpanFromPosition maybeOldPosition = do
605+
oldPosition <- liftMaybe maybeOldPosition
606+
(_, n) <- liftMaybe $ symbolFromTypecheckedModule lm oldPosition
607+
t <- liftMaybeM (lift $ getTypeForName' tm n)
608+
tyCon <- liftMaybe $ tyConAppTyCon_maybe t
608609
case nameSrcSpan (getName tyCon) of
609-
UnhelpfulSpan _ -> fail "Unhelpful Span" -- this message is never shown
610+
UnhelpfulSpan _ -> throwError ()
610611
realSpan -> return realSpan
611-
612-
runMaybeT (getSrcSpanFromPosition oldPos) >>= \case
613-
Nothing -> return $ IdeResultOk []
614-
Just realSpan -> do
615-
-- Since we found a real SrcSpan, we now translate it
616-
-- to the position in the file
617-
res <- srcSpan2Loc rfm realSpan
618-
case res of
619-
Right l@(J.Location luri range) -> case uriToFilePath luri of
620-
Nothing -> return $ IdeResultOk [l]
621-
Just fp ->
622-
ifCachedModule fp (IdeResultOk [l])
623-
$ \(_ :: ParsedModule) info' ->
624-
case oldRangeToNew info' range of
625-
Just r ->
626-
return $ IdeResultOk [J.Location luri r]
627-
Nothing -> return $ IdeResultOk [l]
628-
Left x -> do
629-
-- SrcSpan does not have a file location!
630-
debugm "findTypeDef: name srcspan not found/valid"
631-
pure
632-
(IdeResultFail
633-
(IdeError PluginError
634-
("hare:findTypeDef" <> ": \"" <> x <> "\"")
635-
Null
636-
)
637-
)
612+
613+
liftMaybe :: Monad m => Maybe a -> ExceptT () m a
614+
liftMaybe val = liftEither $ case val of
615+
Nothing -> Left ()
616+
Just s -> Right s
617+
618+
liftMaybeM :: Monad m => m (Maybe a) -> ExceptT () m a
619+
liftMaybeM mval = do
620+
val <- lift mval
621+
liftMaybe val
622+
623+
runExceptT (getSrcSpanFromPosition oldPos) >>= \case
624+
Left () -> return $ IdeResultOk []
625+
Right realSpan -> lift $ srcSpanToFileLocation "hare:findTypeDef" rfm realSpan
638626
)
639627

640628
-- | Return the definition
@@ -653,23 +641,33 @@ findDef uri pos = pluginGetFile "findDef: " uri $ \file ->
653641
Just (_, n) ->
654642
case nameSrcSpan n of
655643
UnhelpfulSpan _ -> return $ IdeResultOk []
656-
realSpan -> do
657-
res <- srcSpan2Loc rfm realSpan
658-
case res of
659-
Right l@(J.Location luri range) ->
660-
case uriToFilePath luri of
661-
Nothing -> return $ IdeResultOk [l]
662-
Just fp -> ifCachedModule fp (IdeResultOk [l]) $ \(_ :: ParsedModule) info' ->
663-
case oldRangeToNew info' range of
664-
Just r -> return $ IdeResultOk [J.Location luri r]
665-
Nothing -> return $ IdeResultOk [l]
666-
Left x -> do
667-
debugm "findDef: name srcspan not found/valid"
668-
pure (IdeResultFail
669-
(IdeError PluginError
670-
("hare:findDef" <> ": \"" <> x <> "\"")
671-
Null)))
644+
realSpan -> lift $ srcSpanToFileLocation "hare:findDef" rfm realSpan
645+
)
672646

647+
-- | Resolve the given SrcSpan to a Location in a file.
648+
-- Takes the name of the invoking function for error display.
649+
--
650+
-- If the SrcSpan can not be resolved, an error will be returned.
651+
srcSpanToFileLocation :: T.Text -> (FilePath -> FilePath) -> SrcSpan -> IdeM (IdeResult [Location])
652+
srcSpanToFileLocation invoker rfm srcSpan = do
653+
-- Since we found a real SrcSpan, try to map it to real files
654+
res <- srcSpan2Loc rfm srcSpan
655+
case res of
656+
Right l@(J.Location luri range) ->
657+
case uriToFilePath luri of
658+
Nothing -> return $ IdeResultOk [l]
659+
Just fp -> ifCachedModule fp (IdeResultOk [l]) $ \(_ :: ParsedModule) info' ->
660+
case oldRangeToNew info' range of
661+
Just r -> return $ IdeResultOk [J.Location luri r]
662+
Nothing -> return $ IdeResultOk [l]
663+
Left x -> do
664+
debugm (T.unpack invoker <> ": name srcspan not found/valid")
665+
pure (IdeResultFail
666+
(IdeError PluginError
667+
(invoker <> ": \"" <> x <> "\"")
668+
Null))
669+
670+
-- | Goto given module.
673671
gotoModule :: (FilePath -> FilePath) -> ModuleName -> IdeDeferM (IdeResult [Location])
674672
gotoModule rfm mn = do
675673
hscEnvRef <- ghcSession <$> readMTS

0 commit comments

Comments
 (0)