Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
Expand Down Expand Up @@ -112,6 +113,12 @@ internal abstract partial class VisualStudioWorkspaceImpl : VisualStudioWorkspac
private readonly IAsynchronousOperationListener _workspaceListener;
private bool _isExternalErrorDiagnosticUpdateSourceSubscribedToSolutionBuildEvents;

/// <summary>
/// Only read/written on hte UI thread.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// Only read/written on hte UI thread.
/// Only read/written on the UI thread.

/// </summary>
private bool _isShowingDocumentChangeErrorInfoBar = false;
private bool _ignoreDocumentTextChangeErrors;

public VisualStudioWorkspaceImpl(ExportProvider exportProvider, IAsyncServiceProvider asyncServiceProvider)
: base(VisualStudioMefHostServices.Create(exportProvider))
{
Expand Down Expand Up @@ -1192,29 +1199,81 @@ protected override void ApplyAnalyzerConfigDocumentTextChanged(DocumentId docume

private void ApplyTextDocumentChange(DocumentId documentId, SourceText newText)
{
var containedDocument = ContainedDocument.TryGetContainedDocument(documentId);
this._threadingContext.ThrowIfNotOnUIThread();

if (containedDocument != null)
{
containedDocument.UpdateText(newText);
}
else
CodeAnalysis.TextDocument? document = null;

try
{
if (IsDocumentOpen(documentId))
{
var textBuffer = this.CurrentSolution.GetTextDocument(documentId)!.GetTextSynchronously(CancellationToken.None).Container.TryGetTextBuffer();
document = this.CurrentSolution.GetRequiredTextDocument(documentId);

if (textBuffer != null)
var containedDocument = ContainedDocument.TryGetContainedDocument(documentId);
if (containedDocument != null)
{
containedDocument.UpdateText(newText);
}
else
{
if (IsDocumentOpen(documentId))
{
TextEditApplication.UpdateText(newText, textBuffer, EditOptions.DefaultMinimalChange);
return;
var textBuffer = document.GetTextSynchronously(CancellationToken.None).Container.TryGetTextBuffer();
if (textBuffer != null)
{
TextEditApplication.UpdateText(newText, textBuffer, EditOptions.DefaultMinimalChange);
return;
}
}
}

// The document wasn't open in a normal way, so invisible editor time
using var invisibleEditor = OpenInvisibleEditor(documentId);
TextEditApplication.UpdateText(newText, invisibleEditor.TextBuffer, EditOptions.None);
// The document wasn't open in a normal way, so invisible editor time
using var invisibleEditor = OpenInvisibleEditor(documentId);
TextEditApplication.UpdateText(newText, invisibleEditor.TextBuffer, EditOptions.None);
}
}
catch (Exception ex) when (FatalError.ReportAndCatch(ex))
{
ReportErrorChangingDocumentText(ex);
return;
}

void ReportErrorChangingDocumentText(Exception exception)
{
// Don't spam the info bar. If the user already has a message up, leave it at that. Also,
// if they've asked to not be notified about future doc change issue, respect that flag.
if (_ignoreDocumentTextChangeErrors || _isShowingDocumentChangeErrorInfoBar)
return;

var documentName = document?.Name ?? documentId.ToString();

var errorReportingService = this.Services.GetRequiredService<IErrorReportingService>();
errorReportingService.ShowGlobalErrorInfo(
message: string.Format(ServicesVSResources.Error_encountered_updating_0, documentName),
TelemetryFeatureName.Workspace,
exception,
// 'Show stack trace' will not dismiss the info bar.
new(WorkspacesResources.Show_Stack_Trace, InfoBarUI.UIKind.HyperLink,
() => errorReportingService.ShowDetailedErrorInfo(exception), closeAfterAction: false),
// 'Ignore' just closes the info bar, but allows future errors to show up.
new(ServicesVSResources.Ignore, InfoBarUI.UIKind.Button, GetDefaultDismissAction()),
// 'Ignore (including future errors) closes the info bar, but also sets the flag so the user gets no more messages
// in the current session.
new(ServicesVSResources.Ignore_including_future_errors, InfoBarUI.UIKind.Button, GetDefaultDismissAction(
() => _ignoreDocumentTextChangeErrors = true)),
// Close button is the same as 'ignore'. It closes the info bar, but allows future errors to show up.
new(string.Empty, InfoBarUI.UIKind.Close, GetDefaultDismissAction()));

// Mark that we're showing the info bar at this point.
_isShowingDocumentChangeErrorInfoBar = true;
}

Action GetDefaultDismissAction(Action? additionalAction = null)
=> () =>
{
additionalAction?.Invoke();

// All info bar actions (except for 'show stack trace') dismiss the info bar, putting us back in the
// "we're not showing the user anything" state.
_isShowingDocumentChangeErrorInfoBar = false;
Comment on lines +1273 to +1275
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Too bad there's not a generic way for us just to pass a handler for "any way this goes away".... :-/

};
}

protected override void ApplyDocumentInfoChanged(DocumentId documentId, DocumentInfo updatedInfo)
Expand Down
9 changes: 9 additions & 0 deletions src/VisualStudio/Core/Def/ServicesVSResources.resx
Original file line number Diff line number Diff line change
Expand Up @@ -1879,4 +1879,13 @@ Additional information: {1}</value>
<data name="Show_completion_list_after_a_character_is_typed" xml:space="preserve">
<value>Show completion list after a character is typed</value>
</data>
<data name="Error_encountered_updating_0" xml:space="preserve">
<value>Error encountered updating '{0}'</value>
</data>
<data name="Ignore" xml:space="preserve">
<value>Ignore</value>
</data>
<data name="Ignore_including_future_errors" xml:space="preserve">
<value>Ignore (including future errors)</value>
</data>
</root>
15 changes: 15 additions & 0 deletions src/VisualStudio/Core/Def/xlf/ServicesVSResources.cs.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions src/VisualStudio/Core/Def/xlf/ServicesVSResources.de.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions src/VisualStudio/Core/Def/xlf/ServicesVSResources.es.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions src/VisualStudio/Core/Def/xlf/ServicesVSResources.fr.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions src/VisualStudio/Core/Def/xlf/ServicesVSResources.it.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions src/VisualStudio/Core/Def/xlf/ServicesVSResources.ja.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions src/VisualStudio/Core/Def/xlf/ServicesVSResources.ko.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions src/VisualStudio/Core/Def/xlf/ServicesVSResources.pl.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions src/VisualStudio/Core/Def/xlf/ServicesVSResources.pt-BR.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading