Esempio n. 1
0
 //
 public static bool CompareNavigations(KnowledgeBase KB, IOutputService output)
 {
     Utility.CreateModuleNamesFile(KB);
     Navigation.ReplaceModulesInNVGFiles(KB, output);
     return Navigation.CompareLastNVGDirectories(KB, output);
 }
Esempio n. 2
0
        //
        public static void PreProcessPendingObjects(KnowledgeBase KB, IOutputService output, List<KBObject> objs, out List<string[]> lineswriter, out double tech_debt_total)
        {
            tech_debt_total = 0;
            const string KBDOCTOR_OUTPUTID = "KBDoctor";
            output.SelectOutput(KBDOCTOR_OUTPUTID);

            FileIniDataParser fileIniData = new FileIniDataParser();
            InitializeIniFile(KB);

            string filename = KB.UserDirectory + "\\KBDoctor.ini";
            IniData parsedData = fileIniData.ReadFile(filename);
            string SectionName = "ReviewObject";

            List<Tuple<KBObject, string, double>> recommended_list = new List<Tuple<KBObject, string, double>>();

            List<KBObject> atts = new List<KBObject>();
            foreach (KBObject obj in objs)
            {
                int obj_tech_debt = 0;
                int cant = 0;
                int valor = 1;
                string recommendations = "";
                List<KBObject> objlist = new List<KBObject>();
                objlist.Add(obj);
                if (Utility.isRunable(obj) && !Utility.IsGeneratedByPattern(obj))
                {
                    //Check objects with parameteres without inout
                    if (CheckKeyInINI(parsedData, SectionName, "ParamINOUT", "true", "Check if all parameters have IN: OUT: INOUT: keywords", filename))
                    { 
                        Objects.ParmWOInOut(objlist, output, ref recommendations, out cant);
                        obj_tech_debt += cant * valor;
                    }

                    //Clean variables not used
                    if (CheckKeyInINI(parsedData, SectionName, "CleanUnusedVariables", "true", "Remove unused variables from objects", filename))
                        CleanKB.CleanKBObjectVariables(obj, output, ref recommendations);

                    //Check commit on exit
                    if (CheckKeyInINI(parsedData, SectionName, "CheckCommitOnExit", "true", "Check if property Commit on exit = YES", filename))
                    { 
                        Objects.CommitOnExit(objlist, output, ref recommendations, out cant);
                        obj_tech_debt += cant * valor;
                    }

                    //Is in module
                    if (CheckKeyInINI(parsedData, SectionName, "CheckModule", "true", "Use of modules is required", filename))
                    {
                        Objects.isInModule(objlist, output, ref recommendations, out cant);
                        obj_tech_debt += cant * valor;
                    }

                    //Fix variables not based in domains or attributes
                    bool fixvar = true;
                    if (CheckKeyInINI(parsedData, SectionName, "FixVariables", "false", "Fix variables definition, assinging Attribute or Domain", filename))
                        fixvar = false;

                    //With variables not based on attributes
                    if (CheckKeyInINI(parsedData, SectionName, "VariablesBasedAttOrDomain", "true", "Variables must be based on Attributes or Domains", filename))
                    { 
                        Objects.ObjectsWithVarNotBasedOnAtt(objlist, output, fixvar, ref recommendations, out cant);
                        obj_tech_debt += cant * valor;
                    }
                    //Code commented
                    if (CheckKeyInINI(parsedData, SectionName, "CodeCommented", "true", "Code commented is marked as error", filename))
                    { 
                        Objects.CodeCommented(objlist, output, ref recommendations, out cant);
                        obj_tech_debt += cant * valor;
                    }

                    //Assign types comparer
                    if (CheckKeyInINI(parsedData, SectionName, "AssignTypes", "true", "Check if assignments have the correct Type or Domain", filename))
                    { 
                        AssignTypesComprarer(KB, objlist, ref recommendations, out cant);
                        obj_tech_debt += cant * valor;
                    }

                    //Parameter types comparer
                    if (CheckKeyInINI(parsedData, SectionName, "ParameterTypes", "true", "Check if call parameters have the correct Type or Domain", filename))
                    { 
                        ParametersTypeComparer(KB, objlist, ref recommendations, out cant);
                        obj_tech_debt += cant * valor;
                    }

                    //Empty conditional blocks
                    if (CheckKeyInINI(parsedData, SectionName, "EmptyConditionalBlocks", "true", "Checks if exists any IF/Else block without code in it", filename))
                    {
                        EmptyConditionalBlocks(KB, objlist, ref recommendations, out cant);
                        obj_tech_debt += cant * valor; 
                    }
                    //Constants in code
                    if (CheckKeyInINI(parsedData, SectionName, "ConstantsInCode", "true", "Check if there are hardcoded constants", filename))
                    { 
                        ConstantsInCode(KB, objlist, out cant);
                        obj_tech_debt += cant * valor;
                    }
                    //For eachs without when none
                    if (CheckKeyInINI(parsedData, SectionName, "ForEachsWithoutWhenNone", "true", "Check if there is any 'ForEach' block without a 'When None' clause", filename))
                        ForEachsWithoutWhenNone(KB, objlist);
                    //News without when duplicate
                    if (CheckKeyInINI(parsedData, SectionName, "NewsWithoutWhenDuplicate", "true", "Check if there is any 'New' block without 'When Duplicate' clause", filename))
                        NewsWithoutWhenDuplicate(KB, objlist);
                    if (CheckKeyInINI(parsedData, SectionName, "ProceduresCalledAsFuction", "true", "Check if the procedures are called as functions", filename))
                    { 
                        ProceduresCalledAsFunction(KB, objlist, ref recommendations, out cant);
                        obj_tech_debt += cant * valor;
                    }

                    if (CheckKeyInINI(parsedData, SectionName, "DocumentsInWebPanels", "true", "Check if there are File management variables (and some others) in WebPanels", filename))
                    {
                        DocumentsInWebPanels(KB, objlist, ref recommendations, out cant);
                        obj_tech_debt += cant * valor;
                    }

                    //Check complexity metrics
                    //maxNestLevel  6 - ComplexityLevel  30 - MaxCodeBlock  500 - parametersCount  6

                    bool aux;
                    aux = CheckKeyInINI(parsedData, SectionName, "MaxNestLevel", "7", "Maximun nesting level allowed in source", filename);
                    aux = CheckKeyInINI(parsedData, SectionName, "MaxComplexity", "30", "Maximun Complexity level allowed in sources", filename);
                    aux = CheckKeyInINI(parsedData, SectionName, "MaxBlockSize", "500", "Maximun block of code", filename);
                    aux = CheckKeyInINI(parsedData, SectionName, "MaxParameterCount", "6", "Maximun Number of parameters allowed in parm rule", filename);

                    int maxNestLevel = 7;
                    Int32.TryParse(parsedData[SectionName]["MaxNestLevel"], out maxNestLevel);

                    int complexityLevel = 30;
                    Int32.TryParse(parsedData[SectionName]["MaxComplexity"], out complexityLevel);

                    int maxCodeBlock = 500;
                    Int32.TryParse(parsedData[SectionName]["MaxBlockSize"], out maxCodeBlock);

                    int maxParametersCount = 6;
                    Int32.TryParse(parsedData[SectionName]["MaxParameterCount"], out maxParametersCount);

                    int diffNestLevel;
                    int diffcomplexityLevel;
                    int diffCodeBlock;
                    int diffParametersCount;

                    Objects.CheckComplexityMetrics(obj, output, maxNestLevel, complexityLevel, maxCodeBlock, maxParametersCount, ref recommendations, out diffNestLevel, out diffcomplexityLevel, out diffCodeBlock, out diffParametersCount);

                    obj_tech_debt += diffCodeBlock * (10/60);
                    obj_tech_debt += diffcomplexityLevel * 1;
                    obj_tech_debt += diffParametersCount * 1;
                    obj_tech_debt += diffNestLevel * 1;

                }
                if (obj is Artech.Genexus.Common.Objects.Attribute && CheckKeyInINI(parsedData, SectionName, "AttributeBasedOnDomain", "true", "Attributes must be based on domains", filename))
                {
                    atts.Add(obj);
                    //Attribute Has Domain
                    Objects.AttributeHasDomain(objlist, output, ref recommendations, out cant);
                    obj_tech_debt += cant * valor;

                }
                if (obj is SDT && CheckKeyInINI(parsedData, SectionName, "SDTBasedAttOrDomain", "true", "SDT items must be based on attributes or domains", filename))
                {
                    //SDTItems Has Domain
                    Objects.SDTBasedOnAttDomain(objlist, output, ref recommendations, out cant);
                    obj_tech_debt += cant * valor;
                }
                if (obj is Transaction && CheckKeyInINI(parsedData, SectionName, "AttributeBasedOnDomain", "true", "Attributes must be based on domains", filename))
                {
                    Objects.AttributeHasDomain(Objects.GetAttributesFromTrn((Transaction)obj), output, ref recommendations, out cant);
                    obj_tech_debt += cant * valor;
                }
               
                if (recommendations != "")
                {
                    Tuple<KBObject, string, double> recommend_tuple = new Tuple<KBObject, string, double>(obj, recommendations, obj_tech_debt);
                    recommended_list.Add(recommend_tuple);
                }
                tech_debt_total += obj_tech_debt;
            }
            if (atts.Count > 0 && CheckKeyInINI(parsedData, SectionName, "AttributeWithoutTable", "true", "All attributes must be in table", filename))
            {
                // Attributes without table
                Objects.AttributeWithoutTable(atts, output);
            }

            KBDoctorOutput.Message( "KBDoctor Review Object finished");
            output.UnselectOutput(KBDOCTOR_OUTPUTID);
            output.SelectOutput("General");
            lineswriter = new List<string[]>();

            foreach (Tuple<KBObject, string, double> item in recommended_list)
            {
                string[] line = new string[] { Utility.linkObject(item.Item1), item.Item2, item.Item3.ToString() };
                lineswriter.Add(line);
            }

                /*
                * Tiene todas las referencias?
                * Tiene calls que pueden ser UDP
                * Mas de un parametro de salida
                * Constantes en el código
                * Nombre "poco claro" / Descripcion "poco clara"
                * Si es modulo, revisar que no tenga objetos publicos no llamados
                * Si es modulo, revisar que no tenga objetos privados llamados desde fuera
                * Si es modulo, Valor de la propiedad ObjectVisibility <> Private
                * Atributo Varchar que debe ser char
                * Atributo Char que debe ser varchar
                * Column Title muy ancho para el ancho del atributo
                * Nombre del Control en pantalla por Default
                * Todos los eventos son invocados
                *
                */

        }