Retrie/GHC.hs (150 lines of code) (raw):
-- Copyright (c) Facebook, Inc. and its affiliates.
--
-- This source code is licensed under the MIT license found in the
-- LICENSE file in the root directory of this source tree.
--
{-# LANGUAGE CPP #-}
{-# LANGUAGE RecordWildCards #-}
module Retrie.GHC
( module Retrie.GHC
, module GHC.Data.Bag
, module GHC.Data.FastString
, module GHC.Data.FastString.Env
, module GHC.Driver.Errors
, module GHC.Hs
, module GHC.Hs.Expr
, module GHC.Parser.Annotation
, module GHC.Parser.Errors.Ppr
, module GHC.Types.Basic
, module GHC.Types.Error
, module GHC.Types.Fixity
, module GHC.Types.Name
, module GHC.Types.Name.Occurrence
, module GHC.Types.Name.Reader
, module GHC.Types.SourceText
, module GHC.Types.SrcLoc
, module GHC.Types.Unique
, module GHC.Types.Unique.FM
, module GHC.Types.Unique.Set
, module GHC.Unit.Module.Name
) where
import GHC
import GHC.Builtin.Names
import GHC.Data.Bag
import GHC.Data.FastString
import GHC.Data.FastString.Env
import GHC.Driver.Errors
import GHC.Hs
import GHC.Hs.Expr
import GHC.Parser.Annotation
import GHC.Parser.Errors.Ppr
import GHC.Types.Basic hiding (EP)
import GHC.Types.Error
import GHC.Types.Fixity
import GHC.Types.Name
import GHC.Types.Name.Occurrence
import GHC.Types.Name.Reader
import GHC.Types.SourceText
import GHC.Types.SrcLoc
import GHC.Types.Unique
import GHC.Types.Unique.FM
import GHC.Types.Unique.Set
import GHC.Unit.Module.Name
import Data.Bifunctor (second)
import Data.Maybe
cLPat :: LPat (GhcPass p) -> LPat (GhcPass p)
cLPat = id
-- | Only returns located pat if there is a genuine location available.
dLPat :: LPat (GhcPass p) -> Maybe (LPat (GhcPass p))
dLPat = Just
-- | Will always give a location, but it may be noSrcSpan.
dLPatUnsafe :: LPat (GhcPass p) -> LPat (GhcPass p)
dLPatUnsafe = id
#if __GLASGOW_HASKELL__ == 808
stripSrcSpanPat :: LPat (GhcPass p) -> Pat (GhcPass p)
stripSrcSpanPat (XPat (L _ p)) = stripSrcSpanPat p
stripSrcSpanPat p = p
#endif
rdrFS :: RdrName -> FastString
rdrFS (Qual m n) = mconcat [moduleNameFS m, fsDot, occNameFS n]
rdrFS rdr = occNameFS (occName rdr)
fsDot :: FastString
fsDot = mkFastString "."
varRdrName :: HsExpr p -> Maybe (LIdP p)
varRdrName (HsVar _ n) = Just n
varRdrName _ = Nothing
tyvarRdrName :: HsType p -> Maybe (LIdP p)
tyvarRdrName (HsTyVar _ _ n) = Just n
tyvarRdrName _ = Nothing
-- fixityDecls :: HsModule -> [(LIdP p, Fixity)]
fixityDecls :: HsModule -> [(LocatedN RdrName, Fixity)]
fixityDecls m =
[ (nm, fixity)
| L _ (SigD _ (FixSig _ (FixitySig _ nms fixity))) <- hsmodDecls m
, nm <- nms
]
ruleInfo :: RuleDecl GhcPs -> [RuleInfo]
ruleInfo (HsRule _ (L _ (_, riName)) _ tyBs valBs riLHS riRHS) =
let
riQuantifiers =
map unLoc (tyBindersToLocatedRdrNames (fromMaybe [] tyBs)) ++
ruleBindersToQs valBs
in [ RuleInfo{..} ]
ruleBindersToQs :: [LRuleBndr GhcPs] -> [RdrName]
ruleBindersToQs bs = catMaybes
[ case b of
RuleBndr _ (L _ v) -> Just v
RuleBndrSig _ (L _ v) _ -> Just v
| L _ b <- bs
]
tyBindersToLocatedRdrNames :: [LHsTyVarBndr s GhcPs] -> [LocatedN RdrName]
tyBindersToLocatedRdrNames vars = catMaybes
[ case var of
UserTyVar _ _ v -> Just v
KindedTyVar _ _ v _ -> Just v
| L _ var <- vars ]
data RuleInfo = RuleInfo
{ riName :: RuleName
, riQuantifiers :: [RdrName]
, riLHS :: LHsExpr GhcPs
, riRHS :: LHsExpr GhcPs
}
#if __GLASGOW_HASKELL__ < 810
noExtField :: NoExt
noExtField = noExt
#endif
overlaps :: SrcSpan -> SrcSpan -> Bool
overlaps (RealSrcSpan s1 _) (RealSrcSpan s2 _) =
srcSpanFile s1 == srcSpanFile s2 &&
((srcSpanStartLine s1, srcSpanStartCol s1) `within` s2 ||
(srcSpanEndLine s1, srcSpanEndCol s1) `within` s2)
overlaps _ _ = False
within :: (Int, Int) -> RealSrcSpan -> Bool
within (l,p) s =
srcSpanStartLine s <= l &&
srcSpanStartCol s <= p &&
srcSpanEndLine s >= l &&
srcSpanEndCol s >= p
lineCount :: [SrcSpan] -> Int
lineCount ss = sum
[ srcSpanEndLine s - srcSpanStartLine s + 1
| RealSrcSpan s _ <- ss
]
showRdrs :: [RdrName] -> String
showRdrs = show . map (occNameString . occName)
uniqBag :: Uniquable a => [(a,b)] -> UniqFM a [b]
uniqBag = listToUFM_C (++) . map (second pure)
getRealLoc :: SrcLoc -> Maybe RealSrcLoc
#if __GLASGOW_HASKELL__ < 900
getRealLoc (RealSrcLoc l) = Just l
#else
getRealLoc (RealSrcLoc l _) = Just l
#endif
getRealLoc _ = Nothing
getRealSpan :: SrcSpan -> Maybe RealSrcSpan
#if __GLASGOW_HASKELL__ < 900
getRealSpan (RealSrcSpan s) = Just s
#else
getRealSpan (RealSrcSpan s _) = Just s
#endif
getRealSpan _ = Nothing