/Retrie/GHC.hs

https://github.com/facebookincubator/retrie · Haskell · 211 lines · 179 code · 23 blank · 9 comment · 7 complexity · 7d55bf8769b8d89c3934eb377c9eb756 MD5 · raw file

  1. -- Copyright (c) Facebook, Inc. and its affiliates.
  2. --
  3. -- This source code is licensed under the MIT license found in the
  4. -- LICENSE file in the root directory of this source tree.
  5. --
  6. {-# LANGUAGE CPP #-}
  7. {-# LANGUAGE RecordWildCards #-}
  8. module Retrie.GHC
  9. ( module Retrie.GHC
  10. , module ApiAnnotation
  11. , module Bag
  12. , module BasicTypes
  13. , module FastString
  14. , module FastStringEnv
  15. #if __GLASGOW_HASKELL__ < 810
  16. , module HsExpr
  17. , module HsSyn
  18. #else
  19. , module ErrUtils
  20. , module GHC.Hs.Expr
  21. , module GHC.Hs
  22. #endif
  23. , module Module
  24. , module Name
  25. , module OccName
  26. , module RdrName
  27. , module SrcLoc
  28. , module Unique
  29. , module UniqFM
  30. , module UniqSet
  31. ) where
  32. import ApiAnnotation
  33. import Bag
  34. import BasicTypes
  35. import FastString
  36. import FastStringEnv
  37. #if __GLASGOW_HASKELL__ < 810
  38. import HsExpr
  39. #if __GLASGOW_HASKELL__ < 806
  40. import HsSyn hiding (HasDefault(..))
  41. #else
  42. import HsSyn
  43. #endif
  44. #else
  45. import ErrUtils
  46. import GHC.Hs.Expr
  47. import GHC.Hs
  48. #endif
  49. import Module
  50. import Name
  51. import OccName
  52. import RdrName
  53. import SrcLoc
  54. import Unique
  55. import UniqFM
  56. import UniqSet
  57. import Data.Bifunctor (second)
  58. import Data.Maybe
  59. cLPat :: Located (Pat (GhcPass p)) -> LPat (GhcPass p)
  60. #if __GLASGOW_HASKELL__ == 808
  61. cLPat = composeSrcSpan
  62. #else
  63. cLPat = id
  64. #endif
  65. -- | Only returns located pat if there is a genuine location available.
  66. dLPat :: LPat (GhcPass p) -> Maybe (Located (Pat (GhcPass p)))
  67. #if __GLASGOW_HASKELL__ == 808
  68. dLPat (XPat (L s p)) = Just $ L s $ stripSrcSpanPat p
  69. dLPat _ = Nothing
  70. #else
  71. dLPat = Just
  72. #endif
  73. -- | Will always give a location, but it may be noSrcSpan.
  74. dLPatUnsafe :: LPat (GhcPass p) -> Located (Pat (GhcPass p))
  75. #if __GLASGOW_HASKELL__ == 808
  76. dLPatUnsafe = dL
  77. #else
  78. dLPatUnsafe = id
  79. #endif
  80. #if __GLASGOW_HASKELL__ == 808
  81. stripSrcSpanPat :: LPat (GhcPass p) -> Pat (GhcPass p)
  82. stripSrcSpanPat (XPat (L _ p)) = stripSrcSpanPat p
  83. stripSrcSpanPat p = p
  84. #endif
  85. rdrFS :: RdrName -> FastString
  86. rdrFS (Qual m n) = mconcat [moduleNameFS m, fsDot, occNameFS n]
  87. rdrFS rdr = occNameFS (occName rdr)
  88. fsDot :: FastString
  89. fsDot = mkFastString "."
  90. varRdrName :: HsExpr p -> Maybe (Located (IdP p))
  91. #if __GLASGOW_HASKELL__ < 806
  92. varRdrName (HsVar n) = Just n
  93. #else
  94. varRdrName (HsVar _ n) = Just n
  95. #endif
  96. varRdrName _ = Nothing
  97. tyvarRdrName :: HsType p -> Maybe (Located (IdP p))
  98. #if __GLASGOW_HASKELL__ < 806
  99. tyvarRdrName (HsTyVar _ n) = Just n
  100. #else
  101. tyvarRdrName (HsTyVar _ _ n) = Just n
  102. #endif
  103. tyvarRdrName _ = Nothing
  104. fixityDecls :: HsModule p -> [(Located (IdP p), Fixity)]
  105. fixityDecls m =
  106. [ (nm, fixity)
  107. #if __GLASGOW_HASKELL__ < 806
  108. | L _ (SigD (FixSig (FixitySig nms fixity))) <- hsmodDecls m
  109. #else
  110. | L _ (SigD _ (FixSig _ (FixitySig _ nms fixity))) <- hsmodDecls m
  111. #endif
  112. , nm <- nms
  113. ]
  114. ruleInfo :: RuleDecl GhcPs -> [RuleInfo]
  115. #if __GLASGOW_HASKELL__ < 808
  116. #if __GLASGOW_HASKELL__ < 806
  117. ruleInfo (HsRule (L _ (_, riName)) _ bs riLHS _ riRHS _) =
  118. #else
  119. ruleInfo XRuleDecl{} = []
  120. ruleInfo (HsRule _ (L _ (_, riName)) _ bs riLHS riRHS) =
  121. #endif
  122. [ RuleInfo { riQuantifiers = ruleBindersToQs bs, .. } ]
  123. #else
  124. ruleInfo (HsRule _ (L _ (_, riName)) _ tyBs valBs riLHS riRHS) =
  125. let
  126. riQuantifiers =
  127. map unLoc (tyBindersToLocatedRdrNames (fromMaybe [] tyBs)) ++
  128. ruleBindersToQs valBs
  129. in [ RuleInfo{..} ]
  130. ruleInfo XRuleDecl{} = []
  131. #endif
  132. ruleBindersToQs :: [LRuleBndr GhcPs] -> [RdrName]
  133. ruleBindersToQs bs = catMaybes
  134. [ case b of
  135. #if __GLASGOW_HASKELL__ < 806
  136. RuleBndr (L _ v) -> Just v
  137. RuleBndrSig (L _ v) _ -> Just v
  138. #else
  139. RuleBndr _ (L _ v) -> Just v
  140. RuleBndrSig _ (L _ v) _ -> Just v
  141. XRuleBndr{} -> Nothing
  142. #endif
  143. | L _ b <- bs
  144. ]
  145. tyBindersToLocatedRdrNames :: [LHsTyVarBndr GhcPs] -> [Located RdrName]
  146. tyBindersToLocatedRdrNames vars = catMaybes
  147. [ case var of
  148. #if __GLASGOW_HASKELL__ < 806
  149. UserTyVar v -> Just v
  150. KindedTyVar v _ -> Just v
  151. #else
  152. UserTyVar _ v -> Just v
  153. KindedTyVar _ v _ -> Just v
  154. XTyVarBndr{} -> Nothing
  155. #endif
  156. | L _ var <- vars ]
  157. data RuleInfo = RuleInfo
  158. { riName :: RuleName
  159. , riQuantifiers :: [RdrName]
  160. , riLHS :: LHsExpr GhcPs
  161. , riRHS :: LHsExpr GhcPs
  162. }
  163. #if __GLASGOW_HASKELL__ < 806
  164. #elif __GLASGOW_HASKELL__ < 810
  165. noExtField :: NoExt
  166. noExtField = noExt
  167. #endif
  168. overlaps :: SrcSpan -> SrcSpan -> Bool
  169. overlaps (RealSrcSpan s1) (RealSrcSpan s2) =
  170. srcSpanFile s1 == srcSpanFile s2 &&
  171. ((srcSpanStartLine s1, srcSpanStartCol s1) `within` s2 ||
  172. (srcSpanEndLine s1, srcSpanEndCol s1) `within` s2)
  173. overlaps _ _ = False
  174. within :: (Int, Int) -> RealSrcSpan -> Bool
  175. within (l,p) s =
  176. srcSpanStartLine s <= l &&
  177. srcSpanStartCol s <= p &&
  178. srcSpanEndLine s >= l &&
  179. srcSpanEndCol s >= p
  180. lineCount :: [SrcSpan] -> Int
  181. lineCount ss = sum
  182. [ srcSpanEndLine s - srcSpanStartLine s + 1
  183. | RealSrcSpan s <- ss
  184. ]
  185. showRdrs :: [RdrName] -> String
  186. showRdrs = show . map (occNameString . occName)
  187. uniqBag :: Uniquable a => [(a,b)] -> UniqFM [b]
  188. uniqBag = listToUFM_C (++) . map (second pure)