Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix issues with JTF blocking in codemodel #73419

Merged
merged 5 commits into from
May 10, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 32 additions & 24 deletions src/VisualStudio/Core/Impl/CodeModel/RootCodeModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,13 @@
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.VisualStudio.LanguageServices.Implementation.CodeModel.ExternalElements;
using Microsoft.VisualStudio.LanguageServices.Implementation.Interop;
using Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem;
using Microsoft.VisualStudio.LanguageServices.Implementation.Utilities;
using Microsoft.VisualStudio.Threading;
using Roslyn.Utilities;

namespace Microsoft.VisualStudio.LanguageServices.Implementation.CodeModel
Expand Down Expand Up @@ -39,8 +41,8 @@ private RootCodeModel(CodeModelState state, EnvDTE.Project parent, ProjectId pro
private Project GetProject()
=> Workspace.CurrentSolution.GetProject(_projectId);

private Compilation GetCompilation()
=> GetProject().GetCompilationAsync().Result;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so old we're still calling .Result, not even GetAwaiter().GetResult();

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, at least 10 years old from the blame.

private Task<Compilation> GetCompilationAsync()
=> GetProject().GetCompilationAsync();

private ComHandle<EnvDTE80.FileCodeModel2, FileCodeModel> GetFileCodeModel(object location)
{
Expand Down Expand Up @@ -127,27 +129,34 @@ EnvDTE.CodeElements ICodeElementContainer<AbstractExternalCodeElement>.GetCollec
=> CodeElements;

public EnvDTE.CodeElements CodeElements
{
get
=> this.State.ThreadingContext.JoinableTaskFactory.Run(async () =>
{
var compilation = GetCompilation();
var compilation = await GetCompilationAsync().ConfigureAwait(true);

// Need to ensure we're on the UI thread to make the ExternalCodeNamespace. It creates UI thread bound
CyrusNajmabadi marked this conversation as resolved.
Show resolved Hide resolved
// com aggregates.
await this.State.ThreadingContext.JoinableTaskFactory.SwitchToMainThreadAsync();
var rootNamespace = ExternalCodeNamespace.Create(this.State, _projectId, compilation.GlobalNamespace);
return rootNamespace.Members;
}
}
});

public EnvDTE.CodeType CodeTypeFromFullName(string name)
{
var compilation = GetCompilation();
var typeSymbol = CodeModelService.GetTypeSymbolFromFullName(name, compilation);
if (typeSymbol == null ||
typeSymbol.TypeKind is TypeKind.Error or TypeKind.Unknown)
=> this.State.ThreadingContext.JoinableTaskFactory.Run(async () =>
{
return null;
}
var compilation = await GetCompilationAsync().ConfigureAwait(false);
var typeSymbol = CodeModelService.GetTypeSymbolFromFullName(name, compilation);
if (typeSymbol == null ||
typeSymbol.TypeKind is TypeKind.Error or TypeKind.Unknown)
{
return null;
}

return (EnvDTE.CodeType)CodeModelService.CreateCodeType(this.State, _projectId, typeSymbol);
}
// Need to ensure we're on the UI thread to make the call to CreateCodeType. It creates UI thread
// bound com aggregates.
await this.State.ThreadingContext.JoinableTaskFactory.SwitchToMainThreadAsync();

return (EnvDTE.CodeType)CodeModelService.CreateCodeType(this.State, _projectId, typeSymbol);
});

public EnvDTE.CodeTypeRef CreateCodeTypeRef(object type)
=> CodeModelService.CreateCodeTypeRef(this.State, _projectId, type);
Expand All @@ -159,16 +168,15 @@ public void Remove(object element)
=> throw Exceptions.ThrowENotImpl();

public string DotNetNameFromLanguageSpecific(string languageName)
{
var compilation = GetCompilation();
var typeSymbol = CodeModelService.GetTypeSymbolFromFullName(languageName, compilation);
if (typeSymbol == null)
=> this.State.ThreadingContext.JoinableTaskFactory.Run(async () =>
{
throw Exceptions.ThrowEInvalidArg();
}
var compilation = await GetCompilationAsync().ConfigureAwait(false);
var typeSymbol = CodeModelService.GetTypeSymbolFromFullName(languageName, compilation);
if (typeSymbol == null)
throw Exceptions.ThrowEInvalidArg();

return MetadataNameHelpers.GetMetadataName(typeSymbol);
}
return MetadataNameHelpers.GetMetadataName(typeSymbol);
};

public EnvDTE.CodeElement ElementFromID(string id)
=> throw Exceptions.ThrowENotImpl();
Expand Down
Loading