public async Task <Document> AddSourceToAsync(Document document, Compilation symbolCompilation, Microsoft.CodeAnalysis.ISymbol symbol, CancellationToken cancellationToken) { // Get the name of the type the symbol is in var containingOrThis = symbol.GetContainingTypeOrThis(); var fullName = GetFullReflectionName(containingOrThis); var reference = symbolCompilation.GetMetadataReference(symbol.ContainingAssembly); var assemblyLocation = (reference as PortableExecutableReference)?.FilePath; if (assemblyLocation == null) { throw new NotSupportedException("Cannot_navigate_to_the_symbol_under_the_caret"); } // Decompile document = PerformDecompilation(document, fullName, symbolCompilation, assemblyLocation); document = await AddAssemblyInfoRegionAsync(document, symbol, cancellationToken).ConfigureAwait(false); // Convert XML doc comments to regular comments, just like MAS document = await ConvertDocCommentsToRegularCommentsAsync(document, cancellationToken).ConfigureAwait(false); var node = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); // Apply formatting rules document = await Formatter.FormatAsync( document, new[] { node.FullSpan }, options : null, cancellationToken).ConfigureAwait(false); return(document); }
public async Task <Document> AddSourceToAsync(Document document, Compilation symbolCompilation, Microsoft.CodeAnalysis.ISymbol symbol, CancellationToken cancellationToken) { // Get the name of the type the symbol is in var containingOrThis = symbol.GetContainingTypeOrThis(); var fullName = GetFullReflectionName(containingOrThis); string assemblyLocation = null; var isReferenceAssembly = symbol.ContainingAssembly.GetAttributes().Any(attribute => attribute.AttributeClass.Name == nameof(ReferenceAssemblyAttribute) && attribute.AttributeClass.ToNameDisplayString() == typeof(ReferenceAssemblyAttribute).FullName); if (isReferenceAssembly) { try { var fullAssemblyName = symbol.ContainingAssembly.Identity.GetDisplayName(); var globalAssemblyCacheType = typeof(ScriptOptions).Assembly.GetType("Microsoft.CodeAnalysis.GlobalAssemblyCache"); var instance = globalAssemblyCacheType.GetField("Instance", BindingFlags.NonPublic | BindingFlags.Static).GetValue(null); var args = new object[] { fullAssemblyName, assemblyLocation, null, CultureInfo.CurrentCulture }; instance.GetType().InvokeMember("ResolvePartialName", BindingFlags.InvokeMethod, Type.DefaultBinder, instance, args); assemblyLocation = (string)args[1]; } catch (Exception) { // log } } if (assemblyLocation == null) { var reference = symbolCompilation.GetMetadataReference(symbol.ContainingAssembly); assemblyLocation = (reference as PortableExecutableReference)?.FilePath; if (assemblyLocation == null) { throw new NotSupportedException("Cannot_navigate_to_the_symbol_under_the_caret"); } } // Decompile document = PerformDecompilation(document, fullName, symbolCompilation, assemblyLocation); document = await AddAssemblyInfoRegionAsync(document, symbol, cancellationToken).ConfigureAwait(false); // Convert XML doc comments to regular comments, just like MAS var docCommentFormattingService = _csharpDocumentationCommentFormattingService.CreateInstance(); document = await ConvertDocCommentsToRegularCommentsAsync(document, docCommentFormattingService, cancellationToken).ConfigureAwait(false); var node = await document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); // Apply formatting rules document = await Formatter.FormatAsync( document, new[] { node.FullSpan }, options : null, cancellationToken).ConfigureAwait(false); return(document); }