Skip to content

Commit

Permalink
fixed property getter/setter access modifier not taken into account (f…
Browse files Browse the repository at this point in the history
…ixes #151)
  • Loading branch information
Doraku committed Jan 28, 2024
1 parent 6d783d9 commit e007860
Show file tree
Hide file tree
Showing 7 changed files with 110 additions and 31 deletions.
3 changes: 2 additions & 1 deletion documentation/NEXT_RELEASENOTES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
- fixed StackOverflowException when using cyclic inheritdoc (fixes #142)
- fixed property getter/setter access modifier not taken into account (fixes #151)
38 changes: 38 additions & 0 deletions source/DefaultDocumentation.Api/Extensions/IEntityExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using System.Linq;
using DefaultDocumentation;

namespace ICSharpCode.Decompiler.TypeSystem
{
/// <summary>
/// Provides extension methods on the <see cref="IEntity"/> type.
/// </summary>
public static class IEntityExtensions
{
/// <summary>
/// Returns wether an <see cref="IEntity"/> should be part of the documentation or not based on its accessibility.
/// </summary>
/// <param name="entity">The <see cref="IEntity"/> to check.</param>
/// <param name="settings">The <see cref="ISettings"/> used to generate the documentation.</param>
/// <returns><see langword="true"/> if the entity should be part of the documentation; otherwise <see langword="false"/>.</returns>
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
};
}
}
}
20 changes: 2 additions & 18 deletions source/DefaultDocumentation.Common/Internal/DocItemReader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
39 changes: 36 additions & 3 deletions source/DefaultDocumentation.Markdown/Sections/DefinitionSection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ public sealed class DefinitionSection : ISection
{
ConversionFlags =
ConversionFlags.ShowAccessibility
| ConversionFlags.ShowBody
| ConversionFlags.ShowModifiers
| ConversionFlags.ShowParameterDefaultValues
| ConversionFlags.ShowParameterList
Expand Down Expand Up @@ -186,6 +185,40 @@ static IWriter Write(IWriter writer, Action<IWriter> 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 =>
Expand All @@ -210,12 +243,12 @@ static IWriter Write(IWriter writer, Action<IWriter> 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));
Expand Down
8 changes: 7 additions & 1 deletion source/DefaultDocumentation.Test/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{ }
Expand Down Expand Up @@ -117,6 +121,8 @@ void IInterface.Method()
public static readonly FieldDocItem ConstCharFieldDocItem = new(ClassDocItem, Get<IField>($"F:{typeof(AssemblyInfo).FullName}.{nameof(_constCharField)}"), null);
public static readonly FieldDocItem FieldDocItem = new(ClassDocItem, Get<IField>($"F:{typeof(AssemblyInfo).FullName}.{nameof(_field)}"), null);
public static readonly PropertyDocItem PropertyDocItem = new(ClassDocItem, Get<IProperty>($"P:{typeof(AssemblyInfo).FullName}.{nameof(Property)}"), null);
public static readonly PropertyDocItem PropertyPrivateSetDocItem = new(ClassDocItem, Get<IProperty>($"P:{typeof(AssemblyInfo).FullName}.{nameof(PropertyPrivateSet)}"), null);
public static readonly PropertyDocItem PropertyInternalSetDocItem = new(ClassDocItem, Get<IProperty>($"P:{typeof(AssemblyInfo).FullName}.{nameof(PropertyInternalSet)}"), null);
public static readonly MethodDocItem MethodWithGenericConstrainsDocItem = new(ClassDocItem, Get<IMethod>($"M:{typeof(AssemblyInfo).FullName}.{nameof(MethodWithGenericConstrains)}``5"), null);
public static readonly MethodDocItem MethodWithParameterDocItem = new(ClassDocItem, Get<IMethod>($"M:{typeof(AssemblyInfo).FullName}.{nameof(MethodWithParameter)}({typeof(int).FullName})"), null);
public static readonly MethodDocItem MethodWithReturnDocItem = new(ClassDocItem, Get<IMethod>($"M:{typeof(AssemblyInfo).FullName}.{nameof(MoveNext)}"), null);
Expand Down
3 changes: 3 additions & 0 deletions source/DefaultDocumentation.Test/Markdown/AWriterTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
});
Expand All @@ -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[]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,28 @@ public sealed class AssemblyInfo : DefaultDocumentation.AssemblyInfo.IInterface,
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]
Expand Down Expand Up @@ -160,13 +181,6 @@ public sealed record AssemblyInfo.ClassRecord : System.IEquatable<DefaultDocumen
AssemblyInfo.StructRecordDocItem,
@"```csharp
public readonly record struct AssemblyInfo.StructRecord : System.IEquatable<DefaultDocumentation.AssemblyInfo.StructRecord>
```");

//[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; }
```");
}
}

0 comments on commit e007860

Please sign in to comment.