HaskellAnalysisProgram-0.1.0: src/MetaHS/DataModel/Utils/Language/Haskell/Exts/Syntax/Decl.hs
{-|
Module : MetaHS.DataModel.Utils.Language.Haskell.Exts.Syntax.Decl
Description : Utility functions for Decl objects.
Copyright : Copyright (C) 2017-2019 H.H.R.F. Vos, S. Kamps
License : -- This file is distributed under the terms of the Apache License 2.0.
For more information, see the file "LICENSE", which is included in the distribution.
Stability : experimental
Utility functions for Decl objects.
-}
module MetaHS.DataModel.Utils.Language.Haskell.Exts.Syntax.Decl
where
import Data.Maybe ()
import Language.Haskell.Exts.Syntax
import Language.Haskell.Exts.SrcLoc
import qualified MetaHS.DataModel.Utils.Language.Haskell.Exts.Syntax.Name as Name
import qualified MetaHS.DataModel.Utils.Language.Haskell.Exts.Syntax.QName as QName
import qualified MetaHS.DataModel.Utils.Language.Haskell.Exts.Syntax.DeclHead as DeclHead
-- | Returns the SrcSpanInfo object associated with the Decl object.
srcSpanInfo :: Decl SrcSpanInfo -> SrcSpanInfo
srcSpanInfo = ann
-- | Represents the (simplified) information for a data constructor.
data DataConstructor
= DataConstructor
{ dataConstructorName :: String
-- ^ The name of the data constructor.
, valueConstructors :: [ValueConstructor]
-- ^ The value constructors for this data constructor.
}
deriving (Show)
-- | Represents the information for a value constructor.
data ValueConstructor
= ValueConstructor
{ valueConstructorName :: String
-- ^ The name of the value constructor.
, valueConstructorTypes :: [Type SrcSpanInfo]
-- ^ Contains the types used by this value constructor if this is not
-- defined using record notation.
-- For GADT data type declarations, this field will contain the final
-- type irrespective of whether record notation is used for the
-- preceeding types.
, valueConstructorFields :: [Field]
-- ^ In case the value constructor is defined using record notation,
-- this field will contain the fields used by this value constructor.
}
deriving (Show)
-- | Represents a record field of a value constructor.
data Field
= Field
{ fieldNames :: [String]
-- ^ The name(s) for this field.
, fieldTypes :: Type SrcSpanInfo
-- ^ The types used by this field.
}
deriving (Show)
-- | Converts a Decl to a DataConstructor object if possible (DataDecl or
-- GDataDecl).
dataConstructor :: Decl SrcSpanInfo -> Maybe DataConstructor
dataConstructor (DataDecl _ _ _ dh qcds _) = Just DataConstructor
{ dataConstructorName = DeclHead.name dh
, valueConstructors = vcs
}
where
vcs = [ createVC ds | (QualConDecl _ _ _ ds) <- qcds]
createVC :: ConDecl SrcSpanInfo -> ValueConstructor
createVC (ConDecl _ n ts) = ValueConstructor
{ valueConstructorName = Name.name n
, valueConstructorTypes = ts
, valueConstructorFields = []
}
createVC (InfixConDecl _ t1 n t2) = ValueConstructor
{ valueConstructorName = Name.name n
, valueConstructorTypes = [t1, t2]
, valueConstructorFields = []
}
createVC (RecDecl _ n fds) = ValueConstructor
{ valueConstructorName = Name.name n
, valueConstructorTypes = []
, valueConstructorFields = [createField fd | fd <- fds]
}
createField (FieldDecl _ ns t) = Field
{ fieldNames = [Name.name n | n <- ns]
, fieldTypes = t
}
dataConstructor (GDataDecl _ _ _ dh _ gds _) = Just DataConstructor -- dh = (DeclHead l), gds = [GadtDecl l]
{ dataConstructorName = DeclHead.name dh
, valueConstructors = vcs
}
where
vcs = [ createVC gd | gd <- gds]
createVC :: GadtDecl SrcSpanInfo -> ValueConstructor
createVC (GadtDecl _ n Nothing ts) = ValueConstructor -- n = (Name l), ts = (Type l)
{ valueConstructorName = Name.name n
, valueConstructorTypes = [ts]
, valueConstructorFields = []
}
createVC (GadtDecl _ n (Just fds) ts) = ValueConstructor -- n = (Name l), fds = [FieldDecl l], ts = (Type l)
{ valueConstructorName = Name.name n
, valueConstructorTypes = [ts]
, valueConstructorFields = [createField fd | fd <- fds]
}
createField (FieldDecl _ ns t) = Field
{ fieldNames = [Name.name n | n <- ns]
, fieldTypes = t
}
dataConstructor _ = Nothing
-- | Returns the name of the PatBind if possible.
patternName :: Decl SrcSpanInfo
-> Maybe String
patternName (PatBind _ (PVar _ n) _ _) = Just $ Name.name n
patternName _ = Nothing
-- | Returns the name of the FunBind if possible.
functionName :: Decl SrcSpanInfo
-> Maybe String
functionName (FunBind _ []) = Nothing
functionName (FunBind _ ms) = Just . fn $ head ms
where
fn :: Match l -> String
fn (Match _ x _ _ _) = Name.name x
fn (InfixMatch _ _ x _ _ _) = Name.name x
functionName _ = Nothing
-- | Returns the name of the TypeSig if possible.
typeSigName :: Decl SrcSpanInfo
-> Maybe String
typeSigName (TypeSig _ [] _) = Nothing
typeSigName (TypeSig _ n _) = Just $ Name.name $ head n
-- | Returns the name of the typeClass if possible.
typeClassName :: Decl SrcSpanInfo
-> Maybe String
typeClassName (ClassDecl _ _ (DHApp _ (DHead _ n) _) _ _) = Just $ Name.name n
typeClassName _ = Nothing
-- | Returns the name of the Instance (as "<type-class> <data-type>") if possible.
instanceName :: Decl SrcSpanInfo
-> Maybe String
instanceName (InstDecl _ _ (IRule _ _ _ (IHApp _ ih t)) _) = fn ih t
where fn :: InstHead l -> Type l -> Maybe String
fn (IHCon _ qntc) ty = do
qnt <- isTycon ty
n1 <- QName.name qntc
n2 <- QName.name qnt
return $ "(" ++ n1 ++ " " ++ n2 ++ ")"
fn _ _ = Nothing
isTycon (TyCon _ qnt) = Just qnt
isTycon (TyParen _ (TyCon _ qnt)) = Just qnt
isTycon _ = Nothing
instanceName _ = Nothing
-- | Returns the name of the InlineSig if possible.
inlineSigName :: Decl SrcSpanInfo
-> Maybe String
inlineSigName (InlineSig _ _ _ qn) = QName.name qn
inlineSigName _ = Nothing