diff --git a/src/EditorFeatures/CSharp/DecompiledSource/CSharpDecompiledSourceService.cs b/src/EditorFeatures/CSharp/DecompiledSource/CSharpDecompiledSourceService.cs index bb558bf25cc49bbd804581b46d129011db89d97b..99edc1e8f024f030d490381bad42697f6f577c0f 100644 --- a/src/EditorFeatures/CSharp/DecompiledSource/CSharpDecompiledSourceService.cs +++ b/src/EditorFeatures/CSharp/DecompiledSource/CSharpDecompiledSourceService.cs @@ -38,14 +38,12 @@ public CSharpDecompiledSourceService(HostLanguageServices provider) this.provider = provider; } - public async Task AddSourceToAsync(Document document, ISymbol symbol, CancellationToken cancellationToken) + public async Task AddSourceToAsync(Document document, Compilation symbolCompilation, ISymbol symbol, CancellationToken cancellationToken) { // Get the name of the type the symbol is in var containingOrThis = symbol.GetContainingTypeOrThis(); var fullName = GetFullReflectionName(containingOrThis); - var compilation = await document.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); - string assemblyLocation = null; var isReferenceAssembly = symbol.ContainingAssembly.GetAttributes().Any(attribute => attribute.AttributeClass.Name == nameof(ReferenceAssemblyAttribute) && attribute.AttributeClass.ToNameDisplayString() == typeof(ReferenceAssemblyAttribute).FullName); @@ -63,7 +61,7 @@ public async Task AddSourceToAsync(Document document, ISymbol symbol, if (assemblyLocation == null) { - var reference = compilation.GetMetadataReference(symbol.ContainingAssembly); + var reference = symbolCompilation.GetMetadataReference(symbol.ContainingAssembly); assemblyLocation = (reference as PortableExecutableReference)?.FilePath; if (assemblyLocation == null) { @@ -72,7 +70,7 @@ public async Task AddSourceToAsync(Document document, ISymbol symbol, } // Decompile - document = PerformDecompilation(document, fullName, compilation, assemblyLocation); + document = PerformDecompilation(document, fullName, symbolCompilation, assemblyLocation); document = await AddAssemblyInfoRegionAsync(document, symbol, cancellationToken).ConfigureAwait(false); diff --git a/src/EditorFeatures/Core/IDecompiledSourceService.cs b/src/EditorFeatures/Core/IDecompiledSourceService.cs index 838478c28991007a7a9633de08111764a5cbd8c9..b02be411752894ffcc08062c127152a38654231f 100644 --- a/src/EditorFeatures/Core/IDecompiledSourceService.cs +++ b/src/EditorFeatures/Core/IDecompiledSourceService.cs @@ -14,9 +14,10 @@ internal interface IDecompiledSourceService : ILanguageService /// into the given document /// /// The document to generate source into + /// The in which symbol is resolved. /// The symbol to generate source for /// To cancel document operations /// The updated document - Task AddSourceToAsync(Document document, ISymbol symbol, CancellationToken cancellationToken); + Task AddSourceToAsync(Document document, Compilation symbolCompilation, ISymbol symbol, CancellationToken cancellationToken); } } diff --git a/src/EditorFeatures/Core/Implementation/MetadataAsSource/MetadataAsSourceFileService.cs b/src/EditorFeatures/Core/Implementation/MetadataAsSource/MetadataAsSourceFileService.cs index 474a1ec9937bd218109c2b316276ca337fccafb8..9de83e2a1a607e15300ce87aa0c9076d0d44e0f9 100644 --- a/src/EditorFeatures/Core/Implementation/MetadataAsSource/MetadataAsSourceFileService.cs +++ b/src/EditorFeatures/Core/Implementation/MetadataAsSource/MetadataAsSourceFileService.cs @@ -91,6 +91,7 @@ public async Task GetGeneratedFileAsync(Project project, I Location navigateLocation = null; var topLevelNamedType = MetadataAsSourceHelpers.GetTopLevelContainingNamedType(symbol); var symbolId = SymbolKey.Create(symbol, cancellationToken); + var compilation = await project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); using (await _gate.DisposableWaitAsync(cancellationToken).ConfigureAwait(false)) { @@ -123,7 +124,7 @@ public async Task GetGeneratedFileAsync(Project project, I var decompiledSourceService = temporaryDocument.GetLanguageService(); if (decompiledSourceService != null) { - temporaryDocument = await decompiledSourceService.AddSourceToAsync(temporaryDocument, symbol, cancellationToken).ConfigureAwait(false); + temporaryDocument = await decompiledSourceService.AddSourceToAsync(temporaryDocument, compilation, symbol, cancellationToken).ConfigureAwait(false); } else { @@ -139,7 +140,7 @@ public async Task GetGeneratedFileAsync(Project project, I if (!useDecompiler) { var sourceFromMetadataService = temporaryDocument.Project.LanguageServices.GetService(); - temporaryDocument = await sourceFromMetadataService.AddSourceToAsync(temporaryDocument, symbol, cancellationToken).ConfigureAwait(false); + temporaryDocument = await sourceFromMetadataService.AddSourceToAsync(temporaryDocument, compilation, symbol, cancellationToken).ConfigureAwait(false); } // We have the content, so write it out to disk diff --git a/src/Features/CSharp/Portable/MetadataAsSource/CSharpMetadataAsSourceService.cs b/src/Features/CSharp/Portable/MetadataAsSource/CSharpMetadataAsSourceService.cs index b12f4f35706362341ada5bbc9810390a051358bb..6439e459ebcdb0ba0eddd09429810450c124dee3 100644 --- a/src/Features/CSharp/Portable/MetadataAsSource/CSharpMetadataAsSourceService.cs +++ b/src/Features/CSharp/Portable/MetadataAsSource/CSharpMetadataAsSourceService.cs @@ -31,11 +31,10 @@ public CSharpMetadataAsSourceService(HostLanguageServices languageServices) { } - protected override async Task AddAssemblyInfoRegionAsync(Document document, ISymbol symbol, CancellationToken cancellationToken) + protected override async Task AddAssemblyInfoRegionAsync(Document document, Compilation symbolCompilation, ISymbol symbol, CancellationToken cancellationToken) { string assemblyInfo = MetadataAsSourceHelpers.GetAssemblyInfo(symbol.ContainingAssembly); - var compilation = await document.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false); - string assemblyPath = MetadataAsSourceHelpers.GetAssemblyDisplay(compilation, symbol.ContainingAssembly); + string assemblyPath = MetadataAsSourceHelpers.GetAssemblyDisplay(symbolCompilation, symbol.ContainingAssembly); var regionTrivia = SyntaxFactory.RegionDirectiveTrivia(true) .WithTrailingTrivia(new[] { SyntaxFactory.Space, SyntaxFactory.PreprocessingMessage(assemblyInfo) }); diff --git a/src/Features/Core/Portable/MetadataAsSource/AbstractMetadataAsSourceService.cs b/src/Features/Core/Portable/MetadataAsSource/AbstractMetadataAsSourceService.cs index 5f9a107bf27f74502670a569524a0bbf6f92afd1..d8679e4789fe7c56aee231e84b284226b60c294e 100644 --- a/src/Features/Core/Portable/MetadataAsSource/AbstractMetadataAsSourceService.cs +++ b/src/Features/Core/Portable/MetadataAsSource/AbstractMetadataAsSourceService.cs @@ -26,7 +26,7 @@ protected AbstractMetadataAsSourceService(ICodeGenerationService codeGenerationS _codeGenerationService = codeGenerationService; } - public async Task AddSourceToAsync(Document document, ISymbol symbol, CancellationToken cancellationToken) + public async Task AddSourceToAsync(Document document, Compilation symbolCompilation, ISymbol symbol, CancellationToken cancellationToken) { if (document == null) { @@ -47,7 +47,7 @@ public async Task AddSourceToAsync(Document document, ISymbol symbol, var docCommentFormattingService = document.GetLanguageService(); var docWithDocComments = await ConvertDocCommentsToRegularComments(document, docCommentFormattingService, cancellationToken).ConfigureAwait(false); - var docWithAssemblyInfo = await AddAssemblyInfoRegionAsync(docWithDocComments, symbol.GetOriginalUnreducedDefinition(), cancellationToken).ConfigureAwait(false); + var docWithAssemblyInfo = await AddAssemblyInfoRegionAsync(docWithDocComments, symbolCompilation, symbol.GetOriginalUnreducedDefinition(), cancellationToken).ConfigureAwait(false); var node = await docWithAssemblyInfo.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var formattedDoc = await Formatter.FormatAsync( docWithAssemblyInfo, SpecializedCollections.SingletonEnumerable(node.FullSpan), options: null, rules: GetFormattingRules(docWithAssemblyInfo), cancellationToken: cancellationToken).ConfigureAwait(false); @@ -68,7 +68,12 @@ public async Task AddSourceToAsync(Document document, ISymbol symbol, /// a string similar to "location unknown" will be placed in the comment inside the region /// instead of the path. /// - protected abstract Task AddAssemblyInfoRegionAsync(Document document, ISymbol symbol, CancellationToken cancellationToken); + /// The document to generate source into + /// The in which symbol is resolved. + /// The symbol to generate source for + /// To cancel document operations + /// The updated document + protected abstract Task AddAssemblyInfoRegionAsync(Document document, Compilation symbolCompilation, ISymbol symbol, CancellationToken cancellationToken); protected abstract Task ConvertDocCommentsToRegularComments(Document document, IDocumentationCommentFormattingService docCommentFormattingService, CancellationToken cancellationToken); diff --git a/src/Features/Core/Portable/MetadataAsSource/IMetadataAsSourceService.cs b/src/Features/Core/Portable/MetadataAsSource/IMetadataAsSourceService.cs index 53d9e47301f9c215ec07f62665a9dba6cb553ad2..015705e1766d9bb0d6ad5e1495a3a0f1c3647010 100644 --- a/src/Features/Core/Portable/MetadataAsSource/IMetadataAsSourceService.cs +++ b/src/Features/Core/Portable/MetadataAsSource/IMetadataAsSourceService.cs @@ -14,9 +14,10 @@ internal interface IMetadataAsSourceService : ILanguageService /// which the given ISymbol is or is a part of into the given document /// /// The document to generate source into - /// The symbol whose interface to generate source for + /// The in which is resolved. + /// The symbol to generate source for /// To cancel document operations /// The updated document - Task AddSourceToAsync(Document document, ISymbol symbol, CancellationToken cancellationToken = default); + Task AddSourceToAsync(Document document, Compilation symbolCompilation, ISymbol symbol, CancellationToken cancellationToken = default); } } diff --git a/src/Features/Core/Portable/MetadataAsSource/MetadataAsSourceHelpers.cs b/src/Features/Core/Portable/MetadataAsSource/MetadataAsSourceHelpers.cs index 4e83f70967b3db9fd76898d4c36d840e57f65ebc..bc3c701611530dd50882a61bc860be587484e9c8 100644 --- a/src/Features/Core/Portable/MetadataAsSource/MetadataAsSourceHelpers.cs +++ b/src/Features/Core/Portable/MetadataAsSource/MetadataAsSourceHelpers.cs @@ -51,17 +51,7 @@ public static string GetAssemblyDisplay(Compilation compilation, IAssemblySymbol // This method is only used to generate a comment at the top of Metadata-as-Source documents and // previous submissions are never viewed as metadata (i.e. we always have compilations) so there's no // need to consume compilation.ScriptCompilationInfo.PreviousScriptCompilation. - - // TODO (https://github.com/dotnet/roslyn/issues/6859): compilation.GetMetadataReference(assemblySymbol)? - var assemblyReference = compilation.References.Where(r => - { - var referencedSymbol = compilation.GetAssemblyOrModuleSymbol(r) as IAssemblySymbol; - return - referencedSymbol != null && - referencedSymbol.MetadataName == assemblySymbol.MetadataName; - }) - .FirstOrDefault(); - + var assemblyReference = compilation.GetMetadataReference(assemblySymbol); return assemblyReference?.Display ?? FeaturesResources.location_unknown; } diff --git a/src/Features/VisualBasic/Portable/MetadataAsSource/VisualBasicMetadataAsSourceService.vb b/src/Features/VisualBasic/Portable/MetadataAsSource/VisualBasicMetadataAsSourceService.vb index c1aa84dc3aa447b8f7190222657bc908f23c6d0d..16d43063c3784234234f9b4055816cc8fb25a46e 100644 --- a/src/Features/VisualBasic/Portable/MetadataAsSource/VisualBasicMetadataAsSourceService.vb +++ b/src/Features/VisualBasic/Portable/MetadataAsSource/VisualBasicMetadataAsSourceService.vb @@ -11,7 +11,6 @@ Imports Microsoft.CodeAnalysis.MetadataAsSource Imports Microsoft.CodeAnalysis.Options Imports Microsoft.CodeAnalysis.Simplification Imports Microsoft.CodeAnalysis.VisualBasic -Imports Microsoft.CodeAnalysis.VisualBasic.DocumentationComments Imports Microsoft.CodeAnalysis.VisualBasic.Simplification Imports Microsoft.CodeAnalysis.VisualBasic.Syntax @@ -25,10 +24,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.MetadataAsSource MyBase.New(languageServices.GetService(Of ICodeGenerationService)()) End Sub - Protected Overrides Async Function AddAssemblyInfoRegionAsync(document As Document, symbol As ISymbol, cancellationToken As CancellationToken) As Task(Of Document) + Protected Overrides Async Function AddAssemblyInfoRegionAsync(document As Document, symbolCompilation As Compilation, symbol As ISymbol, cancellationToken As CancellationToken) As Task(Of Document) Dim assemblyInfo = MetadataAsSourceHelpers.GetAssemblyInfo(symbol.ContainingAssembly) - Dim compilation = Await document.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(False) - Dim assemblyPath = MetadataAsSourceHelpers.GetAssemblyDisplay(compilation, symbol.ContainingAssembly) + Dim assemblyPath = MetadataAsSourceHelpers.GetAssemblyDisplay(symbolCompilation, symbol.ContainingAssembly) Dim regionTrivia = SyntaxFactory.RegionDirectiveTrivia( SyntaxFactory.Token(SyntaxKind.HashToken),