private ValueTask <ImmutableArray <DiagnosticData> > DeserializeDiagnosticsAsync( IPersistentStorageService persistentService, DiagnosticDataSerializer serializer, Project project, TextDocument?document, object key, string stateKey, CancellationToken cancellationToken ) { Contract.ThrowIfFalse(document == null || document.Project == project); if ( InMemoryStorage.TryGetValue(_owner.Analyzer, (key, stateKey), out var entry) && serializer.Version == entry.Version ) { return(ValueTaskFactory.FromResult(entry.Diagnostics)); } return(serializer.DeserializeAsync( persistentService, project, document, stateKey, cancellationToken )); }
protected override async Task <Solution> GetChangedSolutionAsync(CancellationToken cancellationToken) { var updatedPublicSurfaceAreaText = new List <KeyValuePair <DocumentId, SourceText> >(); foreach (KeyValuePair <Project, ImmutableArray <Diagnostic> > pair in _diagnosticsToFix) { Project project = pair.Key; TextDocument?shippedDocument = DeclarePublicApiFix.GetShippedDocument(project); SourceText? shippedSourceText = shippedDocument is null ? null : await shippedDocument.GetTextAsync(cancellationToken).ConfigureAwait(false); if (shippedSourceText is object) { SourceText newShippedSourceText = AddNullableEnable(shippedSourceText); updatedPublicSurfaceAreaText.Add(new KeyValuePair <DocumentId, SourceText>(shippedDocument !.Id, newShippedSourceText)); } } Solution newSolution = _solution; foreach (KeyValuePair <DocumentId, SourceText> pair in updatedPublicSurfaceAreaText) { newSolution = newSolution.WithAdditionalDocumentText(pair.Key, pair.Value); } return(newSolution); }
protected override async Task <Solution> GetChangedSolutionAsync(CancellationToken cancellationToken) { var updatedPublicSurfaceAreaText = new List <KeyValuePair <DocumentId, SourceText> >(); using var uniqueShippedDocuments = PooledHashSet <string> .GetInstance(); foreach (var project in _projectsToFix) { TextDocument?shippedDocument = project.GetShippedDocument(); if (shippedDocument == null || shippedDocument.FilePath != null && !uniqueShippedDocuments.Add(shippedDocument.FilePath)) { // Skip past duplicate shipped documents. // Multi-tfm projects can likely share the same api files, and we want to avoid duplicate code fix application. continue; } var shippedSourceText = await shippedDocument.GetTextAsync(cancellationToken).ConfigureAwait(false); SourceText newShippedSourceText = AddNullableEnable(shippedSourceText); updatedPublicSurfaceAreaText.Add(new KeyValuePair <DocumentId, SourceText>(shippedDocument !.Id, newShippedSourceText)); } Solution newSolution = _solution; foreach (KeyValuePair <DocumentId, SourceText> pair in updatedPublicSurfaceAreaText) { newSolution = newSolution.WithAdditionalDocumentText(pair.Key, pair.Value); } return(newSolution); }
public sealed override Task RegisterCodeFixesAsync(CodeFixContext context) { Project project = context.Document.Project; foreach (Diagnostic diagnostic in context.Diagnostics) { string minimalSymbolName = diagnostic.Properties[DeclarePublicApiAnalyzer.MinimalNamePropertyBagKey]; string publicSymbolName = diagnostic.Properties[DeclarePublicApiAnalyzer.PublicApiNamePropertyBagKey]; string publicSymbolNameWithNullability = diagnostic.Properties[DeclarePublicApiAnalyzer.PublicApiNameWithNullabilityPropertyBagKey]; string fileName = diagnostic.Properties[DeclarePublicApiAnalyzer.FileName]; TextDocument?document = project.GetPublicApiDocument(fileName); if (document != null) { context.RegisterCodeFix( new DeclarePublicApiFix.AdditionalDocumentChangeAction( $"Annotate {minimalSymbolName} in public API", document.Id, c => GetFix(document, publicSymbolName, publicSymbolNameWithNullability, c)), diagnostic); } } return(Task.CompletedTask);
// Local functions. static Project AddAdditionalDocument(Project project, string name, SourceText text) { TextDocument?additionalDocument = project.AdditionalDocuments.FirstOrDefault(doc => string.Equals(doc.Name, name, StringComparison.OrdinalIgnoreCase)); if (additionalDocument == null) { project = project.AddAdditionalDocument(name, text).Project; } return(project); }
public DiagnosticComputer( TextDocument?document, Project project, TextSpan?span, AnalysisKind?analysisKind, DiagnosticAnalyzerInfoCache analyzerInfoCache) { _document = document; _project = project; _span = span; _analysisKind = analysisKind; _analyzerInfoCache = analyzerInfoCache; // We only track performance from primary branch. All forked branch we don't care such as preview. _performanceTracker = project.IsFromPrimaryBranch() ? project.Solution.Workspace.Services.GetService <IPerformanceTrackerService>() : null; }
private static async Task <Solution> GetFixAsync(TextDocument?publicSurfaceAreaDocument, Project project, string newSymbolName, ImmutableHashSet <string> siblingSymbolNamesToRemove, CancellationToken cancellationToken) { if (publicSurfaceAreaDocument == null) { var newSourceText = AddSymbolNamesToSourceText(sourceText: null, new[] { newSymbolName }); return(AddPublicApiFiles(project, newSourceText)); } else { var sourceText = await publicSurfaceAreaDocument.GetTextAsync(cancellationToken).ConfigureAwait(false); var newSourceText = AddSymbolNamesToSourceText(sourceText, new[] { newSymbolName }); newSourceText = RemoveSymbolNamesFromSourceText(newSourceText, siblingSymbolNamesToRemove); return(publicSurfaceAreaDocument.Project.Solution.WithAdditionalDocumentText(publicSurfaceAreaDocument.Id, newSourceText)); } }
public async ValueTask <ImmutableArray <DiagnosticData> > DeserializeAsync( IPersistentStorageService persistentService, Project project, TextDocument?textDocument, string key, CancellationToken cancellationToken ) { Contract.ThrowIfFalse(textDocument == null || textDocument.Project == project); var storage = await persistentService .GetStorageAsync(project.Solution, cancellationToken) .ConfigureAwait(false); await using var _ = storage.ConfigureAwait(false); var readTask = (textDocument != null) ? textDocument is Document document ? storage.ReadStreamAsync(document, key, cancellationToken) : storage.ReadStreamAsync( GetSerializationKeyForNonSourceDocument(textDocument, key), cancellationToken ) : storage.ReadStreamAsync(project, key, cancellationToken); using var stream = await readTask.ConfigureAwait(false); using var reader = ObjectReader.TryGetReader( stream, cancellationToken: cancellationToken ); if ( reader == null || !TryReadDiagnosticData( reader, project, textDocument, cancellationToken, out var data ) ) { return(default);
void textArea_DocumentChanged(object?sender, EventArgs e) { if (textArea == null) { return; } if (currentDocument != null) { currentDocument.TextChanged -= textArea_Document_TextChanged; } currentDocument = textArea.Document; if (currentDocument != null) { currentDocument.TextChanged += textArea_Document_TextChanged; DoSearch(false); } }
private void AddDocumentDiagnostic( ref Dictionary <DocumentId, List <DiagnosticData> >?map, TextDocument?document, Diagnostic diagnostic ) { if (document is null || !document.SupportsDiagnostics()) { return; } map ??= new Dictionary <DocumentId, List <DiagnosticData> >(); map.GetOrAdd(document.Id, _ => new List <DiagnosticData>()) .Add(DiagnosticData.Create(diagnostic, document)); _lazyDocumentsWithDiagnostics ??= new HashSet <DocumentId>(); _lazyDocumentsWithDiagnostics.Add(document.Id); }
protected override async Task <Solution> GetChangedSolutionAsync(CancellationToken cancellationToken) { var updatedUnshippedText = new List <(DocumentId, SourceText)>(); foreach (KeyValuePair <Project, ImmutableArray <Diagnostic> > pair in _diagnosticsToFix) { Project project = pair.Key; ImmutableArray <Diagnostic> diagnostics = pair.Value; TextDocument?unshippedDocument = project.AdditionalDocuments.FirstOrDefault(a => a.Name == ReleaseTrackingHelper.UnshippedFileName); if (unshippedDocument == null || diagnostics.IsEmpty) { continue; } if (EquivalenceKey == CodeAnalysisDiagnosticsResources.AddEntryForDiagnosticIdInAnalyzerReleaseCodeFixTitle) { var newText = await AddEntriesToUnshippedFileForDiagnosticsAsync(unshippedDocument, diagnostics, cancellationToken).ConfigureAwait(false); updatedUnshippedText.Add((unshippedDocument.Id, newText)); } else if (EquivalenceKey == CodeAnalysisDiagnosticsResources.UpdateEntryForDiagnosticIdInAnalyzerReleaseCodeFixTitle) { var newText = await UpdateEntriesInUnshippedFileForDiagnosticsAsync(unshippedDocument, diagnostics, cancellationToken).ConfigureAwait(false); updatedUnshippedText.Add((unshippedDocument.Id, newText)); } else { throw new NotImplementedException(); } } Solution newSolution = _solution; foreach (var(unshippedDocumentId, newText) in updatedUnshippedText) { newSolution = newSolution.WithAdditionalDocumentText(unshippedDocumentId, newText); } return(newSolution); }
void AttachInternal(TextArea textArea) { this.textArea = textArea; adorner = new SearchPanelAdorner(textArea, this); DataContext = this; //renderer currentDocument = textArea.Document; if (currentDocument != null) { currentDocument.TextChanged += textArea_Document_TextChanged; } textArea.DocumentChanged += textArea_DocumentChanged; KeyDown += SearchLayerKeyDown; this.CommandBindings.Add(new CommandBinding(SearchCommands.FindNext, (sender, e) => FindNext())); this.CommandBindings.Add(new CommandBinding(SearchCommands.FindPrevious, (sender, e) => FindPrevious())); this.CommandBindings.Add(new CommandBinding(SearchCommands.CloseSearchPanel, (sender, e) => Close())); IsClosed = true; }
public sealed override Task RegisterCodeFixesAsync(CodeFixContext context) { Project project = context.Document.Project; foreach (Diagnostic diagnostic in context.Diagnostics) { TextDocument?document = DeclarePublicApiFix.GetShippedDocument(project); if (document != null) { context.RegisterCodeFix( new DeclarePublicApiFix.AdditionalDocumentChangeAction( $"Add '#nullable enable' to public API", c => GetFix(document, c)), diagnostic); } } return(Task.CompletedTask); }
private async Task SerializeAsync( IPersistentStorageService?persistentService, DiagnosticDataSerializer serializer, Project project, TextDocument?document, object key, string stateKey, ImmutableArray <DiagnosticData> diagnostics ) { Contract.ThrowIfFalse(document == null || document.Project == project); // try to serialize it if ( persistentService != null && await serializer .SerializeAsync( persistentService, project, document, stateKey, diagnostics, CancellationToken.None ) .ConfigureAwait(false) ) { // we succeeded saving it to persistent storage. remove it from in memory cache if it exists RemoveInMemoryCacheEntry(key, stateKey); return; } // if serialization fail, hold it in the memory InMemoryStorage.Cache( _owner.Analyzer, (key, stateKey), new CacheEntry(serializer.Version, diagnostics) ); }
public async Task <bool> SerializeAsync( IPersistentStorageService persistentService, Project project, TextDocument?textDocument, string key, ImmutableArray <DiagnosticData> items, CancellationToken cancellationToken ) { Contract.ThrowIfFalse(textDocument == null || textDocument.Project == project); using var stream = SerializableBytes.CreateWritableStream(); using (var writer = new ObjectWriter(stream, leaveOpen: true, cancellationToken)) { WriteDiagnosticData(writer, items, cancellationToken); } var storage = await persistentService .GetStorageAsync(project.Solution, cancellationToken) .ConfigureAwait(false); await using var _ = storage.ConfigureAwait(false); stream.Position = 0; var writeTask = (textDocument != null) ? textDocument is Document document ? storage.WriteStreamAsync(document, key, stream, cancellationToken) : storage.WriteStreamAsync( GetSerializationKeyForNonSourceDocument(textDocument, key), stream, cancellationToken ) : storage.WriteStreamAsync(project, key, stream, cancellationToken); return(await writeTask.ConfigureAwait(false)); }
public sealed override Task RegisterCodeFixesAsync(CodeFixContext context) { Project project = context.Document.Project; foreach (Diagnostic diagnostic in context.Diagnostics) { string minimalSymbolName = diagnostic.Properties[DeclarePublicApiAnalyzer.MinimalNamePropertyBagKey]; string publicSymbolName = diagnostic.Properties[DeclarePublicApiAnalyzer.PublicApiNamePropertyBagKey]; string publicSymbolNameWithNullability = diagnostic.Properties[DeclarePublicApiAnalyzer.PublicApiNameWithNullabilityPropertyBagKey]; bool isShippedDocument = diagnostic.Properties[DeclarePublicApiAnalyzer.PublicApiIsShippedPropertyBagKey] == "true"; TextDocument?document = isShippedDocument ? PublicApiFixHelpers.GetShippedDocument(project) : PublicApiFixHelpers.GetUnshippedDocument(project); if (document != null) { context.RegisterCodeFix( new DeclarePublicApiFix.AdditionalDocumentChangeAction( $"Annotate {minimalSymbolName} in public API", c => GetFix(document, publicSymbolName, publicSymbolNameWithNullability, c)), diagnostic); } } return(Task.CompletedTask);
public static bool SupportsDiagnostics([NotNullWhen(returnValue: true)] this TextDocument?document) => document?.State.SupportsDiagnostics() ?? false;
public static bool CanApplyChange([NotNullWhen(returnValue: true)] this TextDocument?document) => document?.State.CanApplyChange() ?? false;
private ValueTask AddToInMemoryStorageAsync(VersionStamp serializerVersion, Project project, TextDocument?document, object key, string stateKey, ImmutableArray <DiagnosticData> diagnostics) { Contract.ThrowIfFalse(document == null || document.Project == project); // if serialization fail, hold it in the memory InMemoryStorage.Cache(_owner.Analyzer, (key, stateKey), new CacheEntry(serializerVersion, diagnostics)); return(default);