Esempio n. 1
0
        public override bool test(CSsemi.CSemiExp semi)
        {
            Display.displayRules(actionDelegate, "rule   DetectFunction");

            if (semi[semi.count - 1] != "{")
            {
                return(false);
            }

            int index = semi.FindFirst("(");

            if (index > 0 && !isSpecialToken(semi[index - 1]))
            {
                Repository rep = Repository.getInstance();

                CSsemi.CSemiExp local = new CSsemi.CSemiExp();
                local.Add("function").Add(semi[index - 1]);
                doActions(local);

                if (!rep.isFirstPass)
                {
                    /////////////////////////////////////////////////////////////////
                    //
                    // Parse function parameters to look for class dependencies
                    //
                    /////////////////////////////////////////////////////////////////
                    CSsemi.CSemiExp parameters = TokenHelper.GetFunctionParameters(semi);
                    for (int i = 0; i < TokenHelper.GetNumberOfParameters(parameters); i++)
                    {
                        parameters = TokenHelper.RemoveNewLines(parameters);
                        parameters = TokenHelper.RemoveIndicies(parameters);
                        parameters = TokenHelper.RemoveGenerics(parameters);
                        List <string> l = TokenHelper.GetFunctionParameterAtIndex(parameters, i);

                        foreach (CClassInfo ci in rep.parsedData.classList)
                        {
                            if (semi.Contains(ci.className) != -1)
                            {
                                if (rep.stack.count < 2)
                                {
                                    break;
                                }

                                string ns = rep.stack[0].name;                   // namespace
                                string cl = rep.stack[1].name;                   // class
                                string fn = rep.stack[rep.stack.count - 1].name; // function

                                CClassInfo    currentClassInfo    = rep.parsedData.getClassInfo(cl);
                                CFunctionInfo currentFunctioninfo = rep.parsedData.getClassFunctionInfo(cl, fn);

                                currentFunctioninfo.addDependency(l[l.Count - 2]);
                            }
                        }
                    }
                }

                return(true);
            }
            return(false);
        }
Esempio n. 2
0
        //----< calculate cohesion using class data members and function data member references >------------------------------------
        public static int calculateCohesion(CClassInfo classInfo)
        {
            int  cohesionValue = 0;
            bool found;

            foreach (CFunctionInfo functionInfoA in classInfo.functionInfoList)
            {
                found = false;
                foreach (CFunctionInfo functionInfoB in classInfo.functionInfoList)
                {
                    if (functionInfoA.name == functionInfoB.name)
                    {
                        found = true;
                        continue;
                    }

                    if (found)
                    {
                        //Console.WriteLine("comparing {0} {1}", functionInfoA.name, functionInfoB.name);

                        if (!doMembersShareValues(functionInfoA.dataMemberReferences, functionInfoB.dataMemberReferences))
                        {
                            //Console.WriteLine("--- don't share {0} {1}", functionInfoA.name, functionInfoB.name);
                            cohesionValue++;
                        }
                    }
                }
            }

            return(cohesionValue);
        }
Esempio n. 3
0
        //----< show formatted analysis output >-----------------
        static void showOutput()
        {
            Repository  rep   = Repository.getInstance();
            List <Elem> table = rep.locations;

            Console.WriteLine();

            Console.WriteLine(
                "  {0,13}  {1,24}  {2,5}  {3,5}  {4,5}  {5,5}  {6,5}",
                "category", "name", "loc", "cmplx", "cohsn", "coupl", "main"
                );
            Console.WriteLine(
                "  {0,13}  {1,24}  {2,5}  {3,5}  {4,5}  {5,5}  {6,5}",
                "--------", "----", "---", "-----", "-----", "-----", "-----"
                );

            foreach (Elem e in table)
            {
                bool isClass         = false;
                int  locValue        = optLOC ? optLOCCoefficient * (e.endLine - e.beginLine + 1) : 0;
                int  complexityValue = optComplexity ? optComplexityCoefficient * (e.endScopeCount - e.beginScopeCount + 1) : 0;
                int  couplingValue   = 0;
                int  cohesionValue   = 0;
                int  mainIndex       = 0;

                if (e.type == "class" || e.type == "struct")
                {
                    isClass = true;
                    CClassInfo classInfo = rep.parsedData.getClassInfo(e.name);
                    couplingValue = optCoupling ? optCouplingCoefficient * CCalculateMetrics.calculateCoupling(classInfo) : 0;
                    cohesionValue = optCohesion ? optCohesionCoefficient * CCalculateMetrics.calculateCohesion(classInfo) : 0;
                    mainIndex     = locValue + complexityValue + couplingValue + cohesionValue;

                    Console.WriteLine();
                }

                Console.WriteLine(
                    "  {0,13}  {1,24}  {2,5}  {3,5}  {4,5}  {5,5}  {6,5}",
                    e.type,
                    e.name,
                    optLOC ? locValue.ToString() : string.Empty,
                    optComplexity ? complexityValue.ToString() : string.Empty,
                    optCohesion ? (isClass ? cohesionValue.ToString() : string.Empty) : string.Empty,
                    optCoupling ? (isClass ? couplingValue.ToString() : string.Empty) : string.Empty,
                    isClass ? mainIndex.ToString() : string.Empty
                    );

                totalLOC        += locValue;
                totalComplexity += complexityValue;
                totalCohesion   += cohesionValue;
                totalCoupling   += couplingValue;
                totalMainIndex  += mainIndex;
            }
        }
Esempio n. 4
0
        //----< compute coupling using class and function dependencies >------------------------------------
        public static int calculateCoupling(CClassInfo classInfo)
        {
            List <string> uniqueDependencies = new List <string>(classInfo.dependencies);

            foreach (CFunctionInfo functionInfo in classInfo.functionInfoList)
            {
                foreach (string s in functionInfo.dependencies)
                {
                    if (!uniqueDependencies.Contains(s))
                    {
                        uniqueDependencies.Add(s);
                    }
                }
            }

            return(uniqueDependencies.Count);
        }
Esempio n. 5
0
        //----< find the class using the class name >------------------------------------
        public CClassInfo getClassInfo(string className)
        {
            foreach (CClassInfo ci in classList)
            {
                if (ci.className == className)
                {
                    return(ci);
                }
            }

            // allocate a new one
            CClassInfo newClassInfo = new CClassInfo();

            newClassInfo.className = className;
            classList.Add(newClassInfo);

            return(newClassInfo);
        }
Esempio n. 6
0
        //----< get function info for a particular class >------------------------------------
        public CFunctionInfo getClassFunctionInfo(string className, string classFunction)
        {
            CClassInfo classInfo = getClassInfo(className);

            foreach (CFunctionInfo fi in classInfo.functionInfoList)
            {
                if (fi.name == classFunction)
                {
                    return(fi);
                }
            }

            // allocate a new one
            CFunctionInfo newFunctionInfo = new CFunctionInfo();

            newFunctionInfo.name = classFunction;
            classInfo.functionInfoList.Add(newFunctionInfo);

            return(newFunctionInfo);
        }
Esempio n. 7
0
        //----< Test Stub >--------------------------------------------------

#if (TEST_PARSER)
        static void Main(string[] args)
        {
            Console.Write("\n  Demonstrating Parser");
            Console.Write("\n ======================\n");

            ShowCommandLine(args);

            Parser            parser;
            List <string>     files   = TestParser.ProcessCommandline(args);
            BuildCodeAnalyzer builder = null;

            foreach (string file in files)
            {
                Console.Write("\n  Processing file {0}\n", System.IO.Path.GetFileName(file));

                CSsemi.CSemiExp semi = new CSsemi.CSemiExp();
                semi.displayNewLines = false;
                if (!semi.open(file as string))
                {
                    Console.Write("\n  Can't open {0}\n\n", args[0]);
                    return;
                }

                Console.Write("\n  Type and Function Analysis");
                Console.Write("\n ----------------------------");

                builder = new BuildCodeAnalyzer(semi);
                parser  = builder.build(true);

                try
                {
                    while (semi.getSemi())
                    {
                        parser.parse(semi);
                    }
                    Console.Write("\n  locations table contains:");
                }
                catch (Exception ex)
                {
                    Console.Write("\n\n  {0}\n", ex.Message);
                }

                Repository  rep   = Repository.getInstance();
                List <Elem> table = rep.locations;
                Console.Write(
                    "\n  {0,10}, {1,25}, {2,5}, {3,5}, {4,5}, {5,5}, {6,5}, {7,5}",
                    "category", "name", "bLine", "eLine", "bScop", "eScop", "size", "cmplx"
                    );
                Console.Write(
                    "\n  {0,10}, {1,25}, {2,5}, {3,5}, {4,5}, {5,5}, {6,5}, {7,5}",
                    "--------", "----", "-----", "-----", "-----", "-----", "----", "-----"
                    );
                foreach (Elem e in table)
                {
                    if (e.type == "class" || e.type == "struct")
                    {
                        Console.Write("\n");
                    }
                    Console.Write(
                        "\n  {0,10}, {1,25}, {2,5}, {3,5}, {4,5}, {5,5}, {6,5}, {7,5}",
                        e.type, e.name, e.beginLine, e.endLine, e.beginScopeCount, e.endScopeCount + 1,
                        e.endLine - e.beginLine + 1, e.endScopeCount - e.beginScopeCount + 1
                        );
                }

                Console.Write("\n");
                semi.close();
            }



            foreach (string file in files)
            {
                Console.Write("\n  Processing file {0}\n", System.IO.Path.GetFileName(file));

                CSsemi.CSemiExp semi = new CSsemi.CSemiExp();
                semi.displayNewLines = false;
                if (!semi.open(file as string))
                {
                    Console.Write("\n  Can't open {0}\n\n", args[0]);
                    return;
                }

                Console.Write("\n  Type and Function Analysis");
                Console.Write("\n ----------------------------");

                builder = new BuildCodeAnalyzer(semi);
                parser  = builder.build(false);

                try
                {
                    while (semi.getSemi())
                    {
                        parser.parse(semi);
                    }
                    Console.Write("\n  locations table contains:");
                }
                catch (Exception ex)
                {
                    Console.Write("\n\n  {0}\n", ex.Message);
                }

                Repository  rep   = Repository.getInstance();
                List <Elem> table = rep.locations;
                Console.Write(
                    "\n  {0,10}, {1,25}, {2,5}, {3,5}, {4,5}, {5,5}, {6,5}, {7,5}",
                    "category", "name", "bLine", "eLine", "bScop", "eScop", "size", "cmplx"
                    );
                Console.Write(
                    "\n  {0,10}, {1,25}, {2,5}, {3,5}, {4,5}, {5,5}, {6,5}, {7,5}",
                    "--------", "----", "-----", "-----", "-----", "-----", "----", "-----"
                    );
                foreach (Elem e in table)
                {
                    if (e.type == "class" || e.type == "struct")
                    {
                        Console.Write("\n");
                    }

                    Console.Write(
                        "\n  {0,10}, {1,25}, {2,5}, {3,5}, {4,5}, {5,5}, {6,5}, {7,5}",
                        e.type, e.name, e.beginLine, e.endLine, e.beginScopeCount, e.endScopeCount + 1,
                        e.endLine - e.beginLine + 1, e.endScopeCount - e.beginScopeCount + 1
                        );

                    if (e.type == "class" || e.type == "struct")
                    {
                        CClassInfo classInfo = rep.parsedData.getClassInfo(e.name);
                        Console.WriteLine("Coupling: {0}", CCalculateMetrics.calculateCoupling(classInfo));
                        Console.WriteLine("Cohesion: {0}", CCalculateMetrics.calculateCohesion(classInfo));
                    }
                }

                Console.Write("\n");
                semi.close();
            }
            Console.Write("\n\n");
        }
Esempio n. 8
0
        static void Main(string[] args)
        {
            CClassList classList = new CClassList();

            CClassInfo classInfo = new CClassInfo();

            classList.classList.Add(classInfo);

            // CLASS B
            classInfo.className = "CTestClassA";
            classInfo.dependencies.Add("cdCToken");
            classInfo.dependencies.Add("cdITem");
            classInfo.dependencies.Add("cdString");

            CMemberInfo memberInfo = new CMemberInfo();

            memberInfo.type = "cmA";
            memberInfo.name = "nameA";
            classInfo.dataMembers.Add(memberInfo);
            memberInfo      = new CMemberInfo();
            memberInfo.type = "cmB";
            memberInfo.name = "nameB";
            classInfo.dataMembers.Add(memberInfo);

            // FUNCTION A
            CFunctionInfo functionInfo = new CFunctionInfo();

            functionInfo.name = "fnTestFunction1";

            memberInfo      = new CMemberInfo();
            memberInfo.type = "cmA";
            memberInfo.name = "nameA";
            functionInfo.dataMemberReferences.Add(memberInfo);
            memberInfo      = new CMemberInfo();
            memberInfo.type = "cmB";
            memberInfo.name = "nameB";
            functionInfo.dataMemberReferences.Add(memberInfo);

            classInfo.functionInfoList.Add(functionInfo);

            // FUNCTION B
            functionInfo      = new CFunctionInfo();
            functionInfo.name = "fnTestFunction2";

            memberInfo      = new CMemberInfo();
            memberInfo.type = "cmZ";
            memberInfo.name = "newItemA";
            functionInfo.dataMemberReferences.Add(memberInfo);
            memberInfo      = new CMemberInfo();
            memberInfo.type = "cmB";
            memberInfo.name = "nameB";
            functionInfo.dataMemberReferences.Add(memberInfo);

            classInfo.functionInfoList.Add(functionInfo);

            // FUNCTION C
            functionInfo      = new CFunctionInfo();
            functionInfo.name = "fnTestFunction3";

            memberInfo      = new CMemberInfo();
            memberInfo.type = "cmB";
            memberInfo.name = "nameB";
            functionInfo.dataMemberReferences.Add(memberInfo);
            memberInfo      = new CMemberInfo();
            memberInfo.type = "cmJ";
            memberInfo.name = "newItemB";
            functionInfo.dataMemberReferences.Add(memberInfo);

            classInfo.functionInfoList.Add(functionInfo);

            classInfo = new CClassInfo();
            classList.classList.Add(classInfo);

            // CLASS B
            classInfo.className = "CTestClassB";
            classInfo.dependencies.Add("yellow");
            classInfo.dependencies.Add("orange");
            classInfo.dependencies.Add("green");

            memberInfo      = new CMemberInfo();
            memberInfo.type = "Monkey";
            memberInfo.name = "dave";
            classInfo.dataMembers.Add(memberInfo);
            memberInfo      = new CMemberInfo();
            memberInfo.type = "Car";
            memberInfo.name = "Toyota";
            classInfo.dataMembers.Add(memberInfo);

            // FUNCTION A
            functionInfo      = new CFunctionInfo();
            functionInfo.name = "fnTestFunction1B";

            memberInfo      = new CMemberInfo();
            memberInfo.type = "Monkey";
            memberInfo.name = "dave";
            functionInfo.dataMemberReferences.Add(memberInfo);
            memberInfo      = new CMemberInfo();
            memberInfo.type = "Snake";
            memberInfo.name = "Python";
            functionInfo.dataMemberReferences.Add(memberInfo);

            classInfo.functionInfoList.Add(functionInfo);

            // FUNCTION B
            functionInfo      = new CFunctionInfo();
            functionInfo.name = "fnTestFunction2B";

            memberInfo      = new CMemberInfo();
            memberInfo.type = "Bug";
            memberInfo.name = "Beatles";
            functionInfo.dataMemberReferences.Add(memberInfo);
            memberInfo      = new CMemberInfo();
            memberInfo.type = "Snake";
            memberInfo.name = "Python";
            functionInfo.dataMemberReferences.Add(memberInfo);

            classInfo.functionInfoList.Add(functionInfo);

            // FUNCTION C
            functionInfo      = new CFunctionInfo();
            functionInfo.name = "fnTestFunction3B";

            memberInfo      = new CMemberInfo();
            memberInfo.type = "Computer";
            memberInfo.name = "Dell";
            functionInfo.dataMemberReferences.Add(memberInfo);
            memberInfo      = new CMemberInfo();
            memberInfo.type = "Computer";
            memberInfo.name = "HP";
            functionInfo.dataMemberReferences.Add(memberInfo);

            classInfo.functionInfoList.Add(functionInfo);

            Console.WriteLine("Break here and observe ParsedData data structure.");
        }
Esempio n. 9
0
        public override bool test(CSsemi.CSemiExp semi)
        {
            Repository rep = Repository.getInstance();

            if (rep.isFirstPass)
            {
                return(false);
            }

            if (rep.stack.count <= 2)
            {
                // we are not in a class or function scope
                return(false);
            }
            else if (rep.stack[rep.stack.count - 1].type != "function")
            {
                return(false);
            }
            else if (rep.stack.count > 3)
            {
                //Console.WriteLine("skip: unknown code block in function, unhandled");
                return(false);
            }

            Display.displayRules(actionDelegate, "rule   DetectFunctionMembers");

            int index = semi.Contains(";");

            if (index != -1)
            {
                /////////////////////////////////////////////////////////////////
                //
                // Parse function body to look for class member references
                //
                /////////////////////////////////////////////////////////////////

                if (rep.stack.count < 3)
                {
                    return(false);
                }

                string ns = rep.stack[0].name; // namespace
                string cl = rep.stack[1].name; // class
                string fn = rep.stack[2].name; // function

                CClassInfo    currentClassInfo    = rep.parsedData.getClassInfo(cl);
                CFunctionInfo currentFunctionInfo = rep.parsedData.getClassFunctionInfo(cl, fn);

                foreach (CMemberInfo classDataMember in currentClassInfo.dataMembers)
                {
                    if (semi.Contains(classDataMember.name) != -1)
                    {
                        currentFunctionInfo.addDataMemberReference(classDataMember.type, classDataMember.name);
                    }
                }

                /////////////////////////////////////////////////////////////////
                //
                // Parse function body to look for class dependencies
                //
                /////////////////////////////////////////////////////////////////
                foreach (CClassInfo ci in rep.parsedData.classList)
                {
                    if (semi.Contains(ci.className) != -1)
                    {
                        currentFunctionInfo.addDependency(ci.className);
                    }
                }

                return(true);
            }

            return(false);
        }
Esempio n. 10
0
        public override bool test(CSsemi.CSemiExp semi)
        {
            Repository rep = Repository.getInstance();

            //if (!rep.isFirstPass)
            //{
            //return false;
            //}

            if (rep.stack.count <= 0)
            {
                // we are not in a class or function scope
                return(false);
            }
            else if (rep.stack[rep.stack.count - 1].type != "class")
            {
                return(false);
            }
            else if (rep.stack.count > 2)
            {
                //Console.WriteLine("skip: found class in a class, unhandled");
                return(false);
            }

            Display.displayRules(actionDelegate, "rule   DetectClassMembers");

            int index = semi.Contains(";");

            if (index != -1)
            {
                CSsemi.CSemiExp clean = TokenHelper.RemoveNewLines(semi);
                clean = TokenHelper.GetLeftOfEqual(clean);
                clean = TokenHelper.RemoveGenerics(clean);
                clean = TokenHelper.RemoveIndicies(clean);
                clean = TokenHelper.RemoveKeywords(clean);
                clean = TokenHelper.RemoveAccess(clean);
                clean = TokenHelper.CombineNamespace(clean);

                // "if", "for", "foreach", "while", "catch", "using"
                if ((clean[0] == "using") || (clean[0] == "return") || (clean[0] == "if") || (clean[0] == "for") || (clean[0] == "break") || (clean.Contains("(") != -1) || (clean[0] == "get") || (clean[0] == "set"))
                {
                    return(false);
                }

                CSsemi.CSemiExp local = new CSsemi.CSemiExp();
                // create local semiExp with tokens for type and name
                local.displayNewLines = false;

                if (rep.stack.count < 2)
                {
                    return(false);
                }

                string ns = rep.stack[0].name;
                string cl = rep.stack[1].name;

                if (clean.count >= 2)
                {
                    local.Add(clean[0]).Add(clean[1]);

                    if (rep.isFirstPass)
                    {
                        /////////////////////////////////////////////////////////////////
                        //
                        // Parse Class to get class members
                        //
                        /////////////////////////////////////////////////////////////////

                        if (rep.stack.count == 2)
                        {
                            string type = clean[0];
                            string name = clean[1];

                            CClassInfo currentClassInfo = rep.parsedData.getClassInfo(cl);
                            currentClassInfo.addDataMember(type, name);
                        }
                    }
                    else
                    {
                        /////////////////////////////////////////////////////////////////
                        //
                        // Parse Class body to detect class use dependency
                        //
                        /////////////////////////////////////////////////////////////////

                        if (rep.stack.count == 2)
                        {
                            foreach (CClassInfo ci in rep.parsedData.classList)
                            {
                                if (semi.Contains(ci.className) != -1)
                                {
                                    CClassInfo currentClassInfoList = rep.parsedData.getClassInfo(cl);
                                    currentClassInfoList.addDependency(ci.className);
                                }
                            }
                        }
                    }

                    return(true);
                }
            }

            return(false);
        }
Esempio n. 11
0
        public override bool test(CSsemi.CSemiExp semi)
        {
            Display.displayRules(actionDelegate, "rule   DetectClass");

            int indexCL = semi.Contains("class");
            int indexIF = semi.Contains("interface");
            int indexST = semi.Contains("struct");

            int index = Math.Max(indexCL, indexIF);

            index = Math.Max(index, indexST);
            if (index != -1)
            {
                /////////////////////////////////////////////////////////////////
                //
                // Parse Class to get class names
                //
                /////////////////////////////////////////////////////////////////
                Repository rep = Repository.getInstance();

                CSsemi.CSemiExp local = new CSsemi.CSemiExp();

                // local semiExp with tokens for type and name
                local.displayNewLines = false;
                local.Add(semi[index]).Add(semi[index + 1]);
                doActions(local);

                if (rep.stack.count < 2)
                {
                    return(false);
                }

                string ns = rep.stack[0].name;
                string cl = rep.stack[1].name;

                // If it's not there, it's automatically added in getClassInfo()
                CClassInfo currentClassInfo = rep.parsedData.getClassInfo(cl);

                /////////////////////////////////////////////////////////////////
                //
                // Parse Class to detect inheritance
                //
                /////////////////////////////////////////////////////////////////
                if (!rep.isFirstPass)
                {
                    index = semi.Contains(":");
                    if (index != -1)
                    {
                        if (index + 1 < semi.count)
                        {
                            string baseClass = semi[index + 1];
                            currentClassInfo.addDependency(baseClass);
                        }
                    }
                }

                return(true);
            }

            return(false);
        }
Esempio n. 12
0
        static void Main(string[] args)
        {
            CClassList classList = new CClassList();

            CClassInfo classInfo = new CClassInfo();

            // CLASS
            classInfo.className = "CTestClass";
            classInfo.dependencies.Add("cdCToken");
            classInfo.dependencies.Add("cdITem");
            classInfo.dependencies.Add("cdString");

            CMemberInfo memberInfo = new CMemberInfo();

            memberInfo.type = "cmA";
            memberInfo.name = "nameA";
            classInfo.dataMembers.Add(memberInfo);
            memberInfo      = new CMemberInfo();
            memberInfo.type = "cmB";
            memberInfo.name = "nameB";
            classInfo.dataMembers.Add(memberInfo);

            // FUNCTION A
            CFunctionInfo functionInfo = new CFunctionInfo();

            functionInfo.name = "fnTestFunction1";

            memberInfo      = new CMemberInfo();
            memberInfo.type = "cmA";
            memberInfo.name = "nameA";
            functionInfo.dataMemberReferences.Add(memberInfo);
            memberInfo      = new CMemberInfo();
            memberInfo.type = "cmB";
            memberInfo.name = "nameB";
            functionInfo.dataMemberReferences.Add(memberInfo);

            classInfo.functionInfoList.Add(functionInfo);

            // FUNCTION B
            functionInfo      = new CFunctionInfo();
            functionInfo.name = "fnTestFunction2";

            memberInfo      = new CMemberInfo();
            memberInfo.type = "cmZ";
            memberInfo.name = "newItemA";
            functionInfo.dataMemberReferences.Add(memberInfo);
            memberInfo      = new CMemberInfo();
            memberInfo.type = "cmB";
            memberInfo.name = "nameB";
            functionInfo.dataMemberReferences.Add(memberInfo);

            classInfo.functionInfoList.Add(functionInfo);

            // FUNCTION C
            functionInfo      = new CFunctionInfo();
            functionInfo.name = "fnTestFunction3";

            memberInfo      = new CMemberInfo();
            memberInfo.type = "cmB";
            memberInfo.name = "nameB";
            functionInfo.dataMemberReferences.Add(memberInfo);
            memberInfo      = new CMemberInfo();
            memberInfo.type = "cmJ";
            memberInfo.name = "newItemB";
            functionInfo.dataMemberReferences.Add(memberInfo);

            classInfo.functionInfoList.Add(functionInfo);

            int cohesion = calculateCohesion(classInfo);

            int coupling = calculateCoupling(classInfo);

            Console.WriteLine("cohesion {0}, coupling {1}", cohesion, coupling);
        }