Skip to content

Commit

Permalink
Feature overridable Inheritance property (#123)
Browse files Browse the repository at this point in the history
* support overridable property

* Update to use enum, fix tests

---------

Co-authored-by: Chris Pulman <[email protected]>
  • Loading branch information
neominky and ChrisPulman authored Nov 9, 2024
1 parent 954ab78 commit 9c1feac
Show file tree
Hide file tree
Showing 15 changed files with 239 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,16 @@ internal enum AccessModifier
InternalProtected,
PrivateProtected,
}

/// <summary>
/// InheritanceModifier.
/// </summary>
internal enum InheritanceModifier
{
None,
Virtual,
Override,
New,
}
#nullable restore
#pragma warning restore
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ internal sealed class ReactiveAttribute : Attribute
/// The AccessModifier of the set property.
/// </value>
public AccessModifier SetModifier { get; init; }

/// <summary>
/// Gets the InheritanceModifier of the property.
/// </sumary>
public InheritanceModifier Inheritance { get; init; }
}
#nullable restore
#pragma warning restore
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,16 @@ internal enum AccessModifier
InternalProtected,
PrivateProtected,
}

/// <summary>
/// InheritanceModifier.
/// </summary>
internal enum InheritanceModifier
{
None,
Virtual,
Override,
New,
}
#nullable restore
#pragma warning restore
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ internal sealed class ReactiveAttribute : Attribute
/// The AccessModifier of the set property.
/// </value>
public AccessModifier SetModifier { get; init; }

/// <summary>
/// Gets the InheritanceModifier of the property.
/// </sumary>
public InheritanceModifier Inheritance { get; init; }
}
#nullable restore
#pragma warning restore
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,16 @@ internal enum AccessModifier
InternalProtected,
PrivateProtected,
}

/// <summary>
/// InheritanceModifier.
/// </summary>
internal enum InheritanceModifier
{
None,
Virtual,
Override,
New,
}
#nullable restore
#pragma warning restore
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ internal sealed class ReactiveAttribute : Attribute
/// The AccessModifier of the set property.
/// </value>
public AccessModifier SetModifier { get; init; }

/// <summary>
/// Gets the InheritanceModifier of the property.
/// </sumary>
public InheritanceModifier Inheritance { get; init; }
}
#nullable restore
#pragma warning restore
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//HintName: ReactiveUI.SourceGenerators.AccessModifier.g.cs
// Copyright (c) 2024 .NET Foundation and Contributors. All rights reserved.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for full license information.

// <auto-generated/>
#pragma warning disable
#nullable enable
namespace ReactiveUI.SourceGenerators;

/// <summary>
/// AccessModifier.
/// </summary>
internal enum AccessModifier
{
Public,
Protected,
Internal,
Private,
InternalProtected,
PrivateProtected,
}

/// <summary>
/// InheritanceModifier.
/// </summary>
internal enum InheritanceModifier
{
None,
Virtual,
Override,
New,
}
#nullable restore
#pragma warning restore
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
//HintName: ReactiveUI.SourceGenerators.ReactiveAttribute.g.cs
// Copyright (c) 2024 .NET Foundation and Contributors. All rights reserved.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for full license information.

using System;

// <auto-generated/>
#pragma warning disable
#nullable enable
namespace ReactiveUI.SourceGenerators;

/// <summary>
/// ReactiveAttribute.
/// </summary>
/// <seealso cref="Attribute" />
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
internal sealed class ReactiveAttribute : Attribute
{
/// <summary>
/// Gets the AccessModifier of the set property.
/// </summary>
/// <value>
/// The AccessModifier of the set property.
/// </value>
public AccessModifier SetModifier { get; init; }

/// <summary>
/// Gets the InheritanceModifier of the property.
/// </sumary>
public InheritanceModifier Inheritance { get; init; }
}
#nullable restore
#pragma warning restore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//HintName: TestVM.Properties.g.cs
// <auto-generated/>
using ReactiveUI;

#pragma warning disable
#nullable enable

namespace TestNs
{
/// <summary>
/// Partial class for the TestVM which contains ReactiveUI Reactive property initialization.
/// </summary>
public partial class TestVM
{
/// <inheritdoc cref="_name"/>
[global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
[global::System.Runtime.Serialization.DataMemberAttribute()]
[global::System.Text.Json.Serialization.JsonIncludeAttribute()]
public string? Name { get => _name; set => this.RaiseAndSetIfChanged(ref _name, value); }
}
}
#nullable restore
#pragma warning restore
Original file line number Diff line number Diff line change
Expand Up @@ -109,5 +109,39 @@ public partial class TestVM : ReactiveObject
return VerifyGenerator(driver);
}

/// <summary>
/// Froms the reactive properties with attributes and access and inheritance.
/// </summary>
/// <returns>A task to monitor the async.</returns>
[Fact]
public Task FromReactivePropertiesWithAttributesAccessAndInheritance()
{
// Arrange: Setup the source code that matches the generator input expectations.
const string sourceCode = @"
using System;
using System.Runtime.Serialization;
using System.Text.Json.Serialization;
using ReactiveUI;
using ReactiveUI.SourceGenerators;
using System.Reactive.Linq;
namespace TestNs;
public partial class TestVM : ReactiveObject
{
[property: JsonInclude]
[DataMember]
[Reactive(Inheritance = InheritanceModifier.Virtual, SetModifier = AccessModifier.Protected)]
private string? _name;
}
";

// Act: Initialize the helper and run the generator.
var driver = TestHelper.TestPass(sourceCode);

// Assert: Verify the generated code.
return VerifyGenerator(driver);
}

private SettingsTask VerifyGenerator(GeneratorDriver driver) => Verify(driver).UseDirectory(TestHelper.VerifiedFilePath()).ScrubLinesContaining("[global::System.CodeDom.Compiler.GeneratedCode(\"");
}
5 changes: 5 additions & 0 deletions src/ReactiveUI.SourceGenerators.Execute/TestViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@ public partial class TestViewModel : ReactiveObject, IActivatableViewModel, IDis
[Reactive]
private string _myStringProperty = "test";

[property: JsonInclude]
[DataMember]
[Reactive(Inheritance = InheritanceModifier.Virtual, SetModifier = AccessModifier.Protected)]
private string? _name;

/// <summary>
/// Initializes a new instance of the <see cref="TestViewModel"/> class.
/// </summary>
Expand Down
22 changes: 22 additions & 0 deletions src/ReactiveUI.SourceGenerators/AttributeDefinitions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,17 @@ internal enum AccessModifier
InternalProtected,
PrivateProtected,
}

/// <summary>
/// InheritanceModifier.
/// </summary>
internal enum InheritanceModifier
{
None,
Virtual,
Override,
New,
}
#nullable restore
#pragma warning restore
""";
Expand Down Expand Up @@ -105,6 +116,12 @@ internal sealed class ReactiveCommandAttribute : Attribute

public const string ReactiveAttributeType = "ReactiveUI.SourceGenerators.ReactiveAttribute";

/// <summary>
/// Gets the reactive attribute.
/// </summary>
/// <value>
/// The reactive attribute.
/// </value>
public static string ReactiveAttribute => $$"""
// Copyright (c) {{DateTime.Now.Year}} .NET Foundation and Contributors. All rights reserved.
// Licensed to the .NET Foundation under one or more agreements.
Expand Down Expand Up @@ -133,6 +150,11 @@ internal sealed class ReactiveAttribute : Attribute
/// The AccessModifier of the set property.
/// </value>
public AccessModifier SetModifier { get; init; }

/// <summary>
/// Gets the InheritanceModifier of the property.
/// </sumary>
public InheritanceModifier Inheritance { get; init; }
}
#nullable restore
#pragma warning restore
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,16 @@ public sealed partial class ObservableAsPropertyGenerator
// Get the can PropertyName member, if any
attributeData.TryGetNamedArgument("ReadOnly", out bool? isReadonly);

// Get Inheritance value from the attribute
attributeData.TryGetNamedArgument("Inheritance", out int? inheritanceArgument);
var inheritance = inheritanceArgument switch
{
1 => " virtual",
2 => " override",
3 => " new",
_ => string.Empty,
};

token.ThrowIfCancellationRequested();

// Get the property type and name
Expand Down Expand Up @@ -198,7 +208,8 @@ public sealed partial class ObservableAsPropertyGenerator
isReferenceTypeOrUnconstraindTypeParameter,
includeMemberNotNullOnSetAccessor,
forwardedPropertyAttributes,
isReadonly == false ? string.Empty : "readonly"),
isReadonly == false ? string.Empty : "readonly",
inheritance),
builder.ToImmutable());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,5 @@ internal sealed record PropertyInfo(
bool IsReferenceTypeOrUnconstrainedTypeParameter,
bool IncludeMemberNotNullOnSetAccessor,
EquatableArray<string> ForwardedAttributes,
string AccessModifier);
string AccessModifier,
string Inheritance);
Loading

0 comments on commit 9c1feac

Please sign in to comment.