diff --git a/src/ProxyInterfaceSourceGenerator/Extensions/MethodSymbolExtensions.cs b/src/ProxyInterfaceSourceGenerator/Extensions/MethodSymbolExtensions.cs index 818fcd8..ec9cd1e 100644 --- a/src/ProxyInterfaceSourceGenerator/Extensions/MethodSymbolExtensions.cs +++ b/src/ProxyInterfaceSourceGenerator/Extensions/MethodSymbolExtensions.cs @@ -7,6 +7,11 @@ internal static class MethodSymbolExtensions public static string GetMethodNameWithOptionalTypeParameters(this IMethodSymbol method) => !method.IsGenericMethod ? method.Name : $"{method.Name}<{string.Join(", ", method.TypeParameters.Select(tp => tp.Name))}>"; + public static bool IsPublic(this IMethodSymbol? methodSymbol) + { + return methodSymbol is { DeclaredAccessibility: Accessibility.Public }; + } + //public static string GetWhereStatement(this IMethodSymbol method) => // !method.IsGenericMethod ? string.Empty : string.Join("", method.TypeParameters.Select(tp => tp.GetWhereConstraints())); } \ No newline at end of file diff --git a/src/ProxyInterfaceSourceGenerator/Extensions/PropertySymbolExtensions.cs b/src/ProxyInterfaceSourceGenerator/Extensions/PropertySymbolExtensions.cs index 45ee4ae..9bdc1ae 100644 --- a/src/ProxyInterfaceSourceGenerator/Extensions/PropertySymbolExtensions.cs +++ b/src/ProxyInterfaceSourceGenerator/Extensions/PropertySymbolExtensions.cs @@ -7,13 +7,23 @@ internal static class PropertySymbolExtensions { public static TypeEnum GetTypeEnum(this IPropertySymbol p) => p.Type.GetTypeEnum(); - public static (string PropertyType, string? PropertyName, string GetSet) ToPropertyDetails(this IPropertySymbol property, string? overrideType = null) + public static (string PropertyType, string? PropertyName, string GetSet)? ToPropertyDetails(this IPropertySymbol property, string? overrideType = null) { - var get = property.GetMethod != null ? "get; " : string.Empty; - var set = property.SetMethod != null ? "set; " : string.Empty; + var getIsPublic = property.GetMethod.IsPublic(); + var setIsPublic = property.SetMethod.IsPublic(); + + if (!getIsPublic && !setIsPublic) + { + return null; + } + + var get = getIsPublic ? "get; " : string.Empty; + var set = setIsPublic ? "set; " : string.Empty; var type = !string.IsNullOrEmpty(overrideType) ? overrideType : $"{property.Type}"; return (type!, property.GetSanitizedName(), $"{{ {get}{set}}}"); } + + } \ No newline at end of file diff --git a/src/ProxyInterfaceSourceGenerator/FileGenerators/PartialInterfacesGenerator.cs b/src/ProxyInterfaceSourceGenerator/FileGenerators/PartialInterfacesGenerator.cs index d42454c..964d8ff 100644 --- a/src/ProxyInterfaceSourceGenerator/FileGenerators/PartialInterfacesGenerator.cs +++ b/src/ProxyInterfaceSourceGenerator/FileGenerators/PartialInterfacesGenerator.cs @@ -96,9 +96,13 @@ using System; { var type = GetPropertyType(property, out var isReplaced); - (string propertyType, string? propertyName, string getSet) = isReplaced ? - property.ToPropertyDetails(type) : - property.ToPropertyDetails(); + var getterSetter = isReplaced ? property.ToPropertyDetails(type) : property.ToPropertyDetails(); + if (getterSetter is null) + { + continue; + } + + var propertyName = getterSetter.Value.PropertyName; if (property.IsIndexer) { @@ -106,7 +110,7 @@ using System; propertyName = $"this[{string.Join(", ", methodParameters)}]"; } - str.AppendLine($" {propertyType} {propertyName} {getSet}"); + str.AppendLine($" {getterSetter.Value.PropertyType} {propertyName} {getterSetter.Value.GetSet}"); str.AppendLine(); } diff --git a/src/ProxyInterfaceSourceGenerator/FileGenerators/ProxyClassesGenerator.cs b/src/ProxyInterfaceSourceGenerator/FileGenerators/ProxyClassesGenerator.cs index 0d515c4..1849add 100644 --- a/src/ProxyInterfaceSourceGenerator/FileGenerators/ProxyClassesGenerator.cs +++ b/src/ProxyInterfaceSourceGenerator/FileGenerators/ProxyClassesGenerator.cs @@ -155,17 +155,25 @@ using System; overrideOrVirtual = "virtual "; } + var getIsPublic = property.GetMethod.IsPublic(); + var setIsPublic = property.SetMethod.IsPublic(); + + if (!getIsPublic && !setIsPublic) + { + continue; + } + string get; string set; if (isReplaced) { - get = property.GetMethod != null ? $"get => Mapster.TypeAdapter.Adapt<{type}>({instancePropertyName}); " : string.Empty; - set = property.SetMethod != null ? $"set => {instancePropertyName} = Mapster.TypeAdapter.Adapt<{property.Type}>(value); " : string.Empty; + get = getIsPublic ? $"get => Mapster.TypeAdapter.Adapt<{type}>({instancePropertyName}); " : string.Empty; + set = setIsPublic ? $"set => {instancePropertyName} = Mapster.TypeAdapter.Adapt<{property.Type}>(value); " : string.Empty; } else { - get = property.GetMethod != null ? $"get => {instancePropertyName}; " : string.Empty; - set = property.SetMethod != null ? $"set => {instancePropertyName} = value; " : string.Empty; + get = getIsPublic ? $"get => {instancePropertyName}; " : string.Empty; + set = setIsPublic ? $"set => {instancePropertyName} = value; " : string.Empty; } str.AppendLine($" public {overrideOrVirtual}{type} {propertyName} {{ {get}{set}}}"); diff --git a/src/ProxyInterfaceSourceGenerator/Utils/MemberHelper.cs b/src/ProxyInterfaceSourceGenerator/Utils/MemberHelper.cs index 830ffe8..1fc7f9e 100644 --- a/src/ProxyInterfaceSourceGenerator/Utils/MemberHelper.cs +++ b/src/ProxyInterfaceSourceGenerator/Utils/MemberHelper.cs @@ -57,7 +57,8 @@ internal static class MemberHelper private static IEnumerable GetPublicMembers( ClassSymbol classSymbol, bool proxyBaseClasses, - params Func[] filters) where T : ISymbol + params Func[] filters + ) where T : ISymbol { var membersQuery = classSymbol.Symbol.GetMembers().OfType() .Where(m => m.DeclaredAccessibility == Accessibility.Public); diff --git a/tests/ProxyInterfaceSourceGeneratorTests/Destination/ProxyInterfaceSourceGeneratorTests.Source.IMixedVisibility.g.cs b/tests/ProxyInterfaceSourceGeneratorTests/Destination/ProxyInterfaceSourceGeneratorTests.Source.IMixedVisibility.g.cs new file mode 100644 index 0000000..df9afcb --- /dev/null +++ b/tests/ProxyInterfaceSourceGeneratorTests/Destination/ProxyInterfaceSourceGeneratorTests.Source.IMixedVisibility.g.cs @@ -0,0 +1,28 @@ +//---------------------------------------------------------------------------------------- +// +// 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. +// +//---------------------------------------------------------------------------------------- + +#nullable enable +using System; + +namespace ProxyInterfaceSourceGeneratorTests.Source +{ + public partial interface IMixedVisibility + { + ProxyInterfaceSourceGeneratorTests.Source.MixedVisibility _Instance { get; } + + string Foo { get; } + + + + + + + } +} +#nullable disable \ No newline at end of file diff --git a/tests/ProxyInterfaceSourceGeneratorTests/Destination/ProxyInterfaceSourceGeneratorTests.Source.MixedVisibilityProxy.g.cs b/tests/ProxyInterfaceSourceGeneratorTests/Destination/ProxyInterfaceSourceGeneratorTests.Source.MixedVisibilityProxy.g.cs new file mode 100644 index 0000000..35e50b1 --- /dev/null +++ b/tests/ProxyInterfaceSourceGeneratorTests/Destination/ProxyInterfaceSourceGeneratorTests.Source.MixedVisibilityProxy.g.cs @@ -0,0 +1,37 @@ +//---------------------------------------------------------------------------------------- +// +// 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. +// +//---------------------------------------------------------------------------------------- + +#nullable enable +using System; + +namespace ProxyInterfaceSourceGeneratorTests.Source +{ + public partial class MixedVisibilityProxy : IMixedVisibility + { + public ProxyInterfaceSourceGeneratorTests.Source.MixedVisibility _Instance { get; } + + + public string Foo { get => _Instance.Foo; } + + + + + + + + public MixedVisibilityProxy(ProxyInterfaceSourceGeneratorTests.Source.MixedVisibility instance) + { + _Instance = instance; + + + + } + } +} +#nullable disable \ No newline at end of file diff --git a/tests/ProxyInterfaceSourceGeneratorTests/ProxyInterfaceSourceGeneratorTest.cs b/tests/ProxyInterfaceSourceGeneratorTests/ProxyInterfaceSourceGeneratorTest.cs index 2680e17..2b70523 100644 --- a/tests/ProxyInterfaceSourceGeneratorTests/ProxyInterfaceSourceGeneratorTest.cs +++ b/tests/ProxyInterfaceSourceGeneratorTests/ProxyInterfaceSourceGeneratorTest.cs @@ -92,6 +92,48 @@ namespace ProxyInterfaceSourceGeneratorTests } } + [Fact] + public void GenerateFiles_When_MixedVisibility_Should_GenerateCorrectFiles() + { + // Arrange + var fileNames = new[] + { + "ProxyInterfaceSourceGeneratorTests.Source.IMixedVisibility.g.cs", + "ProxyInterfaceSourceGeneratorTests.Source.MixedVisibilityProxy.g.cs" + }; + + var path = "./Source/IMixedVisibility.cs"; + var sourceFile = new SourceFile + { + Path = path, + Text = File.ReadAllText(path), + AttributeToAddToInterface = new ExtraAttribute + { + Name = "ProxyInterfaceGenerator.Proxy", + ArgumentList = "typeof(ProxyInterfaceSourceGeneratorTests.Source.MixedVisibility)" + } + }; + + // Act + var result = _sut.Execute(new[] + { + sourceFile + }); + + // Assert + result.Valid.Should().BeTrue(); + result.Files.Should().HaveCount(fileNames.Length + 1); + + foreach (var fileName in fileNames.Select((fileName, index) => new { fileName, index })) + { + var builder = result.Files[fileName.index + 1]; // +1 means skip the attribute + builder.Path.Should().EndWith(fileName.fileName); + + if (Write) File.WriteAllText($"../../../Destination/{fileName.fileName}", builder.Text); + builder.Text.Should().Be(File.ReadAllText($"../../../Destination/{fileName.fileName}")); + } + } + [Fact] public void GenerateFiles_ForSingleClass_Should_GenerateCorrectFiles() { diff --git a/tests/ProxyInterfaceSourceGeneratorTests/Source/IMixedVisibility.cs b/tests/ProxyInterfaceSourceGeneratorTests/Source/IMixedVisibility.cs new file mode 100644 index 0000000..5ee0fdb --- /dev/null +++ b/tests/ProxyInterfaceSourceGeneratorTests/Source/IMixedVisibility.cs @@ -0,0 +1,5 @@ +namespace ProxyInterfaceSourceGeneratorTests.Source; + +public partial interface IMixedVisibility +{ +} \ No newline at end of file diff --git a/tests/ProxyInterfaceSourceGeneratorTests/Source/MixedVisibility.cs b/tests/ProxyInterfaceSourceGeneratorTests/Source/MixedVisibility.cs new file mode 100644 index 0000000..49aa832 --- /dev/null +++ b/tests/ProxyInterfaceSourceGeneratorTests/Source/MixedVisibility.cs @@ -0,0 +1,6 @@ +namespace ProxyInterfaceSourceGeneratorTests.Source; + +public class MixedVisibility +{ + public string Foo { get; protected set; } //<- this will generate bad code +} \ No newline at end of file