|
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
#if !NET
using System.Text.RegularExpressions;
#endif
using Microsoft.CodeAnalysis;
using Microsoft.DotNet.ApiSymbolExtensions;
using Microsoft.DotNet.ApiSymbolExtensions.Filtering;
using Microsoft.DotNet.ApiSymbolExtensions.Logging;
using Microsoft.DotNet.GenAPI.SyntaxRewriter;
namespace Microsoft.DotNet.GenAPI
{
/// <summary>
/// Processes assembly symbols to build corresponding structures in C# language.
/// </summary>
public sealed class CSharpFileBuilder : IAssemblySymbolWriter
{
private readonly TextWriter _textWriter;
private readonly string? _header;
private readonly CSharpAssemblyDocumentGenerator _docGenerator;
public const string DefaultFileHeader = """
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
""";
public CSharpFileBuilder(ILog log,
TextWriter textWriter,
IAssemblySymbolLoader loader,
ISymbolFilter symbolFilter,
ISymbolFilter attributeDataSymbolFilter,
string? header,
string? exceptionMessage,
bool includeAssemblyAttributes,
IEnumerable<MetadataReference>? metadataReferences = null,
bool addPartialModifier = true)
{
_textWriter = textWriter;
_header = header;
CSharpAssemblyDocumentGeneratorOptions options = new(loader, symbolFilter, attributeDataSymbolFilter)
{
HideImplicitDefaultConstructors = true,
ShouldFormat = true,
ShouldReduce = true,
IncludeAssemblyAttributes = includeAssemblyAttributes,
MetadataReferences = metadataReferences,
SyntaxRewriters = [
new TypeDeclarationCSharpSyntaxRewriter(addPartialModifier),
new BodyBlockCSharpSyntaxRewriter(exceptionMessage),
SingleLineStatementCSharpSyntaxRewriter.Singleton
]
};
_docGenerator = new CSharpAssemblyDocumentGenerator(log, options);
}
/// <inheritdoc />
public void WriteAssembly(IAssemblySymbol assemblySymbol)
{
_textWriter.Write(GetFormattedHeader(_header));
Document document = _docGenerator.GetDocumentForAssemblyAsync(assemblySymbol).Result;
SyntaxNode root = document.GetSyntaxRootAsync().Result ?? throw new InvalidOperationException(Resources.SyntaxNodeNotFound);
root.WriteTo(_textWriter);
}
private static string GetFormattedHeader(string? customHeader)
{
if (customHeader != null)
{
#if NET
return customHeader.ReplaceLineEndings();
#else
return Regex.Replace(customHeader, @"\r\n|\n\r|\n|\r", Environment.NewLine);
#endif
}
return DefaultFileHeader;
}
}
}
|