haskell-tools-ast-0.1.2.1: Language/Haskell/Tools/AST/Ann.hs
{-# LANGUAGE FlexibleInstances
, FlexibleContexts
, TemplateHaskell
, DeriveDataTypeable
, StandaloneDeriving
#-}
-- | Parts of AST representation for keeping extra data
module Language.Haskell.Tools.AST.Ann where
import Data.Data
import Control.Reference
import SrcLoc
import Name
import RdrName
import Module
import Id
import Outputable
import Language.Haskell.Tools.AST.Utils.GHCInstances
-- | An element of the AST keeping extra information.
data Ann elem annot
-- The type parameters are organized this way because we want the annotation type to
-- be more flexible, but the annotation is the first parameter because it eases
-- pattern matching.
= Ann { _annotation :: annot -- ^ The extra information for the AST part
, _element :: elem annot -- ^ The original AST part
}
makeReferences ''Ann
-- | Semantic and source code related information for an AST node.
data NodeInfo sema src
= NodeInfo { _semanticInfo :: sema
, _sourceInfo :: src
}
deriving (Eq, Show, Data)
makeReferences ''NodeInfo
-- | Location info for different types of nodes
data SpanInfo
= NodeSpan { _nodeSpan :: SrcSpan }
| ListPos { _listBefore :: String
, _listAfter :: String
, _listDefaultSep :: String
, _listIndented :: Bool
, _listPos :: SrcLoc
}
| OptionalPos { _optionalBefore :: String
, _optionalAfter :: String
, _optionalPos :: SrcLoc
}
deriving (Eq, Show, Data)
makeReferences ''SpanInfo
-- | Extracts the concrete range corresponding to a given span.
-- In case of lists and optional elements, it may not contain the elements inside.
spanRange :: SpanInfo -> SrcSpan
spanRange (NodeSpan sp) = sp
spanRange ListPos{_listPos = pos} = srcLocSpan pos
spanRange OptionalPos{_optionalPos = pos} = srcLocSpan pos
class HasRange annot where
getRange :: annot -> SrcSpan
instance HasRange (NodeInfo sema SpanInfo) where
getRange = spanRange . (^. sourceInfo)
type RangeInfo = NodeInfo (SemanticInfo RdrName) SpanInfo
type RangeWithName = NodeInfo (SemanticInfo Name) SpanInfo
type RangeWithType = NodeInfo (SemanticInfo Id) SpanInfo
-- | Semantic information for an AST node. Semantic information is
-- currently heterogeneous.
data SemanticInfo n
= NoSemanticInfo -- ^ Semantic info type for any node not
-- carrying additional semantic information
| ScopeInfo { _scopedLocals :: [[Name]]
}
| NameInfo { _scopedLocals :: [[Name]]
, _isDefined :: Bool
, _nameInfo :: n
} -- ^ Info corresponding to a name
| ModuleInfo { _defModuleName :: Module
, _importedNames :: [n] -- ^ Implicitely imported names
} -- ^ Info for the module element
| ImportInfo { _importedModule :: Module -- ^ The name and package of the imported module
, _availableNames :: [n] -- ^ Names available from the imported module
, _importedNames :: [n] -- ^ Names actually imported from the module.
} -- ^ Info corresponding to an import declaration
| AmbiguousNameInfo { _scopedLocals :: [[Name]]
, _isDefined :: Bool
, _ambiguousName :: RdrName
, _ambiguousLocation :: SrcSpan
}
deriving (Eq, Data)
instance Outputable n => Show (SemanticInfo n) where
show NoSemanticInfo = "NoSemanticInfo"
show (ScopeInfo locals) = "(ScopeInfo " ++ showSDocUnsafe (ppr locals) ++ ")"
show (NameInfo locals defined nameInfo) = "(NameInfo " ++ showSDocUnsafe (ppr locals) ++ " " ++ show defined ++ " " ++ showSDocUnsafe (ppr nameInfo) ++ ")"
show (ModuleInfo mod imp) = "(ModuleInfo " ++ showSDocUnsafe (ppr mod) ++ " " ++ showSDocUnsafe (ppr imp) ++ ")"
show (ImportInfo mod avail imported) = "(ImportInfo " ++ showSDocUnsafe (ppr mod) ++ " " ++ showSDocUnsafe (ppr avail) ++ " " ++ showSDocUnsafe (ppr imported) ++ ")"
makeReferences ''SemanticInfo
-- | A list of AST elements
data AnnList e a = AnnList { _annListAnnot :: a
, _annListElems :: [Ann e a]
}
makeReferences ''AnnList
annList :: Traversal (AnnList e a) (AnnList e' a) (Ann e a) (Ann e' a)
annList = annListElems & traversal
-- | An optional AST element
data AnnMaybe e a = AnnMaybe { _annMaybeAnnot :: a
, _annMaybe :: Maybe (Ann e a)
}
makeReferences ''AnnMaybe
annJust :: Partial (AnnMaybe e a) (AnnMaybe e' a) (Ann e a) (Ann e' a)
annJust = annMaybe & just
-- | An empty list of AST elements
annNil :: a -> AnnList e a
annNil a = AnnList a []
isAnnNothing :: AnnMaybe e a -> Bool
isAnnNothing (AnnMaybe _ Nothing) = True
isAnnNothing (AnnMaybe _ _) = False
-- | A non-existing AST part
annNothing :: a -> AnnMaybe e a
annNothing a = AnnMaybe a Nothing
class HasAnnot node where
getAnnot :: node a -> a
instance HasAnnot (Ann e) where
getAnnot = (^. annotation)
instance HasAnnot (AnnList e) where
getAnnot = (^. annListAnnot)
instance HasAnnot (AnnMaybe e) where
getAnnot = (^. annMaybeAnnot)