Skip to content

Commit

Permalink
Don't allow virtual documents to go back in time
Browse files Browse the repository at this point in the history
  • Loading branch information
davidwengier committed Aug 16, 2024
1 parent fb35f2a commit 92743cc
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -72,14 +72,22 @@ public void PublishCSharp(ProjectKey projectKey, string filePath, SourceText sou
previouslyPublishedData = PublishData.Default;
}

if (previouslyPublishedData.HostDocumentVersion > hostDocumentVersion)
{
// We've already published a newer version of this document. No-op.
Debug.Fail("C# document being published that is older than one we've previously published!");
_logger.LogWarning($"Skipping publish of C# for {filePath} because we've already published version {previouslyPublishedData.HostDocumentVersion}, and this request is for {hostDocumentVersion}.");
return;
}

textChanges = SourceTextDiffer.GetMinimalTextChanges(previouslyPublishedData.SourceText, sourceText);
if (textChanges.Count == 0 && hostDocumentVersion == previouslyPublishedData.HostDocumentVersion)
{
// Source texts match along with host document versions. We've already published something that looks like this. No-op.
return;
}

_logger.LogTrace(
_logger.LogDebug(
$"Updating C# buffer of {filePath} for project {documentKey.ProjectKey} to correspond with host document " +
$"version {hostDocumentVersion}. {previouslyPublishedData.SourceText.Length} -> {sourceText.Length} = Change delta of " +
$"{sourceText.Length - previouslyPublishedData.SourceText.Length} via {textChanges.Count} text changes.");
Expand Down Expand Up @@ -111,14 +119,22 @@ public void PublishHtml(ProjectKey projectKey, string filePath, SourceText sourc
previouslyPublishedData = PublishData.Default;
}

if (previouslyPublishedData.HostDocumentVersion > hostDocumentVersion)
{
// We've already published a newer version of this document. No-op.
Debug.Fail("Html document being published that is older than one we've previously published!");
_logger.LogWarning($"Skipping publish of Html for {filePath} because we've already published version {previouslyPublishedData.HostDocumentVersion}, and this request is for {hostDocumentVersion}.");
return;
}

textChanges = SourceTextDiffer.GetMinimalTextChanges(previouslyPublishedData.SourceText, sourceText);
if (textChanges.Count == 0 && hostDocumentVersion == previouslyPublishedData.HostDocumentVersion)
{
// Source texts match along with host document versions. We've already published something that looks like this. No-op.
return;
}

_logger.LogTrace(
_logger.LogDebug(
$"Updating HTML buffer of {filePath} to correspond with host document version {hostDocumentVersion}. {previouslyPublishedData.SourceText.Length} -> {sourceText.Length} = Change delta of {sourceText.Length - previouslyPublishedData.SourceText.Length} via {textChanges.Count} text changes.");

_publishedHtmlData[filePath] = new PublishData(sourceText, hostDocumentVersion);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ private async Task<SynchronizedResult<TVirtualDocumentSnapshot>> TrySynchronizeV
return await TempForCohost_TrySynchronizeVirtualDocumentAsync<TVirtualDocumentSnapshot>(hostDocument, cancellationToken);
}

_logger.LogDebug($"Trying to synchronize for {caller} to version {requiredHostDocumentVersion} of {hostDocument.Uri} for {hostDocument.GetProjectContext()?.Id ?? "(no project context)"}");

// For Html documents we don't do anything fancy, just call the standard service
// If we're not generating unique document file names, then we can treat C# documents the same way
if (!_languageServerFeatureOptions.IncludeProjectKeyInGeneratedFilePath ||
Expand All @@ -154,8 +156,6 @@ private async Task<SynchronizedResult<TVirtualDocumentSnapshot>> TrySynchronizeV
return await _documentSynchronizer.TrySynchronizeVirtualDocumentAsync<TVirtualDocumentSnapshot>(requiredHostDocumentVersion, hostDocument.Uri, cancellationToken).ConfigureAwait(false);
}

_logger.LogDebug($"Trying to synchronize for {caller} to version {requiredHostDocumentVersion} of {hostDocument.Uri} for {hostDocument.GetProjectContext()?.Id ?? "(no project context)"}");

var virtualDocument = FindVirtualDocument<TVirtualDocumentSnapshot>(hostDocument.Uri, hostDocument.GetProjectContext());

if (virtualDocument is { ProjectKey.IsUnknown: true })
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Razor.Logging;
using Microsoft.CodeAnalysis.Razor.Protocol;
using StreamJsonRpc;

Expand Down Expand Up @@ -35,6 +36,9 @@ internal void UpdateHtmlBuffer(UpdateBufferRequest request)
}

var hostDocumentUri = new Uri(request.HostDocumentFilePath);

_logger.LogDebug($"UpdateHtmlBuffer for {request.HostDocumentVersion} of {hostDocumentUri} in {request.ProjectKeyId}");

_documentManager.UpdateVirtualDocument<HtmlVirtualDocument>(
hostDocumentUri,
request.Changes.Select(change => change.ToVisualStudioTextChange()).ToArray(),
Expand Down

0 comments on commit 92743cc

Please sign in to comment.