packages feed

HaskellAnalysisProgram-0.1.0: src/MetaHS/Extensions/LCOM.hs

{-|
Module      : MetaHS.Extensions.LCOM
Description : The MetaHS EDSL LCOM part
Copyright   : Copyright (C) 2017-2019 H.H.R.F. Vos, 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
Metamodel Elements that are interesting (those that are used to determine nodes in
MetaHS.EDSL.Graph.UsesGraph module ) are : TypeSynonym, DataType, Function.
All other Elements that are  part of the _contains relations are ignored.

LCOM4 - Number of connected components in the graph that represents each method as a node and the sharing of at least
        one attribute/method as an edge.
        ref. Hitz and Montazeri (1995)
-}
module MetaHS.Extensions.LCOM
    ( lcom
    , lcomGraph
    , keyLcom
    , lcomAggregator
    ) where

import qualified Data.Set as Set
import Data.Graph.Inductive
import MetaHS.DataModel.MetaModel
import MetaHS.EDSL.MetaModel
import MetaHS.EDSL.Graph

-- | Calculates the LCOM metric value for a specified module name.
lcom :: MetaModel -- ^ The meta-model.
     -> Element   -- ^ The Module Element.
     -> Int       -- ^ The calculated LCOM metric value.
lcom metaModel moduleElement = do
    let (value, _, _) = lcomGraph metaModel moduleElement Directed ""
    value

-- | Generates the internalUsesGraph for the specified Module Element and
-- calculates the corresponding LCOM metric value.
lcomGraph :: MetaModel                    -- ^ The meta-model.
          -> Element                      -- ^ The Module Element.
          -> Directed                     -- ^ Create a directed or undirected graph.
          -> String                       -- ^ The prefix for the links in the generated SVG images to the correct HTML editor for display the source code. Should probably become a hard link if a web server is used.
          -> (Int, GraphType, ParamsType) -- ^ The calculated LCOM metric value and the generated Graph and default parameters.
lcomGraph metaModel moduleElement directed editorLink = do
    let (graph, params) = internalUses metaModel moduleElement directed editorLink
    (noComponents graph, graph, params)

-- | MetaModel key used for the LCOM relation.
keyLcom :: RelationKey
keyLcom = "LCOM"

-- | LCOM aggregator that adds the LCOM relation to the metamodel.
-- key = keyLcom
-- value = (p,c) where p is a Module Element and c is an IntValue Element that
-- contains the LCOM value for the module.
lcomAggregator :: MetaModel
               -> MetaModel
lcomAggregator mm = setRelation keyLcom r mm
  where
    r = foldr f Set.empty $ filter (\x -> x /= Module {name = "?"}) $ getModules mm -- r = relation
    f m = Set.insert (m, lv m) -- f = foldr function
    lv m = IntValue $ lcom mm m                                                        -- lv = LCOM value