{-| Module : Analyse Description : Main test module for program analysis Copyright : Copyright (C) 2019 S. Kamps License : -- This file is distributed under the terms of the Apache License 2.0. For more information, see the file "LICENSE", which is included in the distribution. Stability : experimental -} module Analyse (analyse ) where import qualified Control.Monad as Monad import CsvData import qualified Data.Set as Set import FileOperation import qualified MetaHS.DataModel.MetaModel as MetaModel import MetaHS.EDSL import MetaHS.Extensions.CBO import MetaHS.Extensions.LCOM import MetaHS.Extensions.LOC import qualified ModuleLevelAnalysis as ModuleLevel import qualified ProgramLevelAnalysis as ProgramLevel import Settings import System.Directory (createDirectory, doesDirectoryExist, doesFileExist, removeDirectoryRecursive, removeFile) import System.FilePath.Posix (()) import Text.Printf -- | Start analysis based on the type of required information. -- | Type of analysis is either Evolution or Distribution. -- | Type of metric is either LCOM, LOC or CBO analyse :: Settings -- ^ The settings required for the Implementation Under Test. -> IO () analyse settings@(Settings _ _ _ Evolution LCOM) = do setupOutputDirectory settings metaModel <- generate settings let metaModelCompl = lcomAggregator metaModel analyseEvo settings metaModelCompl analyse settings@(Settings _ _ _ Evolution CBO) = do setupOutputDirectory settings metaModel <- generate settings let metaModelCompl = cboAggregator metaModel analyseEvo settings metaModelCompl analyse settings@(Settings _ _ _ Evolution LOC) = do setupOutputDirectory settings metaModel <- generate settings let metaModelCompl = locAggregator metaModel analyseEvo settings metaModelCompl analyse settings@(Settings _ _ _ Distribution LCOM) = do setupOutputDirectory settings metaModel <- generate settings let metaModelCompl = lcomAggregator metaModel analyseDist settings metaModelCompl analyse settings@(Settings _ _ _ Distribution CBO) = do setupOutputDirectory settings metaModel <- generate settings let metaModelCompl = cboAggregator metaModel analyseDist settings metaModelCompl analyse settings@(Settings _ _ _ Distribution LOC) = do setupOutputDirectory settings metaModel <- generate settings let metaModelCompl = locAggregator metaModel analyseDist settings metaModelCompl -- | Analysis for information on program level. For instance to plot package evolution. analyseEvo :: Settings -- ^ The settings required for the Implementation Under Test. -> MetaModel.MetaModel -- ^ Metamodel complemented with specific metric -> IO () analyseEvo settings mm = do let iutName = programName settings let metricName = show $ metricType settings let id = versionHashId settings let avg = ProgramLevel.calculateAverage id metricName mm let median = ProgramLevel.calculateMedian id metricName mm let gini = ProgramLevel.calculateGiniCoefficient id metricName mm let cg = ProgramLevel.calculateCG id metricName mm let ivd = ProgramLevel.calculateIvd id (metricType settings) mm let cgTimesIvd = ivd * cg let metricDetailInfo = ModuleLevel.extractMetricData id metricName mm appendItemToFile settings ((iutName ++ "_" ++ metricName) ++ "_Detailinfo") metricDetailInfo appendItemToFile settings ((iutName ++ "_" ++ metricName) ++ "_Average") [avg] appendItemToFile settings ((iutName ++ "_" ++ metricName) ++ "_Median") [median] appendItemToFile settings ((iutName ++ "_" ++ metricName) ++ "_Gini") [gini] appendItemToFile settings ((iutName ++ "_" ++ metricName) ++ "_CG") [cg] appendItemToFile settings ((iutName ++ "_" ++ metricName) ++ "_IVD") [ivd] appendItemToFile settings ((iutName ++ "_" ++ metricName) ++ "_CgTimesIvd") [cgTimesIvd] printf "Analysis output located in %s\n" $ show $ outputDirectory settings return () -- | Analysis for information about metric's module distribution. analyseDist :: Settings -- ^ The settings required for the Implementation Under Test. -> MetaModel.MetaModel -- ^ Metamodel complemented with specific metric -> IO () analyseDist settings mm = do setupOutputDirectory settings let metricName = show $ metricType settings printf "Analysing %s.\n" metricName printf "\n" writeMetaModeltoFile settings mm let distList = ProgramLevel.calculateDistribution (commitHash settings) metricName mm let popList = ProgramLevel.calculatePopulation (commitHash settings) metricName mm mapM_ (f settings) distList mapM_ (g settings) popList printf "Analysis output located in %s\n" $ show $ outputDirectory settings return () -- | helper for writing distribution to .csv file. f :: Settings -> (Int,Int) -> IO () f s x = do let z = DistPair x appendDistToFile s ("Distribution " ++ show (metricType s)) z -- | helper for writing population to .csv file. g :: Settings -> Int -> IO () g s x = do appendPopToFile s ("population " ++ show (metricType s)) x -- | Generates the MetaModel based on the provided Settings. generate :: Settings -- ^ The settings required for the Implementation Under Test. -> IO MetaModel.MetaModel -- ^ The generated MetaModel. generate settings = generateMetaModel pn sd pef where pn = programName settings sd = sourcesDirectory settings pef = parseErrorsFile settings versionHashId :: Settings -> String versionHashId s = version s ++ "," ++ commitHash s