/// <summary> /// Initializes a new instance of the <see cref="RazorSourceUpdater"/> class. /// </summary> /// <param name="analyzers">Analyzers to use when analyzing source code in the Razor documents.</param> /// <param name="codeFixProviders">Code fix providers to use when fixing diagnostics found in the Razor documents.</param> /// <param name="textMatcher">The text matching service to use for correlating old sections of text in Razor documents with updated texts.</param> /// <param name="textReplacer">The text replacing service to use for updating replaced texts in the Razor documents.</param> /// <param name="logger">An ILogger to log diagnostics.</param> public RazorSourceUpdater(IEnumerable <DiagnosticAnalyzer> analyzers, IEnumerable <CodeFixProvider> codeFixProviders, ITextMatcher textMatcher, ITextReplacer textReplacer, ILogger <RazorSourceUpdater> logger) { _analyzers = analyzers?.OrderBy(a => a.SupportedDiagnostics.First().Id) ?? throw new ArgumentNullException(nameof(analyzers)); _codeFixProviders = codeFixProviders?.OrderBy(c => c.FixableDiagnosticIds.First()) ?? throw new ArgumentNullException(nameof(codeFixProviders)); _textMatcher = textMatcher ?? throw new ArgumentNullException(nameof(textMatcher)); _textReplacer = textReplacer ?? throw new ArgumentNullException(nameof(textReplacer)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); }
/// <summary> /// Initializes a new instance of the <see cref="RazorSourceUpdater"/> class. /// </summary> /// <param name="analyzers">Analyzers to use when analyzing source code in the Razor documents.</param> /// <param name="codeFixProviders">Code fix providers to use when fixing diagnostics found in the Razor documents.</param> /// <param name="additionalTexts">Additional documents that should be included in analysis. This will typically be additional texts used to configure analyzer behavior.</param> /// <param name="textMatcher">The text matching service to use for correlating old sections of text in Razor documents with updated texts.</param> /// <param name="textReplacer">The text replacing service to use for updating replaced texts in the Razor documents.</param> /// <param name="logger">An ILogger to log diagnostics.</param> public RazorSourceUpdater(IEnumerable <DiagnosticAnalyzer> analyzers, IEnumerable <CodeFixProvider> codeFixProviders, IEnumerable <AdditionalText> additionalTexts, ITextMatcher textMatcher, IMappedTextReplacer textReplacer, ILogger <RazorSourceUpdater> logger) { if (additionalTexts is null) { throw new ArgumentNullException(nameof(additionalTexts)); } _analyzers = analyzers?.OrderBy(a => a.SupportedDiagnostics.First().Id) ?? throw new ArgumentNullException(nameof(analyzers)); _codeFixProviders = codeFixProviders?.OrderBy(c => c.FixableDiagnosticIds.First()) ?? throw new ArgumentNullException(nameof(codeFixProviders)); _additionalTexts = ImmutableArray.CreateRange(additionalTexts); _textMatcher = textMatcher ?? throw new ArgumentNullException(nameof(textMatcher)); _textReplacer = textReplacer ?? throw new ArgumentNullException(nameof(textReplacer)); _logger = logger ?? throw new ArgumentNullException(nameof(logger)); }
private static Task ProcessFiles(IEnumerable <IFileProvider> fileProviders, ITextMatcher matcher, ResultInfo results, bool ignoreBinary, CancellationToken cancellationToken) { var tasks = new ConcurrentBag <Task>(); foreach (var fileProvider in fileProviders) { var files = fileProvider.EnumerateFiles(); var parallelOptions = new ParallelOptions { CancellationToken = cancellationToken }; Parallel.ForEach(files, parallelOptions, (fileInfo) => { parallelOptions.CancellationToken.ThrowIfCancellationRequested(); Interlocked.Increment(ref results.TotalFiles); if (fileInfo.Length == 0) { return; } MemoryMappedFileContentProvider content; try { content = new MemoryMappedFileContentProvider(fileInfo.Path, fileInfo.Length); } catch (Exception ex) when(ex is IOException || ex is UnauthorizedAccessException) { results.Results.Add((Path.GetRelativePath(fileProvider.SearchPath, fileInfo.Path), null, ex.Message)); return; } if (ignoreBinary && content.IsBinary) { return; } var task = matcher.GetMatches(content).ContinueWith(matches => { content.Dispose(); if (matches.Result.Count > 0) { results.Results.Add((Path.GetRelativePath(fileProvider.SearchPath, fileInfo.Path), matches.Result, null)); } }); tasks.Add(task); });