提交 d83c3e60 编写于 作者: T Tomas Matousek

Merge pull request #764 from tmat/AddFilter

Add filter
......@@ -7,9 +7,11 @@
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.ErrorReporting;
using Microsoft.CodeAnalysis.LanguageServices;
using Microsoft.CodeAnalysis.Shared.Extensions;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.SolutionCrawler
{
......@@ -17,89 +19,95 @@ internal abstract class AbstractDocumentDifferenceService : IDocumentDifferenceS
{
public async Task<DocumentDifferenceResult> GetDifferenceAsync(Document oldDocument, Document newDocument, CancellationToken cancellationToken)
{
var syntaxFactsService = newDocument.Project.LanguageServices.GetService<ISyntaxFactsService>();
if (syntaxFactsService == null)
try
{
// somehow, we can't get the service. without it, there is nothing we can do.
return new DocumentDifferenceResult(InvocationReasons.DocumentChanged);
}
var syntaxFactsService = newDocument.Project.LanguageServices.GetService<ISyntaxFactsService>();
if (syntaxFactsService == null)
{
// somehow, we can't get the service. without it, there is nothing we can do.
return new DocumentDifferenceResult(InvocationReasons.DocumentChanged);
}
// this is based on the implementation detail where opened documents use strong references
// to tree and text rather than recoverable versions.
SourceText oldText;
SourceText newText;
if (!oldDocument.TryGetText(out oldText) ||
!newDocument.TryGetText(out newText))
{
// no cheap way to determine top level changes. assumes top level has changed
return new DocumentDifferenceResult(InvocationReasons.DocumentChanged);
}
// this is based on the implementation detail where opened documents use strong references
// to tree and text rather than recoverable versions.
SourceText oldText;
SourceText newText;
if (!oldDocument.TryGetText(out oldText) ||
!newDocument.TryGetText(out newText))
{
// no cheap way to determine top level changes. assumes top level has changed
return new DocumentDifferenceResult(InvocationReasons.DocumentChanged);
}
// quick check whether two tree versions are same
VersionStamp oldVersion;
VersionStamp newVersion;
if (oldDocument.TryGetSyntaxVersion(out oldVersion) &&
newDocument.TryGetSyntaxVersion(out newVersion) &&
oldVersion.Equals(newVersion))
{
// nothing has changed. don't do anything.
// this could happen if a document is opened/closed without any buffer change
return null;
}
// quick check whether two tree versions are same
VersionStamp oldVersion;
VersionStamp newVersion;
if (oldDocument.TryGetSyntaxVersion(out oldVersion) &&
newDocument.TryGetSyntaxVersion(out newVersion) &&
oldVersion.Equals(newVersion))
{
// nothing has changed. don't do anything.
// this could happen if a document is opened/closed without any buffer change
return null;
}
var range = newText.GetEncompassingTextChangeRange(oldText);
if (range == default(TextChangeRange))
{
// nothing has changed. don't do anything
return null;
}
var range = newText.GetEncompassingTextChangeRange(oldText);
if (range == default(TextChangeRange))
{
// nothing has changed. don't do anything
return null;
}
var incrementalParsingCandidate = range.NewLength != newText.Length;
var incrementalParsingCandidate = range.NewLength != newText.Length;
// see whether we can get it without explicit parsing
SyntaxNode oldRoot;
SyntaxNode newRoot;
if (!oldDocument.TryGetSyntaxRoot(out oldRoot) ||
!newDocument.TryGetSyntaxRoot(out newRoot))
{
if (!incrementalParsingCandidate)
// see whether we can get it without explicit parsing
SyntaxNode oldRoot;
SyntaxNode newRoot;
if (!oldDocument.TryGetSyntaxRoot(out oldRoot) ||
!newDocument.TryGetSyntaxRoot(out newRoot))
{
// no cheap way to determine top level changes. assumes top level has changed
return new DocumentDifferenceResult(InvocationReasons.DocumentChanged);
if (!incrementalParsingCandidate)
{
// no cheap way to determine top level changes. assumes top level has changed
return new DocumentDifferenceResult(InvocationReasons.DocumentChanged);
}
// explicitly parse them
oldRoot = await oldDocument.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
newRoot = await newDocument.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
}
// explicitly parse them
oldRoot = await oldDocument.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
newRoot = await newDocument.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
}
// at this point, we must have these version already calculated
VersionStamp oldTopLevelChangeVersion;
VersionStamp newTopLevelChangeVersion;
if (!oldDocument.TryGetTopLevelChangeTextVersion(out oldTopLevelChangeVersion) ||
!newDocument.TryGetTopLevelChangeTextVersion(out newTopLevelChangeVersion))
{
throw ExceptionUtilities.Unreachable;
}
// at this point, we must have these version already calculated
VersionStamp oldTopLevelChangeVersion;
VersionStamp newTopLevelChangeVersion;
if (!oldDocument.TryGetTopLevelChangeTextVersion(out oldTopLevelChangeVersion) ||
!newDocument.TryGetTopLevelChangeTextVersion(out newTopLevelChangeVersion))
{
Debug.Fail("How?");
return new DocumentDifferenceResult(InvocationReasons.DocumentChanged);
}
// quicker common case
if (incrementalParsingCandidate)
{
if (oldTopLevelChangeVersion.Equals(newTopLevelChangeVersion))
{
return new DocumentDifferenceResult(InvocationReasons.SyntaxChanged, GetChangedMember(syntaxFactsService, oldRoot, newRoot, range));
}
return new DocumentDifferenceResult(InvocationReasons.DocumentChanged, GetBestGuessChangedMember(syntaxFactsService, oldRoot, newRoot, range));
}
// quicker common case
if (incrementalParsingCandidate)
{
if (oldTopLevelChangeVersion.Equals(newTopLevelChangeVersion))
{
return new DocumentDifferenceResult(InvocationReasons.SyntaxChanged, GetChangedMember(syntaxFactsService, oldRoot, newRoot, range));
return new DocumentDifferenceResult(InvocationReasons.SyntaxChanged);
}
return new DocumentDifferenceResult(InvocationReasons.DocumentChanged, GetBestGuessChangedMember(syntaxFactsService, oldRoot, newRoot, range));
return new DocumentDifferenceResult(InvocationReasons.DocumentChanged);
}
if (oldTopLevelChangeVersion.Equals(newTopLevelChangeVersion))
catch (Exception e) when (FatalError.ReportUnlessCanceled(e))
{
return new DocumentDifferenceResult(InvocationReasons.SyntaxChanged);
throw ExceptionUtilities.Unreachable;
}
return new DocumentDifferenceResult(InvocationReasons.DocumentChanged);
}
private static SyntaxNode GetChangedMember(
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册