haskell-tools-ast-0.3.0.0: Language/Haskell/Tools/AST/Representation/Decls.hs
-- | Representation of Haskell AST definitions. These include definition of data types, classes, instances and so on.
-- The definition of value bindings are in the Binds module.
module Language.Haskell.Tools.AST.Representation.Decls where
import Language.Haskell.Tools.AST.Representation.Binds
import Language.Haskell.Tools.AST.Representation.Types
import Language.Haskell.Tools.AST.Representation.Patterns
import Language.Haskell.Tools.AST.Representation.Kinds
import Language.Haskell.Tools.AST.Representation.Exprs
import Language.Haskell.Tools.AST.Representation.Names
import Language.Haskell.Tools.AST.Representation.Literals
import Language.Haskell.Tools.AST.Ann
import {-# SOURCE #-} Language.Haskell.Tools.AST.Representation.TH
-- * Declarations
-- | Haskell declaration
data UDecl dom stage
= UTypeDecl { _declHead :: Ann UDeclHead dom stage
, _declType :: Ann UType dom stage
} -- ^ A type synonym ( @type String = [Char]@ )
| UTypeFamilyDecl { _declTypeFamily :: Ann UTypeFamily dom stage
} -- ^ A type family declaration ( @type family F x@ )
| UClosedTypeFamilyDecl { _declHead :: Ann UDeclHead dom stage
, _declKind :: AnnMaybeG UKindConstraint dom stage
, _declDecl :: AnnListG UTypeEqn dom stage -- ^ cannot be empty
} -- ^ A closed type family declaration
| UDataDecl { _declNewtype :: Ann UDataOrNewtypeKeyword dom stage
, _declCtx :: AnnMaybeG UContext dom stage
, _declHead :: Ann UDeclHead dom stage
, _declCons :: AnnListG UConDecl dom stage
, _declDeriving :: AnnMaybeG UDeriving dom stage
} -- ^ A data or newtype declaration. Empty data type declarations without
-- where keyword are always belong to DataDecl.
| UGDataDecl { _declNewtype :: Ann UDataOrNewtypeKeyword dom stage
, _declCtx :: AnnMaybeG UContext dom stage
, _declHead :: Ann UDeclHead dom stage
, _declKind :: AnnMaybeG UKindConstraint dom stage
, _declGadt :: AnnListG UGadtConDecl dom stage
, _declDeriving :: AnnMaybeG UDeriving dom stage
} -- ^ A GADT-style data or newtype declaration.
| UTypeInstDecl { _declInstance :: Ann UInstanceRule dom stage
, _declAssignedType :: Ann UType dom stage
} -- ^ Type family instance declaration (@ type instance Fam T = AssignedT @)
| UDataInstDecl { _declNewtype :: Ann UDataOrNewtypeKeyword dom stage
, _declInstance :: Ann UInstanceRule dom stage
, _declCons :: AnnListG UConDecl dom stage
, _declDeriving :: AnnMaybeG UDeriving dom stage
} -- ^ Data instance declaration (@ data instance Fam T = Con1 | Con2 @)
| UGDataInstDecl { _declNewtype :: Ann UDataOrNewtypeKeyword dom stage
, _declInstance :: Ann UInstanceRule dom stage
, _declKind :: AnnMaybeG UKindConstraint dom stage
, _declGadt :: AnnListG UGadtConDecl dom stage
} -- ^ GADT-style data instance declaration (@ data instance Fam T where ... @)
| UClassDecl { _declCtx :: AnnMaybeG UContext dom stage
, _declHead :: Ann UDeclHead dom stage
, _declFunDeps :: AnnMaybeG UFunDeps dom stage
, _declBody :: AnnMaybeG UClassBody dom stage
} -- ^ Type class declaration (@ class X a [where f = ...] @)
| UInstDecl { _declOverlap :: AnnMaybeG UOverlapPragma dom stage
, _declInstRule :: Ann UInstanceRule dom stage
, _declInstDecl :: AnnMaybeG UInstBody dom stage
} -- ^ Instance declaration (@ instance X T [where f = ...] @)
| UPatternSynonymDecl { _declPatSyn :: Ann UPatternSynonym dom stage
} -- ^ Pattern synonyms (@ pattern Arrow t1 t2 = App "->" [t1, t2] @)
| UDerivDecl { _declOverlap :: AnnMaybeG UOverlapPragma dom stage
, _declInstRule :: Ann UInstanceRule dom stage
} -- ^ Standalone deriving declaration (@ deriving instance X T @)
| UFixityDecl { _declFixity :: Ann UFixitySignature dom stage
} -- ^ Fixity declaration (@ infixl 5 +, - @)
| UDefaultDecl { _declTypes :: AnnListG UType dom stage
} -- ^ Default types (@ default (T1, T2) @)
| UTypeSigDecl { _declTypeSig :: Ann UTypeSignature dom stage
} -- ^ Type signature declaration (@ f :: Int -> Int @)
| UPatTypeSigDecl { _declPatTypeSig :: Ann UPatternTypeSignature dom stage
} -- ^ Pattern type signature declaration (@ pattern Succ :: Int -> Int @)
| UValueBinding { _declValBind :: Ann UValueBind dom stage
} -- ^ Function or value binding (@ f x = 12 @)
| UForeignImport { _declCallConv :: Ann UCallConv dom stage
, _declSafety :: AnnMaybeG USafety dom stage
, _declName :: Ann UName dom stage
, _declType :: Ann UType dom stage
} -- ^ Foreign import (@ foreign import _foo :: Int -> IO Int @)
| UForeignExport { _declCallConv :: Ann UCallConv dom stage
, _declName :: Ann UName dom stage
, _declType :: Ann UType dom stage
} -- ^ Foreign export (@ foreign export ccall _foo :: Int -> IO Int @)
| UPragmaDecl { _declPragma :: Ann UTopLevelPragma dom stage
} -- ^ Top-level pragmas
| URoleDecl { _declRoleType :: Ann UQualifiedName dom stage
, _declRoles :: AnnListG URole dom stage
} -- ^ Role annotations (@ type role Ptr representational @)
| USpliceDecl { _declSplice :: Ann USplice dom stage
} -- ^ A Template Haskell splice declaration (@ $(generateDecls) @)
-- The declared (possibly parameterized) type (@ A x :+: B y @).
data UDeclHead dom stage
= UDeclHead { _dhName :: Ann UName dom stage
} -- ^ Type or class name
| UDHParen { _dhBody :: Ann UDeclHead dom stage
} -- ^ Parenthesized type
| UDHApp { _dhAppFun :: Ann UDeclHead dom stage
, _dhAppOperand :: Ann UTyVar dom stage
} -- ^ Type application
| UDHInfix { _dhLeft :: Ann UTyVar dom stage
, _dhOperator :: Ann UOperator dom stage
, _dhRight :: Ann UTyVar dom stage
} -- ^ Infix application of the type/class name to the left operand
-- * Type class definitions
-- | The list of declarations that can appear in a typeclass
data UClassBody dom stage
= UClassBody { _cbElements :: AnnListG UClassElement dom stage
}
-- | Members of a class declaration
data UClassElement dom stage
= UClsSig { _ceTypeSig :: Ann UTypeSignature dom stage
} -- ^ Signature: @ f :: A -> B @
| UClsDef { _ceBind :: Ann UValueBind dom stage
} -- ^ Default binding: @ f x = "aaa" @
| UClsTypeFam { _ceTypeFam :: Ann UTypeFamily dom stage
} -- ^ Declaration of an associated type synonym: @ type T x :: * @
| UClsTypeDef { _ceHead :: Ann UDeclHead dom stage
, _ceKind :: Ann UType dom stage
} -- ^ Default choice for type synonym: @ type T x = TE @ or @ type instance T x = TE @
| UClsDefSig { _ceName :: Ann UName dom stage
, _ceType :: Ann UType dom stage
} -- ^ Default signature (by using @DefaultSignatures@): @ default _enum :: (Generic a, GEnum (Rep a)) => [a] @
| UClsMinimal { _pragmaFormula :: Ann UMinimalFormula dom stage
} -- ^ Minimal pragma: @ {-# MINIMAL (==) | (/=) #-} @
-- not supported yet (GHC 8.0.1)
-- | UClsPatSig { _cePatSig :: Ann UPatternTypeSignature dom stage
-- } -- ^ Pattern signature in a class declaration (by using @PatternSynonyms@)
-- * Type class instances
-- | The instance declaration rule, which is, roughly, the part of the instance declaration before the where keyword.
data UInstanceRule dom stage
= UInstanceRule { _irVars :: AnnMaybeG (AnnListG UTyVar) dom stage
, _irCtx :: AnnMaybeG UContext dom stage
, _irHead :: Ann UInstanceHead dom stage
} -- ^ Instance head as an instance rule (@ X a => Y a @)
-- | The specification of the class instance declaration
data UInstanceHead dom stage
= UInstanceHeadCon { _ihConName :: Ann UName dom stage
} -- ^ Type or class name
| UInstanceHeadInfix { _ihLeftOp :: Ann UType dom stage
, _ihOperator :: Ann UName dom stage
} -- ^ Infix application of the type/class name to the left operand
| UInstanceHeadParen { _ihHead :: Ann UInstanceHead dom stage
} -- ^ Parenthesized instance head
| UInstanceHeadApp { _ihFun :: Ann UInstanceHead dom stage
, _ihType :: Ann UType dom stage
} -- ^ Application to one more type
-- | Instance body is the implementation of the class functions (@ where a x = 1; b x = 2 @)
data UInstBody dom stage
= UInstBody { _instBodyDecls :: AnnListG UInstBodyDecl dom stage
}
-- | Declarations inside an instance declaration.
data UInstBodyDecl dom stage
= UInstBodyNormalDecl { _instBodyDeclFunbind :: Ann UValueBind dom stage
} -- ^ A normal value binding (@ f x = 12 @)
| UInstBodyTypeSig { _instBodyTypeSig :: Ann UTypeSignature dom stage
} -- ^ Type signature in instance definition with @InstanceSigs@
| UInstBodyTypeDecl { _instBodyTypeEqn :: Ann UTypeEqn dom stage
} -- ^ An associated type definition (@ type A X = B @)
| UInstBodyDataDecl { _instBodyDataNew :: Ann UDataOrNewtypeKeyword dom stage
, _instBodyLhsType :: Ann UInstanceRule dom stage
, _instBodyDataCons :: AnnListG UConDecl dom stage
, _instBodyDerivings :: AnnMaybeG UDeriving dom stage
} -- ^ An associated data type implementation (@ data A X = C1 | C2 @)
| UInstBodyGadtDataDecl { _instBodyDataNew :: Ann UDataOrNewtypeKeyword dom stage
, _instBodyLhsType :: Ann UInstanceRule dom stage
, _instBodyDataKind :: AnnMaybeG UKindConstraint dom stage
, _instBodyGadtCons :: AnnListG UGadtConDecl dom stage
, _instBodyDerivings :: AnnMaybeG UDeriving dom stage
} -- ^ An associated data type implemented using GADT style
| USpecializeInstance { _specializeInstanceType :: Ann UType dom stage
} -- ^ Specialize instance pragma (no phase selection is allowed)
-- not supported yet
-- | UInstBodyPatSyn { _instBodyPatSyn :: Ann UPatternSynonym dom stage
-- } -- ^ A pattern synonym in a class instance
-- | Overlap pragmas. Can be applied to class declarations and class instance declarations.
data UOverlapPragma dom stage
= UEnableOverlap -- ^ @OVERLAP@ pragma
| UDisableOverlap -- ^ @NO_OVERLAP@ pragma
| UOverlappable -- ^ @OVERLAPPABLE@ pragma
| UOverlapping -- ^ @OVERLAPPING@ pragma
| UOverlaps -- ^ @OVERLAPS@ pragma
| UIncoherentOverlap -- ^ @INCOHERENT@ pragma
-- * Type families
-- | Open type and data families
data UTypeFamily dom stage
= UTypeFamily { _tfHead :: Ann UDeclHead dom stage
, _tfSpec :: AnnMaybeG UTypeFamilySpec dom stage
} -- ^ Type family declaration (@ type family A a :: * -> * @)
| UDataFamily { _tfHead :: Ann UDeclHead dom stage
, _tfKind :: AnnMaybeG UKindConstraint dom stage
} -- ^ Data family declaration (@ data family A a :: * -> * @)
-- | Type family specification with kinds specification and injectivity.
data UTypeFamilySpec dom stage
= UTypeFamilyKind { _tfSpecKind :: Ann UKindConstraint dom stage
} -- ^ Specifies the kind of a type family (@ :: * -> * @)
| UTypeFamilyInjectivity { _tfInjectivity :: Ann UInjectivityAnn dom stage
} -- ^ Specifies the injectivity of a type family (@ = r | r -> a @)
-- | Injectivity annotation for type families (@ = r | r -> a @)
data UInjectivityAnn dom stage
= UInjectivityAnn { _injAnnRes :: Ann UName dom stage
, _injAnnDeps :: AnnListG UName dom stage
}
-- | Type equations as found in closed type families (@ T A = S @)
data UTypeEqn dom stage
= UTypeEqn { _teLhs :: Ann UType dom stage
, _teRhs :: Ann UType dom stage
}
-- * Type definitions
-- | GADT constructor declaration (@ D1 :: { val :: Int } -> T String @)
data UGadtConDecl dom stage
= UGadtConDecl { _gadtConNames :: AnnListG UName dom stage
, _gadtConType :: Ann UGadtConType dom stage
}
-- | The @data@ or the @newtype@ keyword to define ADTs.
data UDataOrNewtypeKeyword dom stage
= UDataKeyword
| UNewtypeKeyword
-- | Type of GADT constructors (can be record types: @{ val :: Int }@)
data UGadtConType dom stage
= UGadtNormalType { _gadtConNormalType :: Ann UType dom stage
}
| UGadtRecordType { _gadtConRecordFields :: AnnListG UFieldDecl dom stage
, _gadtConResultType :: Ann UType dom stage
}
-- | A list of functional dependencies: @ | a -> b, c -> d @ separated by commas
data UFunDeps dom stage
= UFunDeps { _funDeps :: AnnListG UFunDep dom stage
}
-- | A functional dependency, given on the form @l1 ... ln -> r1 ... rn@
data UFunDep dom stage
= UFunDep { _funDepLhs :: AnnListG UName dom stage
, _funDepRhs :: AnnListG UName dom stage
}
-- | A constructor declaration for a datatype
data UConDecl dom stage
= UConDecl { _conDeclName :: Ann UName dom stage
, _conDeclArgs :: AnnListG UType dom stage
} -- ^ Ordinary data constructor (@ C t1 t2 @)
| URecordDecl { _conDeclName :: Ann UName dom stage
, _conDeclFields :: AnnListG UFieldDecl dom stage
} -- ^ Record data constructor (@ C { _n1 :: t1, _n2 :: t2 } @)
| UInfixConDecl { _conDeclLhs :: Ann UType dom stage
, _conDeclOp :: Ann UOperator dom stage
, _conDeclRhs :: Ann UType dom stage
} -- ^ Infix data constructor (@ t1 :+: t2 @)
-- | Field declaration (@ fld :: Int @)
data UFieldDecl dom stage
= UFieldDecl { _fieldNames :: AnnListG UName dom stage
, _fieldType :: Ann UType dom stage
}
-- | A deriving clause following a data type declaration. (@ deriving Show @ or @ deriving (Show, Eq) @)
data UDeriving dom stage
= UDerivingOne { _oneDerived :: Ann UInstanceHead dom stage }
| UDerivings { _allDerived :: AnnListG UInstanceHead dom stage }
-- * Pattern synonyms
-- | Pattern type signature declaration (@ pattern Succ :: Int -> Int @)
data UPatternTypeSignature dom stage
= UPatternTypeSignature { _patSigName :: Ann UName dom stage
, _patSigType :: Ann UType dom stage
}
-- | Pattern synonyms: @ pattern Arrow t1 t2 = App "->" [t1, t2] @
data UPatternSynonym dom stage
= UPatternSynonym { _patLhs :: Ann UPatSynLhs dom stage
, _patRhs :: Ann UPatSynRhs dom stage
}
-- | Left hand side of a pattern synonym
data UPatSynLhs dom stage
= UNormalPatSyn { _patName :: Ann UName dom stage
, _patArgs :: AnnListG UName dom stage
} -- ^ A left hand side with a constructor name and arguments (@ Arrow t1 t2 @)
| UInfixPatSyn { _patSynLhs :: Ann UName dom stage
, _patSynOp :: Ann UOperator dom stage
, _patSynRhs :: Ann UName dom stage
} -- ^ An infix pattern synonym left-hand side (@ t1 :+: t2 @)
| URecordPatSyn { _patName :: Ann UName dom stage
, _patArgs :: AnnListG UName dom stage
} -- ^ A record-style pattern synonym left-hand side (@ Arrow { arrowFrom, arrowTo } @)
-- | Right-hand side of pattern synonym
data UPatSynRhs dom stage
-- TODO: this feels bad, changing _patRhsOpposite may switch between <- and =
= UBidirectionalPatSyn { _patRhsPat :: Ann UPattern dom stage
, _patRhsOpposite :: AnnMaybeG UPatSynWhere dom stage
} -- ^ @ pattern Int = App "Int" [] @ or @ pattern Int <- App "Int" [] where Int = App "Int" [] @
| UOneDirectionalPatSyn { _patRhsPat :: Ann UPattern dom stage
} -- ^ @ pattern Int <- App "Int" [] @
-- | Where clause of pattern synonym (explicit expression direction)
data UPatSynWhere dom stage
= UPatSynWhere { _patOpposite :: AnnListG UMatch dom stage }
-- * Foreign imports
-- | Call conventions of foreign functions
data UCallConv dom stage
= UStdCall
| UCCall
| UCPlusPlus
| UDotNet
| UJvm
| UJs
| UJavaScript
| UCApi
-- | Safety annotations for foreign calls
data USafety dom stage
= USafe
| UThreadSafe
| UUnsafe
| UInterruptible
-- * Role annotations
-- | Role annotations for types
data URole dom stage
= UNominal
| URepresentational
| UPhantom
-- * Rewrite rules
-- | Controls the activation of a rewrite rule (@ [1] @)
data UPhaseControl dom stage
= UPhaseControl { _phaseUntil :: AnnMaybeG PhaseInvert dom stage
, _phaseNumber :: Ann PhaseNumber dom stage
}
-- | Phase number for rewrite rules
data PhaseNumber dom stage
= PhaseNumber { _phaseNum :: Integer }
-- | A tilde that marks the inversion of the phase number
data PhaseInvert dom stage = PhaseInvert
-- * Pragmas
-- | Top level pragmas
data UTopLevelPragma dom stage
= URulePragma { _pragmaRule :: AnnListG URule dom stage
} -- ^ A pragma that introduces source rewrite rules (@ {-# RULES "map/map" [2] forall f g xs. map f (map g xs) = map (f.g) xs #-} @)
| UDeprPragma { _pragmaObjects :: AnnListG UName dom stage
, _pragmaMessage :: Ann UStringNode dom stage
} -- ^ A pragma that marks definitions as deprecated (@ {-# DEPRECATED f "f will be replaced by g" @)
| UWarningPragma { _pragmaObjects :: AnnListG UName dom stage
, _pragmaMessage :: Ann UStringNode dom stage
} -- ^ A pragma that marks definitions as deprecated (@ {-# WARNING unsafePerformIO "you should know what you are doing" @)
| UAnnPragma { _annotationSubject :: Ann UAnnotationSubject dom stage
, _annotateExpr :: Ann UExpr dom stage
} -- ^ A pragma that annotates a definition with an arbitrary value (@ {-# ANN f 42 @)
| UInlinePragma { _pragmaConlike :: AnnMaybeG UConlikeAnnot dom stage
, _pragmaPhase :: AnnMaybeG UPhaseControl dom stage
, _inlineDef :: Ann UName dom stage
} -- ^ A pragma that marks a function for inlining to the compiler (@ {-# INLINE thenUs #-} @)
| UNoInlinePragma { _pragmaConlike :: AnnMaybeG UConlikeAnnot dom stage
, _pragmaPhase :: AnnMaybeG UPhaseControl dom stage
, _noInlineDef :: Ann UName dom stage
} -- ^ A pragma that forbids a function from being inlined by the compiler (@ {-# NOINLINE f #-} @)
| UInlinablePragma { _pragmaPhase :: AnnMaybeG UPhaseControl dom stage
, _inlinableDef :: Ann UName dom stage
} -- ^ A pragma that marks a function that it may be inlined by the compiler (@ {-# INLINABLE thenUs #-} @)
| ULinePragma { _pragmaLineNum :: Ann LineNumber dom stage
, _pragmaFileName :: AnnMaybeG UStringNode dom stage
} -- ^ A pragma for maintaining line numbers in generated sources (@ {-# LINE 123 "somefile" #-} @)
| USpecializePragma { _pragmaPhase :: AnnMaybeG UPhaseControl dom stage
, _specializeDef :: Ann UName dom stage
, _specializeType :: AnnListG UType dom stage
} -- ^ A pragma that tells the compiler that a polymorph function should be optimized for a given type (@ {-# SPECIALISE f :: Int -> b -> b #-} @)
-- | A rewrite rule (@ "map/map" forall f g xs. map f (map g xs) = map (f.g) xs @)
data URule dom stage
= URule { _ruleName :: Ann UStringNode dom stage -- ^ User name of the rule
, _rulePhase :: AnnMaybeG UPhaseControl dom stage -- ^ The compilation phases in which the rule can be applied
, _ruleBounded :: AnnListG UTyVar dom stage -- ^ Variables bound in the rule
, _ruleLhs :: Ann UExpr dom stage -- ^ The transformed expression
, _ruleRhs :: Ann UExpr dom stage -- ^ The resulting expression
}
-- | Annotation allows you to connect an expression to any declaration.
data UAnnotationSubject dom stage
= UNameAnnotation { _annotateName :: Ann UName dom stage
} -- ^ The definition with the given name is annotated
| UTypeAnnotation { _annotateName :: Ann UName dom stage
} -- ^ A type with the given name is annotated
| UModuleAnnotation -- ^ The whole module is annotated
-- | Formulas of minimal annotations declaring which functions should be defined.
data UMinimalFormula dom stage
= UMinimalName { _minimalName :: Ann UName dom stage
}
| UMinimalParen { _minimalInner :: Ann UMinimalFormula dom stage
}
| UMinimalOr { _minimalOrs :: AnnListG UMinimalFormula dom stage
} -- ^ One of the minimal formulas are needed (@ min1 | min2 @)
| UMinimalAnd { _minimalAnds :: AnnListG UMinimalFormula dom stage
} -- ^ Both of the minimal formulas are needed (@ min1 , min2 @)
-- | A @CONLIKE@ modifier for an @INLINE@ pragma.
data UConlikeAnnot dom stage = UConlikeAnnot
-- | A line number for a line pragma.
data LineNumber dom stage
= LineNumber { _lineNumber :: Int }