homplexity-0.4.6.0: lib/Language/Haskell/Homplexity/Metric.hs
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
-- | Class for defining code metrics, and its simplest implementation - number of lines of code.
module Language.Haskell.Homplexity.Metric (
Metric (..)
, LOC
, locT
, measureAs
, measureFor
) where
import Data.Data
import Data.Function
--import Data.Functor
import Control.Arrow
import Data.Generics.Uniplate.Data
import Data.List
import Language.Haskell.Exts.SrcLoc
--import Language.Haskell.Exts.Syntax
import Language.Haskell.Homplexity.CodeFragment
-- | Metric can be computed on a set of @CodeFragment@ fragments
-- and then shown.
class (CodeFragment c, Show m) => Metric m c where
measure :: c -> m
-- | Number of lines of code
-- (example metric)
newtype LOC = LOC { _asInt :: Int }
deriving (Ord, Eq, Enum, Num, Real, Integral)
-- | Proxy for passing @LOC@ type as parameter.
locT :: Proxy LOC
locT = Proxy
instance Show LOC where
showsPrec _ (LOC l) = shows l . (" lines of code"++)
instance Read LOC where
readsPrec prec str = first LOC <$> readsPrec prec str
instance (CodeFragment c) => Metric LOC c where
measure = LOC
. length -- total number of lines that contain at least one object with SrcLoc
. concatMap (nub . map srcLine) -- remove duplicate lines within the same file
. groupBy ((==) `on` srcFilename) -- group by filename
. universeBi -- all SrcLoc objects
-- | Convenience function for fixing the @Metric@ type.
measureAs :: (Metric m c) => Proxy m -> c -> m
measureAs _ = measure
-- | Convenience function for fixing both the @Metric@ and @CodeFragment@ for which the metric is computed.
measureFor :: (Metric m c) => Proxy m -> Proxy c -> c -> m
measureFor _ _ = measure