/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/VisualStudio/Core/Impl/CodeModel/ProjectCodeModel.cs
124 строки
5 KB
Cyrus Najmabadi
Use implicit object creation expressions
13 сен 2025, 01:48
13 сен 2025, 01:48
4c6a36a
Код
Авторство
О чём код?
// 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.Generic; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.VisualStudio.LanguageServices.Implementation.Interop; using Roslyn.Utilities; namespace Microsoft.VisualStudio.LanguageServices.Implementation.CodeModel; /// <summary> /// The root type that is held by a project to provide CodeModel support. /// </summary> internal sealed class ProjectCodeModel : IProjectCodeModel { private readonly NonReentrantLock _guard = new(); private readonly IThreadingContext _threadingContext; private readonly ProjectId _projectId; private readonly ICodeModelInstanceFactory _codeModelInstanceFactory; private readonly VisualStudioWorkspace _visualStudioWorkspace; private readonly IServiceProvider _serviceProvider; private readonly ProjectCodeModelFactory _projectCodeModelFactory; private CodeModelProjectCache _codeModelCache; public ProjectCodeModel( IThreadingContext threadingContext, ProjectId projectId, ICodeModelInstanceFactory codeModelInstanceFactory, VisualStudioWorkspace visualStudioWorkspace, IServiceProvider serviceProvider, ProjectCodeModelFactory projectCodeModelFactory) { _threadingContext = threadingContext; _projectId = projectId; _codeModelInstanceFactory = codeModelInstanceFactory; _visualStudioWorkspace = visualStudioWorkspace; _serviceProvider = serviceProvider; _projectCodeModelFactory = projectCodeModelFactory; } public void OnProjectClosed() { _codeModelCache?.OnProjectClosed(); _projectCodeModelFactory.OnProjectClosed(_projectId); } private CodeModelProjectCache GetCodeModelCache() { Contract.ThrowIfNull(_projectId); Contract.ThrowIfNull(_visualStudioWorkspace); using (_guard.DisposableWait()) { if (_codeModelCache == null) { var workspaceProject = _visualStudioWorkspace.CurrentSolution.GetProject(_projectId); if (workspaceProject != null) { _codeModelCache = new CodeModelProjectCache(_threadingContext, _projectId, _codeModelInstanceFactory, _projectCodeModelFactory, _serviceProvider, workspaceProject.Services, _visualStudioWorkspace); } } return _codeModelCache; } } internal IEnumerable<ComHandle<EnvDTE80.FileCodeModel2, FileCodeModel>> GetCachedFileCodeModelInstances() => GetCodeModelCache().GetFileCodeModelInstances(); internal bool TryGetCachedFileCodeModel(string fileName, out ComHandle<EnvDTE80.FileCodeModel2, FileCodeModel> fileCodeModelHandle) { var handle = GetCodeModelCache()?.GetComHandleForFileCodeModel(fileName); fileCodeModelHandle = handle != null ? handle.Value : default; return handle != null; } /// <summary> /// Gets or creates a <see cref="FileCodeModel"/> for the given file name. Because we don't have /// a parent object, this will call back to the project system to provide us the parent object. /// </summary> public ComHandle<EnvDTE80.FileCodeModel2, FileCodeModel> GetOrCreateFileCodeModel(string filePath) => GetCodeModelCache().GetOrCreateFileCodeModel(filePath); public ComHandle<EnvDTE80.FileCodeModel2, FileCodeModel> GetOrCreateFileCodeModel(string filePath, object parent) => GetCodeModelCache().GetOrCreateFileCodeModel(filePath, parent); public EnvDTE.CodeModel GetOrCreateRootCodeModel(EnvDTE.Project parent) => GetCodeModelCache().GetOrCreateRootCodeModel(parent); public void OnSourceFileRemoved(string fileName) { // This uses the field directly. If we haven't yet created the CodeModelProjectCache, then we most definitely // don't have any source files we need to zombie when they go away. There's no reason to create a cache in that case. _codeModelCache?.OnSourceFileRemoved(fileName); } public void OnSourceFileRenaming(string filePath, string newFilePath) { // This uses the field directly. If we haven't yet created the CodeModelProjectCache, then we most definitely // don't have any source files we need to handle a rename for. There's no reason to create a cache in that case. _codeModelCache?.OnSourceFileRenaming(filePath, newFilePath); } EnvDTE.FileCodeModel IProjectCodeModel.GetOrCreateFileCodeModel(string filePath, object parent) => this.GetOrCreateFileCodeModel(filePath, parent).Handle; public EnvDTE.FileCodeModel CreateFileCodeModel(SourceGeneratedDocument sourceGeneratedDocument) { // Unlike for "regular" documents, we make no effort to cache these between callers or hold them for longer lifetimes with // events. return FileCodeModel.Create(GetCodeModelCache().State, parent: null, sourceGeneratedDocument.Id, isSourceGeneratorOutput: true, new TextManagerAdapter()).Handle; } }