using System.Text; using Microsoft.CodeAnalysis.CSharp.Syntax; using ProxyInterfaceSourceGenerator.Enums; using ProxyInterfaceSourceGenerator.Extensions; using ProxyInterfaceSourceGenerator.Model; using ProxyInterfaceSourceGenerator.SyntaxReceiver; using ProxyInterfaceSourceGenerator.Utils; namespace ProxyInterfaceSourceGenerator.FileGenerators; internal class PartialInterfacesGenerator : BaseGenerator, IFilesGenerator { public PartialInterfacesGenerator(Context context, bool supportsNullable) : base(context, supportsNullable) { } public IEnumerable GenerateFiles() { foreach (var ci in Context.CandidateInterfaces) { yield return GenerateFile(ci.Key, ci.Value); } } private FileData GenerateFile(InterfaceDeclarationSyntax ci, ProxyData pd) { var sourceInterfaceSymbol = GetNamedTypeSymbolByFullName(ci.Identifier.ToString(), pd.Usings); var targetClassSymbol = GetNamedTypeSymbolByFullName(pd.TypeName, pd.Usings); var interfaceName = targetClassSymbol.Symbol.ResolveInterfaceNameWithOptionalTypeConstraints(pd.InterfaceName); var file = new FileData( $"{sourceInterfaceSymbol.Symbol.GetFileName()}.g.cs", CreatePartialInterfaceCode(pd.Namespace, targetClassSymbol, interfaceName, pd.ProxyBaseClasses) ); return file; } private string CreatePartialInterfaceCode( string ns, ClassSymbol classSymbol, string interfaceName, bool proxyBaseClasses) => $@"//---------------------------------------------------------------------------------------- // // This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator. // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // //---------------------------------------------------------------------------------------- {(SupportsNullable ? "#nullable enable" : string.Empty)} using System; namespace {ns} {{ public partial interface {interfaceName} {{ {GenerateProperties(classSymbol, proxyBaseClasses)} {GenerateMethods(classSymbol, proxyBaseClasses)} {GenerateEvents(classSymbol, proxyBaseClasses)} }} }} {(SupportsNullable ? "#nullable disable" : string.Empty)}"; private string GenerateProperties(ClassSymbol targetClassSymbol, bool proxyBaseClasses) { var str = new StringBuilder(); foreach (var property in MemberHelper.GetPublicProperties(targetClassSymbol, proxyBaseClasses)) { var type = GetPropertyType(property, out var isReplaced); if (isReplaced) { str.AppendLine($" {property.ToPropertyText(type)}"); } else { str.AppendLine($" {property.ToPropertyText()}"); } str.AppendLine(); } return str.ToString(); } private string GenerateMethods(ClassSymbol targetClassSymbol, bool proxyBaseClasses) { var str = new StringBuilder(); foreach (var method in MemberHelper.GetPublicMethods(targetClassSymbol, proxyBaseClasses)) { var methodParameters = new List(); foreach (var ps in method.Parameters) { var type = ps.GetTypeEnum() == TypeEnum.Complex ? GetParameterType(ps, out _) : ps.Type.ToString(); methodParameters.Add($"{ps.GetParamsPrefix()}{ps.GetRefPrefix()}{type} {ps.GetSanitizedName()}{ps.GetDefaultValue()}"); } str.AppendLine($" {GetReplacedType(method.ReturnType, out _)} {method.GetMethodNameWithOptionalTypeParameters()}({string.Join(", ", methodParameters)}){method.GetWhereStatement()};"); str.AppendLine(); } return str.ToString(); } private string GenerateEvents(ClassSymbol targetClassSymbol, bool proxyBaseClasses) { var str = new StringBuilder(); foreach (var @event in MemberHelper.GetPublicEvents(targetClassSymbol, proxyBaseClasses)) { var ps = @event.First().Parameters.First(); var type = ps.GetTypeEnum() == TypeEnum.Complex ? GetParameterType(ps, out _) : ps.Type.ToString(); str.AppendLine($" event {type} {@event.Key.GetSanitizedName()};"); str.AppendLine(); } return str.ToString(); } }