diff --git a/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPFromObservableGeneratorTests.FromObservableMethods#TestNs.TestVM.ObservableAsPropertyFromObservable.g.verified.cs b/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPFromObservableGeneratorTests.FromObservableMethods#TestNs.TestVM.ObservableAsPropertyFromObservable.g.verified.cs index aa5132a..91b55bc 100644 --- a/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPFromObservableGeneratorTests.FromObservableMethods#TestNs.TestVM.ObservableAsPropertyFromObservable.g.verified.cs +++ b/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPFromObservableGeneratorTests.FromObservableMethods#TestNs.TestVM.ObservableAsPropertyFromObservable.g.verified.cs @@ -8,7 +8,7 @@ namespace TestNs { /// - /// Partial class for the TestVM which contains ReactiveUI Reactive property initialization. + /// Partial class for the TestVM which contains ReactiveUI Observable As Property initialization. /// public partial class TestVM { diff --git a/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPFromObservableGeneratorTests.FromObservableMethodsWithName#TestNs.TestVM.ObservableAsPropertyFromObservable.g.verified.cs b/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPFromObservableGeneratorTests.FromObservableMethodsWithName#TestNs.TestVM.ObservableAsPropertyFromObservable.g.verified.cs index cef2427..05d3bb9 100644 --- a/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPFromObservableGeneratorTests.FromObservableMethodsWithName#TestNs.TestVM.ObservableAsPropertyFromObservable.g.verified.cs +++ b/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPFromObservableGeneratorTests.FromObservableMethodsWithName#TestNs.TestVM.ObservableAsPropertyFromObservable.g.verified.cs @@ -8,7 +8,7 @@ namespace TestNs { /// - /// Partial class for the TestVM which contains ReactiveUI Reactive property initialization. + /// Partial class for the TestVM which contains ReactiveUI Observable As Property initialization. /// public partial class TestVM { diff --git a/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPFromObservableGeneratorTests.FromObservableProp#TestNs.TestVM.ObservableAsPropertyFromObservable.g.verified.cs b/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPFromObservableGeneratorTests.FromObservableProp#TestNs.TestVM.ObservableAsPropertyFromObservable.g.verified.cs index 16efb69..701c79b 100644 --- a/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPFromObservableGeneratorTests.FromObservableProp#TestNs.TestVM.ObservableAsPropertyFromObservable.g.verified.cs +++ b/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPFromObservableGeneratorTests.FromObservableProp#TestNs.TestVM.ObservableAsPropertyFromObservable.g.verified.cs @@ -8,7 +8,7 @@ namespace TestNs { /// - /// Partial class for the TestVM which contains ReactiveUI Reactive property initialization. + /// Partial class for the TestVM which contains ReactiveUI Observable As Property initialization. /// public partial class TestVM { diff --git a/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPFromObservableGeneratorTests.FromObservablePropNestedClasses#ReactiveUI.SourceGenerators.ObservableAsPropertyAttribute.g.verified.cs b/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPFromObservableGeneratorTests.FromObservablePropNestedClasses#ReactiveUI.SourceGenerators.ObservableAsPropertyAttribute.g.verified.cs new file mode 100644 index 0000000..d2a8739 --- /dev/null +++ b/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPFromObservableGeneratorTests.FromObservablePropNestedClasses#ReactiveUI.SourceGenerators.ObservableAsPropertyAttribute.g.verified.cs @@ -0,0 +1,38 @@ +//HintName: ReactiveUI.SourceGenerators.ObservableAsPropertyAttribute.g.cs +// Copyright (c) 2025 .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; + +// +#pragma warning disable +#nullable enable +namespace ReactiveUI.SourceGenerators; + +/// +/// ObservableAsPropertyAttribute. +/// +/// +[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] +internal sealed class ObservableAsPropertyAttribute : Attribute +{ + /// + /// Gets the name of the property. + /// + /// + /// The name of the property. + /// + public string? PropertyName { get; init; } + + /// + /// Gets the Readonly state of the OAPH property. + /// + /// + /// The is read only of the OAPH property. + /// + public bool ReadOnly { get; init; } = true; +} +#nullable restore +#pragma warning restore \ No newline at end of file diff --git a/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPFromObservableGeneratorTests.FromObservablePropNestedClasses#TestNs.TestVM+TestVMInner1.ObservableAsPropertyFromObservable.g.verified.cs b/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPFromObservableGeneratorTests.FromObservablePropNestedClasses#TestNs.TestVM+TestVMInner1.ObservableAsPropertyFromObservable.g.verified.cs new file mode 100644 index 0000000..6aa924a --- /dev/null +++ b/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPFromObservableGeneratorTests.FromObservablePropNestedClasses#TestNs.TestVM+TestVMInner1.ObservableAsPropertyFromObservable.g.verified.cs @@ -0,0 +1,37 @@ +//HintName: TestNs.TestVM+TestVMInner1.ObservableAsPropertyFromObservable.g.cs +// +using ReactiveUI; + +#pragma warning disable +#nullable enable + +namespace TestNs +{ + public partial class TestVM +{ +/// + /// Partial class for the TestVMInner1 which contains ReactiveUI Observable As Property initialization. + /// + public partial class TestVMInner1 + { + /// + private int _testIn1Property; + + /// + private ReactiveUI.ObservableAsPropertyHelper? _testIn1PropertyHelper; + + /// + [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] + public int TestIn1Property { get => _testIn1Property = _testIn1PropertyHelper?.Value ?? _testIn1Property; } + + [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] + protected void InitializeOAPH() + { + _testIn1PropertyHelper = TestIn1!.ToProperty(this, nameof(TestIn1Property)); + } + } +} + +} +#nullable restore +#pragma warning restore \ No newline at end of file diff --git a/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPFromObservableGeneratorTests.FromObservablePropNestedClasses#TestNs.TestVM+TestVMInner2+TestVMInner3.ObservableAsPropertyFromObservable.g.verified.cs b/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPFromObservableGeneratorTests.FromObservablePropNestedClasses#TestNs.TestVM+TestVMInner2+TestVMInner3.ObservableAsPropertyFromObservable.g.verified.cs new file mode 100644 index 0000000..7cad298 --- /dev/null +++ b/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPFromObservableGeneratorTests.FromObservablePropNestedClasses#TestNs.TestVM+TestVMInner2+TestVMInner3.ObservableAsPropertyFromObservable.g.verified.cs @@ -0,0 +1,40 @@ +//HintName: TestNs.TestVM+TestVMInner2+TestVMInner3.ObservableAsPropertyFromObservable.g.cs +// +using ReactiveUI; + +#pragma warning disable +#nullable enable + +namespace TestNs +{ + public partial class TestVM +{ +public partial class TestVMInner2 +{ +/// + /// Partial class for the TestVMInner3 which contains ReactiveUI Observable As Property initialization. + /// + public partial class TestVMInner3 + { + /// + private int _testIn3Property; + + /// + private ReactiveUI.ObservableAsPropertyHelper? _testIn3PropertyHelper; + + /// + [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] + public int TestIn3Property { get => _testIn3Property = _testIn3PropertyHelper?.Value ?? _testIn3Property; } + + [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] + protected void InitializeOAPH() + { + _testIn3PropertyHelper = TestIn3!.ToProperty(this, nameof(TestIn3Property)); + } + } +} +} + +} +#nullable restore +#pragma warning restore \ No newline at end of file diff --git a/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPFromObservableGeneratorTests.FromObservablePropNestedClasses#TestNs.TestVM+TestVMInner2.ObservableAsPropertyFromObservable.g.verified.cs b/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPFromObservableGeneratorTests.FromObservablePropNestedClasses#TestNs.TestVM+TestVMInner2.ObservableAsPropertyFromObservable.g.verified.cs new file mode 100644 index 0000000..809dcd9 --- /dev/null +++ b/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPFromObservableGeneratorTests.FromObservablePropNestedClasses#TestNs.TestVM+TestVMInner2.ObservableAsPropertyFromObservable.g.verified.cs @@ -0,0 +1,37 @@ +//HintName: TestNs.TestVM+TestVMInner2.ObservableAsPropertyFromObservable.g.cs +// +using ReactiveUI; + +#pragma warning disable +#nullable enable + +namespace TestNs +{ + public partial class TestVM +{ +/// + /// Partial class for the TestVMInner2 which contains ReactiveUI Observable As Property initialization. + /// + public partial class TestVMInner2 + { + /// + private int _testIn2Property; + + /// + private ReactiveUI.ObservableAsPropertyHelper? _testIn2PropertyHelper; + + /// + [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] + public int TestIn2Property { get => _testIn2Property = _testIn2PropertyHelper?.Value ?? _testIn2Property; } + + [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] + protected void InitializeOAPH() + { + _testIn2PropertyHelper = TestIn2!.ToProperty(this, nameof(TestIn2Property)); + } + } +} + +} +#nullable restore +#pragma warning restore \ No newline at end of file diff --git a/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPFromObservableGeneratorTests.FromObservablePropNestedClasses#TestNs.TestVM.ObservableAsPropertyFromObservable.g.verified.cs b/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPFromObservableGeneratorTests.FromObservablePropNestedClasses#TestNs.TestVM.ObservableAsPropertyFromObservable.g.verified.cs new file mode 100644 index 0000000..701c79b --- /dev/null +++ b/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPFromObservableGeneratorTests.FromObservablePropNestedClasses#TestNs.TestVM.ObservableAsPropertyFromObservable.g.verified.cs @@ -0,0 +1,33 @@ +//HintName: TestNs.TestVM.ObservableAsPropertyFromObservable.g.cs +// +using ReactiveUI; + +#pragma warning disable +#nullable enable + +namespace TestNs +{ + /// + /// Partial class for the TestVM which contains ReactiveUI Observable As Property initialization. + /// + public partial class TestVM + { + /// + private int _test1Property; + + /// + private ReactiveUI.ObservableAsPropertyHelper? _test1PropertyHelper; + + /// + [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] + public int Test1Property { get => _test1Property = _test1PropertyHelper?.Value ?? _test1Property; } + + [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] + protected void InitializeOAPH() + { + _test1PropertyHelper = Test1!.ToProperty(this, nameof(Test1Property)); + } + } +} +#nullable restore +#pragma warning restore \ No newline at end of file diff --git a/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPFromObservableGeneratorTests.FromObservablePropertiesWithAttribute#TestNs.TestVM.ObservableAsPropertyFromObservable.g.verified.cs b/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPFromObservableGeneratorTests.FromObservablePropertiesWithAttribute#TestNs.TestVM.ObservableAsPropertyFromObservable.g.verified.cs index 844a6e7..ac0b780 100644 --- a/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPFromObservableGeneratorTests.FromObservablePropertiesWithAttribute#TestNs.TestVM.ObservableAsPropertyFromObservable.g.verified.cs +++ b/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPFromObservableGeneratorTests.FromObservablePropertiesWithAttribute#TestNs.TestVM.ObservableAsPropertyFromObservable.g.verified.cs @@ -8,7 +8,7 @@ namespace TestNs { /// - /// Partial class for the TestVM which contains ReactiveUI Reactive property initialization. + /// Partial class for the TestVM which contains ReactiveUI Observable As Property initialization. /// public partial class TestVM { diff --git a/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPFromObservableGeneratorTests.FromObservablePropertiesWithAttributeNullableRef#TestNs.TestVM.ObservableAsPropertyFromObservable.g.verified.cs b/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPFromObservableGeneratorTests.FromObservablePropertiesWithAttributeNullableRef#TestNs.TestVM.ObservableAsPropertyFromObservable.g.verified.cs index bbb3b49..a140e04 100644 --- a/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPFromObservableGeneratorTests.FromObservablePropertiesWithAttributeNullableRef#TestNs.TestVM.ObservableAsPropertyFromObservable.g.verified.cs +++ b/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPFromObservableGeneratorTests.FromObservablePropertiesWithAttributeNullableRef#TestNs.TestVM.ObservableAsPropertyFromObservable.g.verified.cs @@ -8,7 +8,7 @@ namespace TestNs { /// - /// Partial class for the TestVM which contains ReactiveUI Reactive property initialization. + /// Partial class for the TestVM which contains ReactiveUI Observable As Property initialization. /// public partial class TestVM { diff --git a/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPFromObservableGeneratorTests.FromObservablePropertiesWithAttributeRef#TestNs.TestVM.ObservableAsPropertyFromObservable.g.verified.cs b/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPFromObservableGeneratorTests.FromObservablePropertiesWithAttributeRef#TestNs.TestVM.ObservableAsPropertyFromObservable.g.verified.cs index de44028..c480a82 100644 --- a/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPFromObservableGeneratorTests.FromObservablePropertiesWithAttributeRef#TestNs.TestVM.ObservableAsPropertyFromObservable.g.verified.cs +++ b/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPFromObservableGeneratorTests.FromObservablePropertiesWithAttributeRef#TestNs.TestVM.ObservableAsPropertyFromObservable.g.verified.cs @@ -8,7 +8,7 @@ namespace TestNs { /// - /// Partial class for the TestVM which contains ReactiveUI Reactive property initialization. + /// Partial class for the TestVM which contains ReactiveUI Observable As Property initialization. /// public partial class TestVM { diff --git a/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPFromObservableGeneratorTests.FromObservablePropertiesWithName#TestNs.TestVM.ObservableAsPropertyFromObservable.g.verified.cs b/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPFromObservableGeneratorTests.FromObservablePropertiesWithName#TestNs.TestVM.ObservableAsPropertyFromObservable.g.verified.cs index 38ea77f..ff99053 100644 --- a/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPFromObservableGeneratorTests.FromObservablePropertiesWithName#TestNs.TestVM.ObservableAsPropertyFromObservable.g.verified.cs +++ b/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPFromObservableGeneratorTests.FromObservablePropertiesWithName#TestNs.TestVM.ObservableAsPropertyFromObservable.g.verified.cs @@ -8,7 +8,7 @@ namespace TestNs { /// - /// Partial class for the TestVM which contains ReactiveUI Reactive property initialization. + /// Partial class for the TestVM which contains ReactiveUI Observable As Property initialization. /// public partial class TestVM { diff --git a/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPGeneratorTests.FromField#TestNs.TestVM.ObservableAsProperties.g.verified.cs b/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPGeneratorTests.FromField#TestNs.TestVM.ObservableAsProperties.g.verified.cs index d5e0448..869b1d5 100644 --- a/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPGeneratorTests.FromField#TestNs.TestVM.ObservableAsProperties.g.verified.cs +++ b/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPGeneratorTests.FromField#TestNs.TestVM.ObservableAsProperties.g.verified.cs @@ -4,7 +4,9 @@ #nullable enable namespace TestNs { - /// + /// + /// Partial class for the TestVM which contains ReactiveUI Observable As Property initialization. + /// public partial class TestVM { /// diff --git a/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPGeneratorTests.FromFieldNestedClass#ReactiveUI.SourceGenerators.ObservableAsPropertyAttribute.g.verified.cs b/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPGeneratorTests.FromFieldNestedClass#ReactiveUI.SourceGenerators.ObservableAsPropertyAttribute.g.verified.cs new file mode 100644 index 0000000..d2a8739 --- /dev/null +++ b/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPGeneratorTests.FromFieldNestedClass#ReactiveUI.SourceGenerators.ObservableAsPropertyAttribute.g.verified.cs @@ -0,0 +1,38 @@ +//HintName: ReactiveUI.SourceGenerators.ObservableAsPropertyAttribute.g.cs +// Copyright (c) 2025 .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; + +// +#pragma warning disable +#nullable enable +namespace ReactiveUI.SourceGenerators; + +/// +/// ObservableAsPropertyAttribute. +/// +/// +[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property | AttributeTargets.Method, AllowMultiple = false, Inherited = false)] +internal sealed class ObservableAsPropertyAttribute : Attribute +{ + /// + /// Gets the name of the property. + /// + /// + /// The name of the property. + /// + public string? PropertyName { get; init; } + + /// + /// Gets the Readonly state of the OAPH property. + /// + /// + /// The is read only of the OAPH property. + /// + public bool ReadOnly { get; init; } = true; +} +#nullable restore +#pragma warning restore \ No newline at end of file diff --git a/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPGeneratorTests.FromFieldNestedClass#TestNs.TestVM+TestVMInner1.ObservableAsProperties.g.verified.cs b/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPGeneratorTests.FromFieldNestedClass#TestNs.TestVM+TestVMInner1.ObservableAsProperties.g.verified.cs new file mode 100644 index 0000000..92c2804 --- /dev/null +++ b/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPGeneratorTests.FromFieldNestedClass#TestNs.TestVM+TestVMInner1.ObservableAsProperties.g.verified.cs @@ -0,0 +1,25 @@ +//HintName: TestNs.TestVM+TestVMInner1.ObservableAsProperties.g.cs +// +#pragma warning disable +#nullable enable +namespace TestNs +{ + public partial class TestVM +{ +/// + /// Partial class for the TestVMInner1 which contains ReactiveUI Observable As Property initialization. + /// + public partial class TestVMInner1 + { + /// + private readonly ReactiveUI.ObservableAsPropertyHelper _testIn1Helper; + + /// + [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] + public int TestIn1 { get => _testIn1 = _testIn1Helper?.Value ?? _testIn1; } + } +} + +} +#nullable restore +#pragma warning restore \ No newline at end of file diff --git a/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPGeneratorTests.FromFieldNestedClass#TestNs.TestVM+TestVMInner2+TestVMInner3.ObservableAsProperties.g.verified.cs b/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPGeneratorTests.FromFieldNestedClass#TestNs.TestVM+TestVMInner2+TestVMInner3.ObservableAsProperties.g.verified.cs new file mode 100644 index 0000000..7e2f0fc --- /dev/null +++ b/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPGeneratorTests.FromFieldNestedClass#TestNs.TestVM+TestVMInner2+TestVMInner3.ObservableAsProperties.g.verified.cs @@ -0,0 +1,28 @@ +//HintName: TestNs.TestVM+TestVMInner2+TestVMInner3.ObservableAsProperties.g.cs +// +#pragma warning disable +#nullable enable +namespace TestNs +{ + public partial class TestVM +{ +public partial class TestVMInner2 +{ +/// + /// Partial class for the TestVMInner3 which contains ReactiveUI Observable As Property initialization. + /// + public partial class TestVMInner3 + { + /// + private readonly ReactiveUI.ObservableAsPropertyHelper _testIn3Helper; + + /// + [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] + public int TestIn3 { get => _testIn3 = _testIn3Helper?.Value ?? _testIn3; } + } +} +} + +} +#nullable restore +#pragma warning restore \ No newline at end of file diff --git a/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPGeneratorTests.FromFieldNestedClass#TestNs.TestVM+TestVMInner2.ObservableAsProperties.g.verified.cs b/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPGeneratorTests.FromFieldNestedClass#TestNs.TestVM+TestVMInner2.ObservableAsProperties.g.verified.cs new file mode 100644 index 0000000..31f2189 --- /dev/null +++ b/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPGeneratorTests.FromFieldNestedClass#TestNs.TestVM+TestVMInner2.ObservableAsProperties.g.verified.cs @@ -0,0 +1,25 @@ +//HintName: TestNs.TestVM+TestVMInner2.ObservableAsProperties.g.cs +// +#pragma warning disable +#nullable enable +namespace TestNs +{ + public partial class TestVM +{ +/// + /// Partial class for the TestVMInner2 which contains ReactiveUI Observable As Property initialization. + /// + public partial class TestVMInner2 + { + /// + private readonly ReactiveUI.ObservableAsPropertyHelper _testIn2Helper; + + /// + [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] + public int TestIn2 { get => _testIn2 = _testIn2Helper?.Value ?? _testIn2; } + } +} + +} +#nullable restore +#pragma warning restore \ No newline at end of file diff --git a/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPGeneratorTests.FromFieldNestedClass#TestNs.TestVM.ObservableAsProperties.g.verified.cs b/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPGeneratorTests.FromFieldNestedClass#TestNs.TestVM.ObservableAsProperties.g.verified.cs new file mode 100644 index 0000000..869b1d5 --- /dev/null +++ b/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPGeneratorTests.FromFieldNestedClass#TestNs.TestVM.ObservableAsProperties.g.verified.cs @@ -0,0 +1,21 @@ +//HintName: TestNs.TestVM.ObservableAsProperties.g.cs +// +#pragma warning disable +#nullable enable +namespace TestNs +{ + /// + /// Partial class for the TestVM which contains ReactiveUI Observable As Property initialization. + /// + public partial class TestVM + { + /// + private readonly ReactiveUI.ObservableAsPropertyHelper _test1Helper; + + /// + [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] + public int Test1 { get => _test1 = _test1Helper?.Value ?? _test1; } + } +} +#nullable restore +#pragma warning restore \ No newline at end of file diff --git a/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPGeneratorTests.NamedFromField#TestNs.TestVM.ObservableAsProperties.g.verified.cs b/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPGeneratorTests.NamedFromField#TestNs.TestVM.ObservableAsProperties.g.verified.cs index 175406b..da4cef1 100644 --- a/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPGeneratorTests.NamedFromField#TestNs.TestVM.ObservableAsProperties.g.verified.cs +++ b/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPGeneratorTests.NamedFromField#TestNs.TestVM.ObservableAsProperties.g.verified.cs @@ -4,7 +4,9 @@ #nullable enable namespace TestNs { - /// + /// + /// Partial class for the TestVM which contains ReactiveUI Observable As Property initialization. + /// public partial class TestVM { /// diff --git a/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPGeneratorTests.NonReadOnlyFromField#TestNs.TestVM.ObservableAsProperties.g.verified.cs b/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPGeneratorTests.NonReadOnlyFromField#TestNs.TestVM.ObservableAsProperties.g.verified.cs index 175406b..da4cef1 100644 --- a/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPGeneratorTests.NonReadOnlyFromField#TestNs.TestVM.ObservableAsProperties.g.verified.cs +++ b/src/ReactiveUI.SourceGenerator.Tests/OAPH/OAPGeneratorTests.NonReadOnlyFromField#TestNs.TestVM.ObservableAsProperties.g.verified.cs @@ -4,7 +4,9 @@ #nullable enable namespace TestNs { - /// + /// + /// Partial class for the TestVM which contains ReactiveUI Observable As Property initialization. + /// public partial class TestVM { /// diff --git a/src/ReactiveUI.SourceGenerator.Tests/REACTIVE/ReactiveGeneratorTests.FromReactivePropertiesWithNestedClass#TestNs1.TestViewModel3+TestInnerClass1.Properties.g.verified.cs b/src/ReactiveUI.SourceGenerator.Tests/REACTIVE/ReactiveGeneratorTests.FromReactivePropertiesWithNestedClass#TestNs1.TestViewModel3+TestInnerClass1.Properties.g.verified.cs index 0ba3a48..c6a03c8 100644 --- a/src/ReactiveUI.SourceGenerator.Tests/REACTIVE/ReactiveGeneratorTests.FromReactivePropertiesWithNestedClass#TestNs1.TestViewModel3+TestInnerClass1.Properties.g.verified.cs +++ b/src/ReactiveUI.SourceGenerator.Tests/REACTIVE/ReactiveGeneratorTests.FromReactivePropertiesWithNestedClass#TestNs1.TestViewModel3+TestInnerClass1.Properties.g.verified.cs @@ -22,7 +22,6 @@ public int TestInner1 [global::System.Diagnostics.CodeAnalysis.MemberNotNull("_testInner1")] set => this.RaiseAndSetIfChanged(ref _testInner1, value); } - /// [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] public int TestInner11 diff --git a/src/ReactiveUI.SourceGenerator.Tests/REACTIVE/ReactiveGeneratorTests.FromReactivePropertiesWithNestedClass#TestNs1.TestViewModel3+TestInnerClass2+TestInnerClass3.Properties.g.verified.cs b/src/ReactiveUI.SourceGenerator.Tests/REACTIVE/ReactiveGeneratorTests.FromReactivePropertiesWithNestedClass#TestNs1.TestViewModel3+TestInnerClass2+TestInnerClass3.Properties.g.verified.cs index 7351928..d0bdca0 100644 --- a/src/ReactiveUI.SourceGenerator.Tests/REACTIVE/ReactiveGeneratorTests.FromReactivePropertiesWithNestedClass#TestNs1.TestViewModel3+TestInnerClass2+TestInnerClass3.Properties.g.verified.cs +++ b/src/ReactiveUI.SourceGenerator.Tests/REACTIVE/ReactiveGeneratorTests.FromReactivePropertiesWithNestedClass#TestNs1.TestViewModel3+TestInnerClass2+TestInnerClass3.Properties.g.verified.cs @@ -24,7 +24,6 @@ public int TestInner3 [global::System.Diagnostics.CodeAnalysis.MemberNotNull("_testInner3")] set => this.RaiseAndSetIfChanged(ref _testInner3, value); } - /// [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] public int TestInner33 diff --git a/src/ReactiveUI.SourceGenerator.Tests/REACTIVE/ReactiveGeneratorTests.FromReactivePropertiesWithNestedClass#TestNs1.TestViewModel3+TestInnerClass2.Properties.g.verified.cs b/src/ReactiveUI.SourceGenerator.Tests/REACTIVE/ReactiveGeneratorTests.FromReactivePropertiesWithNestedClass#TestNs1.TestViewModel3+TestInnerClass2.Properties.g.verified.cs index 0fb3d63..6e4d188 100644 --- a/src/ReactiveUI.SourceGenerator.Tests/REACTIVE/ReactiveGeneratorTests.FromReactivePropertiesWithNestedClass#TestNs1.TestViewModel3+TestInnerClass2.Properties.g.verified.cs +++ b/src/ReactiveUI.SourceGenerator.Tests/REACTIVE/ReactiveGeneratorTests.FromReactivePropertiesWithNestedClass#TestNs1.TestViewModel3+TestInnerClass2.Properties.g.verified.cs @@ -22,7 +22,6 @@ public int TestInner2 [global::System.Diagnostics.CodeAnalysis.MemberNotNull("_testInner2")] set => this.RaiseAndSetIfChanged(ref _testInner2, value); } - /// [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] public int TestInner22 diff --git a/src/ReactiveUI.SourceGenerator.Tests/REACTIVE/ReactiveGeneratorTests.FromReactivePropertiesWithNestedClass#TestNs1.TestViewModel3.Properties.g.verified.cs b/src/ReactiveUI.SourceGenerator.Tests/REACTIVE/ReactiveGeneratorTests.FromReactivePropertiesWithNestedClass#TestNs1.TestViewModel3.Properties.g.verified.cs index 4cbdff3..3c4b0ee 100644 --- a/src/ReactiveUI.SourceGenerator.Tests/REACTIVE/ReactiveGeneratorTests.FromReactivePropertiesWithNestedClass#TestNs1.TestViewModel3.Properties.g.verified.cs +++ b/src/ReactiveUI.SourceGenerator.Tests/REACTIVE/ReactiveGeneratorTests.FromReactivePropertiesWithNestedClass#TestNs1.TestViewModel3.Properties.g.verified.cs @@ -20,7 +20,6 @@ public float TestVM3Property [global::System.Diagnostics.CodeAnalysis.MemberNotNull("_testVM3Property")] set => this.RaiseAndSetIfChanged(ref _testVM3Property, value); } - /// [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] public float TestVM3Property2 diff --git a/src/ReactiveUI.SourceGenerator.Tests/UnitTests/OAPFromObservableGeneratorTests.cs b/src/ReactiveUI.SourceGenerator.Tests/UnitTests/OAPFromObservableGeneratorTests.cs index 2ab6723..a1c328d 100644 --- a/src/ReactiveUI.SourceGenerator.Tests/UnitTests/OAPFromObservableGeneratorTests.cs +++ b/src/ReactiveUI.SourceGenerator.Tests/UnitTests/OAPFromObservableGeneratorTests.cs @@ -41,6 +41,51 @@ public partial class TestVM : ReactiveObject return TestHelper.TestPass(sourceCode); } + /// + /// Tests that the source generator correctly generates observable properties. + /// + /// A task to monitor the async. + [Fact] + public Task FromObservablePropNestedClasses() + { + // Arrange: Setup the source code that matches the generator input expectations. + const string sourceCode = """ + using System; + using ReactiveUI; + using ReactiveUI.SourceGenerators; + using System.Reactive.Linq; + + namespace TestNs; + + public partial class TestVM : ReactiveObject + { + [ObservableAsProperty] + public IObservable Test1 => Observable.Return(42); + + public partial class TestVMInner1 : ReactiveObject + { + [ObservableAsProperty] + public IObservable TestIn1 => Observable.Return(42); + } + + public partial class TestVMInner2 : ReactiveObject + { + [ObservableAsProperty] + public IObservable TestIn2 => Observable.Return(42); + + public partial class TestVMInner3 : ReactiveObject + { + [ObservableAsProperty] + public IObservable TestIn3 => Observable.Return(42); + } + } + } + """; + + // Act: Initialize the helper and run the generator. Assert: Verify the generated code. + return TestHelper.TestPass(sourceCode); + } + /// /// Tests that the source generator correctly generates observable properties. /// diff --git a/src/ReactiveUI.SourceGenerator.Tests/UnitTests/OAPGeneratorTests.cs b/src/ReactiveUI.SourceGenerator.Tests/UnitTests/OAPGeneratorTests.cs index 0e2f920..a2dc0bc 100644 --- a/src/ReactiveUI.SourceGenerator.Tests/UnitTests/OAPGeneratorTests.cs +++ b/src/ReactiveUI.SourceGenerator.Tests/UnitTests/OAPGeneratorTests.cs @@ -41,6 +41,51 @@ public partial class TestVM : ReactiveObject return TestHelper.TestPass(sourceCode); } + /// + /// Tests that the source generator correctly generates observable properties. + /// + /// A task to monitor the async. + [Fact] + public Task FromFieldNestedClass() + { + // Arrange: Setup the source code that matches the generator input expectations. + const string sourceCode = """ + using System; + using ReactiveUI; + using ReactiveUI.SourceGenerators; + using System.Reactive.Linq; + + namespace TestNs; + + public partial class TestVM : ReactiveObject + { + [ObservableAsProperty] + private int _test1 = 10; + + public partial class TestVMInner1 : ReactiveObject + { + [ObservableAsProperty] + private int _testIn1 = 10; + } + + public partial class TestVMInner2 : ReactiveObject + { + [ObservableAsProperty] + private int _testIn2 = 10; + + public partial class TestVMInner3 : ReactiveObject + { + [ObservableAsProperty] + private int _testIn3 = 10; + } + } + } + """; + + // Act: Initialize the helper and run the generator. Assert: Verify the generated code. + return TestHelper.TestPass(sourceCode); + } + /// /// Tests that the source generator correctly generates observable properties. /// diff --git a/src/ReactiveUI.SourceGenerators/Core/Models/TargetInfo.cs b/src/ReactiveUI.SourceGenerators/Core/Models/TargetInfo.cs index b703c19..f93c833 100644 --- a/src/ReactiveUI.SourceGenerators/Core/Models/TargetInfo.cs +++ b/src/ReactiveUI.SourceGenerators/Core/Models/TargetInfo.cs @@ -42,7 +42,20 @@ public static TargetInfo From(INamedTypeSymbol namedTypeSymbol) parentInfo); } - public static void GetParentClasses(List parentClassDeclarations, TargetInfo? targetInfo) + public static (string Declarations, string ClosingBrackets) GenerateParentClassDeclarations(TargetInfo?[] targetInfos) + { + var parentClassDeclarations = new List(); + foreach (var targetInfo in targetInfos) + { + GetParentClasses(parentClassDeclarations, targetInfo); + } + + var parentClassDeclarationsString = GenerateParentClassDeclarations(parentClassDeclarations); + var closingBrackets = GenerateClosingBrackets(parentClassDeclarations.Count); + return (parentClassDeclarationsString, closingBrackets); + } + + private static void GetParentClasses(List parentClassDeclarations, TargetInfo? targetInfo) { if (targetInfo is not null) { @@ -62,7 +75,7 @@ public static void GetParentClasses(List parentClassDeclarations, Target } } - public static string GenerateParentClassDeclarations(List parentClassDeclarations) + private static string GenerateParentClassDeclarations(List parentClassDeclarations) { // Reverse the list to get the parent classes in the correct order parentClassDeclarations.Reverse(); @@ -77,7 +90,7 @@ public static string GenerateParentClassDeclarations(List parentClassDec return parentClassDeclarationsString; } - public static string GenerateClosingBrackets(int numberOfBrackets) + private static string GenerateClosingBrackets(int numberOfBrackets) { var closingBrackets = new string('}', numberOfBrackets); closingBrackets = closingBrackets.Replace("}", "}\n"); diff --git a/src/ReactiveUI.SourceGenerators/ObservableAsProperty/ObservableAsPropertyGenerator{FromField}.Execute.cs b/src/ReactiveUI.SourceGenerators/ObservableAsProperty/ObservableAsPropertyGenerator{FromField}.Execute.cs index cf3a244..fa52b26 100644 --- a/src/ReactiveUI.SourceGenerators/ObservableAsProperty/ObservableAsPropertyGenerator{FromField}.Execute.cs +++ b/src/ReactiveUI.SourceGenerators/ObservableAsProperty/ObservableAsPropertyGenerator{FromField}.Execute.cs @@ -3,6 +3,7 @@ // 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.Collections.Generic; using System.Collections.Immutable; using System.Globalization; using System.Linq; @@ -210,7 +211,10 @@ public sealed partial class ObservableAsPropertyGenerator private static string GenerateSource(string containingTypeName, string containingNamespace, string containingClassVisibility, string containingType, ObservableFieldInfo[] properties) { - var propertyDeclarations = string.Join("\n\r", properties.Select(GetPropertySyntax)); + // Get Parent class details from properties.ParentInfo + var (parentClassDeclarationsString, closingBrackets) = TargetInfo.GenerateParentClassDeclarations(properties.Select(p => p.TargetInfo.ParentInfo).ToArray()); + + var classes = GenerateClassWithProperties(containingTypeName, containingNamespace, containingClassVisibility, containingType, properties); return $$""" // @@ -218,15 +222,37 @@ private static string GenerateSource(string containingTypeName, string containin #nullable enable namespace {{containingNamespace}} { - /// + {{parentClassDeclarationsString}}{{classes}}{{closingBrackets}} +} +#nullable restore +#pragma warning restore +"""; + } + + /// + /// Generates the source code. + /// + /// The contain type name. + /// The containing namespace. + /// The containing class visibility. + /// The containing type. + /// The properties. + /// The value. + private static string GenerateClassWithProperties(string containingTypeName, string containingNamespace, string containingClassVisibility, string containingType, ObservableFieldInfo[] properties) + { + // Includes 2 tabs from the property declarations so no need to add them here. + var propertyDeclarations = string.Join("\n", properties.Select(GetPropertySyntax)); + + return +$$""" +/// + /// Partial class for the {{containingTypeName}} which contains ReactiveUI Observable As Property initialization. + /// {{containingClassVisibility}} partial {{containingType}} {{containingTypeName}} { [global::System.CodeDom.Compiler.GeneratedCode("{{GeneratorName}}", "{{GeneratorVersion}}")] {{propertyDeclarations}} } -} -#nullable restore -#pragma warning restore """; } diff --git a/src/ReactiveUI.SourceGenerators/ObservableAsProperty/ObservableAsPropertyGenerator{FromObservable}.Execute.cs b/src/ReactiveUI.SourceGenerators/ObservableAsProperty/ObservableAsPropertyGenerator{FromObservable}.Execute.cs index e99a768..9ebc995 100644 --- a/src/ReactiveUI.SourceGenerators/ObservableAsProperty/ObservableAsPropertyGenerator{FromObservable}.Execute.cs +++ b/src/ReactiveUI.SourceGenerators/ObservableAsProperty/ObservableAsPropertyGenerator{FromObservable}.Execute.cs @@ -3,6 +3,7 @@ // 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.Collections.Generic; using System.Collections.Immutable; using System.Linq; using System.Threading; @@ -12,6 +13,7 @@ using ReactiveUI.SourceGenerators.Helpers; using ReactiveUI.SourceGenerators.Models; using ReactiveUI.SourceGenerators.ObservableAsProperty.Models; +using ReactiveUI.SourceGenerators.Reactive.Models; using static ReactiveUI.SourceGenerators.Diagnostics.DiagnosticDescriptors; namespace ReactiveUI.SourceGenerators; @@ -132,7 +134,10 @@ public sealed partial class ObservableAsPropertyGenerator private static string GenerateObservableSource(string containingTypeName, string containingNamespace, string containingClassVisibility, string containingType, ObservableMethodInfo[] properties) { - var propertyDeclarations = string.Join("\n\r ", properties.Select(GetPropertySyntax)); + // Get Parent class details from properties.ParentInfo + var (parentClassDeclarationsString, closingBrackets) = TargetInfo.GenerateParentClassDeclarations(properties.Select(p => p.TargetInfo.ParentInfo).ToArray()); + + var classes = GenerateClassWithProperties(containingTypeName, containingNamespace, containingClassVisibility, containingType, properties); return $$""" @@ -144,8 +149,31 @@ private static string GenerateObservableSource(string containingTypeName, string namespace {{containingNamespace}} { + {{parentClassDeclarationsString}}{{classes}}{{closingBrackets}} +} +#nullable restore +#pragma warning restore +"""; + } + /// - /// Partial class for the {{containingTypeName}} which contains ReactiveUI Reactive property initialization. + /// Generates the source code. + /// + /// The contain type name. + /// The containing namespace. + /// The containing class visibility. + /// The containing type. + /// The properties. + /// The value. + private static string GenerateClassWithProperties(string containingTypeName, string containingNamespace, string containingClassVisibility, string containingType, ObservableMethodInfo[] properties) + { + // Includes 2 tabs from the property declarations so no need to add them here. + var propertyDeclarations = string.Join("\n", properties.Select(GetPropertySyntax)); + + return +$$""" +/// + /// Partial class for the {{containingTypeName}} which contains ReactiveUI Observable As Property initialization. /// {{containingClassVisibility}} partial {{containingType}} {{containingTypeName}} { @@ -154,9 +182,6 @@ namespace {{containingNamespace}} {{GetPropertyInitiliser(properties)}} } -} -#nullable restore -#pragma warning restore """; } diff --git a/src/ReactiveUI.SourceGenerators/Reactive/ReactiveGenerator.Execute.cs b/src/ReactiveUI.SourceGenerators/Reactive/ReactiveGenerator.Execute.cs index 9163c6e..0f1786b 100644 --- a/src/ReactiveUI.SourceGenerators/Reactive/ReactiveGenerator.Execute.cs +++ b/src/ReactiveUI.SourceGenerators/Reactive/ReactiveGenerator.Execute.cs @@ -235,20 +235,10 @@ public sealed partial class ReactiveGenerator private static string GenerateSource(string containingTypeName, string containingNamespace, string containingClassVisibility, string containingType, PropertyInfo[] properties) { // Get Parent class details from properties.ParentInfo - var parentClassDeclarations = new List(); - foreach (var property in properties) - { - TargetInfo.GetParentClasses(parentClassDeclarations, property.TargetInfo.ParentInfo); - } - - // Generate the parent class declarations - var parentClassDeclarationsString = TargetInfo.GenerateParentClassDeclarations(parentClassDeclarations); + var (parentClassDeclarationsString, closingBrackets) = TargetInfo.GenerateParentClassDeclarations(properties.Select(p => p.TargetInfo.ParentInfo).ToArray()); var classes = GenerateClassWithProperties(containingTypeName, containingNamespace, containingClassVisibility, containingType, properties); - // Create closing brackets for parent classes - var closingBrackets = TargetInfo.GenerateClosingBrackets(parentClassDeclarations.Count); - return $$""" // @@ -278,7 +268,7 @@ namespace {{containingNamespace}} private static string GenerateClassWithProperties(string containingTypeName, string containingNamespace, string containingClassVisibility, string containingType, PropertyInfo[] properties) { // Includes 2 tabs from the property declarations so no need to add them here. - var propertyDeclarations = string.Join("\n\r", properties.Select(GetPropertySyntax)); + var propertyDeclarations = string.Join("\n", properties.Select(GetPropertySyntax)); return $$""" diff --git a/src/ReactiveUI.SourceGenerators/ReactiveCommand/ReactiveCommandGenerator.Execute.cs b/src/ReactiveUI.SourceGenerators/ReactiveCommand/ReactiveCommandGenerator.Execute.cs index db791a2..592186e 100644 --- a/src/ReactiveUI.SourceGenerators/ReactiveCommand/ReactiveCommandGenerator.Execute.cs +++ b/src/ReactiveUI.SourceGenerators/ReactiveCommand/ReactiveCommandGenerator.Execute.cs @@ -109,20 +109,10 @@ public partial class ReactiveCommandGenerator private static string GenerateSource(string containingTypeName, string containingNamespace, string containingClassVisibility, string containingType, CommandInfo[] commands) { // Get Parent class details from properties.ParentInfo - var parentClassDeclarations = new List(); - foreach (var command in commands) - { - TargetInfo.GetParentClasses(parentClassDeclarations, command.TargetInfo.ParentInfo); - } - - // Generate the parent class declarations - var parentClassDeclarationsString = TargetInfo.GenerateParentClassDeclarations(parentClassDeclarations); + var (parentClassDeclarationsString, closingBrackets) = TargetInfo.GenerateParentClassDeclarations(commands.Select(p => p.TargetInfo.ParentInfo).ToArray()); var classes = GenerateClassWithCommands(containingTypeName, containingNamespace, containingClassVisibility, containingType, commands); - // Create closing brackets for parent classes - var closingBrackets = TargetInfo.GenerateClosingBrackets(parentClassDeclarations.Count); - return $$""" // @@ -151,7 +141,7 @@ namespace {{containingNamespace}} private static string GenerateClassWithCommands(string containingTypeName, string containingNamespace, string containingClassVisibility, string containingType, CommandInfo[] commands) { // Includes 2 tabs from the property declarations so no need to add them here. - var commandDeclarations = string.Join("\n\r", commands.Select(GetCommandSyntax)); + var commandDeclarations = string.Join("\n", commands.Select(GetCommandSyntax)); return $$"""