diff --git a/documentation/NEXT_RELEASENOTES.txt b/documentation/NEXT_RELEASENOTES.txt
index 00c828d4..63f282c9 100644
--- a/documentation/NEXT_RELEASENOTES.txt
+++ b/documentation/NEXT_RELEASENOTES.txt
@@ -7,4 +7,5 @@
- fixed string and char const field definition
- fixed ExplicitInterfaceImplementationsSection config name (fixes #141)
-- fixed StackOverflowException when using cyclic inheritdoc (fixes #142)
\ No newline at end of file
+- fixed StackOverflowException when using cyclic inheritdoc (fixes #142)
+- fixed property getter/setter access modifier not taken into account (fixes #151)
\ No newline at end of file
diff --git a/source/DefaultDocumentation.Api/Extensions/IEntityExtensions.cs b/source/DefaultDocumentation.Api/Extensions/IEntityExtensions.cs
new file mode 100644
index 00000000..5f46c5c5
--- /dev/null
+++ b/source/DefaultDocumentation.Api/Extensions/IEntityExtensions.cs
@@ -0,0 +1,38 @@
+using System.Linq;
+using DefaultDocumentation;
+
+namespace ICSharpCode.Decompiler.TypeSystem
+{
+ ///
+ /// Provides extension methods on the type.
+ ///
+ public static class IEntityExtensions
+ {
+ ///
+ /// Returns wether an should be part of the documentation or not based on its accessibility.
+ ///
+ /// The to check.
+ /// The used to generate the documentation.
+ /// if the entity should be part of the documentation; otherwise .
+ public static bool IsVisibleInDocumentation(this IEntity? entity, ISettings settings)
+ {
+ ArgumentNullException.ThrowIfNull(settings);
+
+ return entity?.EffectiveAccessibility() switch
+ {
+ Accessibility.Public => (settings.GeneratedAccessModifiers & GeneratedAccessModifiers.Public) != 0,
+ Accessibility.Private => entity switch
+ {
+ IProperty property when property.IsExplicitInterfaceImplementation => property.ExplicitlyImplementedInterfaceMembers.First().DeclaringTypeDefinition.IsVisibleInDocumentation(settings),
+ IMethod method when method.IsExplicitInterfaceImplementation => method.ExplicitlyImplementedInterfaceMembers.First().DeclaringTypeDefinition.IsVisibleInDocumentation(settings),
+ _ => (settings.GeneratedAccessModifiers & GeneratedAccessModifiers.Private) != 0
+ },
+ Accessibility.Protected => (settings.GeneratedAccessModifiers & GeneratedAccessModifiers.Protected) != 0,
+ Accessibility.Internal => (settings.GeneratedAccessModifiers & GeneratedAccessModifiers.Internal) != 0,
+ Accessibility.ProtectedOrInternal => (settings.GeneratedAccessModifiers & GeneratedAccessModifiers.ProtectedInternal) != 0,
+ Accessibility.ProtectedAndInternal => (settings.GeneratedAccessModifiers & GeneratedAccessModifiers.PrivateProtected) != 0,
+ _ => false
+ };
+ }
+ }
+}
diff --git a/source/DefaultDocumentation.Common/Internal/DocItemReader.cs b/source/DefaultDocumentation.Common/Internal/DocItemReader.cs
index e1773cc7..bd1972f4 100644
--- a/source/DefaultDocumentation.Common/Internal/DocItemReader.cs
+++ b/source/DefaultDocumentation.Common/Internal/DocItemReader.cs
@@ -27,22 +27,6 @@ internal sealed class DocItemReader
private DocItemReader(Settings settings)
{
- bool IsGenerated(IEntity? entity) => entity.EffectiveAccessibility() switch
- {
- Accessibility.Public => (settings.GeneratedAccessModifiers & GeneratedAccessModifiers.Public) != 0,
- Accessibility.Private => entity switch
- {
- IProperty property when property.IsExplicitInterfaceImplementation => IsGenerated(property.ExplicitlyImplementedInterfaceMembers.First().DeclaringTypeDefinition),
- IMethod method when method.IsExplicitInterfaceImplementation => IsGenerated(method.ExplicitlyImplementedInterfaceMembers.First().DeclaringTypeDefinition),
- _ => (settings.GeneratedAccessModifiers & GeneratedAccessModifiers.Private) != 0
- },
- Accessibility.Protected => (settings.GeneratedAccessModifiers & GeneratedAccessModifiers.Protected) != 0,
- Accessibility.Internal => (settings.GeneratedAccessModifiers & GeneratedAccessModifiers.Internal) != 0,
- Accessibility.ProtectedOrInternal => (settings.GeneratedAccessModifiers & GeneratedAccessModifiers.ProtectedInternal) != 0,
- Accessibility.ProtectedAndInternal => (settings.GeneratedAccessModifiers & GeneratedAccessModifiers.PrivateProtected) != 0,
- _ => false
- };
-
_logger = settings.Logger;
_decompiler = new CSharpDecompiler(settings.AssemblyFile.FullName, new DecompilerSettings { ThrowOnAssemblyResolveErrors = false });
_resolver = new CSharpResolver(_decompiler.TypeSystem);
@@ -75,7 +59,7 @@ private DocItemReader(Settings settings)
continue;
}
- if (!IsGenerated(type))
+ if (!type.IsVisibleInDocumentation(settings))
{
_logger.Debug($"Skipping documentation for type \"{type.FullName}\": accessibility \"{type.EffectiveAccessibility()}\" not generated");
continue;
@@ -155,7 +139,7 @@ private DocItemReader(Settings settings)
continue;
}
- if (!IsGenerated(entity))
+ if (!entity.IsVisibleInDocumentation(settings))
{
_logger.Debug($"Skipping documentation for member \"{entity.FullName}\": accessibility \"{entity.EffectiveAccessibility()}\" not generated");
continue;
diff --git a/source/DefaultDocumentation.Markdown/Sections/DefinitionSection.cs b/source/DefaultDocumentation.Markdown/Sections/DefinitionSection.cs
index 25e6979a..c65f13b4 100644
--- a/source/DefaultDocumentation.Markdown/Sections/DefinitionSection.cs
+++ b/source/DefaultDocumentation.Markdown/Sections/DefinitionSection.cs
@@ -89,7 +89,6 @@ public sealed class DefinitionSection : ISection
{
ConversionFlags =
ConversionFlags.ShowAccessibility
- | ConversionFlags.ShowBody
| ConversionFlags.ShowModifiers
| ConversionFlags.ShowParameterDefaultValues
| ConversionFlags.ShowParameterList
@@ -186,6 +185,40 @@ static IWriter Write(IWriter writer, Action writeAction)
.Append("```");
}
+
+ static void WritePropertyMethod(IWriter writer, IMethod? method, string name)
+ {
+ if (!method.IsVisibleInDocumentation(writer.Context.Settings))
+ {
+ return;
+ }
+
+ writer
+ .Append((method!.IsExplicitInterfaceImplementation ? method.ExplicitlyImplementedInterfaceMembers.FirstOrDefault() : method).Accessibility switch
+ {
+ Accessibility.Private => " private ",
+ Accessibility.Internal => " internal ",
+ Accessibility.Protected => " protected ",
+ Accessibility.ProtectedAndInternal => " private protected ",
+ Accessibility.ProtectedOrInternal => " protected internal ",
+ _ => " "
+ })
+ .Append(name)
+ .Append(";");
+ }
+
+ static void WriteProperty(IWriter writer, IProperty property)
+ {
+ writer
+ .Append(property.ToString(_propertyAmbience))
+ .Append(" {");
+
+ WritePropertyMethod(writer, property.Getter, "get");
+ WritePropertyMethod(writer, property.Setter, property.Setter?.IsInitOnly ?? false ? "init" : "set");
+
+ writer.Append(" }");
+ }
+
_ = writer.GetCurrentItem() switch
{
FieldDocItem item => Write(writer, w =>
@@ -210,12 +243,12 @@ static IWriter Write(IWriter writer, Action writeAction)
w.Append(";");
}),
- PropertyDocItem item => Write(writer, w => w.Append(item.Property.ToString(_propertyAmbience))),
+ PropertyDocItem item => Write(writer, w => WriteProperty(w, item.Property)),
EventDocItem item => Write(writer, w => w.Append(item.Event.ToString(_eventAmbience))),
ConstructorDocItem item => Write(writer, w => w.Append(item.Method.ToString(_methodAmbience)).Append(";")),
OperatorDocItem item => Write(writer, w => w.Append(item.Method.ToString(_methodAmbience)).Append(";")),
ExplicitInterfaceImplementationDocItem item when item.Member is IEvent => Write(writer, w => w.Append(item.Member.ToString(_eventAmbience))),
- ExplicitInterfaceImplementationDocItem item when item.Member is IProperty => Write(writer, w => w.Append(item.Member.ToString(_propertyAmbience))),
+ ExplicitInterfaceImplementationDocItem item when item.Member is IProperty property => Write(writer, w => WriteProperty(w, property)),
ExplicitInterfaceImplementationDocItem item when item.Member is IMethod => Write(writer, w =>
{
w.Append(item.Member.ToString(_methodAmbience));
diff --git a/source/DefaultDocumentation.Test/AssemblyInfo.cs b/source/DefaultDocumentation.Test/AssemblyInfo.cs
index e44283ed..9eb1e833 100644
--- a/source/DefaultDocumentation.Test/AssemblyInfo.cs
+++ b/source/DefaultDocumentation.Test/AssemblyInfo.cs
@@ -63,7 +63,11 @@ public sealed record ClassRecord(
private static readonly int _field;
- private static int Property { get; }
+ public static int Property { get; }
+
+ public static int PropertyPrivateSet { get; private set; }
+
+ public static int PropertyInternalSet { get; internal set; }
private static void MethodWithParameter(int parameter)
{ }
@@ -117,6 +121,8 @@ void IInterface.Method()
public static readonly FieldDocItem ConstCharFieldDocItem = new(ClassDocItem, Get($"F:{typeof(AssemblyInfo).FullName}.{nameof(_constCharField)}"), null);
public static readonly FieldDocItem FieldDocItem = new(ClassDocItem, Get($"F:{typeof(AssemblyInfo).FullName}.{nameof(_field)}"), null);
public static readonly PropertyDocItem PropertyDocItem = new(ClassDocItem, Get($"P:{typeof(AssemblyInfo).FullName}.{nameof(Property)}"), null);
+ public static readonly PropertyDocItem PropertyPrivateSetDocItem = new(ClassDocItem, Get($"P:{typeof(AssemblyInfo).FullName}.{nameof(PropertyPrivateSet)}"), null);
+ public static readonly PropertyDocItem PropertyInternalSetDocItem = new(ClassDocItem, Get($"P:{typeof(AssemblyInfo).FullName}.{nameof(PropertyInternalSet)}"), null);
public static readonly MethodDocItem MethodWithGenericConstrainsDocItem = new(ClassDocItem, Get($"M:{typeof(AssemblyInfo).FullName}.{nameof(MethodWithGenericConstrains)}``5"), null);
public static readonly MethodDocItem MethodWithParameterDocItem = new(ClassDocItem, Get($"M:{typeof(AssemblyInfo).FullName}.{nameof(MethodWithParameter)}({typeof(int).FullName})"), null);
public static readonly MethodDocItem MethodWithReturnDocItem = new(ClassDocItem, Get($"M:{typeof(AssemblyInfo).FullName}.{nameof(MoveNext)}"), null);
diff --git a/source/DefaultDocumentation.Test/Markdown/AWriterTest.cs b/source/DefaultDocumentation.Test/Markdown/AWriterTest.cs
index 868978a3..a7d3d1f7 100644
--- a/source/DefaultDocumentation.Test/Markdown/AWriterTest.cs
+++ b/source/DefaultDocumentation.Test/Markdown/AWriterTest.cs
@@ -87,6 +87,7 @@ protected AWriterTest()
settings.AssemblyFile.Returns(new FileInfo("test.dll"));
settings.ProjectDirectory.Returns(new DirectoryInfo(Path.GetTempPath()));
settings.GeneratedPages.Returns(GetGeneratedPages());
+ settings.GeneratedAccessModifiers.Returns(GetGeneratedAccessModifiers());
return settings;
});
@@ -103,6 +104,8 @@ protected AWriterTest()
protected virtual GeneratedPages GetGeneratedPages() => GeneratedPages.Assembly | GeneratedPages.Namespaces | GeneratedPages.Types | GeneratedPages.Members;
+ protected virtual GeneratedAccessModifiers GetGeneratedAccessModifiers() => GeneratedAccessModifiers.Api;
+
protected virtual IFileNameFactory GetFileNameFactory() => new DummyFileNameFactory();
protected virtual IUrlFactory[] GetUrlFactories() => new IUrlFactory[]
diff --git a/source/DefaultDocumentation.Test/Markdown/Sections/DefinitionSectionTest.cs b/source/DefaultDocumentation.Test/Markdown/Sections/DefinitionSectionTest.cs
index 3fb6f057..ee5c7b45 100644
--- a/source/DefaultDocumentation.Test/Markdown/Sections/DefinitionSectionTest.cs
+++ b/source/DefaultDocumentation.Test/Markdown/Sections/DefinitionSectionTest.cs
@@ -63,7 +63,28 @@ public void Write_should_write_When_FieldDocItem_and_constant_char() => Test(
public void Write_should_write_When_PropertyDocItem() => Test(
AssemblyInfo.PropertyDocItem,
@"```csharp
-private static int Property { get; }
+public static int Property { get; }
+```");
+
+ [Fact]
+ public void Write_should_write_When_PropertyDocItem_with_private_set() => Test(
+ AssemblyInfo.PropertyPrivateSetDocItem,
+@"```csharp
+public static int PropertyPrivateSet { get; }
+```");
+
+ [Fact]
+ public void Write_should_write_When_PropertyDocItem_with_internal_set() => Test(
+ AssemblyInfo.PropertyInternalSetDocItem,
+@"```csharp
+public static int PropertyInternalSet { get; }
+```");
+
+ [Fact]
+ public void Write_should_write_When_PropertyDocItem_with_init() => Test(
+ AssemblyInfo.RecordPropertyDocItem,
+@"```csharp
+public int Property { get; init; }
```");
[Fact]
@@ -160,13 +181,6 @@ public void Write_should_write_When_TypeDocItem_for_record_struct() => Test(
AssemblyInfo.StructRecordDocItem,
@"```csharp
public readonly record struct AssemblyInfo.StructRecord : System.IEquatable
-```");
-
- //[Fact] to uncomment once https://github.com/icsharpcode/ILSpy/issues/3159 is solved
- public void Write_should_write_When_PropertyDocItem_with_init() => Test(
- AssemblyInfo.RecordPropertyDocItem,
-@"```csharp
-public int Property { get; init; }
```");
}
}