PageRenderTime 48ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/compiler/main/Annotations.hs

https://bitbucket.org/carter/ghc
Haskell | 107 lines | 57 code | 20 blank | 30 comment | 0 complexity | 29f70fa9d24492e582f6539e56872066 MD5 | raw file
  1. -- |
  2. -- Support for source code annotation feature of GHC. That is the ANN pragma.
  3. --
  4. -- (c) The University of Glasgow 2006
  5. -- (c) The GRASP/AQUA Project, Glasgow University, 1992-1998
  6. --
  7. module Annotations (
  8. -- * Main Annotation data types
  9. Annotation(..),
  10. AnnTarget(..), CoreAnnTarget,
  11. getAnnTargetName_maybe,
  12. -- * AnnEnv for collecting and querying Annotations
  13. AnnEnv,
  14. mkAnnEnv, extendAnnEnvList, plusAnnEnv, emptyAnnEnv, findAnns,
  15. deserializeAnns
  16. ) where
  17. import Module ( Module )
  18. import Name
  19. import Outputable
  20. import Serialized
  21. import UniqFM
  22. import Unique
  23. import Data.Maybe
  24. import Data.Typeable
  25. import Data.Word ( Word8 )
  26. -- | Represents an annotation after it has been sufficiently desugared from
  27. -- it's initial form of 'HsDecls.AnnDecl'
  28. data Annotation = Annotation {
  29. ann_target :: CoreAnnTarget, -- ^ The target of the annotation
  30. ann_value :: Serialized -- ^ 'Serialized' version of the annotation that
  31. -- allows recovery of its value or can
  32. -- be persisted to an interface file
  33. }
  34. -- | An annotation target
  35. data AnnTarget name
  36. = NamedTarget name -- ^ We are annotating something with a name:
  37. -- a type or identifier
  38. | ModuleTarget Module -- ^ We are annotating a particular module
  39. -- | The kind of annotation target found in the middle end of the compiler
  40. type CoreAnnTarget = AnnTarget Name
  41. instance Functor AnnTarget where
  42. fmap f (NamedTarget nm) = NamedTarget (f nm)
  43. fmap _ (ModuleTarget mod) = ModuleTarget mod
  44. -- | Get the 'name' of an annotation target if it exists.
  45. getAnnTargetName_maybe :: AnnTarget name -> Maybe name
  46. getAnnTargetName_maybe (NamedTarget nm) = Just nm
  47. getAnnTargetName_maybe _ = Nothing
  48. instance Uniquable name => Uniquable (AnnTarget name) where
  49. getUnique (NamedTarget nm) = getUnique nm
  50. getUnique (ModuleTarget mod) = deriveUnique (getUnique mod) 0
  51. -- deriveUnique prevents OccName uniques clashing with NamedTarget
  52. instance Outputable name => Outputable (AnnTarget name) where
  53. ppr (NamedTarget nm) = text "Named target" <+> ppr nm
  54. ppr (ModuleTarget mod) = text "Module target" <+> ppr mod
  55. instance Outputable Annotation where
  56. ppr ann = ppr (ann_target ann)
  57. -- | A collection of annotations
  58. -- Can't use a type synonym or we hit bug #2412 due to source import
  59. newtype AnnEnv = MkAnnEnv (UniqFM [Serialized])
  60. -- | An empty annotation environment.
  61. emptyAnnEnv :: AnnEnv
  62. emptyAnnEnv = MkAnnEnv emptyUFM
  63. -- | Construct a new annotation environment that contains the list of
  64. -- annotations provided.
  65. mkAnnEnv :: [Annotation] -> AnnEnv
  66. mkAnnEnv = extendAnnEnvList emptyAnnEnv
  67. -- | Add the given annotation to the environment.
  68. extendAnnEnvList :: AnnEnv -> [Annotation] -> AnnEnv
  69. extendAnnEnvList (MkAnnEnv env) anns
  70. = MkAnnEnv $ addListToUFM_C (++) env $
  71. map (\ann -> (getUnique (ann_target ann), [ann_value ann])) anns
  72. -- | Union two annotation environments.
  73. plusAnnEnv :: AnnEnv -> AnnEnv -> AnnEnv
  74. plusAnnEnv (MkAnnEnv env1) (MkAnnEnv env2) = MkAnnEnv $ plusUFM_C (++) env1 env2
  75. -- | Find the annotations attached to the given target as 'Typeable'
  76. -- values of your choice. If no deserializer is specified,
  77. -- only transient annotations will be returned.
  78. findAnns :: Typeable a => ([Word8] -> a) -> AnnEnv -> CoreAnnTarget -> [a]
  79. findAnns deserialize (MkAnnEnv ann_env)
  80. = (mapMaybe (fromSerialized deserialize))
  81. . (lookupWithDefaultUFM ann_env [])
  82. -- | Deserialize all annotations of a given type. This happens lazily, that is
  83. -- no deserialization will take place until the [a] is actually demanded and
  84. -- the [a] can also be empty (the UniqFM is not filtered).
  85. deserializeAnns :: Typeable a => ([Word8] -> a) -> AnnEnv -> UniqFM [a]
  86. deserializeAnns deserialize (MkAnnEnv ann_env)
  87. = mapUFM (mapMaybe (fromSerialized deserialize)) ann_env