From 7dc83441cf303c3835876e628a4a504d90f582a0 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Wed, 23 Aug 2017 10:04:10 +0200 Subject: [PATCH 1/2] Handle inline comments in projection buffers. Previously we were crashing trying to show inline comments when a projection buffer was opened in a diff. Don't crash, and actually show inline comments. Fixes #1186 --- .../InlineCommentMarginProvider.cs | 13 +++++++++++ .../Services/PullRequestSessionManager.cs | 8 ++++--- .../Tags/InlineCommentTagger.cs | 23 ++++++++++++++++++- .../UI/Views/PullRequestDetailView.xaml.cs | 11 +++++++++ 4 files changed, 51 insertions(+), 4 deletions(-) diff --git a/src/GitHub.InlineReviews/InlineCommentMarginProvider.cs b/src/GitHub.InlineReviews/InlineCommentMarginProvider.cs index af4c1696f5..3dc3d7eabe 100644 --- a/src/GitHub.InlineReviews/InlineCommentMarginProvider.cs +++ b/src/GitHub.InlineReviews/InlineCommentMarginProvider.cs @@ -13,6 +13,7 @@ using GitHub.InlineReviews.Views; using GitHub.Services; using GitHub.Settings; +using Microsoft.VisualStudio.Text.Projection; namespace GitHub.InlineReviews { @@ -108,6 +109,18 @@ bool IsMarginVisible(ITextBuffer buffer) } } + var projection = buffer as IProjectionBuffer; + if (projection != null) + { + foreach (var source in projection.SourceBuffers) + { + if (IsMarginVisible(source)) + { + return true; + } + } + } + return false; } } diff --git a/src/GitHub.InlineReviews/Services/PullRequestSessionManager.cs b/src/GitHub.InlineReviews/Services/PullRequestSessionManager.cs index bd68ab9d14..dfeaf5c1be 100644 --- a/src/GitHub.InlineReviews/Services/PullRequestSessionManager.cs +++ b/src/GitHub.InlineReviews/Services/PullRequestSessionManager.cs @@ -84,12 +84,14 @@ public async Task GetSession(IPullRequestModel pullRequest) public PullRequestTextBufferInfo GetTextBufferInfo(ITextBuffer buffer) { var projectionBuffer = buffer as IProjectionBuffer; + PullRequestTextBufferInfo result; - if (projectionBuffer == null) + if (buffer.Properties.TryGetProperty(typeof(PullRequestTextBufferInfo), out result)) { - return buffer.Properties.GetProperty(typeof(PullRequestTextBufferInfo), null); + return result; } - else + + if (projectionBuffer != null) { foreach (var sourceBuffer in projectionBuffer.SourceBuffers) { diff --git a/src/GitHub.InlineReviews/Tags/InlineCommentTagger.cs b/src/GitHub.InlineReviews/Tags/InlineCommentTagger.cs index df0a4e9560..a67cac3914 100644 --- a/src/GitHub.InlineReviews/Tags/InlineCommentTagger.cs +++ b/src/GitHub.InlineReviews/Tags/InlineCommentTagger.cs @@ -160,7 +160,7 @@ Task IEditorContentSource.GetContent() void Initialize() { - document = buffer.Properties.GetProperty(typeof(ITextDocument)); + document = TryGetDocument(buffer); if (document == null) return; @@ -195,6 +195,27 @@ void Initialize() initialized = true; } + static ITextDocument TryGetDocument(ITextBuffer buffer) + { + ITextDocument result; + + if (buffer.Properties.TryGetProperty(typeof(ITextDocument), out result)) + return result; + + var projection = buffer as IProjectionBuffer; + + if (projection != null) + { + foreach (var source in projection.SourceBuffers) + { + if ((result = TryGetDocument(source)) != null) + return result; + } + } + + return null; + } + static void ForgetWithLogging(Task task) { task.Catch(e => VsOutputLogger.WriteLine("Exception caught while executing background task: {0}", e)).Forget(); diff --git a/src/GitHub.VisualStudio/UI/Views/PullRequestDetailView.xaml.cs b/src/GitHub.VisualStudio/UI/Views/PullRequestDetailView.xaml.cs index 6ce693cfc8..94688f3cd5 100644 --- a/src/GitHub.VisualStudio/UI/Views/PullRequestDetailView.xaml.cs +++ b/src/GitHub.VisualStudio/UI/Views/PullRequestDetailView.xaml.cs @@ -26,6 +26,7 @@ using Task = System.Threading.Tasks.Task; using Microsoft.VisualStudio.TextManager.Interop; using System.Text; +using Microsoft.VisualStudio.Text.Projection; namespace GitHub.VisualStudio.UI.Views { @@ -168,6 +169,16 @@ void AddBufferTag(ITextBuffer buffer, IPullRequestSession session, string path, buffer.Properties.GetOrCreateSingletonProperty( typeof(PullRequestTextBufferInfo), () => new PullRequestTextBufferInfo(session, path, isLeftBuffer)); + + var projection = buffer as IProjectionBuffer; + + if (projection != null) + { + foreach (var source in projection.SourceBuffers) + { + AddBufferTag(source, session, path, isLeftBuffer); + } + } } void ShowErrorInStatusBar(string message, Exception e) From fe4271ce9e36f744663430b1cf8f6cf4f70bd0ee Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Wed, 23 Aug 2017 11:48:46 +0200 Subject: [PATCH 2/2] Don't use projection buffer as content source. `.cshtml` files have a projection buffer which is the contents of the generated C#. Don't use this as a content source for diff matching as it's completely different to the file in git. --- src/GitHub.InlineReviews/Tags/InlineCommentTagger.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/GitHub.InlineReviews/Tags/InlineCommentTagger.cs b/src/GitHub.InlineReviews/Tags/InlineCommentTagger.cs index a67cac3914..b4fbbb4c20 100644 --- a/src/GitHub.InlineReviews/Tags/InlineCommentTagger.cs +++ b/src/GitHub.InlineReviews/Tags/InlineCommentTagger.cs @@ -265,7 +265,8 @@ async Task SessionChanged(IPullRequestSession session) if (snapshot == null) return; var repository = gitService.GetRepository(session.LocalRepository.LocalPath); - file = await session.GetFile(relativePath, !leftHandSide ? this : null); + var isContentSource = !leftHandSide && !(buffer is IProjectionBuffer); + file = await session.GetFile(relativePath, isContentSource ? this : null); if (file == null) return;