private static async Task <IEnumerable <AnalysisResult> > AnalyzeSingleSyntaxTreesAsync(VisualStudioWorkspace visualStudioWorkspace, IProgress <int> progress) { var analysisResults = new ConcurrentBag <AnalysisResult>(); SyntaxTree syntaxTree = null; SingleSyntaxTreeAnalysisContext analysisContext = null; var analyseSyntaxTreeActions = AnalyzeSingleSyntaxTreeAndCollectResultsActions // We intentionally access the modified closure here (syntaxTree, analysisContext), // because we want to avoid creation of a huge number of temporary Action objects. // ReSharper disable AccessToModifiedClosure .Select(action => new Action(() => action(syntaxTree, analysisContext, analysisResults))) // ReSharper restore AccessToModifiedClosure .ToArray(); // WARNING: Keep the progress counter in sync with the logic behind the calculation of the maximum progress! int progressCounter = 0; foreach (var project in visualStudioWorkspace.CurrentSolution.Projects.Where(ProjectSatisfiesProjectFilter)) { foreach (var document in project.Documents.Where(DocumentSatisfiesDocumentFilter)) { analysisContext = new SingleSyntaxTreeAnalysisContext(document); syntaxTree = await document.GetSyntaxTreeAsync().ConfigureAwait(false); // Each of the actions will operate on the same (current) syntaxTree. Parallel.Invoke(analyseSyntaxTreeActions); progress.Report(++progressCounter); } } return(analysisResults); }
internal AnalysisResult(ISharpenSuggestion suggestion, SingleSyntaxTreeAnalysisContext analysisContext, string filePath, SyntaxToken startingToken, SyntaxNode displayTextNode) { this.displayTextNode = displayTextNode; Suggestion = suggestion; AnalysisContext = analysisContext; FilePath = filePath; Position = startingToken.GetLocation().GetLineSpan(); }
internal AnalysisResult(ISharpenSuggestion suggestion, SingleSyntaxTreeAnalysisContext analysisContext, string filePath, SyntaxToken startingToken, SyntaxNode displayTextNode) : this(suggestion, analysisContext, filePath, startingToken, displayTextNode, Engine.DisplayText.For) { }