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); }
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."); }
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!"); }