public DefinitionTreeItem( DefinitionItem definitionItem, ImmutableArray<SourceReferenceTreeItem> referenceItems) : base(definitionItem.Tags.GetGlyph().GetGlyphIndex()) { _definitionItem = definitionItem; this.Children.AddRange(referenceItems); this.DisplayText = CreateDisplayText(); }
public RoslynDefinitionBucket( StreamingFindReferencesPresenter presenter, TableDataSourceFindReferencesContext context, DefinitionItem definitionItem) : base(name: definitionItem.DisplayParts.JoinText() + " " + definitionItem.GetHashCode(), sourceTypeIdentifier: context.SourceTypeIdentifier, identifier: context.Identifier) { _presenter = presenter; _context = context; DefinitionItem = definitionItem; }
private ImmutableArray<SourceReferenceTreeItem> CreateReferenceItems( DefinitionItem definitionItem, DefinitionsAndReferences definitionsAndReferences, int commonPathElements) { var result = ImmutableArray.CreateBuilder<SourceReferenceTreeItem>(); var definitionGlyph = definitionItem.Tags.GetGlyph(); // Skip the first definition. We'll present it in the definition item. var definitionLocationsAndGlyphs = from loc in definitionItem.SourceSpans.Skip(1) select ValueTuple.Create(loc, definitionGlyph); var referenceLocationsAndGlyphs = from r in definitionsAndReferences.References where r.Definition == definitionItem select ValueTuple.Create(r.SourceSpan, Glyph.Reference); var allLocationsAndGlyphs = definitionLocationsAndGlyphs.Concat(referenceLocationsAndGlyphs); foreach (var locationAndGlyph in allLocationsAndGlyphs) { var documentLocation = locationAndGlyph.Item1; var glyph = locationAndGlyph.Item2; result.Add(new SourceReferenceTreeItem( documentLocation.Document, documentLocation.SourceSpan, glyph.GetGlyphIndex(), commonPathElements)); } var linkedReferences = result.GroupBy(r => r.DisplayText.ToLowerInvariant()).Where(g => g.Count() > 1).SelectMany(g => g); foreach (var linkedReference in linkedReferences) { linkedReference.AddProjectNameDisambiguator(); } result.Sort(); return result.ToImmutable(); }
private static string GetMessage(DefinitionItem definition) { if (definition.IsExternal) { return ServicesVisualStudioNextResources.External_reference_found; } return string.Format( ServicesVisualStudioNextResources.No_references_found_to_0, definition.DisplayParts.JoinText()); }
public static SourceReferenceItem TryCreateSourceReferenceItem( this ReferenceLocation referenceLocation, DefinitionItem definitionItem) { var location = referenceLocation.Location; Debug.Assert(location.IsInSource); if (!location.IsVisibleSourceLocation()) { return null; } return new SourceReferenceItem(definitionItem, new DocumentSpan(referenceLocation.Document, location.SourceSpan)); }
private static void CreateReferences( ReferencedSymbol referencedSymbol, ImmutableArray<SourceReferenceItem>.Builder references, DefinitionItem definitionItem, HashSet<DocumentSpan> uniqueSpans) { foreach (var referenceLocation in referencedSymbol.Locations) { var sourceReferenceItem = referenceLocation.TryCreateSourceReferenceItem(definitionItem); if (sourceReferenceItem == null) { continue; } if (uniqueSpans.Add(sourceReferenceItem.SourceSpan)) { references.Add(sourceReferenceItem); } } }
private bool HasEntriesForDefinition(DefinitionItem definition) { lock (_gate) { return _entries.Any(e => e.DefinitionBucket.DefinitionItem == definition); } }
private async Task OnEntryFoundAsync( DefinitionItem definition, Func<RoslynDefinitionBucket, Task<Entry>> createEntryAsync) { CancellationToken.ThrowIfCancellationRequested(); // 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; } var entry = await createEntryAsync(definitionBucket).ConfigureAwait(false); if (entry == null) { 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) { // Once we can make the new entry, add it to our list. _entries = _entries.Add(entry); CurrentVersionNumber++; } // Let all our subscriptions know that we've updated. _tableDataSink.FactorySnapshotChanged(this); }
private async Task OnEntryFoundAsync( DefinitionItem definition, Func<RoslynDefinitionBucket, CancellationToken, Task<Entry>> createEntryAsync) { var cancellationToken = _cancellationTokenSource.Token; cancellationToken.ThrowIfCancellationRequested(); // 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; } var entry = await createEntryAsync( definitionBucket, cancellationToken).ConfigureAwait(false); if (entry == null) { return; } lock (_gate) { // Once we can make the new entry, add it to our list. _entries = _entries.Add(entry); CurrentVersionNumber++; } // Let all our subscriptions know that we've updated. _tableDataSink.FactorySnapshotChanged(this); }
private static void CreateReferences( ReferencedSymbol referencedSymbol, ImmutableArray<SourceReferenceItem>.Builder references, DefinitionItem definitionItem, HashSet<DocumentLocation> uniqueLocations) { foreach (var referenceLocation in referencedSymbol.Locations) { var location = referenceLocation.Location; Debug.Assert(location.IsInSource); var document = referenceLocation.Document; var sourceSpan = location.SourceSpan; var documentLocation = new DocumentLocation(document, sourceSpan); if (!documentLocation.CanNavigateTo()) { continue; } if (uniqueLocations.Add(documentLocation)) { references.Add(new SourceReferenceItem(definitionItem, documentLocation)); } } }
public virtual Task OnDefinitionFoundAsync(DefinitionItem definition) => SpecializedTasks.EmptyTask;
public SourceReferenceItem(DefinitionItem definition, DocumentSpan sourceSpan) { Definition = definition; SourceSpan = sourceSpan; }
public virtual void OnDefinitionFound(DefinitionItem definition) { }
public override void OnDefinitionFound(DefinitionItem definition) { lock (_gate) { _definitions.Add(definition); } foreach (var location in definition.SourceSpans) { OnEntryFound(definition, (db, c) => CreateDocumentLocationEntryAsync( db, location, isDefinitionLocation: true, cancellationToken: c)); } }
public override async Task OnDefinitionFoundAsync(DefinitionItem definition) { lock (_gate) { _definitions.Add(definition); } // If this is a definition we always want to show, then create entries // for all the definition locations immediately. if (definition.DisplayIfNoReferences) { await AddDefinitionEntriesAsync(definition).ConfigureAwait(false); } }
private async void OnEntryFound( DefinitionItem definition, Func<RoslynDefinitionBucket, CancellationToken, Task<Entry>> createEntryAsync) { try { // We're told about this reference synchronously, but we need to get the // SourceText for the definition/reference's Document so that we can determine // things like it's line/column/text. We don't want to block this method getting // that data, so instead we just fire off the async work to get the text // and use it. Because we're starting some async work, let the test harness // know so that it doesn't verify results until this completes. using (var token = Presenter._asyncListener.BeginAsyncOperation(nameof(OnReferenceFound))) { await OnEntryFoundAsync(definition, createEntryAsync).ConfigureAwait(false); } } catch (Exception e) when (FatalError.ReportWithoutCrashUnlessCanceled(e)) { } }
private async Task AddDefinitionEntriesAsync(DefinitionItem definition) { CancellationToken.ThrowIfCancellationRequested(); // Don't do anything if we already have entries for this definition // (i.e. another thread beat us to this). 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 that 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).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); }
private RoslynDefinitionBucket GetOrCreateDefinitionBucket(DefinitionItem definition) { lock (_gate) { RoslynDefinitionBucket bucket; if (!_definitionToBucket.TryGetValue(definition, out bucket)) { bucket = new RoslynDefinitionBucket(Presenter, this, definition); _definitionToBucket.Add(definition, bucket); } return bucket; } }
public SourceReferenceItem(DefinitionItem definition, DocumentLocation location) { Definition = definition; Location = location; }