content: {-# LANGUAGE CPP                        #-}
  {-# LANGUAGE FlexibleContexts           #-}
  {-# LANGUAGE FlexibleInstances          #-}
  {-# LANGUAGE GeneralizedNewtypeDeriving #-}
  {-# LANGUAGE MultiParamTypeClasses      #-}
  {-# LANGUAGE RecordWildCards            #-}
  {-# LANGUAGE ScopedTypeVariables        #-}
  {-# LANGUAGE UndecidableInstances       #-}
  module Language.Haskell.Homplexity.RecordFieldsCount(
      RecordFieldsCount
    , recordFieldsCountT
    ) where
  
  --import Data.Maybe
  import           Data.Proxy
  import           Language.Haskell.Exts.SrcLoc
  import           Language.Haskell.Exts.Syntax
  import           Language.Haskell.Homplexity.CodeFragment
  import           Language.Haskell.Homplexity.Metric
  import           Language.Haskell.Homplexity.Utilities
  
  newtype RecordFieldsCount = RecordFieldsCount { unFieldCount :: Int }
    deriving (Eq, Ord, Enum, Num, Real, Integral)
  
  recordFieldsCountT :: Proxy RecordFieldsCount
  recordFieldsCountT  = Proxy
  
  instance Metric RecordFieldsCount DataDef where
    measure DataDef { .. } = RecordFieldsCount $ either measureCons measureGadts dataDefCtors
  
  measureCons :: [QualConDecl SrcLoc] -> Int
  measureCons = sumOf (\(QualConDecl _ _ _ decl) -> count decl)
    where
      count (ConDecl _ _ lst) = length lst
      count (RecDecl _ _ lst) = length lst
      count InfixConDecl {}   = 2
  
  measureGadts :: [GadtDecl SrcLoc] -> Int
  measureGadts = sumOf count
    where
  #if MIN_VERSION_haskell_src_exts(1,21,0)
      count (GadtDecl _ _ _ _ maybeFields _) = maybe 0 length maybeFields
  #else
      count (GadtDecl _ _     maybeFields _) = maybe 0 length maybeFields
  #endif
  
  instance Show RecordFieldsCount where
    showsPrec _ (RecordFieldsCount rfc) = ("record fields count of " ++)
                                        . shows rfc
  