{-# LANGUAGE CPP                   #-}

{-# LANGUAGE DuplicateRecordFields #-}
{-# LANGUAGE GADTs                 #-}
{-# LANGUAGE RankNTypes            #-}

module Development.IDE.LSP.Outline
  ( moduleOutline
  )
where

import           Control.Monad.IO.Class
import           Data.Functor
import           Data.Generics                  hiding (Prefix)
import           Data.Maybe
import           Development.IDE.Core.Rules
import           Development.IDE.Core.Shake
import           Development.IDE.GHC.Compat
import           Development.IDE.GHC.Error      (rangeToRealSrcSpan,
                                                 realSrcSpanToRange)
import           Development.IDE.Types.Location
import           Development.IDE.GHC.Util       (printOutputable)
import           Ide.Types
import           Language.LSP.Protocol.Types             (DocumentSymbol (..),
                                                 DocumentSymbolParams (DocumentSymbolParams, _textDocument),
                                                 SymbolKind (..),
                                                 TextDocumentIdentifier (TextDocumentIdentifier),
                                                 type (|?) (InL, InR), uriToFilePath)
import          Language.LSP.Protocol.Message

-- See Note [Guidelines For Using CPP In GHCIDE Import Statements]

#if MIN_VERSION_ghc(9,2,0)
import           Data.List.NonEmpty             (nonEmpty)
import           Data.Foldable                  (toList)
#endif

#if !MIN_VERSION_ghc(9,3,0)
import qualified Data.Text                      as T
#endif

moduleOutline
  :: PluginMethodHandler IdeState Method_TextDocumentDocumentSymbol
moduleOutline :: PluginMethodHandler IdeState 'Method_TextDocumentDocumentSymbol
moduleOutline IdeState
ideState PluginId
_ DocumentSymbolParams{ $sel:_textDocument:DocumentSymbolParams :: DocumentSymbolParams -> TextDocumentIdentifier
_textDocument = TextDocumentIdentifier Uri
uri }
  = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ case Uri -> Maybe FilePath
uriToFilePath Uri
uri of
    Just (FilePath -> NormalizedFilePath
toNormalizedFilePath' -> NormalizedFilePath
fp) -> do
      Maybe ParsedModule
mb_decls <- forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a b. (a, b) -> a
fst forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. FilePath -> IdeState -> Action a -> IO a
runAction FilePath
"Outline" IdeState
ideState (forall k v.
IdeRule k v =>
k -> NormalizedFilePath -> Action (Maybe (v, PositionMapping))
useWithStale GetParsedModule
GetParsedModule NormalizedFilePath
fp)
      forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ case Maybe ParsedModule
mb_decls of
        Maybe ParsedModule
Nothing -> forall a b. a -> a |? b
InL []
        Just ParsedModule { pm_parsed_source :: ParsedModule -> ParsedSource
pm_parsed_source = L SrcSpan
_ltop HsModule { Maybe (GenLocated SrcSpanAnnA ModuleName)
hsmodName :: HsModule -> Maybe (GenLocated SrcSpanAnnA ModuleName)
hsmodName :: Maybe (GenLocated SrcSpanAnnA ModuleName)
hsmodName, [LHsDecl GhcPs]
hsmodDecls :: HsModule -> [LHsDecl GhcPs]
hsmodDecls :: [LHsDecl GhcPs]
hsmodDecls, [LImportDecl GhcPs]
hsmodImports :: HsModule -> [LImportDecl GhcPs]
hsmodImports :: [LImportDecl GhcPs]
hsmodImports } }
          -> let
               declSymbols :: [DocumentSymbol]
declSymbols  = forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe LHsDecl GhcPs -> Maybe DocumentSymbol
documentSymbolForDecl [LHsDecl GhcPs]
hsmodDecls
               moduleSymbol :: Maybe DocumentSymbol
moduleSymbol = Maybe (GenLocated SrcSpanAnnA ModuleName)
hsmodName forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
                 (L (forall a. SrcSpanAnn' a -> SrcSpan
locA -> (RealSrcSpan RealSrcSpan
l Maybe BufSpan
_)) ModuleName
m) -> forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$
                   (RealSrcSpan -> DocumentSymbol
defDocumentSymbol RealSrcSpan
l :: DocumentSymbol)
                     { $sel:_name:DocumentSymbol :: Text
_name  = forall a. Outputable a => a -> Text
printOutputable ModuleName
m
                     , $sel:_kind:DocumentSymbol :: SymbolKind
_kind  = SymbolKind
SymbolKind_File
                     , $sel:_range:DocumentSymbol :: Range
_range = Position -> Position -> Range
Range (UInt -> UInt -> Position
Position UInt
0 UInt
0) (UInt -> UInt -> Position
Position forall a. Bounded a => a
maxBound UInt
0) -- _ltop is 0 0 0 0
                     }
                 GenLocated SrcSpanAnnA ModuleName
_ -> forall a. Maybe a
Nothing
               importSymbols :: [DocumentSymbol]
importSymbols = forall b a. b -> (a -> b) -> Maybe a -> b
maybe [] forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$
                  [DocumentSymbol] -> Maybe DocumentSymbol
documentSymbolForImportSummary
                    (forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe LImportDecl GhcPs -> Maybe DocumentSymbol
documentSymbolForImport [LImportDecl GhcPs]
hsmodImports)
               allSymbols :: [DocumentSymbol]
allSymbols    = case Maybe DocumentSymbol
moduleSymbol of
                 Maybe DocumentSymbol
Nothing -> [DocumentSymbol]
importSymbols forall a. Semigroup a => a -> a -> a
<> [DocumentSymbol]
declSymbols
                 Just DocumentSymbol
x ->
                   [ DocumentSymbol
x { $sel:_children:DocumentSymbol :: Maybe [DocumentSymbol]
_children = forall a. a -> Maybe a
Just ([DocumentSymbol]
importSymbols forall a. Semigroup a => a -> a -> a
<> [DocumentSymbol]
declSymbols)
                       }
                   ]
             in
               forall a b. b -> a |? b
InR (forall a b. a -> a |? b
InL [DocumentSymbol]
allSymbols)


    Maybe FilePath
Nothing -> forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a b. a -> a |? b
InL []

documentSymbolForDecl :: LHsDecl GhcPs -> Maybe DocumentSymbol
documentSymbolForDecl :: LHsDecl GhcPs -> Maybe DocumentSymbol
documentSymbolForDecl (L (forall a. SrcSpanAnn' a -> SrcSpan
locA -> (RealSrcSpan RealSrcSpan
l Maybe BufSpan
_)) (TyClD XTyClD GhcPs
_ FamDecl { tcdFam :: forall pass. TyClDecl pass -> FamilyDecl pass
tcdFam = FamilyDecl { fdLName :: forall pass. FamilyDecl pass -> LIdP pass
fdLName = L SrcSpanAnnN
_ RdrName
n, FamilyInfo GhcPs
fdInfo :: forall pass. FamilyDecl pass -> FamilyInfo pass
fdInfo :: FamilyInfo GhcPs
fdInfo, LHsQTyVars GhcPs
fdTyVars :: forall pass. FamilyDecl pass -> LHsQTyVars pass
fdTyVars :: LHsQTyVars GhcPs
fdTyVars } }))
  = forall a. a -> Maybe a
Just (RealSrcSpan -> DocumentSymbol
defDocumentSymbol RealSrcSpan
l :: DocumentSymbol)
    { $sel:_name:DocumentSymbol :: Text
_name   = forall a. Outputable a => a -> Text
printOutputable RdrName
n
                  forall a. Semigroup a => a -> a -> a
<> (case forall a. Outputable a => a -> Text
printOutputable LHsQTyVars GhcPs
fdTyVars of
                       Text
"" -> Text
""
                       Text
t  -> Text
" " forall a. Semigroup a => a -> a -> a
<> Text
t
                     )
    , $sel:_detail:DocumentSymbol :: Maybe Text
_detail = forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. Outputable a => a -> Text
printOutputable FamilyInfo GhcPs
fdInfo
    , $sel:_kind:DocumentSymbol :: SymbolKind
_kind   = SymbolKind
SymbolKind_Function
    }
documentSymbolForDecl (L (forall a. SrcSpanAnn' a -> SrcSpan
locA -> (RealSrcSpan RealSrcSpan
l Maybe BufSpan
_)) (TyClD XTyClD GhcPs
_ ClassDecl { tcdLName :: forall pass. TyClDecl pass -> LIdP pass
tcdLName = L SrcSpanAnnN
_ RdrName
name, [LSig GhcPs]
tcdSigs :: forall pass. TyClDecl pass -> [LSig pass]
tcdSigs :: [LSig GhcPs]
tcdSigs, LHsQTyVars GhcPs
tcdTyVars :: forall pass. TyClDecl pass -> LHsQTyVars pass
tcdTyVars :: LHsQTyVars GhcPs
tcdTyVars }))
  = forall a. a -> Maybe a
Just (RealSrcSpan -> DocumentSymbol
defDocumentSymbol RealSrcSpan
l :: DocumentSymbol)
    { $sel:_name:DocumentSymbol :: Text
_name     = forall a. Outputable a => a -> Text
printOutputable RdrName
name
                    forall a. Semigroup a => a -> a -> a
<> (case forall a. Outputable a => a -> Text
printOutputable LHsQTyVars GhcPs
tcdTyVars of
                         Text
"" -> Text
""
                         Text
t  -> Text
" " forall a. Semigroup a => a -> a -> a
<> Text
t
                       )
    , $sel:_kind:DocumentSymbol :: SymbolKind
_kind     = SymbolKind
SymbolKind_Interface
    , $sel:_detail:DocumentSymbol :: Maybe Text
_detail   = forall a. a -> Maybe a
Just Text
"class"
    , $sel:_children:DocumentSymbol :: Maybe [DocumentSymbol]
_children =
      forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$
        [ (RealSrcSpan -> DocumentSymbol
defDocumentSymbol RealSrcSpan
l' :: DocumentSymbol)
            { $sel:_name:DocumentSymbol :: Text
_name           = forall a. Outputable a => a -> Text
printOutputable RdrName
n
            , $sel:_kind:DocumentSymbol :: SymbolKind
_kind           = SymbolKind
SymbolKind_Method
            , $sel:_selectionRange:DocumentSymbol :: Range
_selectionRange = RealSrcSpan -> Range
realSrcSpanToRange RealSrcSpan
l''
            }
        | L (forall a. SrcSpanAnn' a -> SrcSpan
locA -> (RealSrcSpan RealSrcSpan
l' Maybe BufSpan
_))  (ClassOpSig XClassOpSig GhcPs
_ Bool
False [LIdP GhcPs]
names LHsSigType GhcPs
_) <- [LSig GhcPs]
tcdSigs
        , L (forall a. SrcSpanAnn' a -> SrcSpan
locA -> (RealSrcSpan RealSrcSpan
l'' Maybe BufSpan
_)) RdrName
n                            <- [LIdP GhcPs]
names
        ]
    }
documentSymbolForDecl (L (forall a. SrcSpanAnn' a -> SrcSpan
locA -> (RealSrcSpan RealSrcSpan
l Maybe BufSpan
_)) (TyClD XTyClD GhcPs
_ DataDecl { tcdLName :: forall pass. TyClDecl pass -> LIdP pass
tcdLName = L SrcSpanAnnN
_ RdrName
name, tcdDataDefn :: forall pass. TyClDecl pass -> HsDataDefn pass
tcdDataDefn = HsDataDefn { [LConDecl GhcPs]
dd_cons :: forall pass. HsDataDefn pass -> [LConDecl pass]
dd_cons :: [LConDecl GhcPs]
dd_cons } }))
  = forall a. a -> Maybe a
Just (RealSrcSpan -> DocumentSymbol
defDocumentSymbol RealSrcSpan
l :: DocumentSymbol)
    { $sel:_name:DocumentSymbol :: Text
_name     = forall a. Outputable a => a -> Text
printOutputable RdrName
name
    , $sel:_kind:DocumentSymbol :: SymbolKind
_kind     = SymbolKind
SymbolKind_Struct
    , $sel:_children:DocumentSymbol :: Maybe [DocumentSymbol]
_children =
      forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$
#if MIN_VERSION_ghc(9,2,0)
          [ (RealSrcSpan -> DocumentSymbol
defDocumentSymbol RealSrcSpan
l'' :: DocumentSymbol)
            { $sel:_name:DocumentSymbol :: Text
_name           = forall a. Outputable a => a -> Text
printOutputable RdrName
n
            , $sel:_kind:DocumentSymbol :: SymbolKind
_kind           = SymbolKind
SymbolKind_Constructor
            , $sel:_selectionRange:DocumentSymbol :: Range
_selectionRange = RealSrcSpan -> Range
realSrcSpanToRange RealSrcSpan
l'
            , $sel:_children:DocumentSymbol :: Maybe [DocumentSymbol]
_children       = forall (t :: * -> *) a. Foldable t => t a -> [a]
toList forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> forall a. [a] -> Maybe (NonEmpty a)
nonEmpty [DocumentSymbol]
childs
            }
        | GenLocated SrcSpanAnnA (ConDecl GhcPs)
con <- forall {a}. a -> a
extract_cons [LConDecl GhcPs]
dd_cons
        , let ([LIdP GhcPs]
cs, [LFieldOcc GhcPs]
flds) = LConDecl GhcPs -> ([LIdP GhcPs], [LFieldOcc GhcPs])
hsConDeclsBinders GenLocated SrcSpanAnnA (ConDecl GhcPs)
con
        , let childs :: [DocumentSymbol]
childs = forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe LFieldOcc GhcPs -> Maybe DocumentSymbol
cvtFld [LFieldOcc GhcPs]
flds
        , L (forall a. SrcSpanAnn' a -> SrcSpan
locA -> RealSrcSpan RealSrcSpan
l' Maybe BufSpan
_) RdrName
n <- [LIdP GhcPs]
cs
        , let l'' :: RealSrcSpan
l'' = case GenLocated SrcSpanAnnA (ConDecl GhcPs)
con of
                L (forall a. SrcSpanAnn' a -> SrcSpan
locA -> RealSrcSpan RealSrcSpan
l''' Maybe BufSpan
_) ConDecl GhcPs
_ -> RealSrcSpan
l'''
                GenLocated SrcSpanAnnA (ConDecl GhcPs)
_ -> RealSrcSpan
l'
        ]
    }
  where
    cvtFld :: LFieldOcc GhcPs -> Maybe DocumentSymbol
#if MIN_VERSION_ghc(9,3,0)
    cvtFld (L (locA -> RealSrcSpan l' _) n) = Just $ (defDocumentSymbol l' :: DocumentSymbol)
#else
    cvtFld :: LFieldOcc GhcPs -> Maybe DocumentSymbol
cvtFld (L (RealSrcSpan RealSrcSpan
l' Maybe BufSpan
_) FieldOcc GhcPs
n) = forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ (RealSrcSpan -> DocumentSymbol
defDocumentSymbol RealSrcSpan
l' :: DocumentSymbol)
#endif
#if MIN_VERSION_ghc(9,3,0)
                { _name = printOutputable (unLoc (foLabel n))
#else
                { $sel:_name:DocumentSymbol :: Text
_name = forall a. Outputable a => a -> Text
printOutputable (forall l e. GenLocated l e -> e
unLoc (forall pass. FieldOcc pass -> GenLocated SrcSpanAnnN RdrName
rdrNameFieldOcc FieldOcc GhcPs
n))
#endif
                , $sel:_kind:DocumentSymbol :: SymbolKind
_kind = SymbolKind
SymbolKind_Field
                }
    cvtFld LFieldOcc GhcPs
_  = forall a. Maybe a
Nothing
#else
          [ (defDocumentSymbol l'' :: DocumentSymbol)
            { _name           = printOutputable n
            , _kind           = SymbolKind_Constructor
            , _selectionRange = realSrcSpanToRange l'
           , _children       = conArgRecordFields (con_args x)
            }
        | L (locA -> (RealSrcSpan l'' _ )) x <- dd_cons
        , L (locA -> (RealSrcSpan l' _)) n <- getConNames' x
        ]
    }
  where
    -- | Extract the record fields of a constructor
    conArgRecordFields (RecCon (L _ lcdfs)) = Just
      [ (defDocumentSymbol l' :: DocumentSymbol)
          { _name = printOutputable n
          , _kind = SymbolKind_Field
          }
      | L _ cdf <- lcdfs
      , L (locA -> (RealSrcSpan l' _)) n <- rdrNameFieldOcc . unLoc <$> cd_fld_names cdf
      ]
    conArgRecordFields _ = Nothing
#endif
documentSymbolForDecl (L (forall a. SrcSpanAnn' a -> SrcSpan
locA -> (RealSrcSpan RealSrcSpan
l Maybe BufSpan
_)) (TyClD XTyClD GhcPs
_ SynDecl { tcdLName :: forall pass. TyClDecl pass -> LIdP pass
tcdLName = L (forall a. SrcSpanAnn' a -> SrcSpan
locA -> (RealSrcSpan RealSrcSpan
l' Maybe BufSpan
_)) RdrName
n })) = forall a. a -> Maybe a
Just
  (RealSrcSpan -> DocumentSymbol
defDocumentSymbol RealSrcSpan
l :: DocumentSymbol) { $sel:_name:DocumentSymbol :: Text
_name           = forall a. Outputable a => a -> Text
printOutputable RdrName
n
                                          , $sel:_kind:DocumentSymbol :: SymbolKind
_kind           = SymbolKind
SymbolKind_TypeParameter
                                          , $sel:_selectionRange:DocumentSymbol :: Range
_selectionRange = RealSrcSpan -> Range
realSrcSpanToRange RealSrcSpan
l'
                                          }
documentSymbolForDecl (L (forall a. SrcSpanAnn' a -> SrcSpan
locA -> (RealSrcSpan RealSrcSpan
l Maybe BufSpan
_)) (InstD XInstD GhcPs
_ ClsInstD { cid_inst :: forall pass. InstDecl pass -> ClsInstDecl pass
cid_inst = ClsInstDecl { LHsSigType GhcPs
cid_poly_ty :: forall pass. ClsInstDecl pass -> LHsSigType pass
cid_poly_ty :: LHsSigType GhcPs
cid_poly_ty } }))
  = forall a. a -> Maybe a
Just (RealSrcSpan -> DocumentSymbol
defDocumentSymbol RealSrcSpan
l :: DocumentSymbol) { $sel:_name:DocumentSymbol :: Text
_name = forall a. Outputable a => a -> Text
printOutputable LHsSigType GhcPs
cid_poly_ty
                                                 , $sel:_kind:DocumentSymbol :: SymbolKind
_kind = SymbolKind
SymbolKind_Interface
                                                 }
#if MIN_VERSION_ghc(9,2,0)
documentSymbolForDecl (L (forall a. SrcSpanAnn' a -> SrcSpan
locA -> (RealSrcSpan RealSrcSpan
l Maybe BufSpan
_)) (InstD XInstD GhcPs
_ DataFamInstD { dfid_inst :: forall pass. InstDecl pass -> DataFamInstDecl pass
dfid_inst = DataFamInstDecl FamEqn { LIdP GhcPs
feqn_tycon :: forall pass rhs. FamEqn pass rhs -> LIdP pass
feqn_tycon :: LIdP GhcPs
feqn_tycon, HsTyPats GhcPs
feqn_pats :: forall pass rhs. FamEqn pass rhs -> HsTyPats pass
feqn_pats :: HsTyPats GhcPs
feqn_pats } }))
#else
documentSymbolForDecl (L (RealSrcSpan l _) (InstD _ DataFamInstD { dfid_inst = DataFamInstDecl HsIB { hsib_body = FamEqn { feqn_tycon, feqn_pats } } }))
#endif
  = forall a. a -> Maybe a
Just (RealSrcSpan -> DocumentSymbol
defDocumentSymbol RealSrcSpan
l :: DocumentSymbol)
    { $sel:_name:DocumentSymbol :: Text
_name =
#if MIN_VERSION_ghc(9,3,0)
        printOutputable $ pprHsArgsApp (unLoc feqn_tycon) Prefix (feqn_pats)
#else
        forall a. Outputable a => a -> Text
printOutputable (forall l e. GenLocated l e -> e
unLoc LIdP GhcPs
feqn_tycon) forall a. Semigroup a => a -> a -> a
<> Text
" " forall a. Semigroup a => a -> a -> a
<> [Text] -> Text
T.unwords
                (forall a b. (a -> b) -> [a] -> [b]
map forall a. Outputable a => a -> Text
printOutputable HsTyPats GhcPs
feqn_pats)
#endif
    , $sel:_kind:DocumentSymbol :: SymbolKind
_kind = SymbolKind
SymbolKind_Interface
    }
#if MIN_VERSION_ghc(9,2,0)
documentSymbolForDecl (L (forall a. SrcSpanAnn' a -> SrcSpan
locA -> (RealSrcSpan RealSrcSpan
l Maybe BufSpan
_)) (InstD XInstD GhcPs
_ TyFamInstD { tfid_inst :: forall pass. InstDecl pass -> TyFamInstDecl pass
tfid_inst = TyFamInstDecl XCTyFamInstDecl GhcPs
_ FamEqn { LIdP GhcPs
feqn_tycon :: LIdP GhcPs
feqn_tycon :: forall pass rhs. FamEqn pass rhs -> LIdP pass
feqn_tycon, HsTyPats GhcPs
feqn_pats :: HsTyPats GhcPs
feqn_pats :: forall pass rhs. FamEqn pass rhs -> HsTyPats pass
feqn_pats } }))
#else
documentSymbolForDecl (L (RealSrcSpan l _) (InstD _ TyFamInstD { tfid_inst = TyFamInstDecl HsIB { hsib_body = FamEqn { feqn_tycon, feqn_pats } } }))
#endif
  = forall a. a -> Maybe a
Just (RealSrcSpan -> DocumentSymbol
defDocumentSymbol RealSrcSpan
l :: DocumentSymbol)
    { $sel:_name:DocumentSymbol :: Text
_name =
#if MIN_VERSION_ghc(9,3,0)
        printOutputable $ pprHsArgsApp (unLoc feqn_tycon) Prefix (feqn_pats)
#else
        forall a. Outputable a => a -> Text
printOutputable (forall l e. GenLocated l e -> e
unLoc LIdP GhcPs
feqn_tycon) forall a. Semigroup a => a -> a -> a
<> Text
" " forall a. Semigroup a => a -> a -> a
<> [Text] -> Text
T.unwords
                (forall a b. (a -> b) -> [a] -> [b]
map forall a. Outputable a => a -> Text
printOutputable HsTyPats GhcPs
feqn_pats)
#endif
    , $sel:_kind:DocumentSymbol :: SymbolKind
_kind = SymbolKind
SymbolKind_Interface
    }
documentSymbolForDecl (L (forall a. SrcSpanAnn' a -> SrcSpan
locA -> (RealSrcSpan RealSrcSpan
l Maybe BufSpan
_)) (DerivD XDerivD GhcPs
_ DerivDecl { LHsSigWcType GhcPs
deriv_type :: forall pass. DerivDecl pass -> LHsSigWcType pass
deriv_type :: LHsSigWcType GhcPs
deriv_type })) =
  forall x y. (Data x, Typeable y) => x -> Maybe y
gfindtype LHsSigWcType GhcPs
deriv_type forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \(L (SrcSpan
_ :: SrcSpan) HsType GhcPs
name) ->
    (RealSrcSpan -> DocumentSymbol
defDocumentSymbol RealSrcSpan
l :: DocumentSymbol) { $sel:_name:DocumentSymbol :: Text
_name = forall a. Outputable a => a -> Text
printOutputable @(HsType GhcPs)
                                              HsType GhcPs
name
                                            , $sel:_kind:DocumentSymbol :: SymbolKind
_kind = SymbolKind
SymbolKind_Interface
                                            }
documentSymbolForDecl (L (forall a. SrcSpanAnn' a -> SrcSpan
locA -> (RealSrcSpan RealSrcSpan
l Maybe BufSpan
_)) (ValD XValD GhcPs
_ FunBind{fun_id :: forall idL idR. HsBindLR idL idR -> LIdP idL
fun_id = L SrcSpanAnnN
_ RdrName
name})) = forall a. a -> Maybe a
Just
    (RealSrcSpan -> DocumentSymbol
defDocumentSymbol RealSrcSpan
l :: DocumentSymbol)
      { $sel:_name:DocumentSymbol :: Text
_name   = forall a. Outputable a => a -> Text
printOutputable RdrName
name
      , $sel:_kind:DocumentSymbol :: SymbolKind
_kind   = SymbolKind
SymbolKind_Function
      }
documentSymbolForDecl (L (forall a. SrcSpanAnn' a -> SrcSpan
locA -> (RealSrcSpan RealSrcSpan
l Maybe BufSpan
_)) (ValD XValD GhcPs
_ PatBind{LPat GhcPs
pat_lhs :: forall idL idR. HsBindLR idL idR -> LPat idL
pat_lhs :: LPat GhcPs
pat_lhs})) = forall a. a -> Maybe a
Just
    (RealSrcSpan -> DocumentSymbol
defDocumentSymbol RealSrcSpan
l :: DocumentSymbol)
      { $sel:_name:DocumentSymbol :: Text
_name   = forall a. Outputable a => a -> Text
printOutputable LPat GhcPs
pat_lhs
      , $sel:_kind:DocumentSymbol :: SymbolKind
_kind   = SymbolKind
SymbolKind_Function
      }

documentSymbolForDecl (L (forall a. SrcSpanAnn' a -> SrcSpan
locA -> (RealSrcSpan RealSrcSpan
l Maybe BufSpan
_)) (ForD XForD GhcPs
_ ForeignDecl GhcPs
x)) = forall a. a -> Maybe a
Just
  (RealSrcSpan -> DocumentSymbol
defDocumentSymbol RealSrcSpan
l :: DocumentSymbol)
    { $sel:_name:DocumentSymbol :: Text
_name   = case ForeignDecl GhcPs
x of
                  ForeignImport{} -> Text
name
                  ForeignExport{} -> Text
name
                  XForeignDecl{}  -> Text
"?"
    , $sel:_kind:DocumentSymbol :: SymbolKind
_kind   = SymbolKind
SymbolKind_Object
    , $sel:_detail:DocumentSymbol :: Maybe Text
_detail = case ForeignDecl GhcPs
x of
                  ForeignImport{} -> forall a. a -> Maybe a
Just Text
"import"
                  ForeignExport{} -> forall a. a -> Maybe a
Just Text
"export"
                  XForeignDecl{}  -> forall a. Maybe a
Nothing
    }
  where name :: Text
name = forall a. Outputable a => a -> Text
printOutputable forall a b. (a -> b) -> a -> b
$ forall l e. GenLocated l e -> e
unLoc forall a b. (a -> b) -> a -> b
$ forall pass. ForeignDecl pass -> LIdP pass
fd_name ForeignDecl GhcPs
x

documentSymbolForDecl LHsDecl GhcPs
_ = forall a. Maybe a
Nothing

-- | Wrap the Document imports into a hierarchical outline for
-- a better overview of symbols in scope.
-- If there are no imports, then no hierarchy will be created.
documentSymbolForImportSummary :: [DocumentSymbol] -> Maybe DocumentSymbol
documentSymbolForImportSummary :: [DocumentSymbol] -> Maybe DocumentSymbol
documentSymbolForImportSummary [] = forall a. Maybe a
Nothing
documentSymbolForImportSummary [DocumentSymbol]
importSymbols =
    let
      -- safe because if we have no ranges then we don't take this branch
      mergeRanges :: [Range] -> Range
mergeRanges [Range]
xs = Position -> Position -> Range
Range (forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
minimum forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map Range -> Position
_start [Range]
xs) (forall (t :: * -> *) a. (Foldable t, Ord a) => t a -> a
maximum forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map Range -> Position
_end [Range]
xs)
      importRange :: Range
importRange = [Range] -> Range
mergeRanges forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (\DocumentSymbol{Range
_range :: Range
$sel:_range:DocumentSymbol :: DocumentSymbol -> Range
_range} -> Range
_range) [DocumentSymbol]
importSymbols
    in
      forall a. a -> Maybe a
Just (RealSrcSpan -> DocumentSymbol
defDocumentSymbol (NormalizedFilePath -> Range -> RealSrcSpan
rangeToRealSrcSpan NormalizedFilePath
"" Range
importRange))
          { $sel:_name:DocumentSymbol :: Text
_name = Text
"imports"
          , $sel:_kind:DocumentSymbol :: SymbolKind
_kind = SymbolKind
SymbolKind_Module
          , $sel:_children:DocumentSymbol :: Maybe [DocumentSymbol]
_children = forall a. a -> Maybe a
Just [DocumentSymbol]
importSymbols
          }

documentSymbolForImport :: LImportDecl GhcPs -> Maybe DocumentSymbol
documentSymbolForImport :: LImportDecl GhcPs -> Maybe DocumentSymbol
documentSymbolForImport (L (forall a. SrcSpanAnn' a -> SrcSpan
locA -> (RealSrcSpan RealSrcSpan
l Maybe BufSpan
_)) ImportDecl { XRec GhcPs ModuleName
ideclName :: forall pass. ImportDecl pass -> XRec pass ModuleName
ideclName :: XRec GhcPs ModuleName
ideclName, ImportDeclQualifiedStyle
ideclQualified :: forall pass. ImportDecl pass -> ImportDeclQualifiedStyle
ideclQualified :: ImportDeclQualifiedStyle
ideclQualified }) = forall a. a -> Maybe a
Just
  (RealSrcSpan -> DocumentSymbol
defDocumentSymbol RealSrcSpan
l :: DocumentSymbol)
    { $sel:_name:DocumentSymbol :: Text
_name   = Text
"import " forall a. Semigroup a => a -> a -> a
<> forall a. Outputable a => a -> Text
printOutputable XRec GhcPs ModuleName
ideclName
    , $sel:_kind:DocumentSymbol :: SymbolKind
_kind   = SymbolKind
SymbolKind_Module
    , $sel:_detail:DocumentSymbol :: Maybe Text
_detail = case ImportDeclQualifiedStyle
ideclQualified of { ImportDeclQualifiedStyle
NotQualified -> forall a. Maybe a
Nothing; ImportDeclQualifiedStyle
_ -> forall a. a -> Maybe a
Just Text
"qualified" }
    }
documentSymbolForImport LImportDecl GhcPs
_ = forall a. Maybe a
Nothing

defDocumentSymbol :: RealSrcSpan -> DocumentSymbol
defDocumentSymbol :: RealSrcSpan -> DocumentSymbol
defDocumentSymbol RealSrcSpan
l = DocumentSymbol { Text
Range
SymbolKind
forall a. Maybe a
$sel:_tags:DocumentSymbol :: Maybe [SymbolTag]
$sel:_deprecated:DocumentSymbol :: Maybe Bool
_tags :: forall a. Maybe a
_children :: forall a. Maybe a
_selectionRange :: Range
_range :: Range
_kind :: SymbolKind
_name :: Text
_deprecated :: forall a. Maybe a
_detail :: forall a. Maybe a
$sel:_selectionRange:DocumentSymbol :: Range
$sel:_detail:DocumentSymbol :: Maybe Text
$sel:_children:DocumentSymbol :: Maybe [DocumentSymbol]
$sel:_range:DocumentSymbol :: Range
$sel:_kind:DocumentSymbol :: SymbolKind
$sel:_name:DocumentSymbol :: Text
.. } where
  _detail :: Maybe a
_detail         = forall a. Maybe a
Nothing
  _deprecated :: Maybe a
_deprecated     = forall a. Maybe a
Nothing
  _name :: Text
_name           = Text
""
  -- This used to be SkUnknown 0, which is invalid, as SymbolKinds start at 1,
  -- therefore, I am replacing it with SymbolKind_File, which is the type for 1
  _kind :: SymbolKind
_kind           = SymbolKind
SymbolKind_File
  _range :: Range
_range          = RealSrcSpan -> Range
realSrcSpanToRange RealSrcSpan
l
  _selectionRange :: Range
_selectionRange = RealSrcSpan -> Range
realSrcSpanToRange RealSrcSpan
l
  _children :: Maybe a
_children       = forall a. Maybe a
Nothing
  _tags :: Maybe a
_tags           = forall a. Maybe a
Nothing

-- the version of getConNames for ghc9 is restricted to only the renaming phase
#if !MIN_VERSION_ghc(9,2,0)
getConNames' :: ConDecl GhcPs -> [Located (IdP GhcPs)]
getConNames' ConDeclH98  {con_name  = name}  = [name]
getConNames' ConDeclGADT {con_names = names} = names
#if !MIN_VERSION_ghc(8,10,0)
getConNames' (XConDecl NoExt)                = []
#elif !MIN_VERSION_ghc(9,0,0)
getConNames' (XConDecl x)                    = noExtCon x
#endif
#else
hsConDeclsBinders :: LConDecl GhcPs
                  -> ([LIdP GhcPs], [LFieldOcc GhcPs])
   -- See hsLTyClDeclBinders for what this does
   -- The function is boringly complicated because of the records
   -- And since we only have equality, we have to be a little careful
hsConDeclsBinders :: LConDecl GhcPs -> ([LIdP GhcPs], [LFieldOcc GhcPs])
hsConDeclsBinders LConDecl GhcPs
cons
  = LConDecl GhcPs -> ([LIdP GhcPs], [LFieldOcc GhcPs])
go LConDecl GhcPs
cons
  where
    go :: LConDecl GhcPs
       -> ([LIdP GhcPs], [LFieldOcc GhcPs])
    go :: LConDecl GhcPs -> ([LIdP GhcPs], [LFieldOcc GhcPs])
go LConDecl GhcPs
r
      -- Don't re-mangle the location of field names, because we don't
      -- have a record of the full location of the field declaration anyway
      = case forall l e. GenLocated l e -> e
unLoc LConDecl GhcPs
r of
           -- remove only the first occurrence of any seen field in order to
           -- avoid circumventing detection of duplicate fields (#9156)
           ConDeclGADT { con_names :: forall pass. ConDecl pass -> [LIdP pass]
con_names = [LIdP GhcPs]
names, con_g_args :: forall pass. ConDecl pass -> HsConDeclGADTDetails pass
con_g_args = HsConDeclGADTDetails GhcPs
args }
             -> (forall (t :: * -> *) a. Foldable t => t a -> [a]
toList [LIdP GhcPs]
names, [LFieldOcc GhcPs]
flds)
             where
                flds :: [LFieldOcc GhcPs]
flds = HsConDeclGADTDetails GhcPs -> [LFieldOcc GhcPs]
get_flds_gadt HsConDeclGADTDetails GhcPs
args

           ConDeclH98 { con_name :: forall pass. ConDecl pass -> LIdP pass
con_name = LIdP GhcPs
name, con_args :: forall pass. ConDecl pass -> HsConDeclH98Details pass
con_args = HsConDeclH98Details GhcPs
args }
             -> ([LIdP GhcPs
name], [LFieldOcc GhcPs]
flds)
             where
                flds :: [LFieldOcc GhcPs]
flds = HsConDeclH98Details GhcPs -> [LFieldOcc GhcPs]
get_flds_h98 HsConDeclH98Details GhcPs
args

    get_flds_h98 :: HsConDeclH98Details GhcPs
                 -> [LFieldOcc GhcPs]
    get_flds_h98 :: HsConDeclH98Details GhcPs -> [LFieldOcc GhcPs]
get_flds_h98 (RecCon XRec GhcPs [LConDeclField GhcPs]
flds) = Located [LConDeclField GhcPs] -> [LFieldOcc GhcPs]
get_flds (forall a e. LocatedAn a e -> Located e
reLoc XRec GhcPs [LConDeclField GhcPs]
flds)
    get_flds_h98 HsConDeclH98Details GhcPs
_ = []

    get_flds_gadt :: HsConDeclGADTDetails GhcPs
                  -> ([LFieldOcc GhcPs])
#if MIN_VERSION_ghc(9,3,0)
    get_flds_gadt (RecConGADT flds _) = get_flds (reLoc flds)
#else
    get_flds_gadt :: HsConDeclGADTDetails GhcPs -> [LFieldOcc GhcPs]
get_flds_gadt (RecConGADT XRec GhcPs [LConDeclField GhcPs]
flds) = Located [LConDeclField GhcPs] -> [LFieldOcc GhcPs]
get_flds (forall a e. LocatedAn a e -> Located e
reLoc XRec GhcPs [LConDeclField GhcPs]
flds)
#endif
    get_flds_gadt HsConDeclGADTDetails GhcPs
_ = []

    get_flds :: Located [LConDeclField GhcPs]
             -> ([LFieldOcc GhcPs])
    get_flds :: Located [LConDeclField GhcPs] -> [LFieldOcc GhcPs]
get_flds Located [LConDeclField GhcPs]
flds = forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (forall pass. ConDeclField pass -> [LFieldOcc pass]
cd_fld_names forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall l e. GenLocated l e -> e
unLoc) (forall l e. GenLocated l e -> e
unLoc Located [LConDeclField GhcPs]
flds)
#endif