diff --git a/src/EditorFeatures/CSharp/DecompiledSource/CSharpDecompiledSourceService.cs b/src/EditorFeatures/CSharp/DecompiledSource/CSharpDecompiledSourceService.cs index f869fd78de105..cfdb436eefda5 100644 --- a/src/EditorFeatures/CSharp/DecompiledSource/CSharpDecompiledSourceService.cs +++ b/src/EditorFeatures/CSharp/DecompiledSource/CSharpDecompiledSourceService.cs @@ -41,14 +41,19 @@ public CSharpDecompiledSourceService() { } - public async Task AddSourceToAsync(Document document, Compilation symbolCompilation, ISymbol symbol, MetadataReference metadataReference, string assemblyLocation, SyntaxFormattingOptions formattingOptions, CancellationToken cancellationToken) + public async Task AddSourceToAsync(Document document, Compilation symbolCompilation, ISymbol symbol, MetadataReference? metadataReference, string? assemblyLocation, SyntaxFormattingOptions formattingOptions, CancellationToken cancellationToken) { // Get the name of the type the symbol is in var containingOrThis = symbol.GetContainingTypeOrThis(); var fullName = GetFullReflectionName(containingOrThis); // Decompile - document = PerformDecompilation(document, fullName, symbolCompilation, metadataReference, assemblyLocation); + var decompiledDocument = PerformDecompilation(document, fullName, symbolCompilation, metadataReference, assemblyLocation); + + if (decompiledDocument is null) + return null; + + document = decompiledDocument; document = await AddAssemblyInfoRegionAsync(document, symbol, cancellationToken).ConfigureAwait(false); @@ -74,7 +79,7 @@ public static async Task FormatDocumentAsync(Document document, Syntax return formattedDoc; } - private static Document PerformDecompilation(Document document, string fullName, Compilation compilation, MetadataReference? metadataReference, string assemblyLocation) + private static Document? PerformDecompilation(Document document, string fullName, Compilation compilation, MetadataReference? metadataReference, string? assemblyLocation) { var logger = new StringBuilder(); var resolver = new AssemblyResolver(compilation, logger); @@ -84,12 +89,11 @@ private static Document PerformDecompilation(Document document, string fullName, if (metadataReference is not null) file = resolver.TryResolve(metadataReference, PEStreamOptions.PrefetchEntireImage); - if (file is null && assemblyLocation is null) - { - throw new NotSupportedException(FeaturesResources.Cannot_navigate_to_the_symbol_under_the_caret); - } + if (file is null && assemblyLocation is not null) + file = new PEFile(assemblyLocation, PEStreamOptions.PrefetchEntireImage); - file ??= new PEFile(assemblyLocation, PEStreamOptions.PrefetchEntireImage); + if (file is null) + return null; // Initialize a decompiler with default settings. var decompiler = new CSharpDecompiler(file, resolver, new DecompilerSettings()); diff --git a/src/Features/Core/Portable/DecompiledSource/IDecompiledSourceService.cs b/src/Features/Core/Portable/DecompiledSource/IDecompiledSourceService.cs index c5c79c91c484a..f93bf43260d7f 100644 --- a/src/Features/Core/Portable/DecompiledSource/IDecompiledSourceService.cs +++ b/src/Features/Core/Portable/DecompiledSource/IDecompiledSourceService.cs @@ -2,8 +2,6 @@ // 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.Threading; using System.Threading.Tasks; using Microsoft.CodeAnalysis.Formatting; @@ -24,7 +22,7 @@ internal interface IDecompiledSourceService : ILanguageService /// The reference that contains the symbol /// The location of the implementation assembly to decompile /// To cancel document operations - /// The updated document - Task AddSourceToAsync(Document document, Compilation symbolCompilation, ISymbol symbol, MetadataReference metadataReference, string assemblyLocation, SyntaxFormattingOptions formattingOptions, CancellationToken cancellationToken); + /// The updated document, or null if the decompilation could not be performed + Task AddSourceToAsync(Document document, Compilation symbolCompilation, ISymbol symbol, MetadataReference? metadataReference, string? assemblyLocation, SyntaxFormattingOptions formattingOptions, CancellationToken cancellationToken); } } diff --git a/src/Features/Core/Portable/MetadataAsSource/DecompilationMetadataAsSourceFileProvider.cs b/src/Features/Core/Portable/MetadataAsSource/DecompilationMetadataAsSourceFileProvider.cs index abafe25befaea..cd9cc69fd9f60 100644 --- a/src/Features/Core/Portable/MetadataAsSource/DecompilationMetadataAsSourceFileProvider.cs +++ b/src/Features/Core/Portable/MetadataAsSource/DecompilationMetadataAsSourceFileProvider.cs @@ -92,7 +92,15 @@ public DecompilationMetadataAsSourceFileProvider(IImplementationAssemblyLookupSe if (decompiledSourceService != null) { - temporaryDocument = await decompiledSourceService.AddSourceToAsync(temporaryDocument, compilation, symbol, refInfo.metadataReference, refInfo.assemblyLocation, options.GenerationOptions.CleanupOptions.FormattingOptions, cancellationToken).ConfigureAwait(false); + var decompilationDocument = await decompiledSourceService.AddSourceToAsync(temporaryDocument, compilation, symbol, refInfo.metadataReference, refInfo.assemblyLocation, options.GenerationOptions.CleanupOptions.FormattingOptions, cancellationToken).ConfigureAwait(false); + if (decompilationDocument is not null) + { + temporaryDocument = decompilationDocument; + } + else + { + useDecompiler = false; + } } else {