/
githubmirror
/
roslyn
Обзор
Документация
Войти
/
githubmirror
/
roslyn
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/VisualStudio/Core/Impl/RoslynVisualStudioWorkspace.cs
192 строки
8 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. using System; using System.Collections.Generic; using System.ComponentModel.Composition; using System.Linq; using System.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.Editor.Host; using Microsoft.CodeAnalysis.Editor.Shared.Utilities; using Microsoft.CodeAnalysis.Editor.Undo; using Microsoft.CodeAnalysis.FindSymbols; using Microsoft.CodeAnalysis.GoToDefinition; using Microsoft.CodeAnalysis.Host.Mef; using Microsoft.CodeAnalysis.Shared.Extensions; using Microsoft.VisualStudio.Composition; using Microsoft.VisualStudio.LanguageServices.Implementation.CodeModel; using Microsoft.VisualStudio.LanguageServices.Implementation.Interop; using Microsoft.VisualStudio.LanguageServices.Implementation.Library.ObjectBrowser.Lists; using Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem; using Microsoft.VisualStudio.Shell; using Roslyn.Utilities; using IAsyncServiceProvider = Microsoft.VisualStudio.Shell.IAsyncServiceProvider; namespace Microsoft.VisualStudio.LanguageServices; [Export(typeof(VisualStudioWorkspace))] [Export(typeof(VisualStudioWorkspaceImpl))] internal sealed class RoslynVisualStudioWorkspace : VisualStudioWorkspaceImpl { private readonly IThreadingContext _threadingContext; /// <remarks> /// Must be lazily constructed since the <see cref="IStreamingFindUsagesPresenter"/> implementation imports a /// backreference to <see cref="VisualStudioWorkspace"/>. /// </remarks> private readonly Lazy<IStreamingFindUsagesPresenter> _streamingPresenter; [ImportingConstructor] [Obsolete(MefConstruction.ImportingConstructorMessage, error: true)] public RoslynVisualStudioWorkspace( ExportProvider exportProvider, IThreadingContext threadingContext, Lazy<IStreamingFindUsagesPresenter> streamingPresenter, [Import(typeof(SVsServiceProvider))] IAsyncServiceProvider asyncServiceProvider) : base(exportProvider, asyncServiceProvider) { _threadingContext = threadingContext; _streamingPresenter = streamingPresenter; } internal override IInvisibleEditor OpenInvisibleEditor(DocumentId documentId) { var globalUndoService = this.Services.GetRequiredService<IGlobalUndoService>(); var needsUndoDisabled = false; var textDocument = this.CurrentSolution.GetTextDocument(documentId); if (textDocument == null) { throw new InvalidOperationException(string.Format(WorkspacesResources._0_is_not_part_of_the_workspace, documentId)); } // Do not save the file if is open and there is not a global undo transaction. var needsSave = globalUndoService.IsGlobalTransactionOpen(this) || !this.IsDocumentOpen(documentId); if (needsSave) { if (textDocument is Document document) { // Disable undo on generated documents needsUndoDisabled = document.IsGeneratedCode(CancellationToken.None); } else { // Enable undo on "additional documents" or if no document can be found. needsUndoDisabled = false; } } // Documents in the VisualStudioWorkspace always have file paths since that's how we get files given // to us from the project system. Contract.ThrowIfNull(textDocument.FilePath); return new InvisibleEditor(ServiceProvider.GlobalProvider, textDocument.FilePath, GetHierarchy(documentId.ProjectId), needsSave, needsUndoDisabled); } [Obsolete("Use TryGoToDefinitionAsync instead", error: true)] public override bool TryGoToDefinition(ISymbol symbol, Project project, CancellationToken cancellationToken) => _threadingContext.JoinableTaskFactory.Run(() => TryGoToDefinitionAsync(symbol, project, cancellationToken)); public override async Task<bool> TryGoToDefinitionAsync( ISymbol symbol, Project project, CancellationToken cancellationToken) { var currentProject = project.Solution.Workspace.CurrentSolution.GetProject(project.Id); if (currentProject == null) return false; var symbolId = SymbolKey.Create(symbol, cancellationToken); var currentCompilation = await currentProject.GetRequiredCompilationAsync(cancellationToken).ConfigureAwait(false); var symbolInfo = symbolId.Resolve(currentCompilation, cancellationToken: cancellationToken); if (symbolInfo.Symbol == null) return false; return await GoToDefinitionHelpers.TryNavigateToLocationAsync( symbolInfo.Symbol, currentProject.Solution, _threadingContext, _streamingPresenter.Value, cancellationToken).ConfigureAwait(false); } public override bool TryFindAllReferences(ISymbol symbol, Project project, CancellationToken cancellationToken) { // Legacy API. Previously used by ObjectBrowser to support 'FindRefs' off of an // object browser item. Now ObjectBrowser goes through the streaming-FindRefs system. return false; } public override void DisplayReferencedSymbols(Solution solution, IEnumerable<ReferencedSymbol> referencedSymbols) { // Legacy API. Previously used by ObjectBrowser to support 'FindRefs' off of an // object browser item. Now ObjectBrowser goes through the streaming-FindRefs system. } internal override async Task<object?> GetBrowseObjectAsync( SymbolListItem symbolListItem, CancellationToken cancellationToken) { var compilation = await symbolListItem.GetCompilationAsync(this, cancellationToken).ConfigureAwait(true); if (compilation == null) return null; var symbol = symbolListItem.ResolveSymbol(compilation); var sourceLocation = symbol.Locations.Where(l => l.IsInSource).FirstOrDefault(); if (sourceLocation == null) { return null; } var projectId = symbolListItem.ProjectId; if (projectId == null) { return null; } var project = this.CurrentSolution.GetProject(projectId); if (project == null) { return null; } var codeModelService = project.Services.GetService<ICodeModelService>(); if (codeModelService == null) { return null; } var tree = sourceLocation.SourceTree; Contract.ThrowIfNull(tree, "We have a location that was in source, but doesn't have a SourceTree."); var document = project.GetDocument(tree); Contract.ThrowIfNull(document, "We have a symbol coming from a tree, and that tree isn't in the Project it supposedly came from."); var vsFileCodeModel = this.GetFileCodeModel(document.Id); var fileCodeModel = ComAggregate.GetManagedObject<FileCodeModel>(vsFileCodeModel); if (fileCodeModel != null) { var syntaxNode = tree.GetRoot(cancellationToken).FindNode(sourceLocation.SourceSpan); while (syntaxNode != null) { if (!codeModelService.TryGetNodeKey(syntaxNode).IsEmpty) { break; } syntaxNode = syntaxNode.Parent; } if (syntaxNode != null) { var codeElement = fileCodeModel.GetOrCreateCodeElement<EnvDTE.CodeElement>(syntaxNode); if (codeElement != null) { return codeElement; } } } return null; } }