{-# LANGUAGE BangPatterns        #-}
{-# LANGUAGE CPP                 #-}
{-# LANGUAGE LambdaCase          #-}
{-# LANGUAGE NamedFieldPuns      #-}
{-# LANGUAGE OverloadedStrings   #-}
{-# LANGUAGE ScopedTypeVariables #-}

#if __GLASGOW_HASKELL__ >= 810
#define GHC_IMPORT(NAME) GHC.Hs.NAME
#else
#define GHC_IMPORT(NAME) Hs ## NAME
#endif


-- | Generate tags from @'HsModule' 'GhcPs'@ representation.
--
module GhcTags.Ghc
  ( GhcTag (..)
  , GhcTags
  , GhcTagKind (..)
  , getGhcTags
  , hsDeclsToGhcTags
  ) where


import           Data.Maybe    (mapMaybe)
import           Data.Foldable (foldl')
import           Data.ByteString (ByteString)

-- Ghc imports
#if   __GLASGOW_HASKELL__ >= 902
import           GHC.Types.SourceText (SourceText (..))
#elif __GLASGOW_HASKELL__ >= 900
import           GHC.Types.Basic (SourceText (..))
#else
import           BasicTypes      (SourceText (..))
#endif
#if   __GLASGOW_HASKELL__ >= 900
import           GHC.Data.FastString (bytesFS)
#elif __GLASGOW_HASKELL__ >= 810
import           FastString          (bytesFS)
#else
import           FastString          (FastString (fs_bs))
#endif
#if   __GLASGOW_HASKELL__ >= 900 && __GLASGOW_HASKELL__ < 902
import           GHC.Types.FieldLabel (FieldLbl (..))
#elif __GLASGOW_HASKELL__ < 900
import           FieldLabel           (FieldLbl (..))
#endif
import           GHC_IMPORT(Binds)
                              ( HsBindLR (..)
                              , PatSynBind (..)
                              , Sig (..)
                              )
import           GHC_IMPORT(Decls)
                              ( ForeignImport (..)
                              , ClsInstDecl (..)
                              , ConDecl (..)
                              , DataFamInstDecl (..)
                              , FamEqn (..)
                              , FamilyDecl (..)
                              , FamilyInfo (..)
                              , FamilyResultSig (..)
                              , ForeignDecl (..)
                              , LHsDecl
#if   __GLASGOW_HASKELL__ >= 902
                              , HsConDeclH98Details
#else
                              , HsConDeclDetails
#endif
                              , HsDecl (..)
                              , HsDataDefn (..)
                              , InstDecl (..)
                              , TyClDecl (..)
                              , TyFamInstDecl (..)
                              )
#if   __GLASGOW_HASKELL__ >= 810
import           GHC.Hs.Decls ( StandaloneKindSig (..) )
#endif
import           GHC_IMPORT(ImpExp)
                              ( IE (..)
                              , IEWildcard (..)
                              , ieWrappedName
                              )
import           GHC_IMPORT(Extension)
                              ( GhcPs
                              )

#if   __GLASGOW_HASKELL__ >= 900
import           GHC.Hs.Type
#elif __GLASGOW_HASKELL__ >= 810
import           GHC.Hs.Types
#else
import           HsTypes
#endif
                              ( ConDeclField (..)
                              , FieldOcc (..)
                              , HsConDetails (..)
#if   __GLASGOW_HASKELL__ < 902
                              , HsImplicitBndrs (..)
#endif
                              , HsKind
                              , HsTyVarBndr (..)
                              , HsType (..)
                              , HsWildCardBndrs
                              , LConDeclField
                              , LFieldOcc
                              , LHsQTyVars (..)
                              , LHsSigType
                              , LHsType
                              )

#if   __GLASGOW_HASKELL__ >= 900
import           GHC.Types.SrcLoc
                                ( GenLocated (..)
                                , Located
                                , SrcSpan (..)
                                , unLoc
                                )
import           GHC.Types.Name.Reader
                                ( RdrName (..)
                                , rdrNameOcc
                                )
import           GHC.Types.Name ( nameOccName
                                , occNameFS
                                )
#else
import           SrcLoc         ( GenLocated (..)
                                , Located
                                , SrcSpan (..)
                                , unLoc
                                )
import           RdrName        ( RdrName (..)
                                , rdrNameOcc
                                )
import           Name           ( nameOccName
                                , occNameFS
                                )
#endif
#if   __GLASGOW_HASKELL__ >= 902
import           GHC.Hs       ( HsModule (..)
                              , HsSigType (..)
                              , HsConDeclGADTDetails (..)
                              )
import           GHC.Parser.Annotation (SrcSpanAnn' (..))
#elif __GLASGOW_HASKELL__ >= 810
import           GHC.Hs       ( HsModule (..) )
#else
import           HsSyn        ( HsModule (..) )
#endif

#if __GLASGOW_HASKELL__ < 902
type HsConDeclH98Details ps = HsConDeclDetails ps
#endif

#if __GLASGOW_HASKELL__ >= 900
type GhcPsModule = HsModule
type GhcPsHsTyVarBndr = HsTyVarBndr () GhcPs
#else
type GhcPsModule = HsModule GhcPs
type GhcPsHsTyVarBndr = HsTyVarBndr    GhcPs
#endif

#if __GLASGOW_HASKELL__ < 810
bytesFS :: FastString -> ByteString
bytesFS = fs_bs
#endif


-- | Kind of the term.
--
data GhcTagKind
    = GtkTerm
    | GtkFunction
    | GtkTypeConstructor        (Maybe (HsKind GhcPs))

    -- | H98 data construtor
    | GtkDataConstructor               (ConDecl GhcPs)

    -- | GADT constructor with its type
    | GtkGADTConstructor               (ConDecl GhcPs)
    | GtkRecordField
    | GtkTypeSynonym                   (HsType GhcPs)
    | GtkTypeSignature                 (HsWildCardBndrs GhcPs (LHsSigType GhcPs))
    | GtkTypeKindSignature             (LHsSigType GhcPs)
    | GtkPatternSynonym
    | GtkTypeClass
    | GtkTypeClassMember               (HsType GhcPs)
    | GtkTypeClassInstance             (HsType GhcPs)
    | GtkTypeFamily             (Maybe ([GhcPsHsTyVarBndr], Either (HsKind GhcPs) GhcPsHsTyVarBndr))
    -- ghc-8.6.5 does not provide 'TyFamInstDecl' for assicated type families
    | GtkTypeFamilyInstance     (Maybe (TyFamInstDecl GhcPs))
    | GtkDataTypeFamily         (Maybe ([GhcPsHsTyVarBndr], Either (HsKind GhcPs) GhcPsHsTyVarBndr))
    | GtkDataTypeFamilyInstance (Maybe (HsKind GhcPs))
    | GtkForeignImport
    | GtkForeignExport


-- | We can read names from using fields of type 'GHC.Hs.Extensions.IdP' (a type
-- family) which for @'Parsed@ resolved to 'RdrName'
--
data GhcTag = GhcTag {
    GhcTag -> SrcSpan
gtSrcSpan    :: !SrcSpan
    -- ^ term location
  , GhcTag -> ByteString
gtTag        :: !ByteString
    -- ^ utf8 encoded tag's name
  , GhcTag -> GhcTagKind
gtKind       :: !GhcTagKind
    -- ^ tag's kind
  , GhcTag -> Bool
gtIsExported :: !Bool
    -- ^ 'True' iff the term is exported
  , GhcTag -> Maybe String
gtFFI        :: !(Maybe String)
    -- ^ @ffi@ import
  }

type GhcTags = [GhcTag]


-- | Check if an identifier is exported.
--
isExported :: Maybe [IE GhcPs] -> Located RdrName -> Bool
isExported :: Maybe [IE GhcPs] -> Located RdrName -> Bool
isExported Maybe [IE GhcPs]
Nothing   Located RdrName
_name = Bool
True
isExported (Just [IE GhcPs]
ies) (L SrcSpan
_ RdrName
name) =
    (IE GhcPs -> Bool) -> [IE GhcPs] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (\IE GhcPs
ie -> IE GhcPs -> Maybe RdrName
ieName IE GhcPs
ie Maybe RdrName -> Maybe RdrName -> Bool
forall a. Eq a => a -> a -> Bool
== RdrName -> Maybe RdrName
forall a. a -> Maybe a
Just RdrName
name) [IE GhcPs]
ies
  where
    -- TODO: the GHC's one is partial, and I got a panic error.
    ieName :: IE GhcPs -> Maybe RdrName
    ieName :: IE GhcPs -> Maybe RdrName
ieName (IEVar XIEVar GhcPs
_ (L SrcSpan
_ IEWrappedName (IdP GhcPs)
n))              = RdrName -> Maybe RdrName
forall a. a -> Maybe a
Just (RdrName -> Maybe RdrName) -> RdrName -> Maybe RdrName
forall a b. (a -> b) -> a -> b
$ IEWrappedName RdrName -> RdrName
forall name. IEWrappedName name -> name
ieWrappedName IEWrappedName (IdP GhcPs)
IEWrappedName RdrName
n
    ieName (IEThingAbs  XIEThingAbs GhcPs
_ (L SrcSpan
_ IEWrappedName (IdP GhcPs)
n))        = RdrName -> Maybe RdrName
forall a. a -> Maybe a
Just (RdrName -> Maybe RdrName) -> RdrName -> Maybe RdrName
forall a b. (a -> b) -> a -> b
$ IEWrappedName RdrName -> RdrName
forall name. IEWrappedName name -> name
ieWrappedName IEWrappedName (IdP GhcPs)
IEWrappedName RdrName
n
#if __GLASGOW_HASKELL__ < 902
    ieName (IEThingWith XIEThingWith GhcPs
_ (L SrcSpan
_ IEWrappedName (IdP GhcPs)
n) IEWildcard
_ [GenLocated SrcSpan (IEWrappedName (IdP GhcPs))]
_ [Located (FieldLbl (IdP GhcPs))]
_)  = RdrName -> Maybe RdrName
forall a. a -> Maybe a
Just (RdrName -> Maybe RdrName) -> RdrName -> Maybe RdrName
forall a b. (a -> b) -> a -> b
$ IEWrappedName RdrName -> RdrName
forall name. IEWrappedName name -> name
ieWrappedName IEWrappedName (IdP GhcPs)
IEWrappedName RdrName
n
#else
    ieName (IEThingWith _ (L _ n) _ _)    = Just $ ieWrappedName n
#endif
    ieName (IEThingAll  XIEThingAll GhcPs
_ (L SrcSpan
_ IEWrappedName (IdP GhcPs)
n))        = RdrName -> Maybe RdrName
forall a. a -> Maybe a
Just (RdrName -> Maybe RdrName) -> RdrName -> Maybe RdrName
forall a b. (a -> b) -> a -> b
$ IEWrappedName RdrName -> RdrName
forall name. IEWrappedName name -> name
ieWrappedName IEWrappedName (IdP GhcPs)
IEWrappedName RdrName
n
    ieName IE GhcPs
_ = Maybe RdrName
forall a. Maybe a
Nothing


-- | Check if a class member or a type constructors is exported.
--
isMemberExported :: Maybe [IE GhcPs]
                 -> Located RdrName -- member name / constructor name
                 -> Located RdrName -- type class name / type constructor name
                 -> Bool
isMemberExported :: Maybe [IE GhcPs] -> Located RdrName -> Located RdrName -> Bool
isMemberExported Maybe [IE GhcPs]
Nothing    Located RdrName
_memberName Located RdrName
_className = Bool
True
isMemberExported (Just [IE GhcPs]
ies) Located RdrName
memberName  Located RdrName
className  = (IE GhcPs -> Bool) -> [IE GhcPs] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any IE GhcPs -> Bool
go [IE GhcPs]
ies
  where
    go :: IE GhcPs -> Bool

    go :: IE GhcPs -> Bool
go (IEVar XIEVar GhcPs
_ (L SrcSpan
_ IEWrappedName (IdP GhcPs)
n)) = IEWrappedName RdrName -> RdrName
forall name. IEWrappedName name -> name
ieWrappedName IEWrappedName (IdP GhcPs)
IEWrappedName RdrName
n RdrName -> RdrName -> Bool
forall a. Eq a => a -> a -> Bool
== Located RdrName -> SrcSpanLess (Located RdrName)
forall a. HasSrcSpan a => a -> SrcSpanLess a
unLoc Located RdrName
memberName

    go (IEThingAbs XIEThingAbs GhcPs
_ GenLocated SrcSpan (IEWrappedName (IdP GhcPs))
_)  = Bool
False

    go (IEThingAll XIEThingAll GhcPs
_ (L SrcSpan
_ IEWrappedName (IdP GhcPs)
n)) = IEWrappedName RdrName -> RdrName
forall name. IEWrappedName name -> name
ieWrappedName IEWrappedName (IdP GhcPs)
IEWrappedName RdrName
n RdrName -> RdrName -> Bool
forall a. Eq a => a -> a -> Bool
== Located RdrName -> SrcSpanLess (Located RdrName)
forall a. HasSrcSpan a => a -> SrcSpanLess a
unLoc Located RdrName
className

#if __GLASGOW_HASKELL__ < 902
    go (IEThingWith XIEThingWith GhcPs
_ GenLocated SrcSpan (IEWrappedName (IdP GhcPs))
_ IEWildcard{} [GenLocated SrcSpan (IEWrappedName (IdP GhcPs))]
_ [Located (FieldLbl (IdP GhcPs))]
_) = Bool
True
#else
    go (IEThingWith _ _ IEWildcard{} _)   = True
#endif

#if __GLASGOW_HASKELL__ < 902
    go (IEThingWith XIEThingWith GhcPs
_ (L SrcSpan
_ IEWrappedName (IdP GhcPs)
n) IEWildcard
NoIEWildcard [GenLocated SrcSpan (IEWrappedName (IdP GhcPs))]
ns [Located (FieldLbl (IdP GhcPs))]
lfls) =
#else
    go (IEThingWith _ (L _ n) NoIEWildcard ns) =
#endif
            IEWrappedName RdrName -> RdrName
forall name. IEWrappedName name -> name
ieWrappedName IEWrappedName (IdP GhcPs)
IEWrappedName RdrName
n RdrName -> RdrName -> Bool
forall a. Eq a => a -> a -> Bool
== Located RdrName -> SrcSpanLess (Located RdrName)
forall a. HasSrcSpan a => a -> SrcSpanLess a
unLoc Located RdrName
className
#if __GLASGOW_HASKELL__ < 902
         Bool -> Bool -> Bool
&& (Bool
isInWrappedNames Bool -> Bool -> Bool
|| Bool
isInFieldLbls)
#else
         &&  isInWrappedNames
#endif
      where
        -- the 'NameSpace' does not agree between things that are in the 'IE'
        -- list and passed member or type class names (constructor / type
        -- constructor names, respectively)
        isInWrappedNames :: Bool
isInWrappedNames = (LIEWrappedName RdrName -> Bool)
-> [LIEWrappedName RdrName] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any ((FastString -> FastString -> Bool
forall a. Eq a => a -> a -> Bool
== OccName -> FastString
occNameFS (RdrName -> OccName
rdrNameOcc (Located RdrName -> SrcSpanLess (Located RdrName)
forall a. HasSrcSpan a => a -> SrcSpanLess a
unLoc Located RdrName
memberName))) (FastString -> Bool)
-> (LIEWrappedName RdrName -> FastString)
-> LIEWrappedName RdrName
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OccName -> FastString
occNameFS (OccName -> FastString)
-> (LIEWrappedName RdrName -> OccName)
-> LIEWrappedName RdrName
-> FastString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RdrName -> OccName
rdrNameOcc (RdrName -> OccName)
-> (LIEWrappedName RdrName -> RdrName)
-> LIEWrappedName RdrName
-> OccName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IEWrappedName RdrName -> RdrName
forall name. IEWrappedName name -> name
ieWrappedName (IEWrappedName RdrName -> RdrName)
-> (LIEWrappedName RdrName -> IEWrappedName RdrName)
-> LIEWrappedName RdrName
-> RdrName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LIEWrappedName RdrName -> IEWrappedName RdrName
forall a. HasSrcSpan a => a -> SrcSpanLess a
unLoc) [GenLocated SrcSpan (IEWrappedName (IdP GhcPs))]
[LIEWrappedName RdrName]
ns
#if __GLASGOW_HASKELL__ < 902
        isInFieldLbls :: Bool
isInFieldLbls    = (Located (FieldLbl RdrName) -> Bool)
-> [Located (FieldLbl RdrName)] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any ((FastString -> FastString -> Bool
forall a. Eq a => a -> a -> Bool
== OccName -> FastString
occNameFS (RdrName -> OccName
rdrNameOcc (Located RdrName -> SrcSpanLess (Located RdrName)
forall a. HasSrcSpan a => a -> SrcSpanLess a
unLoc Located RdrName
memberName))) (FastString -> Bool)
-> (Located (FieldLbl RdrName) -> FastString)
-> Located (FieldLbl RdrName)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OccName -> FastString
occNameFS (OccName -> FastString)
-> (Located (FieldLbl RdrName) -> OccName)
-> Located (FieldLbl RdrName)
-> FastString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RdrName -> OccName
rdrNameOcc (RdrName -> OccName)
-> (Located (FieldLbl RdrName) -> RdrName)
-> Located (FieldLbl RdrName)
-> OccName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FieldLbl RdrName -> RdrName
forall a. FieldLbl a -> a
flSelector(FieldLbl RdrName -> RdrName)
-> (Located (FieldLbl RdrName) -> FieldLbl RdrName)
-> Located (FieldLbl RdrName)
-> RdrName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Located (FieldLbl RdrName) -> FieldLbl RdrName
forall a. HasSrcSpan a => a -> SrcSpanLess a
unLoc) [Located (FieldLbl (IdP GhcPs))]
[Located (FieldLbl RdrName)]
lfls
#endif

    go IE GhcPs
_ = Bool
False


-- | Create a 'GhcTag', effectively a smart constructor.
--
mkGhcTag :: Located RdrName
         -- ^ @RdrName ~ IdP GhcPs@ it *must* be a name of a top level identifier.
         -> GhcTagKind
         -- ^ tag's kind
         -> Bool
         -- ^ is term exported
         -> GhcTag
mkGhcTag :: Located RdrName -> GhcTagKind -> Bool -> GhcTag
mkGhcTag (L SrcSpan
gtSrcSpan RdrName
rdrName) GhcTagKind
gtKind Bool
gtIsExported =
    case RdrName
rdrName of
      Unqual OccName
occName ->
        GhcTag :: SrcSpan
-> ByteString -> GhcTagKind -> Bool -> Maybe String -> GhcTag
GhcTag { gtTag :: ByteString
gtTag = FastString -> ByteString
bytesFS (OccName -> FastString
occNameFS OccName
occName)
               , SrcSpan
gtSrcSpan :: SrcSpan
gtSrcSpan :: SrcSpan
gtSrcSpan
               , GhcTagKind
gtKind :: GhcTagKind
gtKind :: GhcTagKind
gtKind
               , Bool
gtIsExported :: Bool
gtIsExported :: Bool
gtIsExported
               , gtFFI :: Maybe String
gtFFI = Maybe String
forall a. Maybe a
Nothing
               }

      Qual ModuleName
_ OccName
occName ->
        GhcTag :: SrcSpan
-> ByteString -> GhcTagKind -> Bool -> Maybe String -> GhcTag
GhcTag { gtTag :: ByteString
gtTag = FastString -> ByteString
bytesFS (OccName -> FastString
occNameFS OccName
occName)
               , SrcSpan
gtSrcSpan :: SrcSpan
gtSrcSpan :: SrcSpan
gtSrcSpan
               , GhcTagKind
gtKind :: GhcTagKind
gtKind :: GhcTagKind
gtKind
               , Bool
gtIsExported :: Bool
gtIsExported :: Bool
gtIsExported
               , gtFFI :: Maybe String
gtFFI = Maybe String
forall a. Maybe a
Nothing
               }

      -- Orig is the only one we are interested in
      Orig Module
_ OccName
occName ->
        GhcTag :: SrcSpan
-> ByteString -> GhcTagKind -> Bool -> Maybe String -> GhcTag
GhcTag { gtTag :: ByteString
gtTag = FastString -> ByteString
bytesFS (OccName -> FastString
occNameFS OccName
occName)
               , SrcSpan
gtSrcSpan :: SrcSpan
gtSrcSpan :: SrcSpan
gtSrcSpan
               , GhcTagKind
gtKind :: GhcTagKind
gtKind :: GhcTagKind
gtKind
               , Bool
gtIsExported :: Bool
gtIsExported :: Bool
gtIsExported
               , gtFFI :: Maybe String
gtFFI = Maybe String
forall a. Maybe a
Nothing
               }

      Exact Name
eName ->
        GhcTag :: SrcSpan
-> ByteString -> GhcTagKind -> Bool -> Maybe String -> GhcTag
GhcTag { gtTag :: ByteString
gtTag = FastString -> ByteString
bytesFS (OccName -> FastString
occNameFS (Name -> OccName
nameOccName Name
eName))
               , SrcSpan
gtSrcSpan :: SrcSpan
gtSrcSpan :: SrcSpan
gtSrcSpan
               , GhcTagKind
gtKind :: GhcTagKind
gtKind :: GhcTagKind
gtKind
               , Bool
gtIsExported :: Bool
gtIsExported :: Bool
gtIsExported
               , gtFFI :: Maybe String
gtFFI = Maybe String
forall a. Maybe a
Nothing
               }


-- | Generate tags for a module - simple walk over the syntax tree.
--
-- Supported identifiers:
--
--  * /top level terms/
--  * /data types/
--  * /record fields/
--  * /type synonyms/
--  * /type classes/
--  * /type class members/
--  * /type class instances/
--  * /type families/
--  * /type family instances/
--  * /data type families/
--  * /data type families instances/
--  * /data type family instances constructors/
--
getGhcTags :: Located GhcPsModule
           -> GhcTags
getGhcTags :: Located GhcPsModule -> GhcTags
getGhcTags (L SrcSpan
_ HsModule { [LHsDecl GhcPs]
hsmodDecls :: forall pass. HsModule pass -> [LHsDecl pass]
hsmodDecls :: [LHsDecl GhcPs]
hsmodDecls, Maybe (Located [LIE GhcPs])
hsmodExports :: forall pass. HsModule pass -> Maybe (Located [LIE pass])
hsmodExports :: Maybe (Located [LIE GhcPs])
hsmodExports }) =
    Maybe [IE GhcPs] -> [LHsDecl GhcPs] -> GhcTags
hsDeclsToGhcTags Maybe [IE GhcPs]
mies [LHsDecl GhcPs]
hsmodDecls
  where
    mies :: Maybe [IE GhcPs]
    mies :: Maybe [IE GhcPs]
mies = (LIE GhcPs -> IE GhcPs) -> [LIE GhcPs] -> [IE GhcPs]
forall a b. (a -> b) -> [a] -> [b]
map LIE GhcPs -> IE GhcPs
forall a. HasSrcSpan a => a -> SrcSpanLess a
unLoc ([LIE GhcPs] -> [IE GhcPs])
-> (Located [LIE GhcPs] -> [LIE GhcPs])
-> Located [LIE GhcPs]
-> [IE GhcPs]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Located [LIE GhcPs] -> [LIE GhcPs]
forall a. HasSrcSpan a => a -> SrcSpanLess a
unLoc (Located [LIE GhcPs] -> [IE GhcPs])
-> Maybe (Located [LIE GhcPs]) -> Maybe [IE GhcPs]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (Located [LIE GhcPs])
hsmodExports


hsDeclsToGhcTags :: Maybe [IE GhcPs]
                 -> [LHsDecl GhcPs]
                 -> GhcTags
hsDeclsToGhcTags :: Maybe [IE GhcPs] -> [LHsDecl GhcPs] -> GhcTags
hsDeclsToGhcTags Maybe [IE GhcPs]
mies =
    GhcTags -> GhcTags
forall a. [a] -> [a]
reverse (GhcTags -> GhcTags)
-> ([LHsDecl GhcPs] -> GhcTags) -> [LHsDecl GhcPs] -> GhcTags
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (GhcTags -> LHsDecl GhcPs -> GhcTags)
-> GhcTags -> [LHsDecl GhcPs] -> GhcTags
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' GhcTags -> LHsDecl GhcPs -> GhcTags
go []
  where
    fixLoc :: SrcSpan -> GhcTag -> GhcTag
    fixLoc :: SrcSpan -> GhcTag -> GhcTag
fixLoc SrcSpan
loc gt :: GhcTag
gt@GhcTag { gtSrcSpan :: GhcTag -> SrcSpan
gtSrcSpan = UnhelpfulSpan {} } = GhcTag
gt { gtSrcSpan :: SrcSpan
gtSrcSpan = SrcSpan
loc }
    fixLoc SrcSpan
_   GhcTag
gt                                      = GhcTag
gt

    -- like 'mkGhcTag' but checks if the identifier is exported
    mkGhcTag' :: SrcSpan
              -- ^ declaration's location; it is useful when the term does not
              -- contain useful inforamtion (e.g. code generated from template
              -- haskell splices).
              ->  Located RdrName
              --  ^ @RdrName ~ IdP GhcPs@ it *must* be a name of a top level
              --  identifier.
              -> GhcTagKind
              -- ^ tag's kind
              -> GhcTag
    mkGhcTag' :: SrcSpan -> Located RdrName -> GhcTagKind -> GhcTag
mkGhcTag' SrcSpan
l Located RdrName
a GhcTagKind
k = SrcSpan -> GhcTag -> GhcTag
fixLoc SrcSpan
l (GhcTag -> GhcTag) -> GhcTag -> GhcTag
forall a b. (a -> b) -> a -> b
$ Located RdrName -> GhcTagKind -> Bool -> GhcTag
mkGhcTag Located RdrName
a GhcTagKind
k (Maybe [IE GhcPs] -> Located RdrName -> Bool
isExported Maybe [IE GhcPs]
mies Located RdrName
a)


    mkGhcTagForMember :: SrcSpan
                      -- ^ declartion's 'SrcSpan'
                      -> Located RdrName -- member name
                      -> Located RdrName -- class name
                      -> GhcTagKind
                      -> GhcTag
    mkGhcTagForMember :: SrcSpan
-> Located RdrName -> Located RdrName -> GhcTagKind -> GhcTag
mkGhcTagForMember SrcSpan
decLoc Located RdrName
memberName Located RdrName
className GhcTagKind
kind =
      SrcSpan -> GhcTag -> GhcTag
fixLoc SrcSpan
decLoc (GhcTag -> GhcTag) -> GhcTag -> GhcTag
forall a b. (a -> b) -> a -> b
$ Located RdrName -> GhcTagKind -> Bool -> GhcTag
mkGhcTag Located RdrName
memberName GhcTagKind
kind
                               (Maybe [IE GhcPs] -> Located RdrName -> Located RdrName -> Bool
isMemberExported Maybe [IE GhcPs]
mies Located RdrName
memberName Located RdrName
className)

    -- Main routine which traverse all top level declarations.
    --
    go :: GhcTags -> LHsDecl GhcPs -> GhcTags
    go :: GhcTags -> LHsDecl GhcPs -> GhcTags
go GhcTags
tags (L SrcSpan
decLoc' HsDecl GhcPs
hsDecl) = let decLoc :: SrcSpan
decLoc = SrcSpan -> SrcSpan
locAnn SrcSpan
decLoc' in case HsDecl GhcPs
hsDecl of

      -- type or class declaration
      TyClD XTyClD GhcPs
_ TyClDecl GhcPs
tyClDecl ->
        case TyClDecl GhcPs
tyClDecl of

          -- type family declarations
          FamDecl { FamilyDecl GhcPs
tcdFam :: forall pass. TyClDecl pass -> FamilyDecl pass
tcdFam :: FamilyDecl GhcPs
tcdFam } ->
            case SrcSpan
-> FamilyDecl GhcPs -> Maybe (Located RdrName) -> Maybe GhcTag
mkFamilyDeclTags SrcSpan
decLoc FamilyDecl GhcPs
tcdFam Maybe (Located RdrName)
forall a. Maybe a
Nothing of
              Just GhcTag
tag -> GhcTag
tag GhcTag -> GhcTags -> GhcTags
forall a. a -> [a] -> [a]
: GhcTags
tags
              Maybe GhcTag
Nothing  ->       GhcTags
tags

          -- type synonyms
          SynDecl { Located (IdP GhcPs)
tcdLName :: forall pass. TyClDecl pass -> Located (IdP pass)
tcdLName :: Located (IdP GhcPs)
tcdLName, tcdRhs :: forall pass. TyClDecl pass -> LHsType pass
tcdRhs = L SrcSpan
_ HsType GhcPs
hsType } ->
            SrcSpan -> Located RdrName -> GhcTagKind -> GhcTag
mkGhcTag' SrcSpan
decLoc (Located RdrName -> Located RdrName
unSpanAnn Located (IdP GhcPs)
Located RdrName
tcdLName) (HsType GhcPs -> GhcTagKind
GtkTypeSynonym HsType GhcPs
hsType) GhcTag -> GhcTags -> GhcTags
forall a. a -> [a] -> [a]
: GhcTags
tags

          -- data declaration:
          --   type,
          --   constructors,
          --   record fields
          --
          DataDecl { Located (IdP GhcPs)
tcdLName :: Located (IdP GhcPs)
tcdLName :: forall pass. TyClDecl pass -> Located (IdP pass)
tcdLName, HsDataDefn GhcPs
tcdDataDefn :: forall pass. TyClDecl pass -> HsDataDefn pass
tcdDataDefn :: HsDataDefn GhcPs
tcdDataDefn } ->
            case HsDataDefn GhcPs
tcdDataDefn of
              HsDataDefn { [LConDecl GhcPs]
dd_cons :: forall pass. HsDataDefn pass -> [LConDecl pass]
dd_cons :: [LConDecl GhcPs]
dd_cons, Maybe (GenLocated SrcSpan (HsType GhcPs))
dd_kindSig :: forall pass. HsDataDefn pass -> Maybe (LHsKind pass)
dd_kindSig :: Maybe (GenLocated SrcSpan (HsType GhcPs))
dd_kindSig } ->
                     SrcSpan -> Located RdrName -> GhcTagKind -> GhcTag
mkGhcTag' SrcSpan
decLoc (Located RdrName -> Located RdrName
unSpanAnn Located (IdP GhcPs)
Located RdrName
tcdLName) (Maybe (HsType GhcPs) -> GhcTagKind
GtkTypeConstructor (GenLocated SrcSpan (HsType GhcPs) -> HsType GhcPs
forall a. HasSrcSpan a => a -> SrcSpanLess a
unLoc (GenLocated SrcSpan (HsType GhcPs) -> HsType GhcPs)
-> Maybe (GenLocated SrcSpan (HsType GhcPs))
-> Maybe (HsType GhcPs)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (GenLocated SrcSpan (HsType GhcPs))
dd_kindSig))
                   GhcTag -> GhcTags -> GhcTags
forall a. a -> [a] -> [a]
: (SrcSpan -> Located RdrName -> ConDecl GhcPs -> GhcTags
mkConsTags SrcSpan
decLoc (Located RdrName -> Located RdrName
unSpanAnn Located (IdP GhcPs)
Located RdrName
tcdLName) (ConDecl GhcPs -> GhcTags)
-> (LConDecl GhcPs -> ConDecl GhcPs) -> LConDecl GhcPs -> GhcTags
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LConDecl GhcPs -> ConDecl GhcPs
forall a. HasSrcSpan a => a -> SrcSpanLess a
unLoc) (LConDecl GhcPs -> GhcTags) -> [LConDecl GhcPs] -> GhcTags
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
`concatMap` [LConDecl GhcPs]
dd_cons
                  GhcTags -> GhcTags -> GhcTags
forall a. [a] -> [a] -> [a]
++ GhcTags
tags

#if __GLASGOW_HASKELL__ < 900
              XHsDataDefn {} -> GhcTags
tags
#endif

          -- Type class declaration:
          --   type class name,
          --   type class members,
          --   default methods,
          --   default data type instance
          --
          ClassDecl { Located (IdP GhcPs)
tcdLName :: Located (IdP GhcPs)
tcdLName :: forall pass. TyClDecl pass -> Located (IdP pass)
tcdLName, [LSig GhcPs]
tcdSigs :: forall pass. TyClDecl pass -> [LSig pass]
tcdSigs :: [LSig GhcPs]
tcdSigs, LHsBinds GhcPs
tcdMeths :: forall pass. TyClDecl pass -> LHsBinds pass
tcdMeths :: LHsBinds GhcPs
tcdMeths, [LFamilyDecl GhcPs]
tcdATs :: forall pass. TyClDecl pass -> [LFamilyDecl pass]
tcdATs :: [LFamilyDecl GhcPs]
tcdATs, [LTyFamDefltDecl GhcPs]
tcdATDefs :: forall pass. TyClDecl pass -> [LTyFamDefltDecl pass]
tcdATDefs :: [LTyFamDefltDecl GhcPs]
tcdATDefs } ->
              -- class name
              SrcSpan -> Located RdrName -> GhcTagKind -> GhcTag
mkGhcTag' SrcSpan
decLoc (Located RdrName -> Located RdrName
unSpanAnn Located (IdP GhcPs)
Located RdrName
tcdLName) GhcTagKind
GtkTypeClass
               -- class methods
             GhcTag -> GhcTags -> GhcTags
forall a. a -> [a] -> [a]
: (SrcSpan -> Located RdrName -> Sig GhcPs -> GhcTags
mkClsMemberTags SrcSpan
decLoc (Located RdrName -> Located RdrName
unSpanAnn Located (IdP GhcPs)
Located RdrName
tcdLName) (Sig GhcPs -> GhcTags)
-> (LSig GhcPs -> Sig GhcPs) -> LSig GhcPs -> GhcTags
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LSig GhcPs -> Sig GhcPs
forall a. HasSrcSpan a => a -> SrcSpanLess a
unLoc) (LSig GhcPs -> GhcTags) -> [LSig GhcPs] -> GhcTags
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
`concatMap` [LSig GhcPs]
tcdSigs
               -- default methods
            GhcTags -> GhcTags -> GhcTags
forall a. [a] -> [a] -> [a]
++ (GhcTags -> LHsBindLR GhcPs GhcPs -> GhcTags)
-> GhcTags -> LHsBinds GhcPs -> GhcTags
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (\GhcTags
tags' LHsBindLR GhcPs GhcPs
hsBind -> SrcSpan -> HsBindLR GhcPs GhcPs -> GhcTags
mkHsBindLRTags SrcSpan
decLoc (LHsBindLR GhcPs GhcPs -> SrcSpanLess (LHsBindLR GhcPs GhcPs)
forall a. HasSrcSpan a => a -> SrcSpanLess a
unLoc LHsBindLR GhcPs GhcPs
hsBind) GhcTags -> GhcTags -> GhcTags
forall a. [a] -> [a] -> [a]
++ GhcTags
tags')
                     []
                     LHsBinds GhcPs
tcdMeths
            -- associated types
            GhcTags -> GhcTags -> GhcTags
forall a. [a] -> [a] -> [a]
++ ((\FamilyDecl GhcPs
a -> SrcSpan
-> FamilyDecl GhcPs -> Maybe (Located RdrName) -> Maybe GhcTag
mkFamilyDeclTags SrcSpan
decLoc FamilyDecl GhcPs
a (Located RdrName -> Maybe (Located RdrName)
forall a. a -> Maybe a
Just (Located RdrName -> Maybe (Located RdrName))
-> Located RdrName -> Maybe (Located RdrName)
forall a b. (a -> b) -> a -> b
$ Located RdrName -> Located RdrName
unSpanAnn Located (IdP GhcPs)
Located RdrName
tcdLName)) (FamilyDecl GhcPs -> Maybe GhcTag)
-> (LFamilyDecl GhcPs -> FamilyDecl GhcPs)
-> LFamilyDecl GhcPs
-> Maybe GhcTag
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LFamilyDecl GhcPs -> FamilyDecl GhcPs
forall a. HasSrcSpan a => a -> SrcSpanLess a
unLoc) (LFamilyDecl GhcPs -> Maybe GhcTag)
-> [LFamilyDecl GhcPs] -> GhcTags
forall a b. (a -> Maybe b) -> [a] -> [b]
`mapMaybe` [LFamilyDecl GhcPs]
tcdATs
            -- associated type defaults (data type families, type families
            -- (open or closed)
            GhcTags -> GhcTags -> GhcTags
forall a. [a] -> [a] -> [a]
++ (GhcTags -> LTyFamDefltDecl GhcPs -> GhcTags)
-> GhcTags -> [LTyFamDefltDecl GhcPs] -> GhcTags
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl'
#if __GLASGOW_HASKELL__ < 810
                (\tags' (L _ tyFamDeflEqn) ->
                  let decl = Nothing in
#elif __GLASGOW_HASKELL__ < 902
                (\GhcTags
tags' (L SrcSpan
_ decl' :: TyFamInstDecl GhcPs
decl'@(TyFamInstDecl (HsIB { hsib_body :: forall pass thing. HsImplicitBndrs pass thing -> thing
hsib_body = FamEqn GhcPs (GenLocated SrcSpan (HsType GhcPs))
tyFamDeflEqn }))) ->
                  let decl :: Maybe (TyFamInstDecl GhcPs)
decl = TyFamInstDecl GhcPs -> Maybe (TyFamInstDecl GhcPs)
forall a. a -> Maybe a
Just TyFamInstDecl GhcPs
decl' in
#else
                (\tags' (L _ decl'@(TyFamInstDecl { tfid_eqn = tyFamDeflEqn })) ->
                  let decl = Just decl' in
#endif
                    case FamEqn GhcPs (GenLocated SrcSpan (HsType GhcPs))
tyFamDeflEqn of
                      FamEqn { feqn_rhs :: forall pass rhs. FamEqn pass rhs -> rhs
feqn_rhs = L SrcSpan
_ HsType GhcPs
hsType } ->
                        case HsType GhcPs -> Maybe (Located RdrName)
hsTypeTagName HsType GhcPs
hsType of
                          -- TODO: add a `default` field
                          Just Located RdrName
a  -> SrcSpan -> Located RdrName -> GhcTagKind -> GhcTag
mkGhcTag' SrcSpan
decLoc Located RdrName
a (Maybe (TyFamInstDecl GhcPs) -> GhcTagKind
GtkTypeFamilyInstance Maybe (TyFamInstDecl GhcPs)
decl) GhcTag -> GhcTags -> GhcTags
forall a. a -> [a] -> [a]
: GhcTags
tags'
                          Maybe (Located RdrName)
Nothing -> GhcTags
tags'
#if __GLASGOW_HASKELL__ < 900
                      XFamEqn {} -> GhcTags
tags'
#endif
                )
                [] [LTyFamDefltDecl GhcPs]
tcdATDefs
            GhcTags -> GhcTags -> GhcTags
forall a. [a] -> [a] -> [a]
++ GhcTags
tags

#if __GLASGOW_HASKELL__ < 900
          XTyClDecl {} -> GhcTags
tags
#endif

      -- Instance declarations
      --  class instances
      --  type family instance
      --  data type family instances
      --
      InstD XInstD GhcPs
_ InstDecl GhcPs
instDecl ->
        case InstDecl GhcPs
instDecl of
          -- class instance declaration
          ClsInstD { ClsInstDecl GhcPs
cid_inst :: forall pass. InstDecl pass -> ClsInstDecl pass
cid_inst :: ClsInstDecl GhcPs
cid_inst } ->
            case ClsInstDecl GhcPs
cid_inst of
#if __GLASGOW_HASKELL__ < 900
              XClsInstDecl {} -> GhcTags
tags
#endif

              ClsInstDecl { LHsSigType GhcPs
cid_poly_ty :: forall pass. ClsInstDecl pass -> LHsSigType pass
cid_poly_ty :: LHsSigType GhcPs
cid_poly_ty, [LTyFamDefltDecl GhcPs]
cid_tyfam_insts :: forall pass. ClsInstDecl pass -> [LTyFamInstDecl pass]
cid_tyfam_insts :: [LTyFamDefltDecl GhcPs]
cid_tyfam_insts, [LDataFamInstDecl GhcPs]
cid_datafam_insts :: forall pass. ClsInstDecl pass -> [LDataFamInstDecl pass]
cid_datafam_insts :: [LDataFamInstDecl GhcPs]
cid_datafam_insts } ->
                  case LHsSigType GhcPs
cid_poly_ty of
#if __GLASGOW_HASKELL__ < 900
                    XHsImplicitBndrs {} ->
                      GhcTags
tyFamTags GhcTags -> GhcTags -> GhcTags
forall a. [a] -> [a] -> [a]
++ GhcTags
dataFamTags GhcTags -> GhcTags -> GhcTags
forall a. [a] -> [a] -> [a]
++ GhcTags
tags
#endif

                    -- TODO: @hsbib_body :: LHsType GhcPs@
#if __GLASGOW_HASKELL__ < 902
                    HsIB { hsib_body :: forall pass thing. HsImplicitBndrs pass thing -> thing
hsib_body = GenLocated SrcSpan (HsType GhcPs)
body } ->
#else
                    L _ HsSig { sig_body = body } ->
#endif
                      case SrcSpan -> GenLocated SrcSpan (HsType GhcPs) -> Maybe GhcTag
mkLHsTypeTag SrcSpan
decLoc GenLocated SrcSpan (HsType GhcPs)
body of
                        Maybe GhcTag
Nothing  ->       GhcTags
tyFamTags GhcTags -> GhcTags -> GhcTags
forall a. [a] -> [a] -> [a]
++ GhcTags
dataFamTags GhcTags -> GhcTags -> GhcTags
forall a. [a] -> [a] -> [a]
++ GhcTags
tags
                        Just GhcTag
tag -> GhcTag
tag GhcTag -> GhcTags -> GhcTags
forall a. a -> [a] -> [a]
: GhcTags
tyFamTags GhcTags -> GhcTags -> GhcTags
forall a. [a] -> [a] -> [a]
++ GhcTags
dataFamTags GhcTags -> GhcTags -> GhcTags
forall a. [a] -> [a] -> [a]
++ GhcTags
tags
                where
                  -- associated type and data type family instances
                  dataFamTags :: GhcTags
dataFamTags = (SrcSpan -> DataFamInstDecl GhcPs -> GhcTags
mkDataFamInstDeclTag SrcSpan
decLoc (DataFamInstDecl GhcPs -> GhcTags)
-> (LDataFamInstDecl GhcPs -> DataFamInstDecl GhcPs)
-> LDataFamInstDecl GhcPs
-> GhcTags
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LDataFamInstDecl GhcPs -> DataFamInstDecl GhcPs
forall a. HasSrcSpan a => a -> SrcSpanLess a
unLoc) (LDataFamInstDecl GhcPs -> GhcTags)
-> [LDataFamInstDecl GhcPs] -> GhcTags
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
`concatMap` [LDataFamInstDecl GhcPs]
cid_datafam_insts
                  tyFamTags :: GhcTags
tyFamTags   = (SrcSpan -> TyFamInstDecl GhcPs -> Maybe GhcTag
mkTyFamInstDeclTag   SrcSpan
decLoc (TyFamInstDecl GhcPs -> Maybe GhcTag)
-> (LTyFamDefltDecl GhcPs -> TyFamInstDecl GhcPs)
-> LTyFamDefltDecl GhcPs
-> Maybe GhcTag
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LTyFamDefltDecl GhcPs -> TyFamInstDecl GhcPs
forall a. HasSrcSpan a => a -> SrcSpanLess a
unLoc) (LTyFamDefltDecl GhcPs -> Maybe GhcTag)
-> [LTyFamDefltDecl GhcPs] -> GhcTags
forall a b. (a -> Maybe b) -> [a] -> [b]
`mapMaybe`  [LTyFamDefltDecl GhcPs]
cid_tyfam_insts

          -- data family instance
          DataFamInstD { DataFamInstDecl GhcPs
dfid_inst :: forall pass. InstDecl pass -> DataFamInstDecl pass
dfid_inst :: DataFamInstDecl GhcPs
dfid_inst } ->
            SrcSpan -> DataFamInstDecl GhcPs -> GhcTags
mkDataFamInstDeclTag SrcSpan
decLoc DataFamInstDecl GhcPs
dfid_inst GhcTags -> GhcTags -> GhcTags
forall a. [a] -> [a] -> [a]
++ GhcTags
tags

          -- type family instance
          TyFamInstD { TyFamInstDecl GhcPs
tfid_inst :: forall pass. InstDecl pass -> TyFamInstDecl pass
tfid_inst :: TyFamInstDecl GhcPs
tfid_inst } ->
            case SrcSpan -> TyFamInstDecl GhcPs -> Maybe GhcTag
mkTyFamInstDeclTag SrcSpan
decLoc TyFamInstDecl GhcPs
tfid_inst of
              Maybe GhcTag
Nothing  ->       GhcTags
tags
              Just GhcTag
tag -> GhcTag
tag GhcTag -> GhcTags -> GhcTags
forall a. a -> [a] -> [a]
: GhcTags
tags

#if __GLASGOW_HASKELL__ < 900
          XInstDecl {} -> GhcTags
tags
#endif

      -- deriving declaration
      DerivD {} -> GhcTags
tags

      -- value declaration
      ValD XValD GhcPs
_ HsBindLR GhcPs GhcPs
hsBind  -> SrcSpan -> HsBindLR GhcPs GhcPs -> GhcTags
mkHsBindLRTags SrcSpan
decLoc HsBindLR GhcPs GhcPs
hsBind GhcTags -> GhcTags -> GhcTags
forall a. [a] -> [a] -> [a]
++ GhcTags
tags

      -- signature declaration
      SigD XSigD GhcPs
_ Sig GhcPs
sig -> SrcSpan -> Sig GhcPs -> GhcTags
mkSigTags SrcSpan
decLoc Sig GhcPs
sig GhcTags -> GhcTags -> GhcTags
forall a. [a] -> [a] -> [a]
++ GhcTags
tags

#if __GLASGOW_HASKELL__ >= 810
      -- standalone kind signatures
      KindSigD XKindSigD GhcPs
_ StandaloneKindSig GhcPs
stdKindSig ->
        case StandaloneKindSig GhcPs
stdKindSig of
          StandaloneKindSig XStandaloneKindSig GhcPs
_ Located (IdP GhcPs)
ksName LHsSigType GhcPs
sigType ->
           SrcSpan -> Located RdrName -> GhcTagKind -> GhcTag
mkGhcTag' SrcSpan
decLoc (Located RdrName -> Located RdrName
unSpanAnn Located (IdP GhcPs)
Located RdrName
ksName)  (LHsSigType GhcPs -> GhcTagKind
GtkTypeKindSignature LHsSigType GhcPs
sigType) GhcTag -> GhcTags -> GhcTags
forall a. a -> [a] -> [a]
: GhcTags
tags

#if __GLASGOW_HASKELL__ < 900
          XStandaloneKindSig {} -> GhcTags
tags
#endif
#endif

      -- default declaration
      DefD {} -> GhcTags
tags

      -- foreign declaration
      ForD XForD GhcPs
_ ForeignDecl GhcPs
foreignDecl ->
        case ForeignDecl GhcPs
foreignDecl of
          ForeignImport { Located (IdP GhcPs)
fd_name :: forall pass. ForeignDecl pass -> Located (IdP pass)
fd_name :: Located (IdP GhcPs)
fd_name, fd_fi :: forall pass. ForeignDecl pass -> ForeignImport
fd_fi = CImport Located CCallConv
_ Located Safety
_ Maybe Header
_mheader CImportSpec
_ (L SrcSpan
_ SourceText
sourceText) } ->
                case SourceText
sourceText of
                  SourceText
NoSourceText -> GhcTag
tag
                  -- TODO: add header information from '_mheader'
                  SourceText String
s -> GhcTag
tag { gtFFI :: Maybe String
gtFFI = String -> Maybe String
forall a. a -> Maybe a
Just String
s }
              GhcTag -> GhcTags -> GhcTags
forall a. a -> [a] -> [a]
: GhcTags
tags
            where
              tag :: GhcTag
tag = SrcSpan -> Located RdrName -> GhcTagKind -> GhcTag
mkGhcTag' SrcSpan
decLoc (Located RdrName -> Located RdrName
unSpanAnn Located (IdP GhcPs)
Located RdrName
fd_name) GhcTagKind
GtkForeignImport

          ForeignExport { Located (IdP GhcPs)
fd_name :: Located (IdP GhcPs)
fd_name :: forall pass. ForeignDecl pass -> Located (IdP pass)
fd_name } ->
              SrcSpan -> Located RdrName -> GhcTagKind -> GhcTag
mkGhcTag' SrcSpan
decLoc (Located RdrName -> Located RdrName
unSpanAnn Located (IdP GhcPs)
Located RdrName
fd_name) GhcTagKind
GtkForeignExport
            GhcTag -> GhcTags -> GhcTags
forall a. a -> [a] -> [a]
: GhcTags
tags

#if __GLASGOW_HASKELL__ < 900
          XForeignDecl {} -> GhcTags
tags
#endif

      WarningD {}   -> GhcTags
tags
      AnnD {}       -> GhcTags
tags

      -- TODO: Rules are named it would be nice to get them too
      RuleD {}      -> GhcTags
tags
      SpliceD {}    -> GhcTags
tags
      DocD {}       -> GhcTags
tags
      RoleAnnotD {} -> GhcTags
tags
#if __GLASGOW_HASKELL__ < 900
      XHsDecl {}    -> GhcTags
tags
#endif


    -- generate tags of all constructors of a type
    --
    mkConsTags :: SrcSpan
               -> Located RdrName
               -- name of the type
               -> ConDecl GhcPs
               -- constructor declaration
               -> GhcTags

#if __GLASGOW_HASKELL__ < 902
    mkConsTags :: SrcSpan -> Located RdrName -> ConDecl GhcPs -> GhcTags
mkConsTags SrcSpan
decLoc Located RdrName
tyName con :: ConDecl GhcPs
con@ConDeclGADT { [Located (IdP GhcPs)]
con_names :: forall pass. ConDecl pass -> [Located (IdP pass)]
con_names :: [Located (IdP GhcPs)]
con_names, HsConDeclDetails GhcPs
con_args :: forall pass. ConDecl pass -> HsConDeclDetails pass
con_args :: HsConDeclDetails GhcPs
con_args } =
#else
    mkConsTags decLoc tyName con@ConDeclGADT { con_names, con_g_args = con_args } =
#endif
         ( (\Located RdrName
n -> SrcSpan
-> Located RdrName -> Located RdrName -> GhcTagKind -> GhcTag
mkGhcTagForMember SrcSpan
decLoc Located RdrName
n Located RdrName
tyName (ConDecl GhcPs -> GhcTagKind
GtkGADTConstructor ConDecl GhcPs
con))
         (Located RdrName -> GhcTag)
-> (Located RdrName -> Located RdrName)
-> Located RdrName
-> GhcTag
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Located RdrName -> Located RdrName
unSpanAnn )
         (Located RdrName -> GhcTag) -> [Located RdrName] -> GhcTags
forall a b. (a -> b) -> [a] -> [b]
`map` [Located (IdP GhcPs)]
[Located RdrName]
con_names
      GhcTags -> GhcTags -> GhcTags
forall a. [a] -> [a] -> [a]
++ SrcSpan -> Located RdrName -> HsConDeclDetails GhcPs -> GhcTags
mkHsConDeclGADTDetails SrcSpan
decLoc Located RdrName
tyName HsConDeclDetails GhcPs
con_args

    mkConsTags SrcSpan
decLoc Located RdrName
tyName con :: ConDecl GhcPs
con@ConDeclH98  { Located (IdP GhcPs)
con_name :: forall pass. ConDecl pass -> Located (IdP pass)
con_name :: Located (IdP GhcPs)
con_name, HsConDeclDetails GhcPs
con_args :: HsConDeclDetails GhcPs
con_args :: forall pass. ConDecl pass -> HsConDeclDetails pass
con_args } =
        SrcSpan
-> Located RdrName -> Located RdrName -> GhcTagKind -> GhcTag
mkGhcTagForMember SrcSpan
decLoc (Located RdrName -> Located RdrName
unSpanAnn Located (IdP GhcPs)
Located RdrName
con_name) Located RdrName
tyName
          (ConDecl GhcPs -> GhcTagKind
GtkDataConstructor ConDecl GhcPs
con)
      GhcTag -> GhcTags -> GhcTags
forall a. a -> [a] -> [a]
: SrcSpan -> Located RdrName -> HsConDeclDetails GhcPs -> GhcTags
mkHsConDeclH98Details SrcSpan
decLoc Located RdrName
tyName HsConDeclDetails GhcPs
con_args

#if __GLASGOW_HASKELL__ < 900
    mkConsTags SrcSpan
_ Located RdrName
_ XConDecl {} = []
#endif

    mkHsConDeclH98Details :: SrcSpan
                          -> Located RdrName
                          -> HsConDeclH98Details GhcPs
                          -> GhcTags
    mkHsConDeclH98Details :: SrcSpan -> Located RdrName -> HsConDeclDetails GhcPs -> GhcTags
mkHsConDeclH98Details SrcSpan
decLoc Located RdrName
tyName (RecCon (L SrcSpan
_ [LConDeclField GhcPs]
fields)) =
        (GhcTags -> LConDeclField GhcPs -> GhcTags)
-> GhcTags -> [LConDeclField GhcPs] -> GhcTags
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' GhcTags -> LConDeclField GhcPs -> GhcTags
f [] [LConDeclField GhcPs]
fields
      where
        f :: GhcTags -> LConDeclField GhcPs -> GhcTags
        f :: GhcTags -> LConDeclField GhcPs -> GhcTags
f GhcTags
ts (L SrcSpan
_ ConDeclField { [LFieldOcc GhcPs]
cd_fld_names :: forall pass. ConDeclField pass -> [LFieldOcc pass]
cd_fld_names :: [LFieldOcc GhcPs]
cd_fld_names }) = (GhcTags -> LFieldOcc GhcPs -> GhcTags)
-> GhcTags -> [LFieldOcc GhcPs] -> GhcTags
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' GhcTags -> LFieldOcc GhcPs -> GhcTags
g GhcTags
ts [LFieldOcc GhcPs]
cd_fld_names
#if __GLASGOW_HASKELL__ < 900
        f GhcTags
ts LConDeclField GhcPs
_ = GhcTags
ts
#endif

        g :: GhcTags -> LFieldOcc GhcPs -> GhcTags
        g :: GhcTags -> LFieldOcc GhcPs -> GhcTags
g GhcTags
ts (L SrcSpan
_ FieldOcc { Located RdrName
rdrNameFieldOcc :: forall pass. FieldOcc pass -> Located RdrName
rdrNameFieldOcc :: Located RdrName
rdrNameFieldOcc }) =
            SrcSpan
-> Located RdrName -> Located RdrName -> GhcTagKind -> GhcTag
mkGhcTagForMember SrcSpan
decLoc (Located RdrName -> Located RdrName
unSpanAnn Located RdrName
rdrNameFieldOcc) Located RdrName
tyName GhcTagKind
GtkRecordField
          GhcTag -> GhcTags -> GhcTags
forall a. a -> [a] -> [a]
: GhcTags
ts
#if __GLASGOW_HASKELL__ < 900
        g GhcTags
ts LFieldOcc GhcPs
_ = GhcTags
ts
#endif

    mkHsConDeclH98Details SrcSpan
_ Located RdrName
_ HsConDeclDetails GhcPs
_ = []

    mkHsConDeclGADTDetails :: SrcSpan
                           -> Located RdrName
#if __GLASGOW_HASKELL__ < 902
                           -> HsConDeclH98Details  GhcPs
#else
                           -> HsConDeclGADTDetails GhcPs
#endif
                           -> GhcTags
#if __GLASGOW_HASKELL__ < 902
    mkHsConDeclGADTDetails :: SrcSpan -> Located RdrName -> HsConDeclDetails GhcPs -> GhcTags
mkHsConDeclGADTDetails = SrcSpan -> Located RdrName -> HsConDeclDetails GhcPs -> GhcTags
mkHsConDeclH98Details
#else
    mkHsConDeclGADTDetails decLoc tyName (RecConGADT (L _ fields)) =
        foldl' f [] fields
      where
        f :: GhcTags -> LConDeclField GhcPs -> GhcTags
        f ts (L _ ConDeclField { cd_fld_names }) = foldl' g ts cd_fld_names

        g :: GhcTags -> LFieldOcc GhcPs -> GhcTags
        g ts (L _ FieldOcc { rdrNameFieldOcc }) =
            mkGhcTagForMember decLoc (unSpanAnn rdrNameFieldOcc) tyName GtkRecordField
          : ts
    mkHsConDeclGADTDetails _ _ _ = []
#endif


    mkHsBindLRTags :: SrcSpan
                   -- ^ declaration's 'SrcSpan'
                   -> HsBindLR GhcPs GhcPs
                   -> GhcTags
    mkHsBindLRTags :: SrcSpan -> HsBindLR GhcPs GhcPs -> GhcTags
mkHsBindLRTags SrcSpan
decLoc HsBindLR GhcPs GhcPs
hsBind =
      case HsBindLR GhcPs GhcPs
hsBind of
        FunBind { Located (IdP GhcPs)
fun_id :: forall idL idR. HsBindLR idL idR -> Located (IdP idL)
fun_id :: Located (IdP GhcPs)
fun_id } -> [SrcSpan -> Located RdrName -> GhcTagKind -> GhcTag
mkGhcTag' SrcSpan
decLoc (Located RdrName -> Located RdrName
unSpanAnn Located (IdP GhcPs)
Located RdrName
fun_id) GhcTagKind
GtkFunction]

        -- TODO
        -- This is useful fo generating tags for
        -- ````
        -- Just x = lhs
        -- ```
        PatBind {} -> []

        VarBind { IdP GhcPs
var_id :: forall idL idR. HsBindLR idL idR -> IdP idL
var_id :: IdP GhcPs
var_id, var_rhs :: forall idL idR. HsBindLR idL idR -> LHsExpr idR
var_rhs = L SrcSpan
srcSpan HsExpr GhcPs
_ } ->
          [SrcSpan -> Located RdrName -> GhcTagKind -> GhcTag
mkGhcTag' SrcSpan
decLoc (Located RdrName -> Located RdrName
unSpanAnn (Located RdrName -> Located RdrName)
-> Located RdrName -> Located RdrName
forall a b. (a -> b) -> a -> b
$ SrcSpan -> RdrName -> Located RdrName
forall l e. l -> e -> GenLocated l e
L SrcSpan
srcSpan IdP GhcPs
RdrName
var_id) GhcTagKind
GtkTerm]

        -- abstraction binding is only used after translation
        AbsBinds {} -> []

        PatSynBind XPatSynBind GhcPs GhcPs
_ PSB { Located (IdP GhcPs)
psb_id :: forall idL idR. PatSynBind idL idR -> Located (IdP idL)
psb_id :: Located (IdP GhcPs)
psb_id } -> [SrcSpan -> Located RdrName -> GhcTagKind -> GhcTag
mkGhcTag' SrcSpan
decLoc (Located RdrName -> Located RdrName
unSpanAnn Located (IdP GhcPs)
Located RdrName
psb_id) GhcTagKind
GtkPatternSynonym]
#if __GLASGOW_HASKELL__ < 900
        PatSynBind XPatSynBind GhcPs GhcPs
_ XPatSynBind {} -> []
#endif

#if __GLASGOW_HASKELL__ < 900
        XHsBindsLR {} -> []
#endif


    mkClsMemberTags :: SrcSpan -> Located RdrName -> Sig GhcPs -> GhcTags
    mkClsMemberTags :: SrcSpan -> Located RdrName -> Sig GhcPs -> GhcTags
mkClsMemberTags SrcSpan
decLoc Located RdrName
clsName (TypeSig   XTypeSig GhcPs
_ [Located (IdP GhcPs)]
lhs LHsSigWcType GhcPs
hsSigWcType) =
      ( (\Located RdrName
n -> SrcSpan
-> Located RdrName -> Located RdrName -> GhcTagKind -> GhcTag
mkGhcTagForMember SrcSpan
decLoc Located RdrName
n Located RdrName
clsName (LHsSigWcType GhcPs -> GhcTagKind
GtkTypeSignature LHsSigWcType GhcPs
hsSigWcType))
      (Located RdrName -> GhcTag)
-> (Located RdrName -> Located RdrName)
-> Located RdrName
-> GhcTag
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Located RdrName -> Located RdrName
unSpanAnn )
      (Located RdrName -> GhcTag) -> [Located RdrName] -> GhcTags
forall a b. (a -> b) -> [a] -> [b]
`map` [Located (IdP GhcPs)]
[Located RdrName]
lhs
    mkClsMemberTags SrcSpan
decLoc Located RdrName
clsName (PatSynSig XPatSynSig GhcPs
_ [Located (IdP GhcPs)]
lhs LHsSigType GhcPs
_) =
      ( (\Located RdrName
n -> SrcSpan
-> Located RdrName -> Located RdrName -> GhcTagKind -> GhcTag
mkGhcTagForMember SrcSpan
decLoc Located RdrName
n Located RdrName
clsName GhcTagKind
GtkPatternSynonym)
      (Located RdrName -> GhcTag)
-> (Located RdrName -> Located RdrName)
-> Located RdrName
-> GhcTag
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Located RdrName -> Located RdrName
unSpanAnn )
      (Located RdrName -> GhcTag) -> [Located RdrName] -> GhcTags
forall a b. (a -> b) -> [a] -> [b]
`map` [Located (IdP GhcPs)]
[Located RdrName]
lhs
#if __GLASGOW_HASKELL__ < 902
    mkClsMemberTags SrcSpan
decLoc Located RdrName
clsName (ClassOpSig XClassOpSig GhcPs
_ Bool
_ [Located (IdP GhcPs)]
lhs HsIB { hsib_body :: forall pass thing. HsImplicitBndrs pass thing -> thing
hsib_body = L SrcSpan
_ HsType GhcPs
hsType}) =
#else
    mkClsMemberTags decLoc clsName (ClassOpSig _ _ lhs (L _ hsType)) =
#endif
      ( (\Located RdrName
n -> SrcSpan
-> Located RdrName -> Located RdrName -> GhcTagKind -> GhcTag
mkGhcTagForMember SrcSpan
decLoc Located RdrName
n Located RdrName
clsName
                                (HsType GhcPs -> GhcTagKind
GtkTypeClassMember (HsType GhcPs -> GhcTagKind) -> HsType GhcPs -> GhcTagKind
forall a b. (a -> b) -> a -> b
$ HsType GhcPs -> HsType GhcPs
hsSigTypeToHsType HsType GhcPs
hsType))
      (Located RdrName -> GhcTag)
-> (Located RdrName -> Located RdrName)
-> Located RdrName
-> GhcTag
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Located RdrName -> Located RdrName
unSpanAnn )
     (Located RdrName -> GhcTag) -> [Located RdrName] -> GhcTags
forall a b. (a -> b) -> [a] -> [b]
`map` [Located (IdP GhcPs)]
[Located RdrName]
lhs
    mkClsMemberTags SrcSpan
_ Located RdrName
_ Sig GhcPs
_ = []


    mkSigTags :: SrcSpan -> Sig GhcPs -> GhcTags
    mkSigTags :: SrcSpan -> Sig GhcPs -> GhcTags
mkSigTags SrcSpan
decLoc (TypeSig   XTypeSig GhcPs
_ [Located (IdP GhcPs)]
lhs LHsSigWcType GhcPs
hsSigWcType)
                                       = ( (Located RdrName -> GhcTagKind -> GhcTag)
-> GhcTagKind -> Located RdrName -> GhcTag
forall a b c. (a -> b -> c) -> b -> a -> c
flip (SrcSpan -> Located RdrName -> GhcTagKind -> GhcTag
mkGhcTag' SrcSpan
decLoc)
                                                (LHsSigWcType GhcPs -> GhcTagKind
GtkTypeSignature LHsSigWcType GhcPs
hsSigWcType)
                                         (Located RdrName -> GhcTag)
-> (Located RdrName -> Located RdrName)
-> Located RdrName
-> GhcTag
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Located RdrName -> Located RdrName
unSpanAnn )
                                         (Located RdrName -> GhcTag) -> [Located RdrName] -> GhcTags
forall a b. (a -> b) -> [a] -> [b]
`map` [Located (IdP GhcPs)]
[Located RdrName]
lhs
    mkSigTags SrcSpan
decLoc (PatSynSig XPatSynSig GhcPs
_ [Located (IdP GhcPs)]
lhs LHsSigType GhcPs
_)
                                       = ( (Located RdrName -> GhcTagKind -> GhcTag)
-> GhcTagKind -> Located RdrName -> GhcTag
forall a b c. (a -> b -> c) -> b -> a -> c
flip (SrcSpan -> Located RdrName -> GhcTagKind -> GhcTag
mkGhcTag' SrcSpan
decLoc) GhcTagKind
GtkPatternSynonym
                                         (Located RdrName -> GhcTag)
-> (Located RdrName -> Located RdrName)
-> Located RdrName
-> GhcTag
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Located RdrName -> Located RdrName
unSpanAnn )
                                         (Located RdrName -> GhcTag) -> [Located RdrName] -> GhcTags
forall a b. (a -> b) -> [a] -> [b]
`map` [Located (IdP GhcPs)]
[Located RdrName]
lhs
#if __GLASGOW_HASKELL__ < 902
    mkSigTags SrcSpan
decLoc (ClassOpSig XClassOpSig GhcPs
_ Bool
_ [Located (IdP GhcPs)]
lhs HsIB { hsib_body :: forall pass thing. HsImplicitBndrs pass thing -> thing
hsib_body = L SrcSpan
_ HsType GhcPs
hsType })
#else
    mkSigTags decLoc (ClassOpSig _ _ lhs (L _ hsType))
#endif
                                       = ( (Located RdrName -> GhcTagKind -> GhcTag)
-> GhcTagKind -> Located RdrName -> GhcTag
forall a b c. (a -> b -> c) -> b -> a -> c
flip (SrcSpan -> Located RdrName -> GhcTagKind -> GhcTag
mkGhcTag' SrcSpan
decLoc)
                                                ( HsType GhcPs -> GhcTagKind
GtkTypeClassMember
                                                (HsType GhcPs -> GhcTagKind) -> HsType GhcPs -> GhcTagKind
forall a b. (a -> b) -> a -> b
$ HsType GhcPs -> HsType GhcPs
hsSigTypeToHsType HsType GhcPs
hsType )
                                         (Located RdrName -> GhcTag)
-> (Located RdrName -> Located RdrName)
-> Located RdrName
-> GhcTag
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Located RdrName -> Located RdrName
unSpanAnn
                                         )
                                         (Located RdrName -> GhcTag) -> [Located RdrName] -> GhcTags
forall a b. (a -> b) -> [a] -> [b]
`map` [Located (IdP GhcPs)]
[Located RdrName]
lhs
#if __GLASGOW_HASKELL__ < 900
    mkSigTags SrcSpan
_ (ClassOpSig XClassOpSig GhcPs
_ Bool
_ [Located (IdP GhcPs)]
_ XHsImplicitBndrs {})
                                       = []
#endif
    mkSigTags SrcSpan
_ IdSig {}               = []
    -- TODO: generate theses with additional info (fixity)
    mkSigTags SrcSpan
_ FixSig {}              = []
    mkSigTags SrcSpan
_ InlineSig {}           = []
    -- SPECIALISE pragmas
    mkSigTags SrcSpan
_ SpecSig {}             = []
    mkSigTags SrcSpan
_ SpecInstSig {}         = []
    -- MINIMAL pragma
    mkSigTags SrcSpan
_ MinimalSig {}          = []
    -- SSC pragma
    mkSigTags SrcSpan
_ SCCFunSig {}           = []
    -- COMPLETE pragma
    mkSigTags SrcSpan
_ CompleteMatchSig {}    = []
#if __GLASGOW_HASKELL__ < 900
    mkSigTags SrcSpan
_ XSig {}                = []
#endif


    mkFamilyDeclTags :: SrcSpan
                     -> FamilyDecl GhcPs
                     -- ^ declaration's 'SrcSpan'
                     -> Maybe (Located RdrName)
                     -- if this type family is associate, pass the name of the
                     -- associated class
                     -> Maybe GhcTag
    mkFamilyDeclTags :: SrcSpan
-> FamilyDecl GhcPs -> Maybe (Located RdrName) -> Maybe GhcTag
mkFamilyDeclTags SrcSpan
decLoc FamilyDecl { Located (IdP GhcPs)
fdLName :: forall pass. FamilyDecl pass -> Located (IdP pass)
fdLName :: Located (IdP GhcPs)
fdLName, 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, fdResultSig :: forall pass. FamilyDecl pass -> LFamilyResultSig pass
fdResultSig = L SrcSpan
_ FamilyResultSig GhcPs
familyResultSig } Maybe (Located RdrName)
assocClsName =
      case Maybe (Located RdrName)
assocClsName of
        Maybe (Located RdrName)
Nothing      -> GhcTag -> Maybe GhcTag
forall a. a -> Maybe a
Just (GhcTag -> Maybe GhcTag) -> GhcTag -> Maybe GhcTag
forall a b. (a -> b) -> a -> b
$ SrcSpan -> Located RdrName -> GhcTagKind -> GhcTag
mkGhcTag' SrcSpan
decLoc (Located RdrName -> Located RdrName
unSpanAnn Located (IdP GhcPs)
Located RdrName
fdLName) GhcTagKind
tk
        Just Located RdrName
clsName -> GhcTag -> Maybe GhcTag
forall a. a -> Maybe a
Just (GhcTag -> Maybe GhcTag) -> GhcTag -> Maybe GhcTag
forall a b. (a -> b) -> a -> b
$ SrcSpan
-> Located RdrName -> Located RdrName -> GhcTagKind -> GhcTag
mkGhcTagForMember SrcSpan
decLoc (Located RdrName -> Located RdrName
unSpanAnn Located (IdP GhcPs)
Located RdrName
fdLName) Located RdrName
clsName GhcTagKind
tk
      where

        mb_fdvars :: Maybe [HsTyVarBndr GhcPs]
mb_fdvars = case LHsQTyVars GhcPs
fdTyVars of
          HsQTvs { [LHsTyVarBndr GhcPs]
hsq_explicit :: forall pass. LHsQTyVars pass -> [LHsTyVarBndr pass]
hsq_explicit :: [LHsTyVarBndr GhcPs]
hsq_explicit } -> [HsTyVarBndr GhcPs] -> Maybe [HsTyVarBndr GhcPs]
forall a. a -> Maybe a
Just ([HsTyVarBndr GhcPs] -> Maybe [HsTyVarBndr GhcPs])
-> [HsTyVarBndr GhcPs] -> Maybe [HsTyVarBndr GhcPs]
forall a b. (a -> b) -> a -> b
$ LHsTyVarBndr GhcPs -> HsTyVarBndr GhcPs
forall a. HasSrcSpan a => a -> SrcSpanLess a
unLoc (LHsTyVarBndr GhcPs -> HsTyVarBndr GhcPs)
-> [LHsTyVarBndr GhcPs] -> [HsTyVarBndr GhcPs]
forall a b. (a -> b) -> [a] -> [b]
`map` [LHsTyVarBndr GhcPs]
hsq_explicit
#if __GLASGOW_HASKELL__ < 900
          XLHsQTyVars {} -> Maybe [HsTyVarBndr GhcPs]
forall a. Maybe a
Nothing
#endif
        mb_resultsig :: Maybe (Either (HsType GhcPs) (HsTyVarBndr GhcPs))
mb_resultsig = FamilyResultSig GhcPs
-> Maybe (Either (HsType GhcPs) (HsTyVarBndr GhcPs))
famResultKindSignature FamilyResultSig GhcPs
familyResultSig

        mb_typesig :: Maybe
  ([HsTyVarBndr GhcPs], Either (HsType GhcPs) (HsTyVarBndr GhcPs))
mb_typesig = (,) ([HsTyVarBndr GhcPs]
 -> Either (HsType GhcPs) (HsTyVarBndr GhcPs)
 -> ([HsTyVarBndr GhcPs],
     Either (HsType GhcPs) (HsTyVarBndr GhcPs)))
-> Maybe [HsTyVarBndr GhcPs]
-> Maybe
     (Either (HsType GhcPs) (HsTyVarBndr GhcPs)
      -> ([HsTyVarBndr GhcPs],
          Either (HsType GhcPs) (HsTyVarBndr GhcPs)))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe [HsTyVarBndr GhcPs]
mb_fdvars Maybe
  (Either (HsType GhcPs) (HsTyVarBndr GhcPs)
   -> ([HsTyVarBndr GhcPs],
       Either (HsType GhcPs) (HsTyVarBndr GhcPs)))
-> Maybe (Either (HsType GhcPs) (HsTyVarBndr GhcPs))
-> Maybe
     ([HsTyVarBndr GhcPs], Either (HsType GhcPs) (HsTyVarBndr GhcPs))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Maybe (Either (HsType GhcPs) (HsTyVarBndr GhcPs))
mb_resultsig

        tk :: GhcTagKind
tk = case FamilyInfo GhcPs
fdInfo of
              FamilyInfo GhcPs
DataFamily           -> Maybe
  ([HsTyVarBndr GhcPs], Either (HsType GhcPs) (HsTyVarBndr GhcPs))
-> GhcTagKind
GtkDataTypeFamily Maybe
  ([HsTyVarBndr GhcPs], Either (HsType GhcPs) (HsTyVarBndr GhcPs))
mb_typesig
              FamilyInfo GhcPs
OpenTypeFamily       -> Maybe
  ([HsTyVarBndr GhcPs], Either (HsType GhcPs) (HsTyVarBndr GhcPs))
-> GhcTagKind
GtkTypeFamily     Maybe
  ([HsTyVarBndr GhcPs], Either (HsType GhcPs) (HsTyVarBndr GhcPs))
mb_typesig
              ClosedTypeFamily {}  -> Maybe
  ([HsTyVarBndr GhcPs], Either (HsType GhcPs) (HsTyVarBndr GhcPs))
-> GhcTagKind
GtkTypeFamily     Maybe
  ([HsTyVarBndr GhcPs], Either (HsType GhcPs) (HsTyVarBndr GhcPs))
mb_typesig
#if __GLASGOW_HASKELL__ < 900
    mkFamilyDeclTags SrcSpan
_ XFamilyDecl {} Maybe (Located RdrName)
_ = Maybe GhcTag
forall a. Maybe a
Nothing
#endif


    -- used to generate tag of an instance declaration
    mkLHsTypeTag :: SrcSpan
                 -- declartaion's 'SrcSpan'
                 -> LHsType GhcPs
                 -> Maybe GhcTag
    mkLHsTypeTag :: SrcSpan -> GenLocated SrcSpan (HsType GhcPs) -> Maybe GhcTag
mkLHsTypeTag SrcSpan
decLoc (L SrcSpan
_ HsType GhcPs
hsType) =
      (\Located RdrName
a -> SrcSpan -> GhcTag -> GhcTag
fixLoc SrcSpan
decLoc (GhcTag -> GhcTag) -> GhcTag -> GhcTag
forall a b. (a -> b) -> a -> b
$ Located RdrName -> GhcTagKind -> Bool -> GhcTag
mkGhcTag Located RdrName
a (HsType GhcPs -> GhcTagKind
GtkTypeClassInstance HsType GhcPs
hsType) Bool
True)
      (Located RdrName -> GhcTag)
-> Maybe (Located RdrName) -> Maybe GhcTag
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> HsType GhcPs -> Maybe (Located RdrName)
hsTypeTagName HsType GhcPs
hsType


    hsTypeTagName :: HsType GhcPs -> Maybe (Located RdrName)
    hsTypeTagName :: HsType GhcPs -> Maybe (Located RdrName)
hsTypeTagName HsType GhcPs
hsType =
      case HsType GhcPs
hsType of
        HsForAllTy {GenLocated SrcSpan (HsType GhcPs)
hst_body :: forall pass. HsType pass -> LHsType pass
hst_body :: GenLocated SrcSpan (HsType GhcPs)
hst_body} -> HsType GhcPs -> Maybe (Located RdrName)
hsTypeTagName (GenLocated SrcSpan (HsType GhcPs)
-> SrcSpanLess (GenLocated SrcSpan (HsType GhcPs))
forall a. HasSrcSpan a => a -> SrcSpanLess a
unLoc GenLocated SrcSpan (HsType GhcPs)
hst_body)

        HsQualTy {GenLocated SrcSpan (HsType GhcPs)
hst_body :: GenLocated SrcSpan (HsType GhcPs)
hst_body :: forall pass. HsType pass -> LHsType pass
hst_body}   -> HsType GhcPs -> Maybe (Located RdrName)
hsTypeTagName (GenLocated SrcSpan (HsType GhcPs)
-> SrcSpanLess (GenLocated SrcSpan (HsType GhcPs))
forall a. HasSrcSpan a => a -> SrcSpanLess a
unLoc GenLocated SrcSpan (HsType GhcPs)
hst_body)

        HsTyVar XTyVar GhcPs
_ PromotionFlag
_ Located (IdP GhcPs)
a         -> Located RdrName -> Maybe (Located RdrName)
forall a. a -> Maybe a
Just (Located RdrName -> Maybe (Located RdrName))
-> Located RdrName -> Maybe (Located RdrName)
forall a b. (a -> b) -> a -> b
$ Located RdrName -> Located RdrName
unSpanAnn Located (IdP GhcPs)
Located RdrName
a

        HsAppTy XAppTy GhcPs
_ GenLocated SrcSpan (HsType GhcPs)
a GenLocated SrcSpan (HsType GhcPs)
_         -> HsType GhcPs -> Maybe (Located RdrName)
hsTypeTagName (GenLocated SrcSpan (HsType GhcPs)
-> SrcSpanLess (GenLocated SrcSpan (HsType GhcPs))
forall a. HasSrcSpan a => a -> SrcSpanLess a
unLoc GenLocated SrcSpan (HsType GhcPs)
a)
        HsOpTy XOpTy GhcPs
_ GenLocated SrcSpan (HsType GhcPs)
_ Located (IdP GhcPs)
a GenLocated SrcSpan (HsType GhcPs)
_        -> Located RdrName -> Maybe (Located RdrName)
forall a. a -> Maybe a
Just (Located RdrName -> Maybe (Located RdrName))
-> Located RdrName -> Maybe (Located RdrName)
forall a b. (a -> b) -> a -> b
$ Located RdrName -> Located RdrName
unSpanAnn Located (IdP GhcPs)
Located RdrName
a
        HsKindSig XKindSig GhcPs
_ GenLocated SrcSpan (HsType GhcPs)
a GenLocated SrcSpan (HsType GhcPs)
_       -> HsType GhcPs -> Maybe (Located RdrName)
hsTypeTagName (GenLocated SrcSpan (HsType GhcPs)
-> SrcSpanLess (GenLocated SrcSpan (HsType GhcPs))
forall a. HasSrcSpan a => a -> SrcSpanLess a
unLoc GenLocated SrcSpan (HsType GhcPs)
a)

        HsType GhcPs
_                     -> Maybe (Located RdrName)
forall a. Maybe a
Nothing


    -- data family instance declaration
    --
    mkDataFamInstDeclTag :: SrcSpan -> DataFamInstDecl GhcPs -> GhcTags
    mkDataFamInstDeclTag :: SrcSpan -> DataFamInstDecl GhcPs -> GhcTags
mkDataFamInstDeclTag SrcSpan
decLoc DataFamInstDecl { FamInstEqn GhcPs (HsDataDefn GhcPs)
dfid_eqn :: forall pass.
DataFamInstDecl pass -> FamInstEqn pass (HsDataDefn pass)
dfid_eqn :: FamInstEqn GhcPs (HsDataDefn GhcPs)
dfid_eqn } =
      case FamInstEqn GhcPs (HsDataDefn GhcPs)
dfid_eqn of
#if __GLASGOW_HASKELL__ < 900
        XHsImplicitBndrs {} -> []
#endif

#if __GLASGOW_HASKELL__ < 902
        HsIB { hsib_body :: forall pass thing. HsImplicitBndrs pass thing -> thing
hsib_body = FamEqn { Located (IdP GhcPs)
feqn_tycon :: forall pass rhs. FamEqn pass rhs -> Located (IdP pass)
feqn_tycon :: Located (IdP GhcPs)
feqn_tycon, HsDataDefn GhcPs
feqn_rhs :: HsDataDefn GhcPs
feqn_rhs :: forall pass rhs. FamEqn pass rhs -> rhs
feqn_rhs } } ->
#else
        FamEqn { feqn_tycon, feqn_rhs } ->
#endif
          case HsDataDefn GhcPs
feqn_rhs of
            HsDataDefn { [LConDecl GhcPs]
dd_cons :: [LConDecl GhcPs]
dd_cons :: forall pass. HsDataDefn pass -> [LConDecl pass]
dd_cons, Maybe (GenLocated SrcSpan (HsType GhcPs))
dd_kindSig :: Maybe (GenLocated SrcSpan (HsType GhcPs))
dd_kindSig :: forall pass. HsDataDefn pass -> Maybe (LHsKind pass)
dd_kindSig } ->
                SrcSpan -> Located RdrName -> GhcTagKind -> GhcTag
mkGhcTag' SrcSpan
decLoc (Located RdrName -> Located RdrName
unSpanAnn Located (IdP GhcPs)
Located RdrName
feqn_tycon)
                          (Maybe (HsType GhcPs) -> GhcTagKind
GtkDataTypeFamilyInstance
                            (GenLocated SrcSpan (HsType GhcPs) -> HsType GhcPs
forall a. HasSrcSpan a => a -> SrcSpanLess a
unLoc (GenLocated SrcSpan (HsType GhcPs) -> HsType GhcPs)
-> Maybe (GenLocated SrcSpan (HsType GhcPs))
-> Maybe (HsType GhcPs)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe (GenLocated SrcSpan (HsType GhcPs))
dd_kindSig))
              GhcTag -> GhcTags -> GhcTags
forall a. a -> [a] -> [a]
: (SrcSpan -> Located RdrName -> ConDecl GhcPs -> GhcTags
mkConsTags SrcSpan
decLoc (Located RdrName -> Located RdrName
unSpanAnn Located (IdP GhcPs)
Located RdrName
feqn_tycon) (ConDecl GhcPs -> GhcTags)
-> (LConDecl GhcPs -> ConDecl GhcPs) -> LConDecl GhcPs -> GhcTags
forall b c a. (b -> c) -> (a -> b) -> a -> c
. LConDecl GhcPs -> ConDecl GhcPs
forall a. HasSrcSpan a => a -> SrcSpanLess a
unLoc)
                (LConDecl GhcPs -> GhcTags) -> [LConDecl GhcPs] -> GhcTags
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
`concatMap` [LConDecl GhcPs]
dd_cons

#if __GLASGOW_HASKELL__ < 900
            XHsDataDefn {} ->
              SrcSpan -> Located RdrName -> GhcTagKind -> GhcTag
mkGhcTag' SrcSpan
decLoc Located (IdP GhcPs)
Located RdrName
feqn_tycon (Maybe (HsType GhcPs) -> GhcTagKind
GtkDataTypeFamilyInstance Maybe (HsType GhcPs)
forall a. Maybe a
Nothing) GhcTag -> GhcTags -> GhcTags
forall a. a -> [a] -> [a]
: []

        HsIB { hsib_body :: forall pass thing. HsImplicitBndrs pass thing -> thing
hsib_body = XFamEqn {} } -> []
#endif


    -- type family instance declaration
    --
    mkTyFamInstDeclTag :: SrcSpan -> TyFamInstDecl GhcPs -> Maybe GhcTag
    mkTyFamInstDeclTag :: SrcSpan -> TyFamInstDecl GhcPs -> Maybe GhcTag
mkTyFamInstDeclTag SrcSpan
decLoc decl :: TyFamInstDecl GhcPs
decl@TyFamInstDecl { HsImplicitBndrs
  GhcPs (FamEqn GhcPs (GenLocated SrcSpan (HsType GhcPs)))
tfid_eqn :: forall pass. TyFamInstDecl pass -> TyFamInstEqn pass
tfid_eqn :: HsImplicitBndrs
  GhcPs (FamEqn GhcPs (GenLocated SrcSpan (HsType GhcPs)))
tfid_eqn } =
      case HsImplicitBndrs
  GhcPs (FamEqn GhcPs (GenLocated SrcSpan (HsType GhcPs)))
tfid_eqn of
#if __GLASGOW_HASKELL__ < 900
        XHsImplicitBndrs {} -> Maybe GhcTag
forall a. Maybe a
Nothing
#endif

        -- TODO: should we check @feqn_rhs :: LHsType GhcPs@ as well?
#if __GLASGOW_HASKELL__ < 902
        HsIB { hsib_body :: forall pass thing. HsImplicitBndrs pass thing -> thing
hsib_body = FamEqn { Located (IdP GhcPs)
feqn_tycon :: Located (IdP GhcPs)
feqn_tycon :: forall pass rhs. FamEqn pass rhs -> Located (IdP pass)
feqn_tycon } } ->
#else
        FamEqn { feqn_tycon } ->
#endif
          GhcTag -> Maybe GhcTag
forall a. a -> Maybe a
Just (GhcTag -> Maybe GhcTag) -> GhcTag -> Maybe GhcTag
forall a b. (a -> b) -> a -> b
$ SrcSpan -> Located RdrName -> GhcTagKind -> GhcTag
mkGhcTag' SrcSpan
decLoc (Located RdrName -> Located RdrName
unSpanAnn Located (IdP GhcPs)
Located RdrName
feqn_tycon) (Maybe (TyFamInstDecl GhcPs) -> GhcTagKind
GtkTypeFamilyInstance (TyFamInstDecl GhcPs -> Maybe (TyFamInstDecl GhcPs)
forall a. a -> Maybe a
Just TyFamInstDecl GhcPs
decl))

#if __GLASGOW_HASKELL__ < 900
        HsIB { hsib_body :: forall pass thing. HsImplicitBndrs pass thing -> thing
hsib_body = XFamEqn {} } -> Maybe GhcTag
forall a. Maybe a
Nothing
#endif

#if __GLASGOW_HASKELL__ < 902
unSpanAnn :: Located RdrName -> Located RdrName
unSpanAnn :: Located RdrName -> Located RdrName
unSpanAnn = Located RdrName -> Located RdrName
forall a. a -> a
id
#else
unSpanAnn :: GenLocated (SrcSpanAnn' x) RdrName -> Located RdrName
unSpanAnn (L s a) = L (locA s) a
#endif

#if __GLASGOW_HASKELL__ < 902
locAnn :: SrcSpan -> SrcSpan
locAnn :: SrcSpan -> SrcSpan
locAnn = SrcSpan -> SrcSpan
forall a. a -> a
id
#else
locAnn :: SrcSpanAnn' a -> SrcSpan
locAnn = locA
#endif

#if __GLASGOW_HASKELL__ < 902
hsSigTypeToHsType :: HsType GhcPs -> HsType GhcPs
hsSigTypeToHsType :: HsType GhcPs -> HsType GhcPs
hsSigTypeToHsType = HsType GhcPs -> HsType GhcPs
forall a. a -> a
id
#else
hsSigTypeToHsType :: HsSigType GhcPs -> HsType GhcPs
hsSigTypeToHsType = unLoc . sig_body
#endif

--
--
--

famResultKindSignature :: FamilyResultSig GhcPs
                       -> Maybe (Either (HsKind GhcPs) GhcPsHsTyVarBndr)
famResultKindSignature :: FamilyResultSig GhcPs
-> Maybe (Either (HsType GhcPs) (HsTyVarBndr GhcPs))
famResultKindSignature (NoSig XNoSig GhcPs
_)           = Maybe (Either (HsType GhcPs) (HsTyVarBndr GhcPs))
forall a. Maybe a
Nothing
famResultKindSignature (KindSig XCKindSig GhcPs
_ GenLocated SrcSpan (HsType GhcPs)
ki)      = Either (HsType GhcPs) (HsTyVarBndr GhcPs)
-> Maybe (Either (HsType GhcPs) (HsTyVarBndr GhcPs))
forall a. a -> Maybe a
Just (HsType GhcPs -> Either (HsType GhcPs) (HsTyVarBndr GhcPs)
forall a b. a -> Either a b
Left (GenLocated SrcSpan (HsType GhcPs)
-> SrcSpanLess (GenLocated SrcSpan (HsType GhcPs))
forall a. HasSrcSpan a => a -> SrcSpanLess a
unLoc GenLocated SrcSpan (HsType GhcPs)
ki))
famResultKindSignature (TyVarSig XTyVarSig GhcPs
_ LHsTyVarBndr GhcPs
bndr)   = Either (HsType GhcPs) (HsTyVarBndr GhcPs)
-> Maybe (Either (HsType GhcPs) (HsTyVarBndr GhcPs))
forall a. a -> Maybe a
Just (HsTyVarBndr GhcPs -> Either (HsType GhcPs) (HsTyVarBndr GhcPs)
forall a b. b -> Either a b
Right (LHsTyVarBndr GhcPs -> SrcSpanLess (LHsTyVarBndr GhcPs)
forall a. HasSrcSpan a => a -> SrcSpanLess a
unLoc LHsTyVarBndr GhcPs
bndr))
#if __GLASGOW_HASKELL__ < 900
famResultKindSignature XFamilyResultSig {} = Maybe (Either (HsType GhcPs) (HsTyVarBndr GhcPs))
forall a. Maybe a
Nothing
#endif