public void Run()
        {
            IAnalysisResult analysisResult;

            if (!ProjectAnalysisUtils.TryChooseAnalysisResult(out analysisResult))
            {
                return;
            }
            Debug.Assert(analysisResult != null);

            var codeBase = analysisResult.CodeBase;
            var types    = codeBase.Application.Types;

            var matchEditor     = new MatchEditor();
            var resultDisplayer = new ResultDisplayer();
            var resultSelector  = new ResultSelector(resultDisplayer);

            matchEditor.Display();

            while (true)
            {
                ConsoleKeyInfo consoleKeyInfo;
                bool           matchersChanged;
                matchEditor.ReadKey(out consoleKeyInfo, out matchersChanged);

                if (!matchersChanged)
                {
                    switch (consoleKeyInfo.Key)
                    {
                    case ConsoleKey.Escape:
                        return;

                    case ConsoleKey.UpArrow:
                        resultSelector.UpArrow();
                        continue;

                    case ConsoleKey.DownArrow:
                        resultSelector.DownArrow();
                        continue;

                    case ConsoleKey.Enter:
                        resultSelector.Enter();
                        continue;
                    }
                    continue;
                }

                var matchersLowerCase = matchEditor.GetMatchersLowerCase();
                var typesMatched      = SearchTypes(types, matchersLowerCase);
                resultDisplayer.Display(typesMatched, matchersLowerCase);
            }
        }
        //
        // A bit of code to test if DebuggerDisplay works well
        //
        internal static void Go()
        {
            // DebuggerDisplay of IAnalysisResult
            IAnalysisResult analysisResult;

            if (!ProjectAnalysisUtils.TryChooseAnalysisResult(out analysisResult))
            {
                return;
            }
            Debug.Assert(analysisResult != null);


            // DebuggerDisplay of IAnalysisResultRef
            var analysisResultRef = analysisResult.AnalysisResultRef;

            // DebuggerDisplay of IProject
            var project = analysisResultRef.Project;

            // DebuggerDisplay of IQuery
            var query = project.CodeQueries.CodeQueriesSet.AllQueriesRecursive.First();

            // DebuggerDisplay of ICodeBase
            var codeBase = analysisResult.CodeBase;

            // DebuggerDisplay of IAssembly
            var assembly = codeBase.Assemblies.First();

            // DebuggerDisplay of INamespace
            var @namespace = codeBase.Namespaces.First();

            // DebuggerDisplay of IType
            var type = codeBase.Types.First();

            // DebuggerDisplay of IField
            var field = codeBase.Fields.First();

            // DebuggerDisplay of IMethod
            var method = codeBase.Methods.Where(m => m.SourceFileDeclAvailable).First();

            // DebuggerDisplay of ISourceFileLine
            var sourceFileLine = method.SourceDecls.First();

            // DebuggerDisplay of ISourceFile
            var sourceFile = sourceFileLine.SourceFile;

            // DebuggerDisplay of IQueryCompiledError
            var queryCompiledError = "query not compilable".Compile(codeBase).QueryCompiledError;

            // DebuggerDisplay of IQueryCompilationError
            var queryCompilationError = queryCompiledError.Errors.First();
        }
        public void Run()
        {
            IAnalysisResult analysisResult;

            if (!ProjectAnalysisUtils.TryChooseAnalysisResult(out analysisResult))
            {
                return;
            }
            Debug.Assert(analysisResult != null);

            var codeBase = analysisResult.CodeBase;

            Console.CursorVisible = false;
            if (codeBase.NbILInstructions > 500 * 1000)
            {
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine("   ***  The search for duplicate can take a few seconds to a few minutes for large application   ***   ");
                Console.ForegroundColor = ConsoleColor.White;
            }
            var stopwatch = new Stopwatch();

            stopwatch.Start();

            //
            // 1) Find pairs of methods that call N or more same methods/fields.
            //
            Console.WriteLine("1) Find pairs of methods that call N or more same methods/fields.");
            var suspectSetsWith2Callers = SuspectSetsWith2CallersComputer.Go(codeBase, N);

            //
            // 2) Merge suspectSets with 2 methods callers methods into some suspectSets with 2 or more methods callers.
            //
            Console.WriteLine("2) Merge suspectSets with 2 methods callers methods into some suspectSets with 2 or more methods callers.");
            var suspectSetsMerged = SuspectSetsMerger.Go(suspectSetsWith2Callers, N);

            //
            // 3) Sort suspectSets, to try showing most suspect ones first.
            //
            Console.WriteLine("3) Sort suspectSets, to try showing most suspect ones first.");
            SuspectSetsSorter.Go(suspectSetsMerged);

            Console.WriteLine("Search for duplicate duration:" + stopwatch.Elapsed.ToString());

            //
            // 4) Show results!
            //
            ShowSuspectSet(suspectSetsMerged);
        }
示例#4
0
        public void Run()
        {
            IAnalysisResult analysisResult;

            if (!ProjectAnalysisUtils.TryChooseAnalysisResult(out analysisResult))
            {
                return;
            }
            Debug.Assert(analysisResult != null);

            var codeBase = analysisResult.CodeBase;

            // make usage of the default NDepend attribute: NDepend.Attributes.IsNotDeadCodeAttribute
            var isNotDeadCodeAttribute = codeBase.Types.WithFullName("NDepend.Attributes.IsNotDeadCodeAttribute").SingleOrDefault();
            var funcHasAttribute       = new Func <IMember, bool>(member =>
                                                                  (isNotDeadCodeAttribute != null && member.HasAttribute(isNotDeadCodeAttribute))
                                                                  );


            //
            // Apply dead code algo!
            //
            var deadTypesMetric   = DeadCodeAlgo.FindDeadTypes(codeBase, funcHasAttribute);
            var deadMethodsMetric = DeadCodeAlgo.FindDeadMethods(codeBase, funcHasAttribute);
            var deadFields        = DeadCodeAlgo.FindDeadFields(codeBase, funcHasAttribute);

            var deadCodeRecords = new List <DeadCodeRecord>();

            deadCodeRecords.Add(new DeadCodeRecord(" unused types", deadTypesMetric.Where(v => v.Value == 0).Select(v => v.CodeElement).Cast <IMember>().ToArray()));
            deadCodeRecords.Add(new DeadCodeRecord(" types used only by unused types", deadTypesMetric.Where(v => v.Value > 0).Select(v => v.CodeElement).Cast <IMember>().ToArray()));

            deadCodeRecords.Add(new DeadCodeRecord(" unused methods", deadMethodsMetric.Where(v => v.Value == 0).Select(v => v.CodeElement).Cast <IMember>().ToArray()));
            deadCodeRecords.Add(new DeadCodeRecord(" methods used only by unused methods", deadMethodsMetric.Where(v => v.Value > 0).Select(v => v.CodeElement).Cast <IMember>().ToArray()));

            deadCodeRecords.Add(new DeadCodeRecord(" unused fields", deadFields.Cast <IMember>().ToArray()));

            //
            // No dead code found!
            //
            var deadCodeFound = deadCodeRecords.Where(record => record.m_Members.Count() > 0).Count() > 0;

            if (!deadCodeFound)
            {
                Console.ForegroundColor = COLOR_NO_WARNING;
                Console.WriteLine("No dead code found!");
                return;
            }


            //
            // Show dead code
            //
            while (true)
            {
                ConsoleUtils.ShowNLinesOnConsole(3, ConsoleColor.Black);

                if (deadCodeRecords.Where(record => record.m_Members.Count() > 0).Count() == 0)
                {
                    Console.ForegroundColor = COLOR_NO_WARNING;
                    Console.WriteLine("No dead code found!");
                }
                else
                {
                    Console.ForegroundColor = COLOR_WARNING;
                    Console.WriteLine("Dead code found! (in Yellow)");
                }

                //
                // Show dead code menu
                //
                var aCharNumber = Convert.ToInt16('a');
                for (var i = 0; i <= deadCodeRecords.Count; i++)
                {
                    var description = "Exit";
                    if (i != deadCodeRecords.Count)
                    {
                        var record = deadCodeRecords[i];
                        Console.ForegroundColor = record.m_Members.Count() == 0 ? COLOR_NO_WARNING : COLOR_WARNING;
                        description             = record.m_Members.Count() + record.m_Description;
                    }
                    Console.WriteLine(" " + Convert.ToChar(aCharNumber + i) + ")  " + description);
                }
                Console.ForegroundColor = COLOR_DEFAULT;


                //
                // Get user choice
                //
                int deadCodeIndex;
                while (true)
                {
                    Console.Write("Enter key:");
                    var keyChar = Char.ToLower(Console.ReadKey().KeyChar);
                    Console.WriteLine("");
                    deadCodeIndex = Convert.ToInt16(keyChar) - aCharNumber;
                    if (deadCodeIndex < 0 || deadCodeIndex > deadCodeRecords.Count)
                    {
                        Console.Write(keyChar + " is not a valid key!");
                        continue;
                    }
                    break;
                }

                if (deadCodeIndex == deadCodeRecords.Count)
                {
                    break;
                }
                var recordTmp = deadCodeRecords[deadCodeIndex];


                //
                // Show dead members
                //
                var membersDisplayer = new MembersDisplayer(recordTmp.m_Members.ToList());
                membersDisplayer.Display();
            }
        }
        public void Run()
        {
            IAnalysisResult analysisResult;

            if (!ProjectAnalysisUtils.TryChooseAnalysisResult(out analysisResult))
            {
                return;
            }
            Debug.Assert(analysisResult != null);

            var codeBase = analysisResult.CodeBase;
            Func <string, IQueryCompiled> compileQueryProc = queryString => queryString.Compile(codeBase);

            // ... but if we can get a compareContext, then compile and execute the query against the compareContext
            ICompareContext compareContext;
            string          baselineDesc;

            if (ProjectAnalysisUtils.TryGetCompareContextDefinedByBaseline(analysisResult, out compareContext, out baselineDesc))
            {
                Debug.Assert(compareContext != null);
                compileQueryProc        = queryString => queryString.Compile(compareContext);
                Console.BackgroundColor = ConsoleColor.Black;
                Console.ForegroundColor = ConsoleColor.White;
                Console.WriteLine(baselineDesc);
            }

            //
            // Fill queriesPreviouslyEdited with current project queries
            //
            IPreviousNextStack <string> queriesPreviouslyEdited = new PreviousNextStack <string>(
                analysisResult.AnalysisResultRef.Project.CodeQueries.CodeQueriesSet.AllQueriesRecursive.Reverse().Select(q => q.QueryString),
                "",
                (s1, s2) => s1 == s2);

            // With this line, make sure to begin with the first queries of the project.
            queriesPreviouslyEdited.GetPrevious();


            //
            // Loop for each query edition
            //
            while (true)
            {
                IQueryCompiled queryCompiled;
                using (var queryEditSession = new QueryEditSession(queriesPreviouslyEdited)) {
                    var queryString = queryEditSession.GetQueryString();
COMPILE_QUERY:
                    Console.BackgroundColor = ConsoleColor.Black;
                    Console.ForegroundColor = ConsoleColor.White;
                    if (queryString == null)
                    {
                        break;
                    }

                    // Try compile query
                    queryCompiled = compileQueryProc(queryString);
                    var queryCompiledError = queryCompiled.QueryCompiledError;
                    if (queryCompiledError != null)
                    {
                        queryString = queryEditSession.ShowCompilatioErrorsAndThenGetQueryString(queryCompiledError);
                        goto COMPILE_QUERY;
                    }
                }

                // Execute query compiled
                var queryCompiledSuccess = queryCompiled.QueryCompiledSuccess;
                Debug.Assert(queryCompiledSuccess != null);
                var result = queryCompiledSuccess.Execute();
                if (result.Status != QueryExecutionStatus.Success)
                {
                    var exception = result.Exception;
                    // The error must be an Exception thrown by the query, since we don't use the Execute(...) overload with time-out!
                    Debug.Assert(exception != null);
                    DisplayQueryThrowAnException(exception);
                    continue;
                }

                QueryExecutionResultDisplayer.Go(result.SuccessResult);
                Console.WriteLine();
            }
        }
        public void Run()
        {
            // Choose project and analysis result
            IAnalysisResult analysisResult;

            if (!ProjectAnalysisUtils.TryChooseAnalysisResult(out analysisResult))
            {
                return;
            }
            Debug.Assert(analysisResult != null);
            var project = analysisResult.AnalysisResultRef.Project;

            // Try load the project baseline
            ICompareContext compareContext;
            string          baselineDesc;

            if (!ProjectAnalysisUtils.TryGetCompareContextDefinedByBaseline(analysisResult, out compareContext, out baselineDesc))
            {
                Console.BackgroundColor = ConsoleColor.Black;
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine("Cannot load a baseline for the project {" + project.Properties.Name + "}");
                return;
            }
            Debug.Assert(compareContext != null);
            SetRegularColors();
            Console.WriteLine(baselineDesc);

            // Compute issues-set-diff
            // To compute issue only on a single analysisResult just use:  analysisResult.ComputeIssues()
            SetRegularColors();
            Console.WriteLine("Computing issues on both now and baseline snapshots.");
            var issuesSetDiff = analysisResult.ComputeIssuesDiff(compareContext);
            var debtFormatter = project.DebtSettings.Values.CreateDebtFormatter();

            //
            // Technical Debt
            //
            WriteTitle("Technical Debt");
            ShowFromToLine("Technical debt",
                           issuesSetDiff,
                           issuesSet => debtFormatter.ToManDayString(issuesSet.AllDebt));

            ShowFromToLine("Technical debt Rating",
                           issuesSetDiff,
                           issuesSet => {
                DebtRating?debtRatingNullable = issuesSet.DebtRating(issuesSet.CodeBase);
                if (!debtRatingNullable.HasValue)
                {
                    return("N/A");
                }
                DebtRating debtRating = debtRatingNullable.Value;

                // Possible to change color in this getValueProc because it is called just before outputing the value on console
                // However cannot use debtRating.ToForeColor() and debtRating.ToBackColor() to change the console
                // since console colors are fixed with the enum ConsoleColor.
                ConsoleColor foreColor, backColor;
                switch (debtRating)
                {
                default: backColor = ConsoleColor.Green; foreColor = ConsoleColor.White; break;   // Case DebtRating.A

                case DebtRating.B: backColor = ConsoleColor.DarkGreen; foreColor = ConsoleColor.White; break;

                case DebtRating.C: backColor = ConsoleColor.Yellow; foreColor = ConsoleColor.Black; break;

                case DebtRating.D: backColor = ConsoleColor.DarkRed; foreColor = ConsoleColor.White; break;

                case DebtRating.E: backColor = ConsoleColor.Red; foreColor = ConsoleColor.White; break;
                }
                SetColors(backColor, foreColor);

                return(debtRatingNullable.Value.ToString());
            });


            ShowFromToLine("Annual Interest",
                           issuesSetDiff,
                           issuesSet => debtFormatter.ToManDayString(issuesSet.AllAnnualInterest));

            //
            // Quality Gates
            //
            WriteTitle("Quality Gates");
            ShowFromToLine("# Quality Gates Fail",
                           issuesSetDiff,
                           issuesSet => issuesSet.AllQualityGates.Count(qg => qg.Fail).ToString(), SetValueRedColors);

            ShowFromToLine("# Quality Gates Warn",
                           issuesSetDiff,
                           issuesSet => issuesSet.AllQualityGates.Count(qg => qg.Warn).ToString(), SetValueYellowColors);

            ShowFromToLine("# Quality Gates Pass",
                           issuesSetDiff,
                           issuesSet => issuesSet.AllQualityGates.Count(qg => qg.Pass).ToString(), SetValueGreenColors);

            SetInfoColors();
            Console.WriteLine("Quality Gates that rely on diff since baseline are not counted in the 'from' number.");


            //
            // Rules
            //
            WriteTitle("Rules");
            ShowFromToLine("# Critical Rules violated",
                           issuesSetDiff,
                           issuesSet => issuesSet.AllRules.Count(r => r.IsCritical && issuesSet.IsViolated(r)).ToString(), SetValueRedColors);

            ShowFromToLine("# Rules violated",
                           issuesSetDiff,
                           issuesSet => issuesSet.AllRules.Count(issuesSet.IsViolated).ToString(), SetValueDarkRedColors);

            ShowFromToLine("# Rules non violated",
                           issuesSetDiff,
                           issuesSet => issuesSet.AllRules.Count(r => !issuesSet.IsViolated(r)).ToString(), SetValueGreenColors);

            SetInfoColors();
            Console.WriteLine("Rules that rely on diff since baseline are not counted in the 'from' number.");

            //
            // Issues
            //
            WriteTitle("Issues");
            ShowFromToLineForIssues("# issues",
                                    issuesSetDiff,
                                    issuesSet => issuesSet.AllIssues.ToArray());

            foreach (var severity in new[] { Severity.Blocker, Severity.Critical, Severity.High, Severity.Medium, Severity.Low })
            {
                var severityTmp = severity; // Needed to avoid access foreach variable in closure!
                ShowFromToLineForIssues("# " + Enum.GetName(typeof(Severity), severityTmp) + " issues",
                                        issuesSetDiff,
                                        issuesSet => issuesSet.AllIssues.Where(i => i.Severity == severityTmp).ToArray());
            }

            SetInfoColors();
            Console.WriteLine("In red # issues added since baseline, in green # issues fixed since baseline.");
            Console.WriteLine("The severity of an issue can change. Hence a change in # total issues for a certain severity level");
            Console.WriteLine("doesn't necessarily correspond to a change in # added / # fixed.");


            //
            // Quality Gates Details
            //
            WriteTitle("Quality Gates Details");
            foreach (var qualityGate in issuesSetDiff.NewerIssuesSet.AllQualityGates)
            {
                WriteQualityGateDetails(qualityGate, issuesSetDiff.OlderVersion(qualityGate));
            }
            SetInfoColors();
            Console.WriteLine("Quality Gates that rely on diff don't have a value computed on baseline.");
        }
示例#7
0
        public void Run()
        {
            IAnalysisResult analysisResult;

            if (!ProjectAnalysisUtils.TryChooseAnalysisResult(out analysisResult))
            {
                return;
            }
            Debug.Assert(analysisResult != null);

            var codeBase = analysisResult.CodeBase;

            //
            // Get weight for each identifier
            //
            var identifierWeights = codeBase.Assemblies.Select(IdentifierWeightComputer.GetWeigth).ToList();

            identifierWeights.AddRange(codeBase.Namespaces.Select(IdentifierWeightComputer.GetWeigth).ToList());
            identifierWeights.AddRange(codeBase.Types.Select(IdentifierWeightComputer.GetWeigth).ToList());
            identifierWeights.AddRange(codeBase.Methods.Select(IdentifierWeightComputer.GetWeigth).ToList());
            identifierWeights.AddRange(codeBase.Fields.Select(IdentifierWeightComputer.GetWeigth).ToList());


            //
            // Extract words and their weight from identifier
            //
            var dico = new Dictionary <string, float>();

            foreach (var identifierWeight in identifierWeights)
            {
                if (identifierWeight == null)
                {
                    continue;
                }
                var weightNullable = identifierWeight.Weight;
                if (weightNullable == null || weightNullable == 0)
                {
                    continue;
                }
                var weight = weightNullable.Value;
                var words  = WordExtracter.ExtractWordsFromIdentifier(identifierWeight.Identifier);
                foreach (var word in words)
                {
                    if (!dico.ContainsKey(word))
                    {
                        dico.Add(word, weight);
                        continue;
                    }
                    dico[word] += weight;
                }
            }

            //
            // Sort weigh descendant
            //
            var wordWeights = dico.Select(pair => new IdentifierWeight(pair.Key, pair.Value)).ToList();

            wordWeights.Sort((w1, w2) => w1.Weight <w2.Weight ? 1 : w1.Weight> w2.Weight ? -1 : 0);



            //
            // show result
            //
            var listOfLines = (from wordWeight in wordWeights
                               let identifier = wordWeight.Identifier
                                                select identifier + (identifier.Length < 30 ? new string(' ', 30 - identifier.Length) : "   ") + "Weight: " + wordWeight.Weight).ToList();

            ShowConsoleListOfLines(listOfLines);
        }
        public void Run()
        {
            IAnalysisResult analysisResult;

            if (!ProjectAnalysisUtils.TryChooseAnalysisResult(out analysisResult))
            {
                return;
            }
            Debug.Assert(analysisResult != null);

            var project = analysisResult.AnalysisResultRef.Project;

            CreateBackupProjectFile(project);

            //
            // Convert all CQL queries compiled successfully!
            //
            var queriesSet         = project.CodeQueries.CodeQueriesSet;
            var queriesController  = queriesSet.Controller;
            var allQueries         = queriesSet.AllQueriesRecursive;
            var allQueriesString   = allQueries.Select(q => q.QueryString).ToArray();
            var allQueriesCompiled = allQueriesString.CompileMany(analysisResult.CodeBase);

            // Do the conversion and build an association dictionary, CQL to CQLinq queryString
            var dicoCQLToCQLinq = new Dictionary <string, string>();

            foreach (var queryCompiled in allQueriesCompiled)
            {
                if (queryCompiled.HasErrors)
                {
                    continue;
                }
                if (queryCompiled.KindOfCodeQuerySyntax != KindOfCodeQuerySyntax.CQL)
                {
                    continue;
                }
                if (dicoCQLToCQLinq.ContainsKey(queryCompiled.OriginalQueryString))
                {
                    continue;
                }

                var queryCompiledSuccess = queryCompiled.QueryCompiledSuccess;
                Debug.Assert(queryCompiledSuccess != null);
                var cqlinqQueryString = queryCompiledSuccess.ConvertToCQLinq(); // <-- The conversion is performed here!
                dicoCQLToCQLinq.Add(queryCompiledSuccess.OriginalQueryString, cqlinqQueryString);
            }

            // Update CQL queries converted to CQLinq
            int nbQueriesConverted = 0;

            foreach (var pair in dicoCQLToCQLinq)
            {
                var queryCQL    = pair.Key;
                var queryCQLinq = pair.Value;
                foreach (var query in queriesController.RootParent.AllQueriesRecursive.ToList())
                {
                    Debug.Assert(query.RootParent == queriesController.RootParent);
                    if (query.QueryString != queryCQL)
                    {
                        continue;
                    }
                    var newQuery = queriesController.CreateQuery(
                        query.IsActive,
                        queryCQLinq,
                        query.DisplayStatInReport,
                        query.DisplayListInReport,
                        query.DisplaySelectionViewInReport,
                        query.IsCriticalRule);
                    nbQueriesConverted++;
                    queriesController.DoUpdateQueryObject(query, newQuery);
                    break;
                }
            }

            var groupToSave = queriesController.RootParent.ChildGroups.Single();

            // This call provokes saving queries in project file
            project.CodeQueries.CodeQueriesSet = groupToSave;

            Console.WriteLine(nbQueriesConverted + " queries converted!");
        }