{-# LANGUAGE CPP #-} {-# LANGUAGE TypeSynonymInstances #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE OverloadedStrings #-} #if __GLASGOW_HASKELL__ < 710 {-# LANGUAGE DeriveDataTypeable #-} #endif module Argon.Types (ComplexityBlock(CC), AnalysisResult, Config(..) , OutputMode(..), GhcParseError(..), defaultConfig) where import Data.List (intercalate) import Data.Aeson import Data.Typeable import Control.Exception (Exception) import qualified DynFlags as GHC import Argon.Loc data GhcParseError = GhcParseError { loc :: Loc , msg :: String } deriving (Typeable) -- | Hold the data associated to a function binding: -- @(location, function name, complexity)@. newtype ComplexityBlock = CC (Loc, String, Int) deriving (Show, Eq, Ord) -- | Represent the result of the analysis of one file. -- It can either be an error message or a list of -- 'ComplexityBlock's. type AnalysisResult = Either String [ComplexityBlock] -- | Type holding all the options passed from the command line. data Config = Config { -- | Minimum complexity a block has to have to be shown in results. minCC :: Int -- | Path to the main Cabal file , exts :: [GHC.ExtensionFlag] -- | Header files to be automatically included before preprocessing , headers :: [FilePath] -- | Additional include directories for the C preprocessor , includeDirs :: [FilePath] -- | Describe how the results should be exported. , outputMode :: OutputMode } -- | Type describing how the results should be exported. data OutputMode = BareText -- ^ Text-only output, no colors. | Colored -- ^ Text-only output, with colors. | JSON -- ^ Data is serialized to JSON. deriving (Show, Eq) -- | Default configuration options. -- -- __Warning__: These are not Argon's default options. defaultConfig :: Config defaultConfig = Config { minCC = 1 , exts = [] , headers = [] , includeDirs = [] , outputMode = JSON } instance Exception GhcParseError instance Show GhcParseError where show e = tagMsg (loc e) $ fixNewlines (msg e) where fixNewlines = intercalate "\n\t\t" . lines instance ToJSON ComplexityBlock where toJSON (CC ((s, c), func, cc)) = object [ "lineno" .= s , "col" .= c , "name" .= func , "complexity" .= cc ] instance {-# OVERLAPPING #-} ToJSON (FilePath, AnalysisResult) where toJSON (p, Left err) = object [ "path" .= p , "type" .= ("error" :: String) , "message" .= err ] toJSON (p, Right rs) = object [ "path" .= p , "type" .= ("result" :: String) , "blocks" .= rs ]