diff --git a/src/EditorFeatures/Core/Implementation/Formatting/InferredIndentationDocumentOptionsProviderFactory.cs b/src/EditorFeatures/Core/Implementation/Formatting/InferredIndentationDocumentOptionsProviderFactory.cs index 6749ba5c6883ba0c7ddd7069f20b6e15e11c40d0..622747ef4f97496f82412e0780fe183ccccba00a 100644 --- a/src/EditorFeatures/Core/Implementation/Formatting/InferredIndentationDocumentOptionsProviderFactory.cs +++ b/src/EditorFeatures/Core/Implementation/Formatting/InferredIndentationDocumentOptionsProviderFactory.cs @@ -5,6 +5,7 @@ using System.ComponentModel.Composition; using System.Threading; using System.Threading.Tasks; +using Microsoft.CodeAnalysis.ErrorReporting; using Microsoft.CodeAnalysis.Formatting; using Microsoft.CodeAnalysis.Options; using Microsoft.CodeAnalysis.Text; @@ -71,8 +72,16 @@ public bool TryGetDocumentOption(OptionKey option, out object? value) var currentDocument = _workspace.CurrentSolution.GetDocument(_documentId); if (currentDocument != null && currentDocument.TryGetText(out var text)) { - var snapshot = text.FindCorrespondingEditorTextSnapshot(); - return TryGetOptionForBuffer(snapshot.TextBuffer, option, out value); + var textBuffer = text.Container.TryGetTextBuffer(); + + if (textBuffer != null) + { + return TryGetOptionForBuffer(textBuffer, option, out value); + } + else + { + FatalError.ReportWithoutCrash(new System.Exception("We had an open document but it wasn't associated with a buffer. That meant we coudln't apply formatting settings.")); + } } } diff --git a/src/EditorFeatures/Text/Extensions.SnapshotSourceText.cs b/src/EditorFeatures/Text/Extensions.SnapshotSourceText.cs index ca0b22a34643fad391d40c9756425ea41be190fa..9022a3134441e6d5b785b8b4fbfbfb9220a7540f 100644 --- a/src/EditorFeatures/Text/Extensions.SnapshotSourceText.cs +++ b/src/EditorFeatures/Text/Extensions.SnapshotSourceText.cs @@ -5,7 +5,6 @@ using System; using System.Collections.Generic; using System.Collections.Immutable; -using System.Diagnostics; using System.IO; using System.Linq; using System.Runtime.CompilerServices; @@ -357,7 +356,7 @@ public override IReadOnlyList GetChangeRanges(SourceText oldTex return GetChangeRanges(oldSnapshot, oldText.Length, newSnapshot); } - private IReadOnlyList GetChangeRanges(ITextImage oldImage, int oldTextLength, ITextImage newImage) + private IReadOnlyList GetChangeRanges(ITextImage? oldImage, int oldTextLength, ITextImage? newImage) { if (oldImage == null || newImage == null || diff --git a/src/EditorFeatures/Text/Extensions.cs b/src/EditorFeatures/Text/Extensions.cs index d6a31ed357078fc43c7efbcbfbc568a1dadd7bd1..8381321c21faac9d219e955e2baf931045554923 100644 --- a/src/EditorFeatures/Text/Extensions.cs +++ b/src/EditorFeatures/Text/Extensions.cs @@ -1,10 +1,11 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +#nullable enable + using System; using System.Collections.Generic; using System.Text; using System.Threading; -using System.Threading.Tasks; using Microsoft.VisualStudio.Text; namespace Microsoft.CodeAnalysis.Text @@ -17,20 +18,20 @@ public static SourceTextContainer AsTextContainer(this ITextBuffer buffer) public static ITextBuffer GetTextBuffer(this SourceTextContainer textContainer) => TryGetTextBuffer(textContainer) ?? throw new ArgumentException(TextEditorResources.textContainer_is_not_a_SourceTextContainer_that_was_created_from_an_ITextBuffer, nameof(textContainer)); - public static ITextBuffer TryGetTextBuffer(this SourceTextContainer textContainer) + public static ITextBuffer? TryGetTextBuffer(this SourceTextContainer? textContainer) => (textContainer as TextBufferContainer)?.TryFindEditorTextBuffer(); /// - /// Returns the ITextSnapshot behind this SourceText, or null if it wasn't created from one. + /// Returns the behind this , or null if it wasn't created from one. /// - /// Note that multiple ITextSnapshots may map to the same SourceText instance if - /// ITextSnapshot.Version.ReiteratedVersionNumber doesn't change. + /// Note that multiple s may map to the same instance if it's + /// doesn't change. /// /// The underlying ITextSnapshot. - public static ITextSnapshot FindCorrespondingEditorTextSnapshot(this SourceText text) + public static ITextSnapshot? FindCorrespondingEditorTextSnapshot(this SourceText? text) => (text as SnapshotSourceText)?.TryFindEditorSnapshot(); - internal static ITextImage TryFindCorrespondingEditorTextImage(this SourceText text) + internal static ITextImage? TryFindCorrespondingEditorTextImage(this SourceText? text) => (text as SnapshotSourceText)?.TextImage; internal static TextLine AsTextLine(this ITextSnapshotLine line) @@ -48,7 +49,7 @@ internal static SourceText AsRoslynText(this ITextSnapshot textSnapshot, ITextBu /// /// Gets the workspace corresponding to the text buffer. /// - public static Workspace GetWorkspace(this ITextBuffer buffer) + public static Workspace? GetWorkspace(this ITextBuffer buffer) { var container = buffer.AsTextContainer(); if (Workspace.TryGetWorkspace(container, out var workspace)) @@ -73,7 +74,7 @@ public static IEnumerable GetRelatedDocumentsWithChanges(this ITextSna /// associated with the buffer if it is linked into multiple projects or is part of a Shared Project. In this case, the /// is responsible for keeping track of which of these s is in the current project context. /// - public static Document GetOpenDocumentInCurrentContextWithChanges(this ITextSnapshot text) + public static Document? GetOpenDocumentInCurrentContextWithChanges(this ITextSnapshot text) => text.AsText().GetOpenDocumentInCurrentContextWithChanges(); /// @@ -90,7 +91,7 @@ public static IEnumerable GetRelatedDocuments(this ITextBuffer buffer) /// with the specified text's container, or the text's container isn't associated with a workspace, /// then the method returns false. /// - internal static Document GetDocumentWithFrozenPartialSemantics(this SourceText text, CancellationToken cancellationToken) + internal static Document? GetDocumentWithFrozenPartialSemantics(this SourceText text, CancellationToken cancellationToken) { var document = text.GetOpenDocumentInCurrentContextWithChanges(); return document?.WithFrozenPartialSemantics(cancellationToken); diff --git a/src/Workspaces/Core/Portable/Workspace/TextExtensions.cs b/src/Workspaces/Core/Portable/Workspace/TextExtensions.cs index f037409cfa92d995fde8501d76cd2164a6275b16..aad6575ef3a62c74a4554597d08360a55946f044 100644 --- a/src/Workspaces/Core/Portable/Workspace/TextExtensions.cs +++ b/src/Workspaces/Core/Portable/Workspace/TextExtensions.cs @@ -1,5 +1,7 @@ // Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. +#nullable enable + using System.Collections.Generic; using System.Linq; using Roslyn.Utilities; @@ -19,7 +21,7 @@ public static IEnumerable GetRelatedDocumentsWithChanges(this SourceTe { var ids = workspace.GetRelatedDocumentIds(text.Container); var sol = workspace.CurrentSolution.WithDocumentText(ids, text, PreservationMode.PreserveIdentity); - return ids.Select(id => sol.GetDocument(id)).Where(d => d != null); + return ids.Select(id => sol.GetDocument(id)).WhereNotNull(); } return SpecializedCollections.EmptyEnumerable(); @@ -29,7 +31,7 @@ public static IEnumerable GetRelatedDocumentsWithChanges(this SourceTe /// Gets the document from the corresponding workspace's current solution that is associated with the source text's container /// in its current project context, updated to contain the same text as the source if necessary. /// - public static Document GetOpenDocumentInCurrentContextWithChanges(this SourceText text) + public static Document? GetOpenDocumentInCurrentContextWithChanges(this SourceText text) { if (Workspace.TryGetWorkspace(text.Container, out var workspace)) { @@ -59,7 +61,7 @@ public static IEnumerable GetRelatedDocuments(this SourceTextContainer { var sol = workspace.CurrentSolution; var ids = workspace.GetRelatedDocumentIds(container); - return ids.Select(id => sol.GetDocument(id)).Where(d => d != null); + return ids.Select(id => sol.GetDocument(id)).WhereNotNull(); } return SpecializedCollections.EmptyEnumerable(); @@ -69,7 +71,7 @@ public static IEnumerable GetRelatedDocuments(this SourceTextContainer /// Gets the document from the corresponding workspace's current solution that is associated with the text container /// in its current project context. /// - public static Document GetOpenDocumentInCurrentContext(this SourceTextContainer container) + public static Document? GetOpenDocumentInCurrentContext(this SourceTextContainer container) { if (Workspace.TryGetWorkspace(container, out var workspace)) {