/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/VisualStudio/LiveShare/Impl/Client/Projects/RoslynRemoteProjectInfoProvider.cs
110 строк
5 KB
Cyrus Najmabadi
Use file scoped namespaces. (#77854)
27 мар 2025, 09:55
Не верифицирован
27 мар 2025, 09:55
98d41b8
Код
Авторство
О чём код?
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. #nullable disable using System; using System.Collections.Immutable; using System.ComponentModel.Composition; using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Host; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.Text; using Microsoft.VisualStudio.LiveShare.LanguageServices; namespace Microsoft.VisualStudio.LanguageServices.LiveShare.Client.Projects; [Export(typeof(IRemoteProjectInfoProvider))] internal sealed class RoslynRemoteProjectInfoProvider : IRemoteProjectInfoProvider { private const string SystemUriSchemeExternal = "vslsexternal"; private readonly string[] _secondaryBufferFileExtensions = [".cshtml", ".razor", ".html", ".aspx", ".vue"]; private readonly CSharpLspClientServiceFactory _roslynLspClientServiceFactory; private readonly RemoteLanguageServiceWorkspace _remoteLanguageServiceWorkspace; [ImportingConstructor] [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] public RoslynRemoteProjectInfoProvider(CSharpLspClientServiceFactory roslynLspClientServiceFactory, RemoteLanguageServiceWorkspace remoteLanguageServiceWorkspace) { _roslynLspClientServiceFactory = roslynLspClientServiceFactory ?? throw new ArgumentNullException(nameof(roslynLspClientServiceFactory)); _remoteLanguageServiceWorkspace = remoteLanguageServiceWorkspace ?? throw new ArgumentNullException(nameof(RemoteLanguageServiceWorkspace)); } public async Task<ImmutableArray<ProjectInfo>> GetRemoteProjectInfosAsync(CancellationToken cancellationToken) { if (!_remoteLanguageServiceWorkspace.IsRemoteSession) { return []; } var lspClient = _roslynLspClientServiceFactory.ActiveLanguageServerClient; if (lspClient == null) { return []; } CustomProtocol.Project[] projects; try { var request = new LspRequest<object, CustomProtocol.Project[]>(CustomProtocol.RoslynMethods.ProjectsName); projects = await lspClient.RequestAsync(request, new object(), cancellationToken).ConfigureAwait(false); } catch (Exception) { projects = null; } if (projects == null) { return []; } var projectInfos = ImmutableArray.CreateBuilder<ProjectInfo>(); foreach (var project in projects) { // We don't want to add cshtml files to the workspace since the Roslyn will add the generated secondary buffer of a cshtml // file to a different project but with the same path. This used to be ok in Dev15 but in Dev16 this confuses Roslyn and causes downstream // issues. There's no need to add the actual cshtml file to the workspace - so filter those out. // This is also the case for files for which TypeScript adds the generated TypeScript buffer to a different project. var filesTasks = project.SourceFiles .Where(f => f.Scheme != SystemUriSchemeExternal) .Where(f => !_secondaryBufferFileExtensions.Any(ext => f.LocalPath.EndsWith(ext))) .Select(f => lspClient.ProtocolConverter.FromProtocolUriAsync(f, false, cancellationToken)); var files = await Task.WhenAll(filesTasks).ConfigureAwait(false); var projectInfo = CreateProjectInfo(project.Name, project.Language, [.. files.Select(f => f.LocalPath)], _remoteLanguageServiceWorkspace.Services.SolutionServices); projectInfos.Add(projectInfo); } return projectInfos.ToImmutableArray(); } private static ProjectInfo CreateProjectInfo(string projectName, string language, ImmutableArray<string> files, SolutionServices services) { var projectId = ProjectId.CreateNewId(); var checksumAlgorithm = SourceHashAlgorithms.Default; var docInfos = files.SelectAsArray(path => DocumentInfo.Create( DocumentId.CreateNewId(projectId), name: Path.GetFileNameWithoutExtension(path), loader: new WorkspaceFileTextLoaderNoException(services, path, defaultEncoding: null), filePath: path)); return ProjectInfo.Create( new ProjectInfo.ProjectAttributes( projectId, VersionStamp.Create(), name: projectName, assemblyName: projectName, language, compilationOutputInfo: default, checksumAlgorithm), documents: docInfos); } }