未验证 提交 45aa7a2d 编写于 作者: S Sam Harwell 提交者: GitHub

Merge pull request #33183 from sharwell/fix-decompile

Resolve Metadata As Source symbols in their original compilations
......@@ -38,14 +38,12 @@ public CSharpDecompiledSourceService(HostLanguageServices provider)
this.provider = provider;
}
public async Task<Document> AddSourceToAsync(Document document, ISymbol symbol, CancellationToken cancellationToken)
public async Task<Document> 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<Document> 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<Document> 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);
......
......@@ -14,9 +14,10 @@ internal interface IDecompiledSourceService : ILanguageService
/// into the given document
/// </summary>
/// <param name="document">The document to generate source into</param>
/// <param name="symbolCompilation">The <see cref="Compilation"/> in which symbol is resolved.</param>
/// <param name="symbol">The symbol to generate source for</param>
/// <param name="cancellationToken">To cancel document operations</param>
/// <returns>The updated document</returns>
Task<Document> AddSourceToAsync(Document document, ISymbol symbol, CancellationToken cancellationToken);
Task<Document> AddSourceToAsync(Document document, Compilation symbolCompilation, ISymbol symbol, CancellationToken cancellationToken);
}
}
......@@ -91,6 +91,7 @@ public async Task<MetadataAsSourceFile> 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<MetadataAsSourceFile> GetGeneratedFileAsync(Project project, I
var decompiledSourceService = temporaryDocument.GetLanguageService<IDecompiledSourceService>();
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<MetadataAsSourceFile> GetGeneratedFileAsync(Project project, I
if (!useDecompiler)
{
var sourceFromMetadataService = temporaryDocument.Project.LanguageServices.GetService<IMetadataAsSourceService>();
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
......
......@@ -31,11 +31,10 @@ public CSharpMetadataAsSourceService(HostLanguageServices languageServices)
{
}
protected override async Task<Document> AddAssemblyInfoRegionAsync(Document document, ISymbol symbol, CancellationToken cancellationToken)
protected override async Task<Document> 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) });
......
......@@ -26,7 +26,7 @@ protected AbstractMetadataAsSourceService(ICodeGenerationService codeGenerationS
_codeGenerationService = codeGenerationService;
}
public async Task<Document> AddSourceToAsync(Document document, ISymbol symbol, CancellationToken cancellationToken)
public async Task<Document> AddSourceToAsync(Document document, Compilation symbolCompilation, ISymbol symbol, CancellationToken cancellationToken)
{
if (document == null)
{
......@@ -47,7 +47,7 @@ public async Task<Document> AddSourceToAsync(Document document, ISymbol symbol,
var docCommentFormattingService = document.GetLanguageService<IDocumentationCommentFormattingService>();
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<Document> AddSourceToAsync(Document document, ISymbol symbol,
/// a string similar to "location unknown" will be placed in the comment inside the region
/// instead of the path.
/// </summary>
protected abstract Task<Document> AddAssemblyInfoRegionAsync(Document document, ISymbol symbol, CancellationToken cancellationToken);
/// <param name="document">The document to generate source into</param>
/// <param name="symbolCompilation">The <see cref="Compilation"/> in which symbol is resolved.</param>
/// <param name="symbol">The symbol to generate source for</param>
/// <param name="cancellationToken">To cancel document operations</param>
/// <returns>The updated document</returns>
protected abstract Task<Document> AddAssemblyInfoRegionAsync(Document document, Compilation symbolCompilation, ISymbol symbol, CancellationToken cancellationToken);
protected abstract Task<Document> ConvertDocCommentsToRegularComments(Document document, IDocumentationCommentFormattingService docCommentFormattingService, CancellationToken cancellationToken);
......
......@@ -14,9 +14,10 @@ internal interface IMetadataAsSourceService : ILanguageService
/// which the given ISymbol is or is a part of into the given document
/// </summary>
/// <param name="document">The document to generate source into</param>
/// <param name="symbol">The symbol whose interface to generate source for</param>
/// <param name="symbolCompilation">The <see cref="Compilation"/> in which <paramref name="symbol"/> is resolved.</param>
/// <param name="symbol">The symbol to generate source for</param>
/// <param name="cancellationToken">To cancel document operations</param>
/// <returns>The updated document</returns>
Task<Document> AddSourceToAsync(Document document, ISymbol symbol, CancellationToken cancellationToken = default);
Task<Document> AddSourceToAsync(Document document, Compilation symbolCompilation, ISymbol symbol, CancellationToken cancellationToken = default);
}
}
......@@ -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;
}
......
......@@ -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),
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册