提交 7966e783 编写于 作者: C CyrusNajmabadi

Don't create definit-entries for items that have no references and have...

Don't create definit-entries for items that have no references and have specified DisplayIfNoReferences=false
上级 3ac50fce
...@@ -230,23 +230,71 @@ public override async Task OnDefinitionFoundAsync(DefinitionItem definition) ...@@ -230,23 +230,71 @@ public override async Task OnDefinitionFoundAsync(DefinitionItem definition)
_definitions.Add(definition); _definitions.Add(definition);
} }
foreach (var location in definition.SourceSpans) // If this is a definition we always want to show, then create entries
// for all the definition locations.
if (definition.DisplayIfNoReferences)
{ {
await OnEntryFoundAsync(definition, await AddDefinitionEntriesAsync(definition).ConfigureAwait(false);
(db, c) => CreateDocumentLocationEntryAsync(
db, location, isDefinitionLocation: true, cancellationToken: c)).ConfigureAwait(false);
} }
} }
private async Task AddDefinitionEntriesAsync(DefinitionItem definition)
{
var cancellationToken = _cancellationTokenSource.Token;
cancellationToken.ThrowIfCancellationRequested();
// Don't do anything if we already have entries for this definition.
if (HasEntriesForDefinition(definition))
{
return;
}
// First find the bucket corresponding to our definition. If we can't find/create
// one, then don't do anything for this reference.
var definitionBucket = GetOrCreateDefinitionBucket(definition);
if (definitionBucket == null)
{
return;
}
// We could do this inside the lock. but htat would mean async activity in a
// lock, and i'd like to avoid that. That does mean that we might do extra
// work if multiple threads end up down htis path. But only one of them will
// win when we access the lock below.
var builder = ImmutableArray.CreateBuilder<Entry>();
foreach (var definitionLocation in definition.SourceSpans)
{
var definitionEntry = await CreateDocumentLocationEntryAsync(
definitionBucket, definitionLocation, isDefinitionLocation: true, cancellationToken: cancellationToken).ConfigureAwait(false);
if (definitionEntry != null)
{
builder.Add(definitionEntry);
}
}
lock (_gate)
{
// Do one final check to ensure that no other thread beat us here.
if (!HasEntriesForDefinition(definition))
{
_entries = _entries.AddRange(builder);
CurrentVersionNumber++;
}
}
// Let all our subscriptions know that we've updated.
_tableDataSink.FactorySnapshotChanged(this);
}
public override Task OnReferenceFoundAsync(SourceReferenceItem reference) public override Task OnReferenceFoundAsync(SourceReferenceItem reference)
{ {
return OnEntryFoundAsync(reference.Definition, return OnEntryFoundAsync(reference.Definition,
(db, c) => CreateDocumentLocationEntryAsync( (db, c) => CreateDocumentLocationEntryAsync(
db, reference.SourceSpan, isDefinitionLocation: false, cancellationToken: c)); db, reference.SourceSpan, isDefinitionLocation: false, cancellationToken: c));
} }
private async Task OnEntryFoundAsync( private async Task OnEntryFoundAsync(
DefinitionItem definition, DefinitionItem definition,
Func<RoslynDefinitionBucket, CancellationToken, Task<Entry>> createEntryAsync) Func<RoslynDefinitionBucket, CancellationToken, Task<Entry>> createEntryAsync)
{ {
var cancellationToken = _cancellationTokenSource.Token; var cancellationToken = _cancellationTokenSource.Token;
...@@ -260,13 +308,19 @@ public override Task OnReferenceFoundAsync(SourceReferenceItem reference) ...@@ -260,13 +308,19 @@ public override Task OnReferenceFoundAsync(SourceReferenceItem reference)
return; return;
} }
var entry = await createEntryAsync( var entry = await createEntryAsync(definitionBucket, cancellationToken).ConfigureAwait(false);
definitionBucket, cancellationToken).ConfigureAwait(false);
if (entry == null) if (entry == null)
{ {
return; return;
} }
// Ok, we got a *reference* to some definition item. This may have been
// a reference for some definition that we haven't created any definition
// entries for (i.e. becuase it had DisplayIfNoReferences = false). Because
// we've now found a reference, we want to make sure all tis definition
// entries are added.
await AddDefinitionEntriesAsync(definition).ConfigureAwait(false);
lock (_gate) lock (_gate)
{ {
// Once we can make the new entry, add it to our list. // Once we can make the new entry, add it to our list.
...@@ -278,6 +332,14 @@ public override Task OnReferenceFoundAsync(SourceReferenceItem reference) ...@@ -278,6 +332,14 @@ public override Task OnReferenceFoundAsync(SourceReferenceItem reference)
_tableDataSink.FactorySnapshotChanged(this); _tableDataSink.FactorySnapshotChanged(this);
} }
private bool HasEntriesForDefinition(DefinitionItem definition)
{
lock (_gate)
{
return _entries.Any(e => e.DefinitionBucket.DefinitionItem == definition);
}
}
private async Task<Entry> CreateDocumentLocationEntryAsync( private async Task<Entry> CreateDocumentLocationEntryAsync(
RoslynDefinitionBucket definitionBucket, RoslynDefinitionBucket definitionBucket,
DocumentSpan documentSpan, DocumentSpan documentSpan,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册