Skip to content
Merged
767 changes: 380 additions & 387 deletions src/VisualStudio/CSharp/Impl/ObjectBrowser/DescriptionBuilder.cs

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#nullable disable

using System;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.VisualStudio.OLE.Interop;
using Microsoft.VisualStudio.Shell.Interop;

Expand All @@ -14,7 +16,7 @@ internal partial class AbstractLibraryManager : IVsSimpleLibrary2
{
public abstract uint GetLibraryFlags();
protected abstract uint GetSupportedCategoryFields(uint category);
protected abstract IVsSimpleObjectList2 GetList(uint listType, uint flags, VSOBSEARCHCRITERIA2[] pobSrch);
protected abstract Task<IVsSimpleObjectList2> GetListAsync(uint listType, uint flags, VSOBSEARCHCRITERIA2[] pobSrch, CancellationToken cancellationToken);
protected abstract uint GetUpdateCounter();

protected virtual int CreateNavInfo(SYMBOL_DESCRIPTION_NODE[] rgSymbolNodes, uint ulcNodes, out IVsNavInfo ppNavInfo)
Expand Down Expand Up @@ -50,7 +52,8 @@ int IVsSimpleLibrary2.GetLibFlags2(out uint pgrfFlags)

int IVsSimpleLibrary2.GetList2(uint listType, uint flags, VSOBSEARCHCRITERIA2[] pobSrch, out IVsSimpleObjectList2 ppIVsSimpleObjectList2)
{
ppIVsSimpleObjectList2 = GetList(listType, flags, pobSrch);
ppIVsSimpleObjectList2 = this.ThreadingContext.JoinableTaskFactory.Run(
() => GetListAsync(listType, flags, pobSrch, CancellationToken.None));

return ppIVsSimpleObjectList2 != null
? VSConstants.S_OK
Expand Down
23 changes: 12 additions & 11 deletions src/VisualStudio/Core/Def/Library/AbstractObjectList.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,8 @@ protected virtual bool TryGetContextMenu(uint index, out Guid menuGuid, out int
return false;
}

protected virtual bool TryGetProperty(uint index, _VSOBJLISTELEMPROPID propertyId, out object pvar)
{
pvar = null;
return false;
}
protected virtual Task<(bool success, object pvar)> TryGetPropertyAsync(uint index, _VSOBJLISTELEMPROPID propertyId, CancellationToken cancellationToken)
=> SpecializedTasks.Default<(bool success, object pvar)>();

protected virtual bool TryCountSourceItems(uint index, out IVsHierarchy hierarchy, out uint itemid, out uint items)
{
Expand Down Expand Up @@ -101,8 +98,8 @@ protected virtual bool SupportsDescription
get { return false; }
}

protected virtual bool TryFillDescription(uint index, _VSOBJDESCOPTIONS options, IVsObjectBrowserDescription3 description)
=> false;
protected virtual Task<bool> TryFillDescriptionAsync(uint index, _VSOBJDESCOPTIONS options, IVsObjectBrowserDescription3 description, CancellationToken cancellationToken)
=> SpecializedTasks.False;

int IVsSimpleObjectList2.CanDelete(uint index, out int pfOK)
{
Expand Down Expand Up @@ -147,11 +144,11 @@ int IVsSimpleObjectList2.EnumClipboardFormats(uint index, uint grfFlags, uint ce
int IVsSimpleObjectList2.FillDescription2(uint index, uint grfOptions, IVsObjectBrowserDescription3 pobDesc)
{
if (!SupportsDescription)
{
return VSConstants.E_NOTIMPL;
}

return TryFillDescription(index, (_VSOBJDESCOPTIONS)grfOptions, pobDesc)
var result = this.LibraryManager.ThreadingContext.JoinableTaskFactory.Run(
() => TryFillDescriptionAsync(index, (_VSOBJDESCOPTIONS)grfOptions, pobDesc, CancellationToken.None));
return result
? VSConstants.S_OK
: VSConstants.E_FAIL;
}
Expand Down Expand Up @@ -270,11 +267,15 @@ int IVsSimpleObjectList2.GetNavInfoNode(uint index, out IVsNavInfoNode ppNavInfo

int IVsSimpleObjectList2.GetProperty(uint index, int propid, out object pvar)
{
if (TryGetProperty(index, (_VSOBJLISTELEMPROPID)propid, out pvar))
var (success, obj) = this.LibraryManager.ThreadingContext.JoinableTaskFactory.Run(() =>
TryGetPropertyAsync(index, (_VSOBJLISTELEMPROPID)propid, CancellationToken.None));
if (success)
{
pvar = obj;
return VSConstants.S_OK;
}

pvar = null;
return VSConstants.E_FAIL;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.DocumentationComments;
using Microsoft.CodeAnalysis.Shared.Extensions;
Expand Down Expand Up @@ -37,12 +38,8 @@ protected AbstractDescriptionBuilder(
_project = project;
}

private Compilation GetCompilation()
{
return _project
.GetCompilationAsync(CancellationToken.None)
.WaitAndGetResult_ObjectBrowser(CancellationToken.None);
}
private Task<Compilation> GetCompilationAsync(CancellationToken cancellationToken)
=> _project.GetCompilationAsync(cancellationToken);

protected void AddAssemblyLink(IAssemblySymbol assemblySymbol)
{
Expand All @@ -67,15 +64,16 @@ protected void AddLineBreak()
protected void AddName(string text)
=> _description.AddDescriptionText3(text, VSOBDESCRIPTIONSECTION.OBDS_NAME, null);

protected void AddNamespaceLink(INamespaceSymbol namespaceSymbol)
protected async Task AddNamespaceLinkAsync(INamespaceSymbol namespaceSymbol, CancellationToken cancellationToken)
{
if (namespaceSymbol.IsGlobalNamespace)
{
return;
}

var text = namespaceSymbol.ToDisplayString();
var navInfo = _libraryManager.LibraryService.NavInfoFactory.CreateForNamespace(namespaceSymbol, _project, GetCompilation(), useExpandedHierarchy: false);
var navInfo = _libraryManager.LibraryService.NavInfoFactory.CreateForNamespace(
namespaceSymbol, _project, await GetCompilationAsync(cancellationToken).ConfigureAwait(true), useExpandedHierarchy: false);

_description.AddDescriptionText3(text, VSOBDESCRIPTIONSECTION.OBDS_TYPE, navInfo);
}
Expand All @@ -86,7 +84,8 @@ protected void AddParam(string text)
protected void AddText(string text)
=> _description.AddDescriptionText3(text, VSOBDESCRIPTIONSECTION.OBDS_MISC, null);

protected void AddTypeLink(ITypeSymbol typeSymbol, LinkFlags flags)
protected async Task AddTypeLinkAsync(
ITypeSymbol typeSymbol, LinkFlags flags, CancellationToken cancellationToken)
{
if (typeSymbol.TypeKind is TypeKind.Unknown or TypeKind.Error or TypeKind.TypeParameter ||
typeSymbol.SpecialType == SpecialType.System_Void)
Expand All @@ -100,7 +99,7 @@ protected void AddTypeLink(ITypeSymbol typeSymbol, LinkFlags flags)

if (splitLink && !typeSymbol.ContainingNamespace.IsGlobalNamespace)
{
AddNamespaceLink(typeSymbol.ContainingNamespace);
await AddNamespaceLinkAsync(typeSymbol.ContainingNamespace, cancellationToken).ConfigureAwait(true);
AddText(".");
}

Expand All @@ -118,7 +117,8 @@ protected void AddTypeLink(ITypeSymbol typeSymbol, LinkFlags flags)
miscellaneousOptions: miscellaneousOptions);

var text = typeSymbol.ToDisplayString(typeDisplayFormat);
var navInfo = _libraryManager.LibraryService.NavInfoFactory.CreateForType(typeSymbol, _project, GetCompilation(), useExpandedHierarchy: false);
var navInfo = _libraryManager.LibraryService.NavInfoFactory.CreateForType(
typeSymbol, _project, await GetCompilationAsync(cancellationToken).ConfigureAwait(true), useExpandedHierarchy: false);

_description.AddDescriptionText3(text, VSOBDESCRIPTIONSECTION.OBDS_TYPE, navInfo);
}
Expand All @@ -142,9 +142,10 @@ private void BuildReference(ReferenceListItem referenceListItem)
}
}

private void BuildNamespace(NamespaceListItem namespaceListItem, _VSOBJDESCOPTIONS options)
private async Task BuildNamespaceAsync(
NamespaceListItem namespaceListItem, _VSOBJDESCOPTIONS options, CancellationToken cancellationToken)
{
var compilation = GetCompilation();
var compilation = await GetCompilationAsync(cancellationToken).ConfigureAwait(true);
if (compilation == null)
{
return;
Expand All @@ -159,12 +160,12 @@ private void BuildNamespace(NamespaceListItem namespaceListItem, _VSOBJDESCOPTIO
BuildNamespaceDeclaration(namespaceSymbol, options);

AddEndDeclaration();
BuildMemberOf(namespaceSymbol.ContainingAssembly);
await BuildMemberOfAsync(namespaceSymbol.ContainingAssembly, cancellationToken).ConfigureAwait(true);
}

private void BuildType(TypeListItem typeListItem, _VSOBJDESCOPTIONS options)
private async Task BuildTypeAsync(TypeListItem typeListItem, _VSOBJDESCOPTIONS options, CancellationToken cancellationToken)
{
var compilation = GetCompilation();
var compilation = await GetCompilationAsync(cancellationToken).ConfigureAwait(true);
if (compilation == null)
{
return;
Expand All @@ -178,49 +179,44 @@ private void BuildType(TypeListItem typeListItem, _VSOBJDESCOPTIONS options)

if (symbol.TypeKind == TypeKind.Delegate)
{
BuildDelegateDeclaration(symbol, options);
await BuildDelegateDeclarationAsync(symbol, options, cancellationToken).ConfigureAwait(true);
}
else
{
BuildTypeDeclaration(symbol, options);
await BuildTypeDeclarationAsync(symbol, options, cancellationToken).ConfigureAwait(true);
}

AddEndDeclaration();
BuildMemberOf(symbol.ContainingNamespace);

BuildXmlDocumentation(symbol, compilation);
await BuildMemberOfAsync(symbol.ContainingNamespace, cancellationToken).ConfigureAwait(true);
await BuildXmlDocumentationAsync(symbol, compilation, cancellationToken).ConfigureAwait(true);
}

private void BuildMember(MemberListItem memberListItem, _VSOBJDESCOPTIONS options)
private async Task BuildMemberAsync(MemberListItem memberListItem, _VSOBJDESCOPTIONS options, CancellationToken cancellationToken)
{
var compilation = GetCompilation();
var compilation = await GetCompilationAsync(cancellationToken).ConfigureAwait(true);
if (compilation == null)
{
return;
}

var symbol = memberListItem.ResolveTypedSymbol(compilation);
if (symbol == null)
{
return;
}

switch (symbol.Kind)
{
case SymbolKind.Method:
BuildMethodDeclaration((IMethodSymbol)symbol, options);
await BuildMethodDeclarationAsync((IMethodSymbol)symbol, options, cancellationToken).ConfigureAwait(true);
break;

case SymbolKind.Field:
BuildFieldDeclaration((IFieldSymbol)symbol, options);
await BuildFieldDeclarationAsync((IFieldSymbol)symbol, options, cancellationToken).ConfigureAwait(true);
break;

case SymbolKind.Property:
BuildPropertyDeclaration((IPropertySymbol)symbol, options);
await BuildPropertyDeclarationAsync((IPropertySymbol)symbol, options, cancellationToken).ConfigureAwait(true);
break;

case SymbolKind.Event:
BuildEventDeclaration((IEventSymbol)symbol, options);
await BuildEventDeclarationAsync((IEventSymbol)symbol, options, cancellationToken).ConfigureAwait(true);
break;

default:
Expand All @@ -229,20 +225,19 @@ private void BuildMember(MemberListItem memberListItem, _VSOBJDESCOPTIONS option
}

AddEndDeclaration();
BuildMemberOf(symbol.ContainingType);

BuildXmlDocumentation(symbol, compilation);
await BuildMemberOfAsync(symbol.ContainingType, cancellationToken).ConfigureAwait(true);
await BuildXmlDocumentationAsync(symbol, compilation, cancellationToken).ConfigureAwait(true);
}

protected abstract void BuildNamespaceDeclaration(INamespaceSymbol namespaceSymbol, _VSOBJDESCOPTIONS options);
protected abstract void BuildDelegateDeclaration(INamedTypeSymbol typeSymbol, _VSOBJDESCOPTIONS options);
protected abstract void BuildTypeDeclaration(INamedTypeSymbol typeSymbol, _VSOBJDESCOPTIONS options);
protected abstract void BuildMethodDeclaration(IMethodSymbol methodSymbol, _VSOBJDESCOPTIONS options);
protected abstract void BuildFieldDeclaration(IFieldSymbol fieldSymbol, _VSOBJDESCOPTIONS options);
protected abstract void BuildPropertyDeclaration(IPropertySymbol propertySymbol, _VSOBJDESCOPTIONS options);
protected abstract void BuildEventDeclaration(IEventSymbol eventSymbol, _VSOBJDESCOPTIONS options);

private void BuildMemberOf(ISymbol containingSymbol)
protected abstract Task BuildDelegateDeclarationAsync(INamedTypeSymbol typeSymbol, _VSOBJDESCOPTIONS options, CancellationToken cancellationToken);
protected abstract Task BuildTypeDeclarationAsync(INamedTypeSymbol typeSymbol, _VSOBJDESCOPTIONS options, CancellationToken cancellationToken);
protected abstract Task BuildMethodDeclarationAsync(IMethodSymbol methodSymbol, _VSOBJDESCOPTIONS options, CancellationToken cancellationToken);
protected abstract Task BuildFieldDeclarationAsync(IFieldSymbol fieldSymbol, _VSOBJDESCOPTIONS options, CancellationToken cancellationToken);
protected abstract Task BuildPropertyDeclarationAsync(IPropertySymbol propertySymbol, _VSOBJDESCOPTIONS options, CancellationToken cancellationToken);
protected abstract Task BuildEventDeclarationAsync(IEventSymbol eventSymbol, _VSOBJDESCOPTIONS options, CancellationToken cancellationToken);

private async Task BuildMemberOfAsync(ISymbol containingSymbol, CancellationToken cancellationToken)
{
if (containingSymbol is INamespaceSymbol &&
((INamespaceSymbol)containingSymbol).IsGlobalNamespace)
Expand Down Expand Up @@ -272,18 +267,20 @@ private void BuildMemberOf(ISymbol containingSymbol)
}
else if (containingSymbol is ITypeSymbol typeSymbol)
{
AddTypeLink(typeSymbol, LinkFlags.SplitNamespaceAndType | LinkFlags.ExpandPredefinedTypes);
await AddTypeLinkAsync(
typeSymbol, LinkFlags.SplitNamespaceAndType | LinkFlags.ExpandPredefinedTypes, cancellationToken).ConfigureAwait(true);
}
else if (containingSymbol is INamespaceSymbol namespaceSymbol)
{
AddNamespaceLink(namespaceSymbol);
await AddNamespaceLinkAsync(namespaceSymbol, cancellationToken).ConfigureAwait(true);
}

AddText(right);
AddEndDeclaration();
}

private void BuildXmlDocumentation(ISymbol symbol, Compilation compilation)
private async Task BuildXmlDocumentationAsync(
ISymbol symbol, Compilation compilation, CancellationToken cancellationToken)
{
var documentationComment = symbol.GetDocumentationComment(compilation, expandIncludes: true, expandInheritdoc: true, cancellationToken: CancellationToken.None);
if (documentationComment == null)
Expand Down Expand Up @@ -425,13 +422,13 @@ private void BuildXmlDocumentation(ISymbol symbol, Compilation compilation)
var exceptionTexts = documentationComment.GetExceptionTexts(exceptionType);
if (exceptionTexts.Length == 0)
{
AddTypeLink(exceptionTypeSymbol, LinkFlags.None);
await AddTypeLinkAsync(exceptionTypeSymbol, LinkFlags.None, cancellationToken).ConfigureAwait(true);
}
else
{
foreach (var exceptionText in exceptionTexts)
{
AddTypeLink(exceptionTypeSymbol, LinkFlags.None);
await AddTypeLinkAsync(exceptionTypeSymbol, LinkFlags.None, cancellationToken).ConfigureAwait(true);
AddText(": ");
AddText(formattingService.Format(exceptionText, compilation));
}
Expand All @@ -455,7 +452,7 @@ private static bool ShowValueDocumentation(ISymbol symbol)
return ShowReturnsDocumentation(symbol);
}

internal bool TryBuild(_VSOBJDESCOPTIONS options)
internal async Task<bool> TryBuildAsync(_VSOBJDESCOPTIONS options, CancellationToken cancellationToken)
{
switch (_listItem)
{
Expand All @@ -466,13 +463,13 @@ internal bool TryBuild(_VSOBJDESCOPTIONS options)
BuildReference(referenceListItem);
return true;
case NamespaceListItem namespaceListItem:
BuildNamespace(namespaceListItem, options);
await BuildNamespaceAsync(namespaceListItem, options, cancellationToken).ConfigureAwait(true);
return true;
case TypeListItem typeListItem:
BuildType(typeListItem, options);
await BuildTypeAsync(typeListItem, options, cancellationToken).ConfigureAwait(true);
return true;
case MemberListItem memberListItem:
BuildMember(memberListItem, options);
await BuildMemberAsync(memberListItem, options, cancellationToken).ConfigureAwait(true);
return true;
}

Expand Down
Loading
Loading