{-| 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