{- Copyright (C) 2009 Ivan Lazar Miljenovic This file is part of SourceGraph. SourceGraph is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -} {- | Module : Analyse.Utils Description : Utility functions and types for analysis. Copyright : (c) Ivan Lazar Miljenovic 2009 License : GPL-3 or later. Maintainer : Ivan.Miljenovic@gmail.com Utility functions and types for analysis. -} module Analyse.Utils where import Data.Graph.Analysis hiding (Bold) import Data.List(groupBy, sortBy) import Data.Function(on) import qualified Data.Set as S import Data.Set(Set) -- ----------------------------------------------------------------------------- -- | Cyclomatic complexity cyclomaticComplexity :: GraphData a b -> Int cyclomaticComplexity gd = e - n + 2*p where p = length $ applyAlg componentsOf gd n = applyAlg noNodes gd e = length $ applyAlg labEdges gd groupSortBy :: (Ord b) => (a -> b) -> [a] -> [[a]] groupSortBy f = groupBy ((==) `on` f) . sortBy (compare `on` f) bool :: a -> a -> Bool -> a bool f t b = if b then t else f chainEdges' :: NGroup -> Set Edge chainEdges' [] = S.empty chainEdges' ns = S.fromList $ zip ns (tail ns) chainEdges :: [NGroup] -> Set Edge chainEdges = S.unions . map chainEdges' cycleEdges' :: NGroup -> Set Edge cycleEdges' [] = S.empty cycleEdges' [_] = S.empty cycleEdges' ns@(n:ns') = (n, last ns') `S.insert` chainEdges' ns cycleEdges :: [NGroup] -> Set Edge cycleEdges = S.unions . map cycleEdges' cliqueEdges' :: NGroup -> Set Edge cliqueEdges' ns = S.fromList [(f,t) | f <- ns, t <- ns, f /= t] cliqueEdges :: [NGroup] -> Set Edge cliqueEdges = S.unions . map cliqueEdges' -- ----------------------------------------------------------------------------- -- For core coreDesc :: String -> DocElement coreDesc w = Paragraph [ Text "The core of" , BlankSpace , Text w , BlankSpace , Text "is calculated by recursively removing roots\ \ and leaves of the call graph; as such, it\ \ can be considered as the section where all\ \ the \"real work\" is done." ]