diff --git a/GitHubReleaseNotes.txt b/GitHubReleaseNotes.txt index 58c3354..7c55da5 100644 --- a/GitHubReleaseNotes.txt +++ b/GitHubReleaseNotes.txt @@ -1,3 +1,3 @@ https://github.com/StefH/GitHubReleaseNotes -GitHubReleaseNotes --output ReleaseNotes.md --skip-empty-releases --exclude-labels question invalid doc --version 0.0.9 \ No newline at end of file +GitHubReleaseNotes --output ReleaseNotes.md --skip-empty-releases --exclude-labels question invalid doc --version 0.0.10 \ No newline at end of file diff --git a/src-examples/ProxyInterfaceConsumerViaNuGet/ProxyInterfaceConsumerViaNuGet.csproj b/src-examples/ProxyInterfaceConsumerViaNuGet/ProxyInterfaceConsumerViaNuGet.csproj index 7e92732..793f0dd 100644 --- a/src-examples/ProxyInterfaceConsumerViaNuGet/ProxyInterfaceConsumerViaNuGet.csproj +++ b/src-examples/ProxyInterfaceConsumerViaNuGet/ProxyInterfaceConsumerViaNuGet.csproj @@ -8,7 +8,7 @@ - + \ No newline at end of file diff --git a/src/ProxyInterfaceSourceGenerator/Extensions/NamedTypeSymbolExtensions.cs b/src/ProxyInterfaceSourceGenerator/Extensions/NamedTypeSymbolExtensions.cs index 71647a6..54369b7 100644 --- a/src/ProxyInterfaceSourceGenerator/Extensions/NamedTypeSymbolExtensions.cs +++ b/src/ProxyInterfaceSourceGenerator/Extensions/NamedTypeSymbolExtensions.cs @@ -1,24 +1,30 @@ -using Microsoft.CodeAnalysis; using System.Linq; using System.Text; +using Microsoft.CodeAnalysis; namespace ProxyInterfaceSourceGenerator.Extensions { internal static class NamedTypeSymbolExtensions { - /// - /// See https://www.codeproject.com/Articles/861548/Roslyn-Code-Analysis-in-Easy-Samples-Part - /// - public static string GetFullTypeString(this INamedTypeSymbol namedTypeSymbol) + public static string GetFileName(this INamedTypeSymbol namedTypeSymbol) { - var str = new StringBuilder(namedTypeSymbol.Name); + var typeName = namedTypeSymbol.GetFullType(); + return !(typeName.Contains('<') && typeName.Contains('>')) ? + typeName : + $"{typeName.Replace('.', '_').Replace('<', '_').Replace('>', '_').Replace(", ", "-")}_{typeName.Count(c => c == ',') + 1}"; + } - if (namedTypeSymbol.TypeArguments.Count() > 0) - { - str.AppendFormat("<{0}>", string.Join(", ", namedTypeSymbol.TypeArguments.OfType().Select(typeArg => typeArg.GetFullTypeString()))); - } + public static string GetFullType(this INamedTypeSymbol namedTypeSymbol) + { + // https://www.codeproject.com/Articles/861548/Roslyn-Code-Analysis-in-Easy-Samples-Part + //var str = new StringBuilder(namedTypeSymbol.Name); - return str.ToString(); + //if (namedTypeSymbol.TypeArguments.Count() > 0) + //{ + // str.AppendFormat("<{0}>", string.Join(", ", namedTypeSymbol.TypeArguments.OfType().Select(typeArg => typeArg.GetFullType()))); + //} + + return namedTypeSymbol.OriginalDefinition.ToString();// str.ToString(); } public static string ResolveInterfaceNameWithOptionalTypeConstraints(this INamedTypeSymbol namedTypeSymbol, string interfaceName) diff --git a/src/ProxyInterfaceSourceGenerator/Extensions/TypeParameterSymbolExtensions.cs b/src/ProxyInterfaceSourceGenerator/Extensions/TypeParameterSymbolExtensions.cs index 40fde56..154f83c 100644 --- a/src/ProxyInterfaceSourceGenerator/Extensions/TypeParameterSymbolExtensions.cs +++ b/src/ProxyInterfaceSourceGenerator/Extensions/TypeParameterSymbolExtensions.cs @@ -27,7 +27,7 @@ namespace ProxyInterfaceSourceGenerator.Extensions constraints.Add("new()"); } - constraints.AddRange(typeParameterSymbol.ConstraintTypes.OfType().Select(contstraintType => contstraintType.GetFullTypeString())); + constraints.AddRange(typeParameterSymbol.ConstraintTypes.OfType().Select(contstraintType => contstraintType.GetFullType())); if (!constraints.Any()) { diff --git a/src/ProxyInterfaceSourceGenerator/FileGenerators/BaseGenerator.cs b/src/ProxyInterfaceSourceGenerator/FileGenerators/BaseGenerator.cs index b58dae3..5203738 100644 --- a/src/ProxyInterfaceSourceGenerator/FileGenerators/BaseGenerator.cs +++ b/src/ProxyInterfaceSourceGenerator/FileGenerators/BaseGenerator.cs @@ -8,10 +8,12 @@ namespace ProxyInterfaceSourceGenerator.FileGenerators internal abstract class BaseGenerator { protected readonly Context _context; + protected readonly bool _supportsNullable; - public BaseGenerator(Context context) + public BaseGenerator(Context context, bool supportsNullable) { _context = context; + _supportsNullable = supportsNullable; } protected string GetPropertyType(IPropertySymbol property, out bool isReplaced) diff --git a/src/ProxyInterfaceSourceGenerator/FileGenerators/PartialInterfacesGenerator.cs b/src/ProxyInterfaceSourceGenerator/FileGenerators/PartialInterfacesGenerator.cs index 512c19a..5479a2c 100644 --- a/src/ProxyInterfaceSourceGenerator/FileGenerators/PartialInterfacesGenerator.cs +++ b/src/ProxyInterfaceSourceGenerator/FileGenerators/PartialInterfacesGenerator.cs @@ -11,8 +11,8 @@ namespace ProxyInterfaceSourceGenerator.FileGenerators { internal class PartialInterfacesGenerator : BaseGenerator, IFilesGenerator { - public PartialInterfacesGenerator(Context context) : - base(context) + public PartialInterfacesGenerator(Context context, bool supportsNullable) : + base(context, supportsNullable) { } @@ -30,7 +30,7 @@ namespace ProxyInterfaceSourceGenerator.FileGenerators var interfaceName = targetClassSymbol.ResolveInterfaceNameWithOptionalTypeConstraints(pd.InterfaceName); var file = new FileData( - $"{pd.FileName}.g.cs", + $"{targetClassSymbol.GetFileName()}.g.cs", CreatePartialInterfaceCode(pd.Namespace, targetClassSymbol, interfaceName, pd.ProxyAll) ); @@ -48,7 +48,7 @@ namespace ProxyInterfaceSourceGenerator.FileGenerators // //---------------------------------------------------------------------------------------- -#nullable enable +{(_supportsNullable ? "#nullable enable" : string.Empty)} using System; namespace {ns} @@ -62,7 +62,7 @@ namespace {ns} {GenerateEvents(targetClassSymbol)} }} }} -#nullable disable"; +{(_supportsNullable ? "#nullable disable" : string.Empty)}"; private string GenerateProperties(INamedTypeSymbol targetClassSymbol, bool proxyAll) { diff --git a/src/ProxyInterfaceSourceGenerator/FileGenerators/ProxyClassesGenerator.cs b/src/ProxyInterfaceSourceGenerator/FileGenerators/ProxyClassesGenerator.cs index 8113240..c694c0e 100644 --- a/src/ProxyInterfaceSourceGenerator/FileGenerators/ProxyClassesGenerator.cs +++ b/src/ProxyInterfaceSourceGenerator/FileGenerators/ProxyClassesGenerator.cs @@ -12,7 +12,7 @@ namespace ProxyInterfaceSourceGenerator.FileGenerators { internal class ProxyClassesGenerator : BaseGenerator, IFilesGenerator { - public ProxyClassesGenerator(Context context) : base(context) + public ProxyClassesGenerator(Context context, bool supportsNullable) : base(context, supportsNullable) { } @@ -32,7 +32,7 @@ namespace ProxyInterfaceSourceGenerator.FileGenerators var constructorName = $"{targetClassSymbol.Name}Proxy"; var file = new FileData( - $"{pd.FileName}Proxy.g.cs", + $"{targetClassSymbol.GetFileName()}Proxy.g.cs", CreateProxyClassCode(pd.Namespace, targetClassSymbol, interfaceName, className, constructorName) ); @@ -41,7 +41,12 @@ namespace ProxyInterfaceSourceGenerator.FileGenerators return file; } - private string CreateProxyClassCode(string ns, INamedTypeSymbol targetClassSymbol, string interfaceName, string className, string constructorName) => $@"//---------------------------------------------------------------------------------------- + private string CreateProxyClassCode( + string ns, + INamedTypeSymbol targetClassSymbol, + string interfaceName, + string className, + string constructorName) => $@"//---------------------------------------------------------------------------------------- // // This code was generated by https://github.com/StefH/ProxyInterfaceSourceGenerator. // @@ -50,7 +55,7 @@ namespace ProxyInterfaceSourceGenerator.FileGenerators // //---------------------------------------------------------------------------------------- -#nullable enable +{(_supportsNullable ? "#nullable enable" : string.Empty)} using System; using AutoMapper; @@ -76,7 +81,7 @@ namespace {ns} {GeneratePrivateAutoMapper()} }} }} -#nullable disable"; +{(_supportsNullable ? "#nullable disable" : string.Empty)}"; private string GeneratePrivateAutoMapper() { return _context.ReplacedTypes.Count == 0 ? string.Empty : " private readonly IMapper _mapper;"; diff --git a/src/ProxyInterfaceSourceGenerator/ProxyInterfaceCodeGenerator.cs b/src/ProxyInterfaceSourceGenerator/ProxyInterfaceCodeGenerator.cs index 23deaf4..39b2800 100644 --- a/src/ProxyInterfaceSourceGenerator/ProxyInterfaceCodeGenerator.cs +++ b/src/ProxyInterfaceSourceGenerator/ProxyInterfaceCodeGenerator.cs @@ -1,5 +1,7 @@ +using System; using System.Text; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.Text; using ProxyInterfaceSourceGenerator.FileGenerators; using ProxyInterfaceSourceGenerator.SyntaxReceiver; @@ -23,14 +25,22 @@ namespace ProxyInterfaceSourceGenerator public void Execute(GeneratorExecutionContext context) { + if (context.ParseOptions is not CSharpParseOptions csharpParseOptions) + { + throw new NotSupportedException("Only C# is supported."); + } + if (context.SyntaxReceiver is not ProxySyntaxReceiver receiver) { return; } + // https://github.com/reactiveui/refit/blob/main/InterfaceStubGenerator.Core/InterfaceStubGenerator.cs + var supportsNullable = csharpParseOptions.LanguageVersion >= LanguageVersion.CSharp8; + GenerateProxyAttribute(context, receiver); - GeneratePartialInterfaces(context, receiver); - GenerateProxyClasses(context, receiver); + GeneratePartialInterfaces(context, receiver, supportsNullable); + GenerateProxyClasses(context, receiver, supportsNullable); } private void GenerateProxyAttribute(GeneratorExecutionContext ctx, ProxySyntaxReceiver receiver) @@ -45,7 +55,7 @@ namespace ProxyInterfaceSourceGenerator context.GeneratorExecutionContext.AddSource(attributeData.FileName, SourceText.From(attributeData.Text, Encoding.UTF8)); } - private static void GeneratePartialInterfaces(GeneratorExecutionContext ctx, ProxySyntaxReceiver receiver) + private static void GeneratePartialInterfaces(GeneratorExecutionContext ctx, ProxySyntaxReceiver receiver, bool supportsNullable) { var context = new Context { @@ -53,14 +63,14 @@ namespace ProxyInterfaceSourceGenerator CandidateInterfaces = receiver.CandidateInterfaces }; - var partialInterfacesGenerator = new PartialInterfacesGenerator(context); + var partialInterfacesGenerator = new PartialInterfacesGenerator(context, supportsNullable); foreach (var data in partialInterfacesGenerator.GenerateFiles()) { context.GeneratorExecutionContext.AddSource(data.FileName, SourceText.From(data.Text, Encoding.UTF8)); } } - private static void GenerateProxyClasses(GeneratorExecutionContext ctx, ProxySyntaxReceiver receiver) + private static void GenerateProxyClasses(GeneratorExecutionContext ctx, ProxySyntaxReceiver receiver, bool supportsNullable) { var context = new Context { @@ -68,7 +78,7 @@ namespace ProxyInterfaceSourceGenerator CandidateInterfaces = receiver.CandidateInterfaces }; - var proxyClassesGenerator = new ProxyClassesGenerator(context); + var proxyClassesGenerator = new ProxyClassesGenerator(context, supportsNullable); foreach (var data in proxyClassesGenerator.GenerateFiles()) { context.GeneratorExecutionContext.AddSource(data.FileName, SourceText.From(data.Text, Encoding.UTF8)); diff --git a/src/ProxyInterfaceSourceGenerator/ProxyInterfaceSourceGenerator.csproj b/src/ProxyInterfaceSourceGenerator/ProxyInterfaceSourceGenerator.csproj index 9056e5c..b4f32d3 100644 --- a/src/ProxyInterfaceSourceGenerator/ProxyInterfaceSourceGenerator.csproj +++ b/src/ProxyInterfaceSourceGenerator/ProxyInterfaceSourceGenerator.csproj @@ -1,7 +1,7 @@ - 0.0.9 + 0.0.10 netstandard2.0 9 enable diff --git a/src/ProxyInterfaceSourceGenerator/SyntaxReceiver/ProxyData.cs b/src/ProxyInterfaceSourceGenerator/SyntaxReceiver/ProxyData.cs index 11c9039..0965348 100644 --- a/src/ProxyInterfaceSourceGenerator/SyntaxReceiver/ProxyData.cs +++ b/src/ProxyInterfaceSourceGenerator/SyntaxReceiver/ProxyData.cs @@ -2,8 +2,7 @@ using System.Collections.Generic; namespace ProxyInterfaceSourceGenerator.SyntaxReceiver { - internal record ProxyData(string Namespace, string InterfaceName, string RawTypeName, string TypeName, List Usings, bool ProxyAll) + internal record ProxyData(string Namespace, string InterfaceName, string RawTypeName, string TypeName, List Usings, bool ProxyAll) { - public string FileName => TypeName.Replace('.', '_').Replace('`', '_'); } } \ No newline at end of file