Skip to content

Commit

Permalink
Merge pull request #653 from CommunityToolkit/dev/generator-xml-docs
Browse files Browse the repository at this point in the history
Improve XML docs over generated code
  • Loading branch information
Sergio0694 authored Mar 25, 2023
2 parents b8df95a + d4d3c26 commit b341ef9
Show file tree
Hide file tree
Showing 5 changed files with 276 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -1113,13 +1113,13 @@ public static ImmutableArray<MemberDeclarationSyntax> GetOnPropertyChangeMethods
/// <summary>
/// Gets a <see cref="CompilationUnitSyntax"/> instance with the cached args of a specified type.
/// </summary>
/// <param name="ContainingTypeName">The name of the generated type.</param>
/// <param name="ArgsTypeName">The argument type name.</param>
/// <param name="containingTypeName">The name of the generated type.</param>
/// <param name="argsTypeName">The argument type name.</param>
/// <param name="names">The sequence of property names to cache args for.</param>
/// <returns>A <see cref="CompilationUnitSyntax"/> instance with the sequence of cached args, if any.</returns>
private static CompilationUnitSyntax? GetKnownPropertyChangingOrChangedArgsSyntax(
string ContainingTypeName,
string ArgsTypeName,
string containingTypeName,
string argsTypeName,
ImmutableArray<string> names)
{
if (names.IsEmpty)
Expand All @@ -1134,6 +1134,10 @@ public static ImmutableArray<MemberDeclarationSyntax> GetOnPropertyChangeMethods
// #nullable enable
// namespace CommunityToolkit.Mvvm.ComponentModel.__Internals
// {
// /// <summary>
// /// A helper type providing cached, reusable <see cref="<ARGS_TYPE_NAME>"/> instances
// /// for all properties generated with <see cref="global::CommunityToolkit.Mvvm.ComponentModel.ObservablePropertyAttribute"/>.
// /// </summary>
// [global::System.CodeDom.Compiler.GeneratedCode("...", "...")]
// [global::System.Diagnostics.DebuggerNonUserCode]
// [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
Expand All @@ -1150,14 +1154,19 @@ public static ImmutableArray<MemberDeclarationSyntax> GetOnPropertyChangeMethods
Comment("// <auto-generated/>"),
Trivia(PragmaWarningDirectiveTrivia(Token(SyntaxKind.DisableKeyword), true)),
Trivia(NullableDirectiveTrivia(Token(SyntaxKind.EnableKeyword), true)))).AddMembers(
ClassDeclaration(ContainingTypeName).AddModifiers(
ClassDeclaration(containingTypeName).AddModifiers(
Token(SyntaxKind.InternalKeyword),
Token(SyntaxKind.StaticKeyword)).AddAttributeLists(
AttributeList(SingletonSeparatedList(
Attribute(IdentifierName($"global::System.CodeDom.Compiler.GeneratedCode"))
.AddArgumentListArguments(
AttributeArgument(LiteralExpression(SyntaxKind.StringLiteralExpression, Literal(typeof(ObservablePropertyGenerator).FullName))),
AttributeArgument(LiteralExpression(SyntaxKind.StringLiteralExpression, Literal(typeof(ObservablePropertyGenerator).Assembly.GetName().Version.ToString())))))),
AttributeArgument(LiteralExpression(SyntaxKind.StringLiteralExpression, Literal(typeof(ObservablePropertyGenerator).Assembly.GetName().Version.ToString()))))))
.WithOpenBracketToken(Token(TriviaList(
Comment("/// <summary>"),
Comment($"/// A helper type providing cached, reusable <see cref=\"{argsTypeName}\"/> instances"),
Comment("/// for all properties generated with <see cref=\"global::CommunityToolkit.Mvvm.ComponentModel.ObservablePropertyAttribute\"/>."),
Comment("/// </summary>")), SyntaxKind.OpenBracketToken, TriviaList())),
AttributeList(SingletonSeparatedList(Attribute(IdentifierName("global::System.Diagnostics.DebuggerNonUserCode")))),
AttributeList(SingletonSeparatedList(Attribute(IdentifierName("global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage")))),
AttributeList(SingletonSeparatedList(
Expand All @@ -1168,31 +1177,32 @@ public static ImmutableArray<MemberDeclarationSyntax> GetOnPropertyChangeMethods
AttributeArgument(LiteralExpression(
SyntaxKind.StringLiteralExpression,
Literal("This type is not intended to be used directly by user code")))))))
.AddMembers(names.Select(name => CreateFieldDeclaration(ArgsTypeName, name)).ToArray())))
.AddMembers(names.Select(name => CreateFieldDeclaration(argsTypeName, name)).ToArray())))
.NormalizeWhitespace();
}

/// <summary>
/// Creates a field declaration for a cached property changing/changed name.
/// </summary>
/// <param name="typeName">The field type name (either <see cref="PropertyChangedEventArgs"/> or <see cref="PropertyChangingEventArgs"/>).</param>
/// <param name="fullyQualifiedTypeName">The field fully qualified type name (either <see cref="PropertyChangedEventArgs"/> or <see cref="PropertyChangingEventArgs"/>).</param>
/// <param name="propertyName">The name of the cached property name.</param>
/// <returns>A <see cref="FieldDeclarationSyntax"/> instance for the input cached property name.</returns>
private static FieldDeclarationSyntax CreateFieldDeclaration(string typeName, string propertyName)
private static FieldDeclarationSyntax CreateFieldDeclaration(string fullyQualifiedTypeName, string propertyName)
{
// Create a static field with a cached property changed/changing argument for a specified property.
// This code produces a field declaration as follows:
//
// /// <summary>The cached <see cref="<TYPE_NAME>"/> instance for all "<PROPERTY_NAME>" generated properties.</summary>
// [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
// [global::System.Obsolete("This field is not intended to be referenced directly by user code")]
// public static readonly <ARG_TYPE> <PROPERTY_NAME> = new("<PROPERTY_NAME>");
return
FieldDeclaration(
VariableDeclaration(IdentifierName(typeName))
VariableDeclaration(IdentifierName(fullyQualifiedTypeName))
.AddVariables(
VariableDeclarator(Identifier(propertyName))
.WithInitializer(EqualsValueClause(
ObjectCreationExpression(IdentifierName(typeName))
ObjectCreationExpression(IdentifierName(fullyQualifiedTypeName))
.AddArgumentListArguments(Argument(
LiteralExpression(SyntaxKind.StringLiteralExpression, Literal(propertyName))))))))
.AddModifiers(
Expand All @@ -1202,7 +1212,10 @@ private static FieldDeclarationSyntax CreateFieldDeclaration(string typeName, st
.AddAttributeLists(
AttributeList(SingletonSeparatedList(
Attribute(IdentifierName("global::System.ComponentModel.EditorBrowsable")).AddArgumentListArguments(
AttributeArgument(ParseExpression("global::System.ComponentModel.EditorBrowsableState.Never"))))),
AttributeArgument(ParseExpression("global::System.ComponentModel.EditorBrowsableState.Never")))))
.WithOpenBracketToken(Token(TriviaList(
Comment($"/// <summary>The cached <see cref=\"{fullyQualifiedTypeName}\"/> instance for all \"{propertyName}\" generated properties.</summary>")),
SyntaxKind.OpenBracketToken, TriviaList())),
AttributeList(SingletonSeparatedList(
Attribute(IdentifierName("global::System.Obsolete")).AddArgumentListArguments(
AttributeArgument(LiteralExpression(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ public static CompilationUnitSyntax GetSyntax(bool isDynamicallyAccessedMembersA

// Prepare the base attributes with are always present:
//
// /// <summary>
// /// A helper type with generated validation stubs for types deriving from <see cref="global::CommunityToolkit.Mvvm.ComponentModel.ObservableValidator"/>.
// /// </summary>
// [global::System.CodeDom.Compiler.GeneratedCode("...", "...")]
// [global::System.Diagnostics.DebuggerNonUserCode]
// [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
Expand All @@ -105,7 +108,11 @@ public static CompilationUnitSyntax GetSyntax(bool isDynamicallyAccessedMembersA
AttributeList(SingletonSeparatedList(
Attribute(IdentifierName($"global::System.CodeDom.Compiler.GeneratedCode")).AddArgumentListArguments(
AttributeArgument(LiteralExpression(SyntaxKind.StringLiteralExpression, Literal(typeof(ObservableValidatorValidateAllPropertiesGenerator).FullName))),
AttributeArgument(LiteralExpression(SyntaxKind.StringLiteralExpression, Literal(typeof(ObservableValidatorValidateAllPropertiesGenerator).Assembly.GetName().Version.ToString())))))));
AttributeArgument(LiteralExpression(SyntaxKind.StringLiteralExpression, Literal(typeof(ObservableValidatorValidateAllPropertiesGenerator).Assembly.GetName().Version.ToString()))))))
.WithOpenBracketToken(Token(TriviaList(
Comment("/// <summary>"),
Comment("/// A helper type with generated validation stubs for types deriving from <see cref=\"global::CommunityToolkit.Mvvm.ComponentModel.ObservableValidator\"/>."),
Comment("/// </summary>")), SyntaxKind.OpenBracketToken, TriviaList())));
attributes.Add(AttributeList(SingletonSeparatedList(Attribute(IdentifierName("global::System.Diagnostics.DebuggerNonUserCode")))));
attributes.Add(AttributeList(SingletonSeparatedList(Attribute(IdentifierName("global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage")))));
attributes.Add(
Expand Down Expand Up @@ -176,8 +183,14 @@ public static CompilationUnitSyntax GetSyntax(ValidationInfo validationInfo)
// #pragma warning disable
// namespace CommunityToolkit.Mvvm.ComponentModel.__Internals
// {
// /// <inheritdoc/>
// partial class __ObservableValidatorExtensions
// {
// /// <summary>
// /// Creates a validation stub for <see cref="<INSTANCE_TYPE>"/> objects.
// /// </summary>
// /// <param name="_">Dummy parameter, only used to disambiguate the method signature.</param>
// /// <returns>A validation stub for <see cref="<INSTANCE_TYPE>"/> objects.</returns>
// [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
// [global::System.Obsolete("This method is not intended to be called directly by user code")]
// public static global::System.Action<object> CreateAllPropertiesValidator(<INSTANCE_TYPE> _)
Expand All @@ -197,13 +210,20 @@ public static CompilationUnitSyntax GetSyntax(ValidationInfo validationInfo)
NamespaceDeclaration(IdentifierName("CommunityToolkit.Mvvm.ComponentModel.__Internals")).WithLeadingTrivia(TriviaList(
Comment("// <auto-generated/>"),
Trivia(PragmaWarningDirectiveTrivia(Token(SyntaxKind.DisableKeyword), true)))).AddMembers(
ClassDeclaration("__ObservableValidatorExtensions").AddModifiers(Token(SyntaxKind.PartialKeyword)).AddMembers(
ClassDeclaration("__ObservableValidatorExtensions").AddModifiers(
Token(TriviaList(Comment("/// <inheritdoc/>")), SyntaxKind.PartialKeyword, TriviaList())).AddMembers(
MethodDeclaration(
GenericName("global::System.Action").AddTypeArgumentListArguments(PredefinedType(Token(SyntaxKind.ObjectKeyword))),
Identifier("CreateAllPropertiesValidator")).AddAttributeLists(
AttributeList(SingletonSeparatedList(
Attribute(IdentifierName("global::System.ComponentModel.EditorBrowsable")).AddArgumentListArguments(
AttributeArgument(ParseExpression("global::System.ComponentModel.EditorBrowsableState.Never"))))),
AttributeArgument(ParseExpression("global::System.ComponentModel.EditorBrowsableState.Never")))))
.WithOpenBracketToken(Token(TriviaList(
Comment("/// <summary>"),
Comment($"/// Creates a validation stub for <see cref=\"{validationInfo.TypeName}\"/> objects."),
Comment("/// </summary>"),
Comment("/// <param name=\"_\">Dummy parameter, only used to disambiguate the method signature.</param>"),
Comment($"/// <returns>A validation stub for <see cref=\"{validationInfo.TypeName}\"/> objects.</returns>")), SyntaxKind.OpenBracketToken, TriviaList())),
AttributeList(SingletonSeparatedList(
Attribute(IdentifierName("global::System.Obsolete")).AddArgumentListArguments(
AttributeArgument(LiteralExpression(
Expand Down
Loading

0 comments on commit b341ef9

Please sign in to comment.